В практике разработки на платформе 1С:Предприятие часто возникает задача определения типа данных, скрытого в строковой переменной. Например, когда в одну и ту же переменную могут попадать либо произвольный текст (названия, артикулы), либо цифровые последовательности, представляющие собой дату (например, в формате "ГГГГММДД"). Если попытаться напрямую преобразовать некорректную строку в дату, система выдаст критическую ошибку "Преобразование значения к типу Дата не может быть выполнено".
В данной статье мы подробно разберем несколько профессиональных способов решения этой задачи, проанализируем их производительность и выберем оптимальные подходы для различных ситуаций. Мы пройдем путь от самых простых проверок до использования механизмов платформы и библиотек.
Это самый очевидный и простой в реализации способ. Мы пробуем принудительно преобразовать строку в дату и, если возникает ошибка, обрабатываем её в блоке исключения. Рассмотрим пример кода:
// Текст — это наша входная переменная
Попытка
ДатаЗначение = Дата(Текст);
// Если преобразование прошло успешно, выполняем ДЕЙСТВИЕ1
Сообщить("Это дата: " + ДатаЗначение);
Исключение
// Если возникла ошибка преобразования, выполняем ДЕЙСТВИЕ2
Сообщить("Это просто текст");
КонецПопытки;
Важный нюанс: как отмечалось в обсуждении на форуме, использование Попытка...Исключение имеет свои особенности производительности. Если в вашем наборе данных "ошибочные" значения (текст вместо даты) встречаются часто, работа этого блока будет значительно медленнее, чем логическая проверка. Это связано с тем, что генерация исключения в 1С — ресурсоемкая операция. Если же большинство значений являются датами, разница в скорости будет ничтожной.
Более изящный способ, который рекомендуют стандарты разработки 1С, — использование объекта ОписаниеТипов. Метод ПривестиЗначение этого объекта не вызывает исключения при неудаче, а возвращает пустое значение указанного типа (для даты это '00010101').
Проанализируем, как это работает на практике:
ОписаниеДаты = Новый ОписаниеТипов("Дата");
ПроверенноеЗначение = ОписаниеДаты.ПривестиЗначение(Текст);
Если ПроверенноеЗначение = '00010101' Тогда
// Если в переменной Текст был мусор, метод вернет пустую дату
// Нужно убедиться, что исходный текст сам не был "пустой датой"
Если Текст = "00010101" Или Текст = "" Тогда
// Действие для даты
Иначе
// Действие для текста
КонецЕсли;
Иначе
// Преобразование прошло успешно
// Выполняем ДЕЙСТВИЕ1
КонецЕсли;
Этот метод считается более "чистым", так как он не прерывает работу отладчика и работает предсказуемо вне зависимости от настроек конфигурации.
Если мы точно знаем формат входящей строки (например, всегда 8 цифр "ГГГГММДД"), мы можем разобрать её по группам цифр. Это позволяет не только проверить формат, но и убедиться в логической корректности даты (что месяц не равен 13, а день не равен 45).
Разберем по шагам алгоритм такого разбора:
Если СтрДлина(Текст) = 8 Тогда
ГодСтрокой = Лев(Текст, 4);
МесяцСтрокой = Сред(Текст, 5, 2);
ДеньСтрокой = Прав(Текст, 2);
// Простейшая проверка на числа
Попытка
ГодЧисло = Число(ГодСтрокой);
МесяцЧисло = Число(МесяцСтрокой);
ДеньЧисло = Число(ДеньСтрокой);
// Создаем дату из чисел. Если значения некорректны (например, месяц 15),
// конструктор Дата() выдаст ошибку, которую поймает Исключение.
ПроверочнаяДата = Дата(ГодЧисло, МесяцЧисло, ДеньЧисло);
// Если дошли сюда — это корректная дата
// ДЕЙСТВИЕ1
Исключение
// ДЕЙСТВИЕ2 (это текст или некорректная дата)
КонецПопытки;
Иначе
// ДЕЙСТВИЕ2 (длина не совпадает с форматом даты)
КонецЕсли;
Для проверки того, состоит ли строка только из цифр, можно воспользоваться объектом VBScript.RegExp. Это особенно полезно, если нужно быстро отсечь строки, содержащие буквы.
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.Pattern = "^\d{8}$"; // Шаблон: ровно 8 цифр от начала до конца строки
Если RegExp.Test(Текст) Тогда
// Это набор из 8 цифр, потенциальная дата
Иначе
// Это текст
КонецЕсли;
Если в вашей конфигурации используется БСП, рекомендуется использовать готовые функции общего модуля СтроковыеФункцииКлиентСервер. Например, функция ТолькоЦифрыВСтроке поможет быстро определить характер данных.
Рассмотрим пример комбинированной проверки:
Дата.
Если СтроковыеФункцииКлиентСервер.ТолькоЦифрыВСтроке(Текст)
И СтрДлина(Текст) = 8 Тогда
// Теперь можно безопасно пробовать преобразование
// или использовать ОписаниеТипов
КонецЕсли;
Выясним причину, почему стоит выбирать тот или иной метод в разных сценариях:
Если Лев(Текст, 1) = "2"), этот метод самый быстрый, но крайне ненадежный. Его можно использовать только как предварительный фильтр перед основной проверкой.Резюме: Для надежного решения задачи в 1С 8.3 рекомендуется комбинировать проверку длины строки с методом ОписаниеТипов.ПривестиЗначение() или использовать блок Попытка, если вы предварительно убедились, что в строке содержатся только цифры. Это гарантирует отсутствие "вылетов" программы и корректную логику обработки данных.