В практике разработки на платформе 1С часто возникает задача создания гибких настроек. Например, когда для разных видов документов требуется разный набор обязательных полей. В этой статье мы подробно разберем, как реализовать механизм, при котором в одном справочнике (назовем его ВидыДокументов) выбираются реквизиты другого справочника (Файлы) и устанавливается признак их обязательности.
Для начала нам необходимо понять, как программа может узнать, какие вообще реквизиты есть у справочника Файлы. Для этого мы обратимся к объекту Метаданные. Проанализируем ситуацию: нам нужно перебрать все реквизиты и записать их имена в табличную часть справочника настроек.
Рассмотрим пример кода, который позволяет обойти коллекцию реквизитов:
Для Каждого Реквизит Из Метаданные.Справочники.Файлы.Реквизиты Цикл
// Здесь мы получаем имя реквизита
ИмяРеквизита = Реквизит.Имя;
// Можно также получить синоним для отображения пользователю
СинонимРеквизита = Реквизит.Синоним;
// Далее логика добавления в табличную часть
НоваяСтрока = Объект.РеквизитыДляКонтроля.Добавить();
НоваяСтрока.ИмяРеквизита = ИмяРеквизита;
НоваяСтрока.ПредставлениеРеквизита = СинонимРеквизита;
КонецЦикла;
Важный момент: если мы используем только коллекцию Реквизиты, в список не попадут стандартные поля, такие как Наименование, Код или Владелец. Если вам нужно контролировать и их, следует отдельно обработать коллекцию СтандартныеРеквизиты.
Теперь разберем, как сделать так, чтобы при выборе определенного вида документа в справочнике Файлы нужные поля подсвечивались как обязательные. Самый простой способ — управлять свойствами элементов формы.
Выясним причину, по которой это удобно: пользователь сразу видит красный пунктир (отметку незаполненного), что повышает юзабилити. Проанализируем пример кода для процедуры ПриИзменении реквизита ВидДокумента на форме:
&НаКлиенте
Процедура ВидДокументаПриИзменении(Элемент)
НастроитьПроверкуЗаполненияНаФорме();
КонецПроцедуры
&НаСервере
Процедура НастроитьПроверкуЗаполненияНаФорме()
// Сначала сбрасываем проверку для всех элементов
// (желательно иметь список управляемых реквизитов)
Для каждого СтрокаНастройки Из Объект.ВидДокумента.РеквизитыДляКонтроля Цикл
ИмяПоля = СтрокаНастройки.ИмяРеквизита;
Если Элементы.Найти(ИмяПоля) <> Неопределено Тогда
// Устанавливаем проверку заполнения
Элементы[ИмяПоля].ПроверкаЗаполнения = ?(СтрокаНастройки.КонтрольЗаполнения,
ПроверкаЗаполнения.ВыдаватьОшибку,
ПроверкаЗаполнения.НеПроверять);
// Включаем визуальную отметку (красный пунктир)
Элементы[ИмяПоля].АвтоОтметкаНезаполненного = СтрокаНастройки.КонтрольЗаполнения;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Управление элементами формы — это только половина решения. Если объект будет записываться программно (например, через загрузку данных), проверка на форме не сработает. Чтобы обеспечить целостность данных, мы должны использовать обработчик ОбработкаПроверкиЗаполнения в модуле объекта справочника Файлы.
Рассмотрим, как это реализовать структурно:
ОбработкаПроверкиЗаполнения перед записью.ВидДокумента.ПроверяемыеРеквизиты.Посмотрим на пример реализации в модуле объекта:
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
Если ЗначениеЗаполнено(ВидДокумента) Тогда
// Получаем настройки из справочника ВидыДокументов
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВидыДокументовРеквизитыДляКонтроля.ИмяРеквизита
|ИЗ
| Справочник.ВидыДокументов.РеквизитыДляКонтроля КАК ВидыДокументовРеквизитыДляКонтроля
|ГДЕ
| ВидыДокументовРеквизитыДляКонтроля.Ссылка = &Ссылка
| И ВидыДокументовРеквизитыДляКонтроля.КонтрольЗаполнения = ИСТИНА";
Запрос.УстановитьПараметр("Ссылка", ВидДокумента);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Добавляем реквизит в список проверяемых платформой
Если ПроверяемыеРеквизиты.Найти(Выборка.ИмяРеквизита) = Неопределено Тогда
ПроверяемыеРеквизиты.Добавить(Выборка.ИмяРеквизита);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Разберем несколько важных моментов, которые помогут сделать решение более профессиональным:
1. Оптимизация производительности. Если обращение к настройкам происходит часто, постоянные запросы к базе данных могут замедлить работу. Рассмотрим вариант кэширования настроек. В современных конфигурациях для этого используются модули с повторным использованием значений.
2. Работа с типами данных. При заполнении табличной части в справочнике ВидыДокументов, лучше не давать пользователю вводить имена реквизитов вручную. Реализуйте выпадающий список или форму выбора на основе метаданных, чтобы исключить опечатки в именах ИмяРеквизита.
3. Использование БСП. Если ваша конфигурация основана на "1С:Библиотека стандартных подсистем", проанализируйте подсистему ДополнительныеРеквизитыИСведения. В ней уже заложен механизм динамического добавления реквизитов и настройки их обязательности без изменения структуры метаданных в конфигураторе.
4. Обработка стандартных реквизитов. Как мы уже упоминали, Наименование или Дата (для документов) проверяются отдельно. В коде ОбработкаПроверкиЗаполнения платформа может уже содержать их в массиве ПроверяемыеРеквизиты, поэтому всегда проверяйте наличие элемента в массиве перед добавлением через метод Найти().
Таким образом, мы создали гибкую систему, которая позволяет администратору системы без привлечения программиста определять, какие поля обязательны для заполнения в зависимости от контекста (вида документа). Это значительно снижает количество ошибок ввода данных и делает систему более отказоустойчивой.