В процессе эксплуатации систем на базе 1С:Предприятие нередко возникает ситуация, когда пользователи по ошибке вводят даты, далеко отстоящие от текущего момента. Например, вместо текущего 2024 года в документе появляются даты 2124, 2324 или даже 3999 год. Это может происходить по разным причинам: от «залипания» клавиш до некорректно настроенных сканеров штрих-кодов или ошибок при копировании данных из внешних источников. Такие ошибки критичны, так как они могут «выбить» итоги регистров далеко вперед, что приведет к замедлению работы системы при расчете остатков и формировании отчетов.
Проанализируем ситуацию и разберем наиболее эффективные способы предотвращения подобных ошибок, начиная от простых настроек платформы и заканчивая профессиональной разработкой через подписки на события.
Прежде чем переходить к коду, выясним причину. Часто пользователи вводят две последние цифры года, и платформа интерпретирует их исходя из настройки Год начала столетия. Также часто встречается административный аспект: использование сканеров штрих-кодов, которые передают лишние символы в поле даты.
С технической стороны, ввод даты типа «31.12.3999» технически допустим в 1С, но может вызвать проблемы в СУБД (например, в SQL Server) или привести к некорректной работе итогов. Если документ с такой датой будет проведен, система при каждом расчете текущих остатков будет вынуждена учитывать эту «запись из будущего», что излишне нагружает сервер.
Рассмотрим наиболее правильный и профессиональный способ решения задачи. Чтобы не изменять каждую форму документа (которых в конфигурации может быть сотни), мы создадим единый механизм проверки для всей системы. Для этого идеально подходит объект метаданных Подписка на событие.
Разберем реализацию по шагам:
РаботаСДокументамиСобытия. Установим ему флаг «Сервер».Подписка на событие.ДокументОбъект. Это позволит нам перехватить запись вообще всех документов в базе.ПередЗаписью.Посмотрим на пример кода, который предотвратит запись документа с датой, превышающей определенный порог. Мы не будем жестко прописывать «2035 год», а сделаем проверку относительно текущей даты, что более гибко:
Процедура ПроверитьДатуДокументаПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
// Определим максимально допустимый порог (например, текущая дата + 1 год)
МаксимальноДопустимаяДата = ДобавитьМесяц(ТекущаяДатаСеанса(), 12);
Если Источник.Дата > МаксимальноДопустимаяДата Тогда
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
"Дата документа не может быть больше " + Формат(МаксимальноДопустимаяДата, "ДЛФ=D") + ".
|Пожалуйста, проверьте правильность ввода года!");
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
Важный нюанс: использование ТекущаяДатаСеанса() предпочтительнее, чем просто ТекущаяДата(), так как это учитывает часовой пояс пользователя, работающего с документом.
Если проблема локализована в конкретных типах документов, мы можем воспользоваться визуальными средствами платформы. У элементов формы типа «Поле ввода», связанных с датой, есть стандартные свойства МинимальнаяДата и МаксимальнаяДата.
Проанализируем этот подход:
Иногда ошибки ввода связаны с тем, как платформа интерпретирует двузначный ввод года (например, «24»). Посмотрим на свойство конфигурации Год начала столетия. По умолчанию в 1С это обычно 1940 год. Это означает, что диапазон 100 лет отсчитывается от 1940 до 2039. Если пользователь введет «41», система поймет это как 1941 год. Если «25» — как 2025 год.
Если ваши пользователи часто ошибаются, корректировка этого параметра в свойствах конфигурации или в настройках конкретных полей может помочь системе правильнее «угадывать» намерение пользователя, однако это не является полноценной защитой от ввода четырехзначного ошибочного года.
В современных типовых конфигурациях (таких как ERP 2, УТ 11 или БП 3.0) уже существуют механизмы валидации. Проанализируем возможности БСП. Существует общий модуль ОбщегоНазначения, в котором часто встречается функция ПроверитьДатуДокумента.
Программисты часто используют механизм прерывания (через расширение) именно этого модуля, чтобы внедрить единую логику проверки дат для всей системы. Если ваша конфигурация построена на БСП, рекомендуется сначала поискать существующие вызовы проверки даты в модулях объектов и «вклиниться» в них. Это сохранит единообразие кода и упростит дальнейшую поддержку.
Для эффективного решения проблемы мы рекомендуем комбинированный подход:
ПередЗаписью для типа ДокументОбъект. Это обеспечит «тотальный» контроль над всеми документами, включая созданные программно.Помните, что проверка в ОбработкеПроведения, которую часто советуют на форумах, менее эффективна в данном случае, так как она сработает только при попытке провести документ, но позволит сохранить документ с «кривой» датой в базе, что все равно будет засорять систему.