Как программно отменить проверку заполнения даты в 1С 8.3 при определенных условиях?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки в среде 1С часто возникает задача сделать заполнение конкретного поля обязательным лишь при определенных обстоятельствах. Например, если в документе или справочнике установлен специальный флажок «Без конечной даты», система не должна требовать от пользователя заполнения реквизита ДатаКонец. В этой статье мы подробно разберем, как реализовать такую логику, задействуя механизмы платформы, и обеспечим корректное поведение интерфейса.

Постановка задачи и базовые настройки в конфигураторе

Представим ситуацию: у нас есть два реквизита — ДатаНачало и ДатаКонец. По умолчанию в свойствах обоих реквизитов в конфигураторе установлено значение Проверка заполнения: Выдавать ошибку. Это стандартный механизм платформы 8.3, который автоматически проверяет наличие данных перед записью объекта. Однако нам нужно, чтобы при установленном флажке БезКонечнойДаты проверка для второго поля отключалась.

Проанализируем ситуацию: если мы просто оставим настройку «Выдавать ошибку», платформа всегда будет блокировать запись при пустой дате. Чтобы управлять этим процессом, нам потребуется программное вмешательство в событие проверки заполнения.

Реализация логики в модуле объекта

Основным инструментом для решения нашей задачи является предопределенная процедура ОбработкаПроверкиЗаполнения, расположенная в модуле объекта (документа, справочника и т.д.). Рассмотрим подробнее, как она работает.

Когда пользователь нажимает кнопку «Записать» или «Провести», платформа формирует массив ПроверяемыеРеквизиты. В этот массив автоматически попадают имена всех реквизитов, у которых в конфигураторе стоит свойство «Выдавать ошибку». Процедура ОбработкаПроверкиЗаполнения позволяет нам отредактировать этот массив до того, как система выдаст предупреждение пользователю.

Разберем пример кода, который решает поставленную задачу:


Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
	
	// Проверяем состояние нашего флажка
	Если БезКонечнойДаты Тогда
		
		// Нам нужно найти индекс реквизита в массиве и удалить его
		Позиция = ПроверяемыеРеквизиты.Найти("ДатаКонец");
		
		// Важно проверить, найден ли реквизит, чтобы избежать ошибки
		Если Позиция <> Неопределено Тогда
			ПроверяемыеРеквизиты.Удалить(Позиция);
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

Важный нюанс: использование метода Найти() перед Удалить() критически необходимо. Если в коде просто написать ПроверяемыеРеквизиты.Удалить(ПроверяемыеРеквизиты.Найти("ДатаКонец")), и при этом реквизита по какой-то причине не окажется в массиве (например, его удалило расширение или другое условие), система вернет Неопределено, что приведет к аварийному завершению работы программы.

Почему лучше использовать модуль объекта, а не модуль формы?

Выясним причину, по которой опытные разработчики рекомендуют размещать этот код именно в модуле объекта. Если вы напишете проверку только в модуле формы, она сработает при интерактивной записи пользователем. Однако, если объект будет создаваться или изменяться программно (например, через внешнюю обработку или интеграцию), проверка в форме будет проигнорирована. Размещение логики в модуле объекта гарантирует соблюдение бизнес-правил при любом способе записи данных.

Визуальная индикация на форме (АвтоОтметкаНезаполненного)

Хотя мы отключили проверку в модуле объекта, пользователь может столкнуться с тем, что поле на форме все равно подчеркнуто красным пунктиром. Это свойство АвтоОтметкаНезаполненного. Чтобы интерфейс динамически реагировал на изменение флажка БезКонечнойДаты, выполним следующие шаги:

  1. Создадим на форме обработчик события ПриИзменении для элемента флажка БезКонечнойДаты.
  2. В этом обработчике будем менять свойство элемента формы.

Посмотрим на пример реализации в модуле формы:


&НаКлиенте
Процедура БезКонечнойДатыПриИзменении(Элемент)
	
	УстановитьВидимостьИПроверкуНаСервере();
	
КонецПроцедуры

&НаСервере
Процедура УстановитьВидимостьИПроверкуНаСервере()
	
	// Управляем красным подчеркиванием поля на форме
	Элементы.ДатаКонец.АвтоОтметкаНезаполненного = НЕ Объект.БезКонечнойДаты;
	
КонецПроцедуры

Также не забудьте вызвать процедуру УстановитьВидимостьИПроверкуНаСервере() в событии ПриСозданииНаСервере или ПриЧтенииНаСервере, чтобы при открытии уже существующего документа форма отображалась корректно в соответствии с сохраненным состоянием флажка.

Дополнительные рекомендации по чистоте данных

Проанализируем ситуацию: пользователь заполнил ДатаКонец, а затем передумал и поставил флаг БезКонечнойДаты. В базе данных останется «мусорное» значение даты, которое может исказить отчеты. Хорошим тоном считается очистка значения реквизита при установке флага.

Дополним наш код в модуле формы:


&НаСервере
Процедура УстановитьВидимостьИПроверкуНаСервере()
	
	Элементы.ДатаКонец.АвтоОтметкаНезаполненного = НЕ Объект.БезКонечнойДаты;
	
	Если Объект.БезКонечнойДаты Тогда
		Объект.ДатаКонец = '00010101'; // Очистка даты
	КонецЕсли;
	
КонецПроцедуры

Работа с табличными частями

Если ваши даты находятся не в шапке документа, а в табличной части, принцип остается тем же, но работа с массивом ПроверяемыеРеквизиты усложняется. В этом случае элементы массива имеют формат ИмяТабличнойЧасти[ИндексСтроки].ИмяРеквизита. Чтобы отменить проверку для конкретной строки или колонки в таблице, потребуется обход массива в цикле с проверкой строковых вхождений.

Например, чтобы удалить проверку для конкретной колонки ДатаКонец во всех строках таблицы Состав, можно использовать такой подход:


Для Каждого ТекущийРеквизит Из ПроверяемыеРеквизиты Цикл
    // Здесь логика поиска по маске "Состав[*].ДатаКонец"
КонецЦикла;

Однако чаще всего для табличных частей проще установить в метаданных «Не проверять», а в ОбработкаПроверкиЗаполнения программно добавлять реквизиты в массив только для тех строк, где проверка действительно нужна, используя метод ПроверяемыеРеквизиты.Добавить().

Таким образом, мы рассмотрели комплексный подход к управлению обязательным заполнением полей. Мы не только обеспечили техническую возможность записи объекта без даты, но и позаботились о чистоте данных и удобстве пользовательского интерфейса.

← На главную