Как правильно загрузить дату из текстового файла в таблицу значений 1С?

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

При разработке обменов данными или загрузок из внешних файлов часто возникает задача чтения информации из текстовых форматов (TXT, CSV). На первый взгляд, задача кажется тривиальной: прочитать строку, разделить её по запятым и записать в справочник. Однако начинающие разработчики часто сталкиваются с ситуацией, когда строковые данные (ФИО, Артикул) загружаются корректно, а даты (Дата рождения, Дата документа) остаются пустыми. Давайте разберем эту ситуацию подробно, выясним причины ошибки и напишем правильный код для загрузки.

Анализ проблемы: почему дата не загружается?

Рассмотрим исходный код, который вызвал проблему. Разработчик считывает файл построчно, разбивает строку на массив и пытается присвоить значение напрямую в колонку таблицы значений.


// Фрагмент кода с ошибкой
ЗначениеВКолонке = ТаблицаЗначений.Добавить();
ЗначениеВКолонке.ФИО = МассивСтрок[0];
ЗначениеВКолонке.ДатаРождения = МассивСтрок[1]; // Здесь происходит ошибка логики

В чем здесь подвох? Дело в типизации данных. В текстовом файле дата — это просто набор символов, например, "25/05/23" или "01.01.1990". Для платформы 1С это тип Строка.

Если колонка ДатаРождения в вашей таблице значений (или реквизит справочника, куда вы потом пишете данные) имеет тип Дата, то платформа не всегда может автоматически понять, как превратить набор символов "25/05/23" в конкретный момент времени. В результате преобразование не происходит, и в поле записывается "пустая дата" (01.01.0001 00:00:00), которую пользователь видит как пустое поле.

Чтобы исправить ситуацию, нам нужно взять на себя ответственность за парсинг (разбор) строки и явное приведение её к типу Дата.

Шаг 1: Правильное создание Таблицы Значений

Первое, что мы должны сделать — убедиться, что наша промежуточная ТаблицаЗначений знает, какие данные она хранит. В примере автора колонки добавляются без указания типа. Это плохая практика, так как ошибки типов всплывут только при записи в базу данных. Давайте определим типы явно.


ТаблицаЗначений = Новый ТаблицаЗначений;
ТаблицаЗначений.Колонки.Добавить("ФИО", Новый ОписаниеТипов("Строка", Новый КвалификаторыСтроки(150)));
ТаблицаЗначений.Колонки.Добавить("ДатаРождения", Новый ОписаниеТипов("Дата"));

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

Шаг 2: Очистка данных от лишнего мусора

В текстовых файлах часто встречаются невидимые проблемы: лишние пробелы в начале или конце строки. Например, вместо "01/01/2000" может прийти " 01/01/2000 ". Эти пробелы помешают преобразованию. Поэтому возьмем за правило всегда использовать функцию СокрЛП() (Сократить Лев Прав) при чтении данных.

СтрокаДаты = СокрЛП(МассивСтрок[1]);

Шаг 3: Преобразование Строки в Дату

Это самый важный этап. Допустим, в файле дата записана в формате ДД/ММ/ГГ (например, 25/12/99 или 25/12/2023). Платформа 1С имеет конструктор Дата(Год, Месяц, День). Наша задача — "вытащить" эти числа из строки.

Рассмотрим универсальный способ через разделение строки даты по разделителю (в данном случае слэш / или точка .).


// Предполагаем формат в файле: ДД/ММ/ГГГГ или ДД/ММ/ГГ
// Например: "25/12/2000"
МассивДаты = СтрРазделить(СтрокаДаты, "/"); 

Если МассивДаты.Количество() = 3 Тогда
    День   = Число(МассивДаты[0]);
    Месяц  = Число(МассивДаты[1]);
    ГодСтр = МассивДаты[2];
    
    // Обработка двухзначного года (если год указан как "23", а не "2023")
    Если СтрДлина(ГодСтр) = 2 Тогда
        // Простая логика: добавляем 2000. 
        // В реальных задачах может потребоваться логика определения века (19xx или 20xx)
        Год = 2000 + Число(ГодСтр);
    Иначе
        Год = Число(ГодСтр);
    КонецЕсли;

    // Создаем настоящую дату
    ИтоговаяДата = Дата(Год, Месяц, День);
Иначе
    // Обработка ошибки, если формат даты неверный
    ИтоговаяДата = Дата(1,1,1); // Пустая дата
КонецЕсли;

Шаг 4: Учет кодировки файла

