Как преобразовать строку формата «ДД.ММ.ГГГГ» в дату в 1С

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

При загрузке данных из внешних источников, таких как файлы Excel, CSV или текстовые документы, разработчики часто сталкиваются с ситуацией, когда дата представлена в виде обычной строки (например, "18.03.2019"). Попытка использовать стандартный конструктор Дата() напрямую к такой строке часто приводит к ошибке: «Преобразование к типу Дата не может быть выполнено». Это происходит потому, что встроенная функция ожидает строку в строго определенном каноническом формате или объект другого типа.

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

Причина ошибки при прямом преобразовании

Прежде всего, выясним причину проблемы. Функция Дата() в 1С может принимать либо числа (год, месяц, день, час, минута, секунда), либо строку в формате "ГГГГММДДччммсс". Если мы передаем строку с точками, например, "18.03.2019", платформа не может автоматически определить, какой фрагмент отвечает за год, а какой — за день, особенно если региональные настройки системы отличаются от формата данных в файле.

Способ 1. Использование строковых функций (Лев, Прав, Сред)

Проанализируем самый классический метод. Если формат входной строки строго фиксирован (всегда ДД.ММ.ГГГГ), мы можем «разрезать» строку на части и передать их в конструктор даты как числа. Рассмотрим пример кода:


ДатаСЛиста = "18.03.2019"; // Исходная строка
// Извлекаем части даты:
// Прав(ДатаСЛиста, 4) - берет 4 символа справа (год)
// Сред(ДатаСЛиста, 4, 2) - берет 2 символа, начиная с 4-й позиции (месяц)
// Лев(ДатаСЛиста, 2) - берет 2 символа слева (день)

Рез = Дата(Число(Прав(ДатаСЛиста, 4)), Число(Сред(ДатаСЛиста, 4, 2)), Число(Лев(ДатаСЛиста, 2)));

Важный момент: использование функции Число() внутри конструктора Дата() гарантирует, что платформа получит именно числовые параметры, что исключает ошибки типизации.

Способ 2. Использование функции СтрРазделить

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

  1. Разделим строку в массив, используя точку как разделитель.
  2. Обратимся к элементам массива по индексам (помним, что индексация в массивах 1С начинается с нуля).
  3. Соберем дату из полученных фрагментов.

ДатаСтрокой = "18.03.2019";
МассивЧастейДаты = СтрРазделить(ДатаСтрокой, ".");

// МассивЧастейДаты[0] - "18"
// МассивЧастейДаты[1] - "03"
// МассивЧастейДаты[2] - "2019"

Рез = Дата(МассивЧастейДаты[2], МассивЧастейДаты[1], МассивЧастейДаты[0]);

Этот способ удобен тем, что если в будущем формат даты сменится на "18/03/2019", вам достаточно будет изменить только один символ в функции СтрРазделить.

Способ 3. Приведение к каноническому формату (ГГГГММДД)

Как мы уже упоминали, 1С «понимает» строку без разделителей. Посмотрим на пример, как можно быстро преобразовать "18.03.2019" в "20190318000000". Это можно сделать комбинированием функций или простым добавлением времени, если формат строки позволяет системе распознать его (иногда срабатывает добавление пустых часов).


// Пример быстрого приведения к формату ГГГГММДД
ИсходнаяДата = "18.03.2019";
ГодЧасть = Прав(ИсходнаяДата, 4);
МесяцЧасть = Сред(ИсходнаяДата, 4, 2);
ДеньЧасть = Лев(ИсходнаяДата, 2);

КаноническаяСтрока = ГодЧасть + МесяцЧасть + ДеньЧасть + "000000";
Результат = Дата(КаноническаяСтрока);

Способ 4. Преобразование через XMLЗначение

Существует «скрытый» и очень эффективный способ преобразования, если ваша строка близка к формату ISO (ГГГГ-ММ-ДД). Функция XMLЗначение работает крайне быстро, так как использует низкоуровневые механизмы платформы.


// Если мы предварительно заменим точки на дефисы и переставим год в начало
ДатаДляXML = "2019-03-18";
Результат = XMLЗначение(Тип("Дата"), ДатаДляXML);

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

Особенности загрузки из Excel

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

Совет: При использовании COM-объекта (Excel.Application), всегда старайтесь обращаться к свойству Value, а не Text. Свойство Value вернет вам уже готовый объект типа Дата, и преобразование не потребуется. Если же вы используете Value2, вы получите число (количество дней с начала эпохи Excel), которое также можно конвертировать в дату 1С простым сложением.

Обработка ошибок и «человеческого фактора»

Выясним причину, по которой даже самый идеальный код может дать сбой. Пользователи могут вводить даты как угодно: "18.03.19", "18/03/2019", "18 марта 2019". Чтобы ваша обработка не «падала», обязательно используйте конструкцию Попытка ... Исключение.


Попытка
    // Здесь ваш код разбора строки
    КонечнаяДата = Дата(Год, Месяц, День);
Исключение
    Сообщить("Не удалось распознать дату в строке: " + СтрокаИзФайла);
    // Можно установить значение по умолчанию или пропустить строку
    КонечнаяДата = '00010101'; 
КонецПопытки;

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

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

← На главную