В процессе разработки в среде 1С часто возникает задача, когда требования к заполнению реквизитов документа меняются в зависимости от его жизненного цикла. Типичный пример: пока документ находится в статусе Готовится, он может быть заполнен частично, но при переводе в статус Готов система должна жестко требовать заполнения всех ключевых полей. Рассмотрим, как правильно реализовать такую логику, избежав типичных ошибок начинающих разработчиков.
Прежде всего, разберем ситуацию: если мы просто установим в свойствах реквизита в Конфигураторе признак Проверка заполнения: Выдавать ошибку, то документ нельзя будет сохранить даже в черновом варианте. Это нам не подходит. Следовательно, нам необходимо программное решение.
Важно определиться, где писать код. Проанализируем два основных варианта:
ПередЗаписью или ОбработкаПроверкиЗаполнения гарантирует целостность данных независимо от способа записи документа.Рассмотрим по шагам, как реализовать проверку в модуле объекта. Это решение является наиболее понятным для новичков и позволяет гибко управлять логикой отказа от записи. Выясним причину, почему стандартное сравнение со строкой "Готов" — это плохая практика. Статусы обычно хранятся в Перечисления, поэтому сравнивать нужно именно со значением перечисления.
Проанализируем пример кода, который объединяет проверку всех обязательных полей:
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
// Проверяем, что документ записывается в нужном статусе
Если ЭтотОбъект.СтатусЗаказа = Перечисления.СтатусыЗаказов.Готов Тогда
ТекстОшибки = "";
// Проверяем заполнение строки (Адрес)
Если СокрЛП(ЭтотОбъект.АдресНедвижимости) = "" Тогда
ТекстОшибки = ТекстОшибки + "Поле 'Адрес недвижимости' должно быть заполнено." + Символы.ПС;
КонецЕсли;
// Проверяем заполнение ссылки (Клиент) через универсальную функцию
Если Не ЗначениеЗаполнено(ЭтотОбъект.Клиент) Тогда
ТекстОшибки = ТекстОшибки + "Поле 'Клиент' должно быть заполнено." + Символы.ПС;
КонецЕсли;
// Если накопились ошибки, отменяем запись
Если ЗначениеЗаполнено(ТекстОшибки) Тогда
Сообщить(ТекстОшибки);
Отказ = Истина;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
В данном примере мы используем переменную Отказ = Истина, которая сообщает платформе, что запись документа должна быть прервана. Обратите внимание на использование ЭтотОбъект — это позволяет нам обращаться к данным документа напрямую из модуля объекта.
Теперь разберем более профессиональный подход. В 1С существует специальное событие ОбработкаПроверкиЗаполнения. Его преимущество в том, что платформа сама может визуально выделить незаполненные поля на форме (подчеркнуть красным пунктиром).
Разберем алгоритм работы этого метода:
Проверка заполнения: Выдавать ошибку.Посмотрим на пример реализации:
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
// Если статус не "Готов", нам не нужно проверять реквизиты жестко
Если ЭтотОбъект.СтатусЗаказа <> Перечисления.СтатусыЗаказов.Готов Тогда
// Удаляем реквизиты из массива проверки, чтобы платформа их игнорировала
УдаляемыеРеквизиты = Новый Массив;
УдаляемыеРеквизиты.Добавить("Клиент");
УдаляемыеРеквизиты.Добавить("АдресНедвижимости");
УдаляемыеРеквизиты.Добавить("СуммаДокумента");
Для Каждого Реквизит Из УдаляемыеРеквизиты Цикл
Индекс = ПроверяемыеРеквизиты.Найти(Реквизит);
Если Индекс <> Неопределено Тогда
ПроверяемыеРеквизиты.Удалить(Индекс);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
При написании проверок крайне важно учитывать типы данных реквизитов, иначе программа будет выдавать ошибки или работать некорректно. Разберем основные правила:
ПустаяСтрока() или СокрЛП(Значение) = "".Неопределено часто не срабатывает. Используйте ЗначениеЗаполнено() или метод Пустая(), например: Если Клиент.Пустая() Тогда....0001-01-01. Универсальная функция ЗначениеЗаполнено() отлично справляется и с датами.Перечисления.ИмяПеречисления.ИмяЗначения.Чтобы сделать интерфейс более дружелюбным, вместо простого Сообщить() в управляемых формах рекомендуется использовать объект СообщениеПользователю. Это позволит привязать текст ошибки к конкретному полю на экране.
Рассмотрим, как это выглядит в коде:
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Необходимо заполнить адрес недвижимости для готовности договора!";
Сообщение.Поле = "АдресНедвижимости"; // Имя реквизита на форме
Сообщение.УстановитьДанные(ЭтотОбъект);
Сообщение.Сообщить();
Таким образом, мы не просто выводим текст, но и даем пользователю возможность кликнуть на сообщение, после чего курсор автоматически переместится в нужное поле. Проанализировав все вышеперечисленные методы, вы сможете создать надежную систему валидации данных, которая обеспечит корректность учета в вашей конфигурации 1С.