Как правильно импортировать данные типа Дата из CSV-файла в 1С 8?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При обмене данными между различными системами через текстовые форматы, такие как CSV, одной из наиболее частых проблем становится несовпадение форматов дат. Внутренний стандарт 1С требует определенной структуры (ГГГГММДДччммсс), в то время как в исходном файле дата может быть представлена как 02.12.1977, 1/5/80 или даже в виде числа. В этой статье мы подробно разберем, как преобразовать эти данные, рассмотрим классические и современные методы парсинга, а также обсудим подводные камни, связанные с кодировками и региональными настройками.

Метод 1: Ручной разбор строки с помощью функций Лев(), Прав() и Сред()

Рассмотрим ситуацию, когда дата в файле представлена в привычном российском формате ДД.ММ.ГГГГ (например, 02.12.1977). Конструктор Дата() в 1С при передаче строки ожидает формат без разделителей. Проанализируем, как можно «собрать» нужную строку из исходной.

Для этого мы воспользуемся функциями манипуляции строками. Нам нужно извлечь год, месяц и день, а затем соединить их в правильном порядке, добавив время (даже если оно нулевое). Разберем по шагам логику, предложенную нашими коллегами:

  1. Год: находится в конце строки (последние 4 символа). Используем функцию Прав(ИсходнаяДата, 4).
  2. Месяц: находится в середине, начиная с 4-го символа. Используем функцию Сред(ИсходнаяДата, 4, 2).
  3. День: находится в начале строки. Используем функцию Лев(ИсходнаяДата, 2).

Посмотрим на пример кода, который реализует эту логику:


// Предположим, Стр.Дата содержит "02.12.1977"
ИсходнаяДата = Стр.Дата; 
Если ЗначениеЗаполнено(ИсходнаяДата) Тогда
    // Собираем строку вида "19771202000000"
    СтрокаДляПреобразования = Прав(ИсходнаяДата, 4) + Сред(ИсходнаяДата, 4, 2) + Лев(ИсходнаяДата, 2) + "000000";
    ИтоговаяДата = Дата(СтрокаДляПреобразования);
КонецЕсли;

Важное замечание: этот метод отлично работает, если вы на 100% уверены в стабильности формата. Однако он «ломается», если в дате отсутствуют ведущие нули (например, 1.5.1980 вместо 01.05.1980), так как позиции символов смещаются.

Метод 2: Использование функции СтрРазделить() для универсального парсинга

Чтобы сделать код более устойчивым к разной длине частей даты, мы рекомендуем использовать функцию СтрРазделить(). Проанализируем ситуацию: части даты разделены точкой. Мы можем разбить строку в массив, и тогда нам не важно, сколько знаков в дне или месяце.

Рассмотрим пример реализации:


ИсходнаяСтрока = "2.12.1977"; // Дата без ведущего нуля
ЧастиДаты = СтрРазделить(ИсходнаяСтрока, ".");

Если ЧастиДаты.Количество() = 3 Тогда
    День   = Формат(Число(ЧастиДаты[0]), "ЧГ=0; ЧВН=");
    Месяц  = Формат(Число(ЧастиДаты[1]), "ЧГ=0; ЧВН=");
    Год    = Формат(Число(ЧастиДаты[2]), "ЧГ=0; ЧВН=");
    
    // Используем конструктор Дата(Год, Месяц, День)
    ИтоговаяДата = Дата(Год, Месяц, День);
КонецЕсли;

Этот способ гораздо надежнее, так как он корректно обрабатывает и 02.12.1977, и 2.12.1977.

Метод 3: Преобразование через международный стандарт и XML

Если данные в вашем CSV-файле следуют международному стандарту ГГГГ-ММ-ДД, то 1С предоставляет еще более быстрый способ импорта. Выясним, как использовать встроенные механизмы XML для этих целей. Функция XMLЗначение() работает на уровне платформы и крайне эффективно преобразует типизированные данные.

Посмотрим на пример:


// СтрДата в формате "1977-12-02"
ИтоговаяДата = XMLЗначение(Тип("Дата"), СтрДата);

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

Проблемы региональных настроек

Иногда встречается совет использовать простую склейку: Дата(Стр.Дата + " 00:00:00"). Мы должны предостеречь вас от этого подхода. Результат выполнения этой функции напрямую зависит от региональных настроек операционной системы.

Если на сервере, где выполняется код, установлены настройки США (MM/DD/YYYY), а в файле данные записаны по-русски (ДД.ММ.ГГГГ), система выдаст ошибку или, что еще хуже, перепутает день с месяцем. Поэтому явный ручной разбор строки, который мы рассмотрели выше, считается «золотым стандартом» для надежных решений.

Обработка пустых значений и формата Excel

Часто в CSV-файлах встречаются «пустые» даты. В текстовом виде это может быть пустая строка "" или несколько пробелов. Попытка применить функцию Дата() к такой строке вызовет исключение и остановку программы.

Разберем, как правильно обрабатывать такие случаи:


Если ПустаяСтрока(Стр.Дата) Тогда
    НовыйКлиент.ДатаРождения = '00010101'; // Пустая дата в 1С
Иначе
    // Тут выполняем один из методов парсинга
КонецЕсли;

Также стоит учитывать специфику Microsoft Excel. Если CSV-файл перед загрузкой открывали и сохраняли в Excel, программа могла автоматически преобразовать даты в числа (количество дней с 1900 года). В таком случае вместо 02.12.1977 в файле окажется число 28461.

Для пересчета такого числа обратно в дату используем следующую формулу:

Дата1С = Дата(1899, 12, 30) + ЧислоИзCSV * 86400;

Где 86400 — это количество секунд в сутках. Обратите внимание на базовую дату 30.12.1899, это связано с особенностями обработки високосных лет в ранних версиях табличных процессоров.

Кодировки и невидимые символы (BOM)

При чтении CSV-файла мы часто сталкиваемся с проблемой BOM (Byte Order Mark). Это невидимые символы в начале файла, которые указывают на кодировку UTF-8. Если начать читать первую строку файла обычным методом, эти символы попадут в первую ячейку (где может быть дата) и функция Лев() вернет мусор.

Чтобы избежать этого, всегда явно указывайте кодировку при открытии файла:

Текст = Новый ЧтениеТекста(ПутьКФайлу, КодировкаТекста.UTF8);

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

← На главную