При работе с внешними данными, такими как файлы Excel, часто возникает необходимость импортировать информацию в базу 1С. Одним из наиболее частых камней преткновения является корректное преобразование строковых представлений дат из Excel в тип Дата в 1С. В данной статье мы подробно рассмотрим, как выполнить это преобразование, а также выясним, какие нюансы и ошибки могут возникнуть на этом пути, и как их эффективно избежать.
Предположим, у нас есть табличный документ 1С, в который загружены данные из Excel, и нам необходимо извлечь из него строковые значения дат, которые выглядят как "ДД.ММ.ГГГГ", и преобразовать их в формат Дата, пригодный для записи в реквизиты объектов 1С.
Для начала, мы извлекаем текстовое значение ячейки табличного документа 1С. Предполагается, что данные уже считаны из Excel в объект ТабДок (например, ТабличныйДокумент). В нашем случае, мы хотим получить дату из определенной ячейки, используя ее координаты (строка и столбец).
Рассмотрим пример кода, который демонстрирует извлечение строкового значения даты из ячейки и его последующее преобразование:
ДатаСтрокой = Строка(ТабДок.ПолучитьОбласть("R" + Формат(НомерСтроки, "ЧГ=0;") + "C" + 4).ТекущаяОбласть.Текст);
ДатаСтрокой1 = Строка(ТабДок.ПолучитьОбласть("R" + Формат(НомерСтроки, "ЧГ=0") + "C" + 5).ТекущаяОбласть.Текст);
// Преобразование строковых дат в тип Дата
спр.ДатаНачала = Дата(ДатаСтрокой + " 00:00:00");
спр.ДатаОкончания = Дата(ДатаСтрокой1 + " 00:00:00");
В этом примере:
Формат(НомерСтроки, "ЧГ=0;") используется для корректного формирования строки с номером строки..ТекущаяОбласть.Текст извлекает текстовое содержимое ячейки.ДатаСтрокой и ДатаСтрокой1. Согласно исходным данным, эти строки имеют формат "ДД.ММ.ГГГГ", например, "07.07.2024" или "17.07.2024".Дата используется встроенная функция Дата(). Мы конкатенируем строковое представление даты с " 00:00:00", чтобы явно указать время, что повышает надежность преобразования.Функция Дата() в 1С является основной для создания значений типа Дата. Она достаточно гибка и может принимать различные форматы входных данных:
Дата() может корректно обрабатывать строки с различными разделителями, например, "ДД.ММ.ГГГГ чч:мм:сс". Однако полагаться на это в полной мере может быть рискованно из-за возможной непоследовательности поведения в разных локалях или версиях платформы.Дата() также может конструировать дату из отдельных числовых компонентов: Дата(Год, Месяц, День, Час, Минута, Секунда). Этот метод является наиболее контролируемым, если у вас есть возможность разобрать строку даты на составляющие.В нашем случае, когда Excel выдает строки типа "ДД.ММ.ГГГГ", добавление " 00:00:00" помогает 1С интерпретировать строку как дату с указанием времени, что часто стабилизирует процесс преобразования, как видно из примера Дата(ДатаСтрокой + " 00:00:00").
В процессе загрузки данных, как правило, все идет гладко для первых нескольких записей, но затем возникают ошибки. В данной ситуации, автор темы столкнулся с проблемой, когда импорт "вылетает после 10 загруженных дат". Это классический симптом того, что не все входные данные соответствуют ожидаемому формату или типу.
Первоначальная попытка упростить преобразование до ДатаНач = Дата(ДатаСтрокой); также приводила к ошибке, подтверждая, что функция Дата() более чувствительна к формату, когда время не указано явно, или к другим проблемам в самой строке.
Ключевым шагом в решении подобных проблем является отладка. Мы настоятельно рекомендуем проверять значение переменной ДатаСтрокой непосредственно перед строкой преобразования (например, спр.ДатаНачала = Дата(ДатаСтрокой +" 00:00:00");) для того элемента, на котором происходит сбой. Для этого необходимо:
ДатаСтрокой в окне "Табло" или "Значения".В рассматриваемой ситуации, диагностика показала, что "в какой-то миг дата стала "" с типом строка". Это означает, что для 11-й (или любой другой, где произошел сбой) записи, ячейка Excel вернула не строковое представление даты, а пустую строку. Попытка преобразовать пустую строку в дату при помощи функции Дата() приводит к ошибке выполнения.
Дальнейшая проверка файла Excel подтвердила, что "в файле были не заполненные даты". Это и оказалось корневой причиной проблемы. Несмотря на первоначальные заявления, что "все строки заполнены датой", детальный анализ выявил пробелы в данных.
Теперь, когда причина ясна, мы можем разработать надежное решение, которое будет устойчиво к пустым значениям и потенциальным ошибкам формата.
Самый важный шаг — это всегда проверять, является ли строка даты непустой, прежде чем пытаться преобразовать ее в тип Дата. Это можно сделать с помощью простой проверки на пустую строку.
Пример кода с проверкой:
ДатаСтрокой = Строка(ТабДок.ПолучитьОбласть("R" + Формат(НомерСтроки, "ЧГ=0;") + "C" + 4).ТекущаяОбласть.Текст);
Если ЗначениеЗаполнено(ДатаСтрокой) Тогда
спр.ДатаНачала = Дата(ДатаСтрокой + " 00:00:00");
Иначе
// Обработка пустой даты
// Можно установить пустую дату 1С (Дата(1,1,1)) или пропустить присвоение
спр.ДатаНачала = Дата(1,1,1); // Или Неопределено, в зависимости от логики
КонецЕсли;
ДатаСтрокой1 = Строка(ТабДок.ПолучитьОбласть("R" + Формат(НомерСтроки, "ЧГ=0") + "C" + 5).ТекущаяОбласть.Текст);
Если ЗначениеЗаполнено(ДатаСтрокой1) Тогда
спр.ДатаОкончания = Дата(ДатаСтрокой1 + " 00:00:00");
Иначе
спр.ДатаОкончания = Дата(1,1,1);
КонецЕсли;
Функция ЗначениеЗаполнено() возвращает Истина, если значение не является пустым (в данном случае, не является пустой строкой), и Ложь в противном случае. Таким образом, мы избегаем попытки преобразования пустой строки в дату.
В 1С "пустая дата" имеет специфическое значение: Дата(1,1,1) или '00010101000000', что соответствует 1 января 1 года 0 часов 0 минут 0 секунд. Это значение используется по умолчанию для реквизитов типа "Дата", если явное значение не указано, и рекомендуется присваивать его в случае отсутствия даты из внешнего источника.
Хотя добавление " 00:00:00" помогает в большинстве случаев с форматом "ДД.ММ.ГГГГ", для максимальной надежности, особенно при работе с разнообразными форматами дат из Excel, мы можем рассмотреть следующие подходы:
Если формат даты стабилен, но функция Дата() все равно "капризничает", вы можете вручную разобрать строку даты на составляющие (день, месяц, год) с помощью строковых функций (например, Лев(), Сред(), Прав()) и затем создать дату, используя Дата(Год, Месяц, День, Час, Минута, Секунда).
Рассмотрим пример, как это может быть реализовано для строки "07.07.2024":
Если ЗначениеЗаполнено(ДатаСтрокой) Тогда
ПозицияТочки1 = Найти(ДатаСтрокой, ".");
ПозицияТочки2 = Найти(ДатаСтрокой, ".", ПозицияТочки1 + 1);
Если ПозицияТочки1 > 0 И ПозицияТочки2 > 0 Тогда
День = Число(Лев(ДатаСтрокой, ПозицияТочки1 - 1));
Месяц = Число(Сред(ДатаСтрокой, ПозицияТочки1 + 1, ПозицияТочки2 - ПозицияТочки1 - 1));
Год = Число(Прав(ДатаСтрокой, СтрДлина(ДатаСтрокой) - ПозицияТочки2));
Если День > 0 И Месяц > 0 И Год > 0 Тогда
спр.ДатаНачала = Дата(Год, Месяц, День, 0, 0, 0);
Иначе
спр.ДатаНачала = Дата(1,1,1); // Некорректные числовые компоненты
КонецЕсли;
Иначе
спр.ДатаНачала = Дата(1,1,1); // Неверный формат строки
КонецЕсли;
Иначе
спр.ДатаНачала = Дата(1,1,1); // Пустая строка
КонецЕсли;
Этот метод более громоздкий, но предоставляет полный контроль над процессом парсинга и позволяет гибко обрабатывать различные форматы.
В типовых конфигурациях 1С часто присутствует функция СтрокаВДату() (или СтрокаВДатуВремя()) в общих модулях, которая позволяет преобразовывать строку в дату с указанием ожидаемого формата (например, "dd.mm.yyyy"). Эта функция обеспечивает более надежное преобразование и может обрабатывать различные разделители и вариации формата, если она доступна в вашей конфигурации. Рекомендуется использовать ее, если она есть, так как она уже протестирована и содержит множество проверок.
Пример использования (псевдокод, так как точное название модуля и функции может варьироваться):
// Предположим, что функция доступна в общем модуле "РаботаСДатами"
спр.ДатаНачала = РаботаСДатами.СтрокаВДату(ДатаСтрокой, "ДД.ММ.ГГГГ");
Обратитесь к документации или коду вашей конфигурации 1С, чтобы найти аналогичные функции в общих модулях.
Для сложных и нестандартных представлений дат можно применять объект Формат в 1С, который предоставляет более гибкие возможности для форматирования и преобразования значений. Однако для прямого преобразования строки в дату объект Формат чаще используется для обратного действия – форматирования даты в строку. Для парсинга, как правило, более применимы методы, описанные выше или специализированные функции БСП.
Крайне важно максимально упрощать исходную таблицу Excel, избегая сложных макросов, формул и форматирования. Иногда, чтобы Excel корректно распознал даты и сохранил их в нужном формате, могут помочь простые операции непосредственно в Excel:
Преобразование дат из Excel в 1С является распространенной задачей, которая требует внимательности к деталям и понимания возможных ошибок. Как мы выяснили, самая частая проблема — это наличие пустых значений в исходном файле, что приводит к сбоям при попытке преобразования пустой строки в дату. Решение заключается в обязательном контроле на заполненность строкового значения перед его конвертацией в тип Дата, а также в использовании надежных методов преобразования, таких как Дата(СтрокаДаты + " 00:00:00") или специализированных функций БСП.
Мы настоятельно рекомендуем всегда проверять исходные данные в Excel на предмет их корректности и полноты, а также использовать инструменты отладки в 1С для выявления точной причины сбоев. Следуя этим рекомендациям, вы сможете значительно повысить надежность ваших механизмов импорта данных.