Еще один момент, который часто упускают — кодировка. Если вы используете объект ТекстовыйДокумент или старый метод чтения, вы можете получить "кракозябры" вместо ФИО, если кодировка файла (например, UTF-8) не совпадает с тем, как его читает 1С (часто Windows-1251 по умолчанию). Для надежности используем объект ЧтениеТекста.

Итоговое решение: Полный код функции

Давайте соберем все рассмотренные нюансы в единую, готовую к работе функцию. Мы добавим обработку ошибок и корректный парсинг даты.


Функция ЗагрузитьСотрудниковИзФайла(ПутьКФайлу) Экспорт
    
    // 1. Создаем типизированную таблицу значений
    ТаблицаСотрудников = Новый ТаблицаЗначений;    
    ТаблицаСотрудников.Колонки.Добавить("ФИО", Новый ОписаниеТипов("Строка", Новый КвалификаторыСтроки(100)));
    ТаблицаСотрудников.Колонки.Добавить("ДатаРождения", Новый ОписаниеТипов("Дата",,, Новый КвалификаторыДаты(ЧастиДаты.Дата)));
    
    // 2. Открываем файл с учетом кодировки (попробуем UTF-8, или ANSI, зависит от файла)
    // Если кодировка неизвестна, можно попробовать не указывать второй параметр
    ФайлЧтения = Новый ЧтениеТекста(ПутьКФайлу, КодировкаТекста.ANSI); 
    
    Сч = 0;
    СтрокаТекста = ФайлЧтения.ПрочитатьСтроку();
    
    Пока СтрокаТекста <> Неопределено Цикл
        Сч = Сч + 1;
        
        // Пропускаем пустые строки
        Если ПустаяСтрока(СтрокаТекста) Тогда
            СтрокаТекста = ФайлЧтения.ПрочитатьСтроку();
            Продолжить;
        КонецЕсли;
        
        // 3. Разбираем строку по разделителю (запятая)
        МассивДанных = СтрРазделить(СтрокаТекста, ",");
        
        Если МассивДанных.Количество() >= 2 Тогда
            
            НоваяСтрока = ТаблицаСотрудников.Добавить();
            
            // Заполняем ФИО, убирая лишние пробелы
            НоваяСтрока.ФИО = СокрЛП(МассивДанных[0]);
            
            // 4. Парсим дату
            // Ожидаем формат в файле: ДД/ММ/ГГ или ДД/ММ/ГГГГ
            СтрокаДаты = СокрЛП(МассивДанных[1]);
            
            // Заменяем возможные точки или дефисы на слэш для унификации
            СтрокаДаты = СтрЗаменить(СтрокаДаты, ".", "/");
            СтрокаДаты = СтрЗаменить(СтрокаДаты, "-", "/");
            
            ЧастиДаты = СтрРазделить(СтрокаДаты, "/");
            
            Попытка
                Если ЧастиДаты.Количество() = 3 Тогда
                    День = Число(ЧастиДаты[0]);
                    Месяц = Число(ЧастиДаты[1]);
                    Год = Число(ЧастиДаты[2]);
                    
                    // Корректировка двухзначного года
                    Если Год < 100 Тогда
                        Год = 2000 + Год;
                    КонецЕсли;
                    
                    НоваяСтрока.ДатаРождения = Дата(Год, Месяц, День);
                Иначе
                     Сообщить("Ошибка формата даты в строке " + Сч + ": " + СтрокаДаты);
                КонецЕсли;
            Исключение
                Сообщить("Не удалось преобразовать дату в строке " + Сч);
            КонецПопытки;
            
        Иначе
            Сообщить("Некорректный формат строки №" + Сч);
        КонецЕсли;
        
        СтрокаТекста = ФайлЧтения.ПрочитатьСтроку();
    КонецЦикла;
    
    ФайлЧтения.Закрыть();
    
    Возврат ТаблицаСотрудников;

КонецФункции

Ключевые выводы

  1. Никогда не присваивайте строку (String) напрямую в поле типа Дата (Date). 1С редко делает это преобразование так, как вам нужно.
  2. Всегда используйте СокрЛП() для данных, полученных из внешних файлов. Пробелы — враг конвертации типов.
  3. Явно указывайте типы колонок в ТаблицаЗначений. Это поможет писать более надежный код и использовать подсказки конфигуратора.
  4. При разборе дат учитывайте формат (порядок дня и месяца) и длину года (2 или 4 символа).

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

← На главную