Проверка заполнения без снятия с поддержки: реквизит, форма и код в расширении
Содержание
Чтобы сделать реквизит обязательным в 1С через расширение, заимствуйте в расширение объект (документ или справочник) и его модуль объекта, а в обработчик ОбработкаПроверкиЗаполнения с аннотацией &После добавьте имя реквизита в массив ПроверяемыеРеквизиты. Платформа сама выдаст сообщение «Поле … не заполнено» и не даст провести документ
. Типовая конфигурация при этом остаётся на поддержке, обновления ставятся как обычно.
Способов настройки обязательного заполнения три, и выбирают их по ситуации:
| Способ | Когда подходит | Что даёт |
|---|---|---|
| Свойство «Проверка заполнения» в палитре | Реквизит добавлен самим расширением | Проверка без единой строки кода |
| Код в модуле объекта расширения | Реквизит типовой, нужно условие или проверка табличной части | Гибкая проверка при записи и проведении |
Отметка на форме (АвтоОтметкаНезаполненного) | Нужно показать пользователю, что поле важное | Только подсказка, запись не блокирует |
На практике первые два способа сочетают с третьим: проверка на сервере запрещает запись, а подчёркивание на форме заранее показывает, что заполнять.
Подготовка расширения и заимствование объекта
Расширения конфигурации появились в платформе 8.3.6. Для нашей задачи подойдёт любая актуальная версия 8.3.2x. Работаем в Конфигураторе, базу перед экспериментами копируем: расширение с ошибкой в обработчике проверки может заблокировать проведение документов у всех пользователей.
Порядок действий:
- Откройте Конфигуратор, меню
Конфигурация → Расширения конфигурации. - Нажмите «Добавить». Задайте имя (например,
ОбязательныеПоля), префикс (оп_) и назначение «Адаптация». - В дереве основной конфигурации найдите нужный документ, например «Реализация (акты, накладные, УПД)» в Бухгалтерии.
- Щёлкните по нему правой кнопкой и выберите «Добавить в расширение».
- В дереве расширения откройте заимствованный объект. Заимствуйте нужный реквизит и, если будете править форму, основную форму документа.
💡 Префикс нужен, чтобы новые процедуры и реквизиты расширения не пересеклись с типовыми именами после обновления. Именуйте всё своё с префиксом: оп_ПроверитьОбязательные, оп_Ответственный.
Чем отличается заимствованный объект от своего:
- 🔹 Заимствованный реквизит — ссылка на типовой. Его тип и большинство свойств берутся из основной конфигурации.
- 🔹 Собственный реквизит расширения (добавлен в заимствованный объект) полностью настраивается в расширении, включая проверку заполнения.
- 🔹 Модуль объекта заимствуется отдельно: в нём пишем свой код, который платформа вызывает до, после или вместо типового.
Если в списке объектов нет нужного документа, проверьте, что вы смотрите дерево основной конфигурации, а не расширения. Переключиться между ними можно в окне Расширения конфигурации.
Проверка заполнения через свойство реквизита
В метаданных 1С 8.3 обязательность задаёт свойство «Проверка заполнения» (ПроверкаЗаполнения). В запросах его часто называют «ОбязательноеЗаполнение», но в палитре свойств оно называется именно так и имеет два значения: «Не проверять» и «Выдавать ошибку».
Для реквизита, который вы сами добавили в расширении:
- Откройте свойства реквизита (Alt+Enter).
- В группе «Использование» найдите «Проверка заполнения».
- Установите «Выдавать ошибку».
- Сохраните расширение и выполните
Конфигурация → Обновить конфигурацию базы данных(F7) в контексте расширения.
После этого проверка срабатывает автоматически при интерактивной записи из формы. Для справочника — при записи элемента. Для документа — только при проведении: документ без проведения сохранится и с пустым обязательным полем. Это поведение платформы, его часто принимают за ошибку настройки.
У типового реквизита это свойство в расширении надёжнее не трогать, а решать задачу кодом. Код не зависит от того, какие свойства заимствованного объекта текущая версия платформы разрешает менять, и переживает обновления конфигурации.
Реквизит типа «Булево» со свойством «Выдавать ошибку» превращается в «галочку, которую нельзя снять»: значение Ложь считается незаполненным. Для флагов обязательность не ставят.
Программная проверка в модуле объекта расширения
Основной рабочий способ для типовых реквизитов. Заимствуйте модуль объекта документа: в дереве расширения откройте документ и на вкладке «Прочее» нажмите «Модуль объекта». Дальше всё зависит от того, есть ли в типовом модуле обработчик ОбработкаПроверкиЗаполнения.
Обработчик в типовом модуле есть
В большинстве документов Бухгалтерии и ЗУП он есть. Тогда пишем процедуру с аннотацией &После:
&После("ОбработкаПроверкиЗаполнения")
Процедура оп_ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
// Типовой реквизит становится обязательным
ПроверяемыеРеквизиты.Добавить("Комментарий");
// Колонка табличной части: проверяется каждая строка
ПроверяемыеРеквизиты.Добавить("Товары.Количество");
КонецПроцедуры
Платформа сверяет реквизиты из массива уже после всех обработчиков. Поэтому добавлять имена в &После безопасно: типовой код не успеет их удалить.
Для табличной части имя пишется через точку: ИмяТабличнойЧасти.ИмяРеквизита. Если строк нет вовсе, колонка не проверяется. Чтобы требовать хотя бы одну строку, добавьте в массив само имя табличной части: ПроверяемыеРеквизиты.Добавить("Товары").
Обработчика в типовом модуле нет
Аннотацию &После к несуществующему методу не повесить. Самый предсказуемый вариант — подписка на событие внутри расширения:
- В расширении создайте общий модуль
оп_ПроверкаЗаполненияс флагом «Сервер». - Создайте подписку на событие: источник —
ДокументОбъект.<ИмяДокумента>, событие — «ОбработкаПроверкиЗаполнения», обработчик — процедура из общего модуля. - Напишите процедуру с тремя параметрами:
Процедура ОбработкаПроверкиЗаполненияДокумента(Источник, Отказ, ПроверяемыеРеквизиты) Экспорт
ПроверяемыеРеквизиты.Добавить("Комментарий");
КонецПроцедуры
Подписка удобна и тогда, когда одно правило нужно сразу нескольким документам: в источнике можно отметить несколько типов.
Обязательность по условию
Частая задача: поле обязательно только для определённого вида операции или контрагента. Добавляйте имя в массив внутри условия:
&После("ОбработкаПроверкиЗаполнения")
Процедура оп_ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
Если СуммаДокумента > 100000 Тогда
ПроверяемыеРеквизиты.Добавить("Комментарий");
КонецЕсли;
КонецПроцедуры
Имя реквизита-условия (СуммаДокумента, ВидОперации) проверьте в дереве метаданных конкретного документа. В разных документах и конфигурациях оно может отличаться.
Несколько обязательных реквизитов одним списком
Когда обязательных полей пять-шесть, удобно держать их в одной строке. Добавить новое поле тогда — дописать имя через запятую:
&После("ОбработкаПроверкиЗаполнения")
Процедура оп_ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
Обязательные = СтрРазделить("Комментарий,Ответственный,ДоговорКонтрагента", ",", Ложь);
Для Каждого ИмяРеквизита Из Обязательные Цикл
Если ПроверяемыеРеквизиты.Найти(ИмяРеквизита) = Неопределено Тогда
ПроверяемыеРеквизиты.Добавить(ИмяРеквизита);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Проверка через Найти() защищает от дублей: если типовой код уже сделал поле обязательным, сообщение не появится дважды.
Как проверить результат
- Сохраните расширение и обновите конфигурацию базы данных (F7).
- Запустите Предприятие из Конфигуратора (F5) под тестовым пользователем без полных прав.
- Создайте документ, оставьте поле пустым и нажмите «Провести».
- Убедитесь, что появилось сообщение, а двойной щелчок по нему ставит курсор в нужное поле.
- Заполните поле и проведите документ ещё раз — проведение должно пройти без ошибок.
Подсветка обязательного поля на форме
Серверная проверка защищает данные, но пользователь узнаёт о ней только при проведении. Красное пунктирное подчёркивание пустого поля подсказывает заранее. За него отвечает свойство элемента формы АвтоОтметкаНезаполненного.
Через палитру свойств
- В дереве расширения заимствуйте основную форму документа.
- Найдите элемент поля на вкладке «Элементы».
- В свойствах установите «Автоотметка незаполненного» = «Да».
Через код формы
Если в заимствованной форме поле добавляется программно или свойство нужно ставить по условию, используйте обработчик ПриСозданииНаСервере:
&НаСервере
&После("ПриСозданииНаСервере")
Процедура оп_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
Элементы.Комментарий.АвтоОтметкаНезаполненного = Истина;
КонецПроцедуры
Имя элемента формы (Элементы.Комментарий) не всегда совпадает с именем реквизита. Посмотрите его в дереве элементов формы, иначе при открытии документа будет ошибка «Поле объекта не обнаружено».
💡 АвтоОтметкаНезаполненного — только визуальная подсказка. Запись она не останавливает. Обязательность всегда дублируйте проверкой в модуле объекта.
Для условной подсветки есть свойство ОтметкаНезаполненного. Его устанавливают вручную, например в обработчике ПриИзменении поля-условия, когда автоматической отметки мало.
Сообщение об ошибке, привязанное к полю
Стандартный текст платформы «Поле “Комментарий” не заполнено» подставляет синоним реквизита. Если нужен свой текст с пояснением, проверяйте значение сами и выводите сообщение, привязанное к полю. Тогда двойной щелчок по сообщению переводит курсор прямо в нужное поле.
В конфигурациях на БСП (Бухгалтерия 3.0, ЗУП 3.1, УТ 11) используйте общую процедуру:
&После("ОбработкаПроверкиЗаполнения")
Процедура оп_ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
Если Не ЗначениеЗаполнено(Комментарий) Тогда
ОбщегоНазначения.СообщитьПользователю(
"Укажите основание отгрузки в комментарии",
ЭтотОбъект, "Комментарий", , Отказ);
КонецЕсли;
КонецПроцедуры
Процедура сама установит Отказ = Истина и привяжет текст к полю. Без БСП то же делается средствами платформы:
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Укажите основание отгрузки в комментарии";
Сообщение.Поле = "Комментарий";
Сообщение.УстановитьДанные(ЭтотОбъект);
Сообщение.Сообщить();
Отказ = Истина;
Правила хороших сообщений:
- ✅ Говорите, что сделать, а не что сломалось: «Укажите…», «Выберите…».
- ✅ Одно сообщение на одно поле. Не добавляйте реквизит одновременно в массив и в ручную проверку, иначе пользователь увидит два сообщения подряд.
- ✅ Для строки табличной части указывайте поле с номером строки, например
"Товары[0].Количество"(индекс с нуля). Его удобно собирать черезСтрШаблон("Товары[%1].Количество", Строка.НомерСтроки - 1).
Тонкий, веб-клиент и толстый клиент: где проверка работает
Проверка в модуле объекта выполняется на сервере. Поэтому для управляемых форм она одинаково работает в тонком клиенте, веб-клиенте и толстом клиенте в режиме управляемого приложения.
| Клиент | Серверная проверка | Подсветка на форме | На что смотреть |
|---|---|---|---|
| Тонкий клиент | Работает | Работает | Типовой случай, особенностей нет |
| Веб-клиент | Работает | Работает | Не используйте модальные Предупреждение() в клиентском коде проверки, только ПоказатьПредупреждение() |
| Толстый клиент, управляемое приложение | Работает | Работает | Как в тонком клиенте |
| Толстый клиент, обычные формы | Автоматически не вызывается | Нет | Расширения не изменяют обычные формы; нужен вызов ПроверитьЗаполнение() |
Ещё один важный момент — запись из кода. Когда объект записывает обработка, обмен данными или загрузка из файла, автоматическая проверка заполнения не выполняется. Обмен с другой базой не «упадёт» из-за нового обязательного поля. Но и пустые значения через него пройдут.
Если правило должно действовать и для программной записи, переносите его в ПередЗаписью с Отказ = Истина. Делайте это осторожно: такая проверка остановит и загрузку данных при обмене. Учтите флаг ОбменДанными.Загрузка и пропускайте проверку, когда он установлен.
Частые ошибки при настройке обязательного заполнения
Отдельно о правах: расширение в режиме «Адаптация», которое только добавляет код в заимствованные объекты, обычно не требует настройки ролей. Если же вы добавили собственный реквизит или общий модуль с особыми настройками, проверьте работу под обычным пользователем, а не только под администратором.
Частые вопросы
Можно ли подключить такое расширение без Конфигуратора?
Администрирование → Печатные формы, отчеты и обработки → Расширения. Создавать и править код всё равно удобнее в Конфигураторе.Слетит ли обязательность после обновления конфигурации?
Как снять обязательность с типового реквизита через расширение?
Найти() и вызовите Удалить(). Проверку, сделанную типовым кодом вручную, так не отключить — нужен &Вместо с осторожной заменой метода.