Как преобразовать дату из Excel в 1С и избежать ошибок с пустыми значениями?

Программист 1С v8.3 (Управляемые формы)
← На главную

При работе с внешними данными, такими как файлы 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");

В этом примере:

  1. Мы получаем область табличного документа по координатам "R" (строка) и "C" (столбец). Формат(НомерСтроки, "ЧГ=0;") используется для корректного формирования строки с номером строки.
  2. Метод .ТекущаяОбласть.Текст извлекает текстовое содержимое ячейки.
  3. Полученные строковые значения присваиваются переменным ДатаСтрокой и ДатаСтрокой1. Согласно исходным данным, эти строки имеют формат "ДД.ММ.ГГГГ", например, "07.07.2024" или "17.07.2024".
  4. Для преобразования строки в значение типа Дата используется встроенная функция Дата(). Мы конкатенируем строковое представление даты с " 00:00:00", чтобы явно указать время, что повышает надежность преобразования.

Подробнее о функции Дата() в 1С

Функция Дата() в 1С является основной для создания значений типа Дата. Она достаточно гибка и может принимать различные форматы входных данных:

  1. Строка в локальном формате даты: Иногда функция Дата() может корректно обрабатывать строки с различными разделителями, например, "ДД.ММ.ГГГГ чч:мм:сс". Однако полагаться на это в полной мере может быть рискованно из-за возможной непоследовательности поведения в разных локалях или версиях платформы.
  2. Канонический вид "ГГГГММДДччммсс": Это наиболее надежный строковый формат, например, "20240717000000". Если вы можете привести входную строку к такому виду, это гарантирует корректное преобразование.
  3. Отдельные числовые компоненты: Функция Дата() также может конструировать дату из отдельных числовых компонентов: Дата(Год, Месяц, День, Час, Минута, Секунда). Этот метод является наиболее контролируемым, если у вас есть возможность разобрать строку даты на составляющие.

В нашем случае, когда Excel выдает строки типа "ДД.ММ.ГГГГ", добавление " 00:00:00" помогает 1С интерпретировать строку как дату с указанием времени, что часто стабилизирует процесс преобразования, как видно из примера Дата(ДатаСтрокой + " 00:00:00").

Столкнувшаяся проблема: "вылетает после 10 загруженных дат"

В процессе загрузки данных, как правило, все идет гладко для первых нескольких записей, но затем возникают ошибки. В данной ситуации, автор темы столкнулся с проблемой, когда импорт "вылетает после 10 загруженных дат". Это классический симптом того, что не все входные данные соответствуют ожидаемому формату или типу.

Первоначальная попытка упростить преобразование до ДатаНач = Дата(ДатаСтрокой); также приводила к ошибке, подтверждая, что функция Дата() более чувствительна к формату, когда время не указано явно, или к другим проблемам в самой строке.

Диагностика и выявление корневой причины

Ключевым шагом в решении подобных проблем является отладка. Мы настоятельно рекомендуем проверять значение переменной ДатаСтрокой непосредственно перед строкой преобразования (например, спр.ДатаНачала = Дата(ДатаСтрокой +" 00:00:00");) для того элемента, на котором происходит сбой. Для этого необходимо:

  1. Установить точку останова (брейкпоинт) на строке преобразования.
  2. Запустить обработку в режиме отладки.
  3. Когда выполнение остановится на брейкпоинте, проанализировать содержимое переменной ДатаСтрокой в окне "Табло" или "Значения".

В рассматриваемой ситуации, диагностика показала, что "в какой-то миг дата стала "" с типом строка". Это означает, что для 11-й (или любой другой, где произошел сбой) записи, ячейка Excel вернула не строковое представление даты, а пустую строку. Попытка преобразовать пустую строку в дату при помощи функции Дата() приводит к ошибке выполнения.

Дальнейшая проверка файла Excel подтвердила, что "в файле были не заполненные даты". Это и оказалось корневой причиной проблемы. Несмотря на первоначальные заявления, что "все строки заполнены датой", детальный анализ выявил пробелы в данных.

Эффективное решение и лучшие практики

Теперь, когда причина ясна, мы можем разработать надежное решение, которое будет устойчиво к пустым значениям и потенциальным ошибкам формата.

1. Проверка на заполненность перед преобразованием

Самый важный шаг — это всегда проверять, является ли строка даты непустой, прежде чем пытаться преобразовать ее в тип Дата. Это можно сделать с помощью простой проверки на пустую строку.

Пример кода с проверкой:


ДатаСтрокой = Строка(ТабДок.ПолучитьОбласть("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 секунд. Это значение используется по умолчанию для реквизитов типа "Дата", если явное значение не указано, и рекомендуется присваивать его в случае отсутствия даты из внешнего источника.

2. Более гибкие методы преобразования для нестандартных форматов

Хотя добавление " 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С, который предоставляет более гибкие возможности для форматирования и преобразования значений. Однако для прямого преобразования строки в дату объект Формат чаще используется для обратного действия – форматирования даты в строку. Для парсинга, как правило, более применимы методы, описанные выше или специализированные функции БСП.

3. Предварительная подготовка данных в Excel

Крайне важно максимально упрощать исходную таблицу Excel, избегая сложных макросов, формул и форматирования. Иногда, чтобы Excel корректно распознал даты и сохранил их в нужном формате, могут помочь простые операции непосредственно в Excel:

  1. "Найти и заменить": Например, если разделителем является тире вместо точки (07-07-2024), можно заменить все тире на точки.
  2. "Текст по столбцам": Эта функция Excel позволяет явно указать формат данных в столбце (например, "Дата ДМГ"), что помогает унифицировать представление даты перед выгрузкой.
  3. Явное форматирование ячеек: Убедитесь, что все ячейки с датами в Excel имеют текстовый формат или формат даты, который Excel корректно распознает. Иногда Excel может хранить дату как числовое значение (порядковый номер дня с 01.01.1900), что потребует дополнительной обработки.

Заключение

Преобразование дат из Excel в 1С является распространенной задачей, которая требует внимательности к деталям и понимания возможных ошибок. Как мы выяснили, самая частая проблема — это наличие пустых значений в исходном файле, что приводит к сбоям при попытке преобразования пустой строки в дату. Решение заключается в обязательном контроле на заполненность строкового значения перед его конвертацией в тип Дата, а также в использовании надежных методов преобразования, таких как Дата(СтрокаДаты + " 00:00:00") или специализированных функций БСП.

Мы настоятельно рекомендуем всегда проверять исходные данные в Excel на предмет их корректности и полноты, а также использовать инструменты отладки в 1С для выявления точной причины сбоев. Следуя этим рекомендациям, вы сможете значительно повысить надежность ваших механизмов импорта данных.

← На главную