При разработке обменов данными или загрузок из внешних файлов часто возникает задача чтения информации из текстовых форматов (TXT, CSV). На первый взгляд, задача кажется тривиальной: прочитать строку, разделить её по запятым и записать в справочник. Однако начинающие разработчики часто сталкиваются с ситуацией, когда строковые данные (ФИО, Артикул) загружаются корректно, а даты (Дата рождения, Дата документа) остаются пустыми. Давайте разберем эту ситуацию подробно, выясним причины ошибки и напишем правильный код для загрузки.
Рассмотрим исходный код, который вызвал проблему. Разработчик считывает файл построчно, разбивает строку на массив и пытается присвоить значение напрямую в колонку таблицы значений.
// Фрагмент кода с ошибкой
ЗначениеВКолонке = ТаблицаЗначений.Добавить();
ЗначениеВКолонке.ФИО = МассивСтрок[0];
ЗначениеВКолонке.ДатаРождения = МассивСтрок[1]; // Здесь происходит ошибка логики
В чем здесь подвох? Дело в типизации данных. В текстовом файле дата — это просто набор символов, например, "25/05/23" или "01.01.1990". Для платформы 1С это тип Строка.
Если колонка ДатаРождения в вашей таблице значений (или реквизит справочника, куда вы потом пишете данные) имеет тип Дата, то платформа не всегда может автоматически понять, как превратить набор символов "25/05/23" в конкретный момент времени. В результате преобразование не происходит, и в поле записывается "пустая дата" (01.01.0001 00:00:00), которую пользователь видит как пустое поле.
Чтобы исправить ситуацию, нам нужно взять на себя ответственность за парсинг (разбор) строки и явное приведение её к типу Дата.
Первое, что мы должны сделать — убедиться, что наша промежуточная ТаблицаЗначений знает, какие данные она хранит. В примере автора колонки добавляются без указания типа. Это плохая практика, так как ошибки типов всплывут только при записи в базу данных. Давайте определим типы явно.
ТаблицаЗначений = Новый ТаблицаЗначений;
ТаблицаЗначений.Колонки.Добавить("ФИО", Новый ОписаниеТипов("Строка", Новый КвалификаторыСтроки(150)));
ТаблицаЗначений.Колонки.Добавить("ДатаРождения", Новый ОписаниеТипов("Дата"));
Теперь, если мы попытаемся записать некорректную строку в колонку ДатаРождения, система может выдать ошибку несоответствия типов сразу, что облегчит отладку. Но наша цель — записать туда правильную дату.
В текстовых файлах часто встречаются невидимые проблемы: лишние пробелы в начале или конце строки. Например, вместо "01/01/2000" может прийти " 01/01/2000 ". Эти пробелы помешают преобразованию. Поэтому возьмем за правило всегда использовать функцию СокрЛП() (Сократить Лев Прав) при чтении данных.
СтрокаДаты = СокрЛП(МассивСтрок[1]);
Это самый важный этап. Допустим, в файле дата записана в формате ДД/ММ/ГГ (например, 25/12/99 или 25/12/2023). Платформа 1С имеет конструктор Дата(Год, Месяц, День). Наша задача — "вытащить" эти числа из строки.
Рассмотрим универсальный способ через разделение строки даты по разделителю (в данном случае слэш / или точка .).
// Предполагаем формат в файле: ДД/ММ/ГГГГ или ДД/ММ/ГГ
// Например: "25/12/2000"
МассивДаты = СтрРазделить(СтрокаДаты, "/");
Если МассивДаты.Количество() = 3 Тогда
День = Число(МассивДаты[0]);
Месяц = Число(МассивДаты[1]);
ГодСтр = МассивДаты[2];
// Обработка двухзначного года (если год указан как "23", а не "2023")
Если СтрДлина(ГодСтр) = 2 Тогда
// Простая логика: добавляем 2000.
// В реальных задачах может потребоваться логика определения века (19xx или 20xx)
Год = 2000 + Число(ГодСтр);
Иначе
Год = Число(ГодСтр);
КонецЕсли;
// Создаем настоящую дату
ИтоговаяДата = Дата(Год, Месяц, День);
Иначе
// Обработка ошибки, если формат даты неверный
ИтоговаяДата = Дата(1,1,1); // Пустая дата
КонецЕсли;
Еще один момент, который часто упускают — кодировка. Если вы используете объект ТекстовыйДокумент или старый метод чтения, вы можете получить "кракозябры" вместо ФИО, если кодировка файла (например, 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 + Год;
КонецЕсли;
НоваяСтрока.ДатаРождения = Дата(Год, Месяц, День);
Иначе
Сообщить("Ошибка формата даты в строке " + Сч + ": " + СтрокаДаты);
КонецЕсли;
Исключение
Сообщить("Не удалось преобразовать дату в строке " + Сч);
КонецПопытки;
Иначе
Сообщить("Некорректный формат строки №" + Сч);
КонецЕсли;
СтрокаТекста = ФайлЧтения.ПрочитатьСтроку();
КонецЦикла;
ФайлЧтения.Закрыть();
Возврат ТаблицаСотрудников;
КонецФункции
String) напрямую в поле типа Дата (Date). 1С редко делает это преобразование так, как вам нужно.СокрЛП() для данных, полученных из внешних файлов. Пробелы — враг конвертации типов.ТаблицаЗначений. Это поможет писать более надежный код и использовать подсказки конфигуратора.Применив этот подход, вы гарантируете, что данные о детях сотрудников загрузятся корректно, и табличная часть документа или справочника будет заполнена без потерь информации.