При разработке в 1С:Предприятие 8.3 мы часто сталкиваемся с необходимостью контролировать заполнение важных реквизитов. Для объектов метаданных, таких как документы и справочники, платформа предоставляет удобный механизм автоматической проверки, который срабатывает при интерактивной записи. Достаточно установить для реквизита свойство "Проверка заполнения" в значение "Выдавать ошибку", и система сама позаботится о контроле. Однако, что делать, если мы работаем в обработке и нам нужно инициировать такую же проверку по нажатию на кнопку, а не при записи объекта?
Именно с такой ситуацией сталкиваются многие разработчики, когда стандартные механизмы не срабатывают автоматически в контексте произвольных форм и обработок. Нам предстоит выяснить, как мы можем программно вызвать этот механизм и обеспечить корректное отображение ошибок.
Давайте сначала разберем, почему стандартная проверка заполнения, настроенная в конфигураторе, не работает "из коробки" в обработках. В документах и справочниках проверка срабатывает в определенные моменты жизненного цикла объекта: при его записи, проведении или при интерактивном вводе данных пользователем. Эти моменты жестко встроены в логику платформы. Обработка же, как правило, не имеет основного объекта, который бы автоматически записывался в базу данных. Ее реквизиты могут быть временными, служебными или представлять собой данные для формирования отчета.
Если мы просто создадим реквизит в обработке и установим ему свойство "Проверка заполнения: Выдавать ошибку", то при попытке записи такого реквизита (что само по себе нетипично для обработки) или при нажатии на кнопку, отвечающую за некую логику, платформа не инициирует проверку автоматически. Это требует нашего прямого вмешательства.
Некоторые разработчики поначалу пытаются реализовать проверку вручную, используя функцию ЗначениеЗаполнено():
Если НЕ ЗначениеЗаполнено(Объект.ФайлДанных) Тогда
ПоказатьПредупреждение(,"Не выбран файл данных");
Возврат;
КонецЕсли;
Такой подход, хотя и решает задачу проверки наличия значения, имеет ряд недостатков:
ПоказатьПредупреждение() выводит общее сообщение, которое не привязано к конкретному полю формы. Платформа же при стандартной проверке подсвечивает незаполненные поля красным и выводит сообщения в едином списке, с возможностью перехода к проблемному полю.Именно поэтому "Руководитель проекта" может "придраться" к такому коду, требуя использования типовых механизмов платформы.
Для решения нашей задачи в 1С существует специальный метод, который позволяет программно инициировать стандартный механизм проверки заполнения — это метод ПроверитьЗаполнение(). Этот метод доступен как у объектов (например, ДокументОбъект, СправочникОбъект), так и у самой формы.
Давайте рассмотрим подробнее, как работает этот метод:
ПроверитьЗаполнение() платформа проходит по всем реквизитам, для которых в конфигураторе установлено свойство "Проверка заполнения: Выдавать ошибку".ПроверитьЗаполнение() возвращает булево значение: Истина, если все проверки прошли успешно, и Ложь, если были обнаружены ошибки. Это позволяет нам принять решение о дальнейших действиях (например, отменить выполнение основной логики кнопки).Используя этот метод, мы можем добиться поведения, аналогичного проверкам при записи документов, но уже в контексте произвольной обработки.
Для того чтобы использовать ПроверитьЗаполнение() в обработке при нажатии на кнопку, нам потребуется выполнить несколько шагов.
Прежде всего, в процедуре, которая обрабатывает нажатие нашей кнопки на форме обработки, нам необходимо вызвать метод ПроверитьЗаполнение(). Обратите внимание, что этот вызов должен быть выполнен на клиенте, так как он напрямую взаимодействует с элементами формы.
Предположим, у нас есть кнопка с именем "Проверить" и соответствующий обработчик команды:
&НаКлиенте
Процедура Проверить(Команда)
// Вызываем стандартную проверку заполнения
Отказ = ПроверитьЗаполнение();
// Если Отказ = Истина, это означает, что были обнаружены ошибки заполнения.
// В этом случае дальнейшие действия выполнять не следует.
Если Отказ Тогда
Возврат;
КонецЕсли;
// Здесь располагается основной код нашей кнопки,
// который будет выполнен только после успешной проверки.
ПоказатьПредупреждение(,"Все реквизиты заполнены корректно!");
КонецПроцедуры
В этом примере переменная Отказ будет содержать Истина, если хотя бы один обязательный реквизит не заполнен. Мы используем это значение для прерывания дальнейшего выполнения процедуры.
Метод ПроверитьЗаполнение() не только проверяет реквизиты, помеченные в конфигураторе, но и вызывает специальные обработчики событий, в которых мы можем добавить свою собственную, программную логику проверки. Существует два основных обработчика:
ОбработкаПроверкиЗаполненияНаСервере (в модуле формы): Этот обработчик вызывается для реквизитов, которые являются реквизитами самой формы обработки (не основного объекта).ОбработкаПроверкиЗаполнения (в модуле объекта): Если наша обработка имеет основной реквизит формы, тип которого является ссылочным или объектным (например, ДокументОбъект или СправочникОбъект), то этот обработчик будет вызван для реквизитов этого основного объекта.Давайте сосредоточимся на `ОбработкаПроверкиЗаполнения` в контексте модуля объекта (или в модуле формы, если обработка не имеет основного объекта). Этот обработчик имеет два важных параметра:
Отказ (Булево): Если мы установим этот параметр в Истина, это означает, что обнаружена ошибка, и запись объекта будет отменена.ПроверяемыеРеквизиты (Массив): Этот массив содержит имена реквизитов, которые платформа собирается проверить на основании настроек в конфигураторе. Мы можем модифицировать этот массив:
Пример использования ОбработкаПроверкиЗаполнения в модуле объекта обработки (если обработка имеет основной реквизит, представляющий собой объект, или если мы используем этот обработчик для реквизитов самой формы):
// Этот обработчик вызывается при вызове ПроверитьЗаполнение()
// в модуле объекта или в модуле формы (для реквизитов формы)
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
// Здесь мы можем добавить свою дополнительную логику проверки.
// Например, проверить какие-то условные реквизиты,
// которые зависят от значений других реквизитов.
// Пример: Допустим, реквизит "Комментарий" обязателен,
// если установлен флажок "ТребуетсяКомментарий".
Если Объект.ТребуетсяКомментарий И НЕ ЗначениеЗаполнено(Объект.Комментарий) Тогда
// Создаем сообщение пользователю, привязанное к полю формы
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Поле 'Комментарий' обязательно для заполнения.";
Сообщение.Поле = "Комментарий"; // Имя реквизита
Сообщение.Сообщить();
Отказ = Истина; // Отменяем дальнейшее выполнение
КонецЕсли;
// Мы также можем модифицировать массив ПроверяемыеРеквизиты.
// Например, если мы хотим, чтобы платформа не проверяла реквизит "Сумма",
// а мы сделали это вручную выше или он всегда заполняется программно:
// ПроверяемыеРеквизиты.Удалить(ПроверяемыеРеквизиты.Найти("Сумма"));
КонецПроцедуры
Важно помнить, что если вы хотите, чтобы сообщения об ошибках были привязаны к конкретным полям формы, как это делает платформа, используйте объект СообщениеПользователю и заполняйте его свойство Поле.
Таким образом, полноценное решение проблемы изначального вопроса будет выглядеть следующим образом:
// В модуле формы обработки:
&НаКлиенте
Процедура Проверить(Команда)
// Вызов ПроверитьЗаполнение() для формы или основного реквизита.
// Если обработка имеет основной реквизит "Объект" (например, типа ДокументОбъект),
// то можно вызвать ПроверитьЗаполнение() для него: Отказ = Объект.ПроверитьЗаполнение();
// Если реквизиты, которые нужно проверить, являются реквизитами самой формы,
// то вызываем ПроверитьЗаполнение() у формы:
Отказ = ПроверитьЗаполнение(); // Этот метод формы вызывает и ОбработкаПроверкиЗаполненияНаСервере
Если Отказ Тогда
Возврат; // Были обнаружены ошибки заполнения, дальнейшие действия отменяем
КонецЕсли;
// Здесь выполняем основную логику кнопки, например, сохранение данных,
// формирование отчета или вызов серверной процедуры.
ПоказатьПредупреждение(,"Все обязательные поля заполнены!");
КонецПроцедура
// В модуле формы обработки, если нужно добавить свою проверку для реквизитов ФОРМЫ
// (не основного объекта, если он есть)
&НаСервере
Процедура ОбработкаПроверкиЗаполненияНаСервере(Отказ, ПроверяемыеРеквизиты)
// Пример дополнительной проверки для реквизита формы "ВидОперации"
// (предполагаем, что "ВидОперации" - это реквизит формы, а не основного объекта)
Если Объект.ВидОперации = Справочники.ВидыОпераций.ПустаяСсылка() Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Необходимо выбрать вид операции.";
Сообщение.Поле = "ВидОперации";
Сообщение.УстановитьОбъект(ЭтотОбъект); // Привязка к форме обработки
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;
// Также можно работать с ПроверяемыеРеквизиты. Например, добавить в него
// имя реквизита формы, который нужно проверить стандартным механизмом.
// Если хотим, чтобы платформа проверила реквизит формы "НачальнаяДата",
// даже если он не помечен в конфигураторе как "Выдавать ошибку":
// Если ПроверяемыеРеквизиты.Найти("НачальнаяДата") = Неопределено Тогда
// ПроверяемыеРеквизиты.Добавить("НачальнаяДата");
// КонецЕсли;
КонецПроцедуры
// Если обработка имеет основной реквизит, например, "Объект" типа "ДокументОбъект.МойДокумент",
// то в модуле этого объекта (Документ.МойДокумент) можно реализовать:
// Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
// // Здесь будет логика проверки для реквизитов Документа "МойДокумент"
// // ...
// КонецПроцедуры
В приведенном примере мы используем ПроверитьЗаполнение() для формы. Это автоматически инициирует проверку всех реквизитов формы, для которых установлено свойство "Выдавать ошибку", и вызывает событие ОбработкаПроверкиЗаполненияНаСервере. Если же ваша обработка предназначена для работы с определенным объектом (например, вы создаете новый документ через обработку), то метод ПроверитьЗаполнение() следует вызывать для этого конкретного объекта (ДокументОбъект.ПроверитьЗаполнение()). В этом случае будут вызваны события, как в модуле формы, так и в модуле самого объекта.
Давайте еще раз подчеркнем принципиальные различия между методом ПроверитьЗаполнение() и функцией глобального контекста ЗначениеЗаполнено(), чтобы избежать путаницы и некорректного использования.
ПроверитьЗаполнение():
ОбработкаПроверкиЗаполненияНаСервере и ОбработкаПроверкиЗаполнения), что позволяет нам расширить или модифицировать стандартную логику проверки.Истина при успешной проверке, Ложь при наличии ошибок.ЗначениеЗаполнено():
ПоказатьПредупреждение() или СообщениеПользователю.Истина или Ложь в зависимости от заполненности конкретного значения.ТаблицаЗначений, ДеревоЗначений) для проверки их наполненности; для них следует использовать метод Количество().Таким образом, если нам нужно использовать стандартный механизм проверки, настроенный в конфигураторе, и получить его преимущества (единое отображение ошибок, расширяемость через события), мы всегда будем использовать ПроверитьЗаполнение(). Если же нам требуется лишь быстро проверить конкретное значение в коде без привязки к форме и ее элементам, тогда ЗначениеЗаполнено() — подходящий выбор.
При работе с проверкой заполнения в обработках и формах, стоит учитывать несколько дополнительных моментов и придерживаться лучших практик:
СообщениеПользователю с указанием свойства Поле, чтобы ваши программные проверки отображались так же, как и системные. Это улучшает пользовательский опыт, позволяя быстро перейти к проблемному полю.ОбработкаПроверкиЗаполненияНаСервере или в серверной процедуре, вызываемой после успешной клиентской проверки).ПроверитьЗаполнение() именно для этого объекта. Это гарантирует, что будут учтены все проверки, определенные в модуле самого объекта.ОчиститьСообщения() объекта СообщенияПользователю или просто убедиться, что каждый новый вызов начинает с чистого листа.ЗначениеЗаполнено() в коде обработчика ОбработкаПроверкиЗаполнения, если только у вас нет специфических, условных требований к этому полю.Следуя этим рекомендациям, мы сможем эффективно использовать встроенные механизмы проверки заполнения 1С:Предприятие 8.3, обеспечивая стабильность, удобство и поддерживаемость наших решений.
Мы выяснили, что для программного вызова стандартной проверки заполнения реквизитов в обработке по нажатию на кнопку необходимо использовать метод ПроверитьЗаполнение(). Этот метод не только инициирует проверку реквизитов, настроенных в конфигураторе, но и вызывает обработчики событий (ОбработкаПроверкиЗаполненияНаСервере в модуле формы и ОбработкаПроверкиЗаполнения в модуле объекта), позволяя нам гибко управлять логикой проверки и интегрировать свои собственные условия. Мы также разобрали, почему не рекомендуется использовать только функцию ЗначениеЗаполнено() для этой задачи и какие преимущества дает комплексный подход с ПроверитьЗаполнение(). Теперь мы можем уверенно реализовывать надежные и соответствующие стандартам 1С проверки в наших обработках.