Как в 1С проверить, является ли строка датой, и избежать ошибок преобразования?

Программист IT и автоматизация бизнеса
← На главную

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

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

Метод 1: Использование конструкции Попытка — Исключение

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


// Текст — это наша входная переменная
Попытка
    ДатаЗначение = Дата(Текст);
    // Если преобразование прошло успешно, выполняем ДЕЙСТВИЕ1
    Сообщить("Это дата: " + ДатаЗначение);
Исключение
    // Если возникла ошибка преобразования, выполняем ДЕЙСТВИЕ2
    Сообщить("Это просто текст");
КонецПопытки;

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

Метод 2: Приведение типа через ОписаниеТипов

Более изящный способ, который рекомендуют стандарты разработки 1С, — использование объекта ОписаниеТипов. Метод ПривестиЗначение этого объекта не вызывает исключения при неудаче, а возвращает пустое значение указанного типа (для даты это '00010101').

Проанализируем, как это работает на практике:


ОписаниеДаты = Новый ОписаниеТипов("Дата");
ПроверенноеЗначение = ОписаниеДаты.ПривестиЗначение(Текст);

Если ПроверенноеЗначение = '00010101' Тогда
    // Если в переменной Текст был мусор, метод вернет пустую дату
    // Нужно убедиться, что исходный текст сам не был "пустой датой"
    Если Текст = "00010101" Или Текст = "" Тогда
         // Действие для даты
    Иначе
         // Действие для текста
    КонецЕсли;
Иначе
    // Преобразование прошло успешно
    // Выполняем ДЕЙСТВИЕ1
КонецЕсли;

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

Метод 3: Логический парсинг строки (ручной разбор)

Если мы точно знаем формат входящей строки (например, всегда 8 цифр "ГГГГММДД"), мы можем разобрать её по группам цифр. Это позволяет не только проверить формат, но и убедиться в логической корректности даты (что месяц не равен 13, а день не равен 45).

Разберем по шагам алгоритм такого разбора:


Если СтрДлина(Текст) = 8 Тогда
    ГодСтрокой  = Лев(Текст, 4);
    МесяцСтрокой = Сред(Текст, 5, 2);
    ДеньСтрокой  = Прав(Текст, 2);
    
    // Простейшая проверка на числа
    Попытка
        ГодЧисло  = Число(ГодСтрокой);
        МесяцЧисло = Число(МесяцСтрокой);
        ДеньЧисло  = Число(ДеньСтрокой);
        
        // Создаем дату из чисел. Если значения некорректны (например, месяц 15), 
        // конструктор Дата() выдаст ошибку, которую поймает Исключение.
        ПроверочнаяДата = Дата(ГодЧисло, МесяцЧисло, ДеньЧисло);
        
        // Если дошли сюда — это корректная дата
        // ДЕЙСТВИЕ1
    Исключение
        // ДЕЙСТВИЕ2 (это текст или некорректная дата)
    КонецПопытки;
Иначе
    // ДЕЙСТВИЕ2 (длина не совпадает с форматом даты)
КонецЕсли;

Метод 4: Использование регулярных выражений (RegExp)

Для проверки того, состоит ли строка только из цифр, можно воспользоваться объектом VBScript.RegExp. Это особенно полезно, если нужно быстро отсечь строки, содержащие буквы.


RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.Pattern = "^\d{8}$"; // Шаблон: ровно 8 цифр от начала до конца строки
Если RegExp.Test(Текст) Тогда
    // Это набор из 8 цифр, потенциальная дата
Иначе
    // Это текст
КонецЕсли;

Метод 5: Функции Библиотеки стандартных подсистем (БСП)

Если в вашей конфигурации используется БСП, рекомендуется использовать готовые функции общего модуля СтроковыеФункцииКлиентСервер. Например, функция ТолькоЦифрыВСтроке поможет быстро определить характер данных.

Рассмотрим пример комбинированной проверки:

  1. Сначала проверяем, что в строке содержатся только цифры.
  2. Затем проверяем длину строки.
  3. В последнюю очередь пытаемся преобразовать в тип Дата.

Если СтроковыеФункцииКлиентСервер.ТолькоЦифрыВСтроке(Текст) 
   И СтрДлина(Текст) = 8 Тогда
    
    // Теперь можно безопасно пробовать преобразование
    // или использовать ОписаниеТипов
КонецЕсли;

Сравнение методов: что выбрать?

Выясним причину, почему стоит выбирать тот или иной метод в разных сценариях:

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

← На главную