Признаюсь честно, я тоже перепробовал различные способы, но в один прекрасный момент дошел до очень удобного и логичного (как мне кажется), который и будет описан в этой статье.
Все началось с того, что поиск решения для этой задачи натолкнул меня на статью из «Методик разработки» под названием «Организация управления доступом в форме». Ключевым моментом в статье является то, что управление доступом сосредотачивается в одной лишь процедуре УстановитьДоступ(). И если необходимо изменить состояния элементов управления, вызывается только эта процедура. Сама процедура не занимается определением доступа, а работает с данными из списков, которые формируются следующими функциями:
ПолучитьСписокУправлениеВидимостью(); ПолучитьСписокУправлениеДоступностью(); ПолучитьСписокУправлениеТолькоПросмотр(); ПолучитьСписокДоступаКУправлениюВидимостью();
То есть сами условия доступности устанавливаются в этих функциях, а уже процедура УстановитьДоступ() присваивает соответствующим свойствам элементов управления эти заранее установленные значения.
Я разделил код на три составляющих. Первая — это методы, которые как раз выполняют изменения значений свойств доступности элементов формы. Вынес их в общий модуль. Назовем его условно УправлениеДоступом. Ниже расположен код, который размещается в нем. Я постарался максимально прокомментировать малопонятные участки кода.
//////////////////////////////////////////////////////////////////////////////// // ПРОЦЕДУРЫ УПРАВЛЕНИЯ ДОСТУПОМ К ЭЛЕМЕНТАМ ФОРМЫ Функция ПолучитьСвойствоЭлементаФормы(Знач ЭлементУправления, Знач ИмяСвойства) Результат = Неопределено; Попытка Результат = ЭлементУправления[ИмяСвойства]; Исключение КонецПопытки; Возврат Результат; КонецФункции Функция ПолучитьЭлементУправленияПоИмени(Форма, Знач ИмяЭлемента) // Переменная хранит результат работы функции ЭлементУправления = Неопределено; ПозицияТочки = Найти(ИмяЭлемента, "."); // Если имя элемента состоит из пути, например "Товары.Колонки.Номенклатура", // разбиваем на составляющие и проходим путь до конечного элемента. Если ПозицияТочки > 0 Тогда // Получаем имя основного элемента управления ЧастьИмени = Лев(ИмяЭлемента, ПозицияТочки - 1); // Исключаем полученную часть из основного имени ИмяЭлемента = Сред(ИмяЭлемента, ПозицияТочки + 1); Элемент = ПолучитьСвойствоЭлементаФормы(Форма.ЭлементыФормы, ЧастьИмени); Если Элемент <> Неопределено Тогда ПозицияТочки = Найти(ИмяЭлемента, "."); Пока ПозицияТочки > 0 Цикл ЧастьИмени = Лев(ИмяЭлемента, ПозицияТочки - 1); ИмяЭлемента = Сред(ИмяЭлемента, ПозицияТочки + 1); Элемент = ПолучитьСвойствоЭлементаФормы(Элемент, ЧастьИмени); Если Элемент = Неопределено Тогда Возврат Неопределено; КонецЕсли; ПозицияТочки = Найти(ИмяЭлемента, "."); КонецЦикла; Элемент = ПолучитьСвойствоЭлементаФормы(Элемент, ИмяЭлемента); ЭлементУправления = Элемент; КонецЕсли; Иначе ЭлементУправления = Форма.ЭлементыФормы[ИмяЭлемента]; КонецЕсли; Возврат ЭлементУправления; КонецФункции Процедура УстановитьДоступ(Форма) Экспорт СписокУправлениеВидимостью = Форма.ПолучитьСписокУправлениеВидимостью(); Для Каждого ЭлементСписка Из СписокУправлениеВидимостью Цикл ЭлементУправления = ПолучитьЭлементУправленияПоИмени(Форма, ЭлементСписка.Представление); Если ТипЗнч(ЭлементУправления) = Тип("КолонкаТабличногоПоля") Тогда Если ЭлементУправления.ИзменятьВидимость Тогда ЭлементУправления.Видимость = ЭлементСписка.Значение; Иначе ЭлементУправления.ИзменятьВидимость = Истина; ЭлементУправления.Видимость = ЭлементСписка.Значение; ЭлементУправления.ИзменятьВидимость = Ложь; КонецЕсли; Иначе ЭлементУправления.Видимость = ЭлементСписка.Значение; КонецЕсли; КонецЦикла; СписокУправлениеДоступностью = Форма.ПолучитьСписокУправлениеДоступностью(); Для Каждого ЭлементСписка Из СписокУправлениеДоступностью Цикл ЭлементУправления = ПолучитьЭлементУправленияПоИмени(Форма, ЭлементСписка.Представление); ЭлементУправления.Доступность = ЭлементСписка.Значение; КонецЦикла; СписокУправлениеТолькоПросмотр = Форма.ПолучитьСписокУправлениеТолькоПросмотр(); Для Каждого ЭлементСписка Из СписокУправлениеТолькоПросмотр Цикл ЭлементУправления = ПолучитьЭлементУправленияПоИмени(Форма, ЭлементСписка.Представление); ЭлементУправления.ТолькоПросмотр = ЭлементСписка.Значение; КонецЦикла; СписокУправлениеРедактированиемТекста = Форма.ПолучитьСписокУправлениеРедактированиемТекста(); Для Каждого ЭлементСписка Из СписокУправлениеРедактированиемТекста Цикл ЭлементУправления = ПолучитьЭлементУправленияПоИмени(Форма, ЭлементСписка.Представление); ЭлементУправления.РедактированиеТекста = ЭлементСписка.Значение; КонецЦикла; КонецПроцедуры
Например, у нас есть табличное поле Товары, в котором присутствует колонка СкидкаПоДисконтнойКарте. Колонка видна только тогда, когда дисконтная карта проставлена в документ, т.е. реквизит ДисконтнаяКарта является заполненным. Соответственно, условие списока управления видимостью для колонки СкидкаПоДисконтнойКарте будет следующим:
Вторая часть когда — это функции, которые отвечают за формирование списков доступности. Они располагаются непосредственно в форме и являются экспортируемыми. Я немного отошел от стандарта 1С и заменил метод ПолучитьСписокДоступаКУправлениюВидимостью() на ПолучитьСписокУправлениеРедактированиемТекста(). Просто мне кажется, что так удобнее и логичнее. Ниже приведен шаблон кода с этими функциями:
//////////////////////////////////////////////////////////////////////////////// // ЭКСПОРТНЫЕ ПРОЦЕДУРЫ И ФУНКЦИИ Функция ПолучитьСписокУправлениеВидимостью() Экспорт СписокУправлениеВидимостью = Новый СписокЗначений; Возврат СписокУправлениеВидимостью; КонецФункции Функция ПолучитьСписокУправлениеДоступностью() Экспорт СписокУправлениеДоступностью = Новый СписокЗначений; Возврат СписокУправлениеДоступностью; КонецФункции Функция ПолучитьСписокУправлениеРедактированиемТекста() Экспорт СписокУправлениеРедактированиемТекста = Новый СписокЗначений; Возврат СписокУправлениеРедактированиемТекста; КонецФункции Функция ПолучитьСписокУправлениеТолькоПросмотр() Экспорт СписокУправлениеТолькоПросмотр = Новый СписокЗначений; Возврат СписокУправлениеТолькоПросмотр; КонецФункции
И, наконец, третья часть — это процедура УстановитьДоступ(), которая тоже расположена в модуле формы. Именно эту процедуру мы вызываем в любом месте кода нашей формы, чтобы переопределить доступность элементов формы.
//////////////////////////////////////////////////////////////////////////////// // ПРОЦЕДУРЫ И ФУНКЦИИ ОБЩЕГО НАЗНАЧЕНИЯ Процедура УстановитьДоступ() УправлениеДоступом.УстановитьДоступ(ЭтаФорма); КонецПроцедуры
Чтобы было все нагляднее и понятнее, давайте рассмотрим следующий пример. Допустим, что у нас есть форма. На ней расположен флажок НаличнаяПродажа (булево), флажок ПробиватьФискальныйЧек (булево), поле ввода ДисконтнаяКарта (ссылка на справочник ДисконтныеКарты), поле ввода Комментарий (строка) и табличное поле Товары. Все связаны с одноименными реквизитами. У табличного поля есть колонка с именем СкидкаПоДисконтнойКарте (число). Кроме этого, есть командная панель ОсновныеДействияФормы, на которой размещена кнопка ПробитьЧек. Определим некоторые условия:
- Если установлен флажок НаличнаяПродажа, флажок ПробиватьФискальныйЧек видим и поле ДисконтнаяКарта доступно для ввода.
- Если стоит флажок ПробиватьФискальныйЧек, кнопка ПробитьЧек доступна.
- Если поле ДисконтнаяКарта заполнено, то видна колонка СкидкаПоДисконтнойКарте табличной части Товары и поле ввода Комментарий доступно для редактирования.
Тогда для нашего примера функции определения списков примут следующий вид:
Функция ПолучитьСписокУправлениеВидимостью() Экспорт СписокУправлениеВидимостью = Новый СписокЗначений; ЗначениеВидимость = НаличнаяПродажа; СписокУправлениеВидимостью.Добавить(ЗначениеВидимость, "ПробиватьФискальныйЧек"); ЗначениеВидимость = НЕ ДисконтнаяКарта.Пустая(); СписокУправлениеВидимостью.Добавить(ЗначениеВидимость, "Товары.Колонки.СкидкаПоДисконтнойКарте"); Возврат СписокУправлениеВидимостью; КонецФункции Функция ПолучитьСписокУправлениеДоступностью() Экспорт СписокУправлениеДоступностью = Новый СписокЗначений; ЗначениеДоступность = ПробиватьФискальныйЧек; СписокУправлениеДоступностью.Добавить(ЗначениеДоступность, "ОсновныеДействияФормы.Кнопки.ПробитьЧек"); Возврат СписокУправлениеДоступностью; КонецФункции Функция ПолучитьСписокУправлениеРедактированиемТекста() Экспорт СписокУправлениеРедактированиемТекста = Новый СписокЗначений; ЗначениеРедактированиеТекста = НаличнаяПродажа И НЕ ДисконтнаяКарта.Пустая(); СписокУправлениеРедактированиемТекста.Добавить(ЗначениеРедактированиеТекста, "Комментарий"); Возврат СписокУправлениеРедактированиемТекста; КонецФункции Функция ПолучитьСписокУправлениеТолькоПросмотр() Экспорт СписокУправлениеТолькоПросмотр = Новый СписокЗначений; ЗначениеТолькоПросмотр = НаличнаяПродажа; СписокУправлениеТолькоПросмотр.Добавить(ЗначениеТолькоПросмотр, "ДисконтнаяКарта"); Возврат СписокУправлениеТолькоПросмотр; КонецФункции
Теперь достаточно вызвать процедуру формы УстановитьДоступ(), и мы получим то состояние элементов, которые задали.
Хочется выделить следующий момент. В списки можно можно добавлять пути к элементам формы. Например, для вышеприведенного примера с таблицей Товары имя элемента определяем как «Товары.Колонки.СкидкаПоДисконтнойКарте». Или путь к кнопке ПробитьЧек. Можно использовать множественные вложения, вроде «ИмяКоманднойПанели.Кнопки.ИмяПодменю.Кнопки.ИмяКнопки».
Предлагаемый вариант не конечный. Можно внести множество мелких дополнений, вроде указаний, какие списки обрабатывать а какие нет. Но это уже зависит от точечных потребностей разработчика.
Спасибо за внимание.
ссылка на оригинал статьи http://habrahabr.ru/post/214581/
Добавить комментарий