В процессе разработки в среде 1С:Предприятие одной из самых частых задач является приведение данных к нужному типу. Особенно это актуально при импорте данных из внешних файлов (Excel, CSV, текстовые документы), где даты представлены в виде строк. В данной статье мы подробно разберем, как правильно преобразовать строку в тип Дата, какие существуют нюансы и как избежать типичных ошибок преобразования.
Прежде всего, проанализируем возможности встроенного языка 1С. Основным инструментом является глобальная функция Дата(). Рассмотрим по шагам два варианта ее использования, которые предоставляет «Синтаксис-помощник».
Вариант 1: По канонической строке
Для того чтобы 1С поняла строку без лишних манипуляций, строка должна быть в формате "ГГГГММДДччммсс". Это так называемый канонический вид. Рассмотрим пример:
СтрокаДаты = "20231025103000"; // 25 октября 2023 года, 10:30:00
НужнаяДата = Дата(СтрокаДаты);
Если в строке переданы только цифры даты без времени ("20231025"), 1С автоматически подставит время 00:00:00.
Вариант 2: По составляющим (числам)
Этот метод считается более надежным, так как мы явно передаем год, месяц и день в виде отдельных чисел. Синтаксис выглядит так: Дата(Год, Месяц, День, Час, Минута, Секунда).
// Пример заполнения реквизита по частям
Год = 2023;
Месяц = 10;
День = 25;
РеквизитДата = Дата(Год, Месяц, День);
Зачастую мы получаем строку в формате, который 1С не понимает напрямую, например: "25.10.2023". В этом случае нам нужно «разрезать» строку и собрать ее заново. Выясним, как это сделать с помощью функций Лев(), Сред() и Прав().
Рассмотрим ситуацию, когда РеквизитСтрока имеет вид "ДД.ММ.ГГГГ":
// Собираем строку в формате ГГГГММДД для функции Дата()
// РеквизитСтрока = "25.10.2023"
ГодЧасть = Прав(РеквизитСтрока, 4); // "2023"
МесяцЧасть = Сред(РеквизитСтрока, 4, 2); // "10" (начиная с 4-го символа)
ДеньЧасть = Лев(РеквизитСтрока, 2); // "25"
РеквизитДата = Дата(ГодЧасть + МесяцЧасть + ДеньЧасть);
Важный нюанс: при использовании этого метода нужно быть уверенным, что в строке всегда есть ведущие нули (например, "05.01.2023", а не "5.1.2023"), иначе индексы символов сместятся, и программа выдаст ошибку.
В современных конфигурациях (таких как 1С:ERP, УТ 11, БП 3.0) разработчики стараются уходить от ручного разбора строк. Выясним, как использовать мощь БСП для этих целей. В составе библиотеки есть функция, которая гораздо «умнее» стандартной.
Рассмотрим пример использования функции из модуля СтроковыеФункцииКлиентСервер:
// Функция пытается сама определить формат разделителей
ЗначениеСтроки = "25/10/2023";
РезультатДаты = СтроковыеФункцииКлиентСервер.СтрокаВДату(ЗначениеСтроки);
Если ЗначениеЗаполнено(РезультатДаты) Тогда
Объект.РеквизитДата = РезультатДаты;
Иначе
Сообщить("Не удалось распознать дату!");
КонецЕсли;
Этот метод значительно сокращает код и делает его более устойчивым к изменению формата входных данных.
Если ваша система обменивается данными через веб-сервисы или JSON, вы можете встретить формат даты вида "2023-10-25T12:00:00". Попытка напрямую преобразовать такую строку через Дата() вызовет ошибку. Проанализируем, как решить эту задачу изящно.
Используем встроенный механизм XML-сериализации:
СтрокаISO = "2023-10-25T15:30:00";
// Метод XMLЗначение преобразует строку международного стандарта в дату 1С
РеквизитДата = XMLЗначение(Тип("Дата"), СтрокаISO);
Этот способ является наиболее предпочтительным при интеграциях, так как он стандартизирован и корректно обрабатывает часовые пояса и разделитель "T".
Иногда дата приходит в непредсказуемом формате: где-то точки, где-то дефисы, а где-то косая черта. Разберем универсальный алгоритм с использованием функции СтрРазделить().
СтрокаСДатой = "25-10-2023"; // Может быть и "25.10.2023"
// Заменяем возможные разделители на один универсальный (например, точку)
ЧистаяСтрока = СтрЗаменить(СтрокаСДатой, "-", ".");
ЧистаяСтрока = СтрЗаменить(ЧистаяСтрока, "/", ".");
МассивЧастей = СтрРазделить(ЧистаяСтрока, ".");
Если МассивЧастей.Количество() >= 3 Тогда
День = Число(МассивЧастей[0]);
Месяц = Число(МассивЧастей[1]);
Год = Число(МассивЧастей[2]);
// Проверка на двузначный год
Если Год < 100 Тогда
Год = 2000 + Год;
КонецЕсли;
Объект.РеквизитДата = Дата(Год, Месяц, День);
КонецЕсли;
При заполнении реквизита всегда существует риск, что в строке окажется текст, не имеющий отношения к дате (например, "Нет данных"). Чтобы программа не завершилась аварийно, обязательно используем конструкцию Попытка ... Исключение.
Рассмотрим шаблон безопасного кода:
Попытка
Объект.РеквизитДата = Дата(СтрЗаменить(СтрокаИзФайла, ".", ""));
Исключение
// Записываем лог или устанавливаем пустую дату
Объект.РеквизитДата = '00010101';
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Ошибка в формате даты: " + СтрокаИзФайла);
КонецПопытки;
Мы рассмотрели несколько способов преобразования. Выбор конкретного метода зависит от вашей ситуации:
Помните, что в 1С пустая дата — это 01.01.0001. Всегда проверяйте результат преобразования функцией ЗначениеЗаполнено(), прежде чем записывать объект в базу данных.