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