Гибкое управление свойствами доступности элементов управления в обычных формах 1С:Предприятия 8.х

04.03.14

Разработка - Работа с интерфейсом

Наверное, одной из самых непростых и скучных задач при проектировании обычной формы в "1С:Предприятии" является управление доступностью элементов в зависимости от того или иного набора данных. Мне встречалось очень много решений: от процедуры вроде УстановитьВидимостьДоступность() с включением в нее всех правил для элементов управления, до совершенно хаотично разбросанных по всему коду обращений к указанным свойствам.

Признаюсь честно, я тоже перепробовал различные способы, но в один прекрасный момент дошел до очень удобного и логичного (как мне кажется), который и будет описан в этой статье.

Все началось с того, что поиск решения для этой задачи натолкнул меня на статью из "Методик разработки" под названием "Организация управления доступом в форме". Ключевым моментом в статье является то, что управление доступом сосредотачивается в одной лишь процедуре УстановитьДоступ(). И если необходимо изменить состояния элементов управления, вызывается только эта процедура. Сама процедура не занимается определением доступа, а работает с данными из списков, которые формируются следующими функциями:

ПолучитьСписокУправлениеВидимостью();
ПолучитьСписокУправлениеДоступностью();
ПолучитьСписокУправлениеТолькоПросмотр();
ПолучитьСписокДоступаКУправлениюВидимостью();

То есть сами условия доступности устанавливаются в этих функциях, а уже процедура УстановитьДоступ() присваивает соответствующим свойствам элементов управления эти заранее установленные значения.

Я разделил код на три составляющих. Первая - это методы, которые как раз выполняют изменения значений свойств доступности элементов формы. Вынес их в общий модуль. Назовем его условно УправлениеДоступом. Ниже расположен код, который размещается в нем. Я постарался максимально прокомментировать малопонятные участки кода.

////////////////////////////////////////////////////////////////////////////////
// ПРОЦЕДУРЫ УПРАВЛЕНИЯ ДОСТУПОМ К ЭЛЕМЕНТАМ ФОРМЫ

Функция ПолучитьСвойствоЭлементаФормы(Знач ЭлементУправления, Знач ИмяСвойства)

    Результат = Неопределено;

    Попытка
        Результат = ЭлементУправления[ИмяСвойства];
    Исключение

    КонецПопытки;

    Возврат Результат;

КонецФункции

Функция ПолучитьЭлементУправленияПоИмени(Форма, Знач ИмяЭлемента)

    // Переменная хранит результат работы функции
    ЭлементУправления = Неопределено;

    ПозицияТочки = Найти(ИмяЭлемента, ".");

    // Если имя элемента состоит из пути, например "Товары.Колонки.Номенклатура",
    // разбиваем на составляющие и проходим путь до конечного элемента.
    Если ПозицияТочки > 0 Тогда
        // Получаем имя основного элемента управления
        ЧастьИмени  = Лев(ИмяЭлемента, ПозицияТочки - 1);

        // Исключаем полученную часть из основного имени
        ИмяЭлемента = Сред(ИмяЭлемента, ПозицияТочки + 1);

        Элемент = ПолучитьСвойствоЭлементаФормы(Форма.ЭлементыФормы, ЧастьИмени);

        Если Элемент <> Неопределено Тогда
            ПозицияТочки = Найти(ИмяЭлемента, ".");

            Пока ПозицияТочки > 0 Цикл
                ЧастьИмени  = Лев(ИмяЭлемента, ПозицияТочки - 1);
                ИмяЭлемента = Сред(ИмяЭлемента, ПозицияТочки + 1);

                Элемент = ПолучитьСвойствоЭлементаФормы(Элемент, ЧастьИмени);
                Если Элемент = Неопределено Тогда
                    Возврат Неопределено;
                КонецЕсли;
  
                ПозицияТочки = Найти(ИмяЭлемента, ".");
            КонецЦикла;

            Элемент = ПолучитьСвойствоЭлементаФормы(Элемент, ИмяЭлемента);
            ЭлементУправления = Элемент;
        КонецЕсли;

    Иначе
        ЭлементУправления = Форма.ЭлементыФормы[ИмяЭлемента];
    КонецЕсли;

    Возврат ЭлементУправления;

КонецФункции

Процедура УстановитьДоступ(Форма) Экспорт

    СписокУправлениеВидимостью = Форма.ПолучитьСписокУправлениеВидимостью();
    Для Каждого ЭлементСписка Из СписокУправлениеВидимостью Цикл
        ЭлементУправления = ПолучитьЭлементУправленияПоИмени(Форма, ЭлементСписка.Представление);

        Если ТипЗнч(ЭлементУправления) = Тип("КолонкаТабличногоПоля") Тогда
            Если ЭлементУправления.ИзменятьВидимость Тогда
                ЭлементУправления.Видимость = ЭлементСписка.Значение;
            Иначе
                ЭлементУправления.ИзменятьВидимость = Истина;
                ЭлементУправления.Видимость         = ЭлементСписка.Значение;
                ЭлементУправления.ИзменятьВидимость = Ложь;
            КонецЕсли;
        Иначе
            ЭлементУправления.Видимость = ЭлементСписка.Значение;
        КонецЕсли;
    КонецЦикла;

    СписокУправлениеДоступностью = Форма.ПолучитьСписокУправлениеДоступностью();
    Для Каждого ЭлементСписка Из СписокУправлениеДоступностью Цикл
        ЭлементУправления = ПолучитьЭлементУправленияПоИмени(Форма, ЭлементСписка.Представление);
        ЭлементУправления.Доступность = ЭлементСписка.Значение;
    КонецЦикла;

    СписокУправлениеТолькоПросмотр = Форма.ПолучитьСписокУправлениеТолькоПросмотр();
    Для Каждого ЭлементСписка Из СписокУправлениеТолькоПросмотр Цикл
        ЭлементУправления = ПолучитьЭлементУправленияПоИмени(Форма, ЭлементСписка.Представление);
        ЭлементУправления.ТолькоПросмотр = ЭлементСписка.Значение;
    КонецЦикла;

    СписокУправлениеРедактированиемТекста = Форма.ПолучитьСписокУправлениеРедактированиемТекста();
    Для Каждого ЭлементСписка Из СписокУправлениеРедактированиемТекста Цикл
        ЭлементУправления = ПолучитьЭлементУправленияПоИмени(Форма, ЭлементСписка.Представление);
        ЭлементУправления.РедактированиеТекста = ЭлементСписка.Значение;
    КонецЦикла;

КонецПроцедуры
Например, у нас есть табличное поле Товары, в котором присутствует колонка СкидкаПоДисконтнойКарте. Колонка видна только тогда, когда дисконтная карта проставлена в документ, т.е. реквизит ДисконтнаяКарта является заполненным. Соответственно, условие списока управления видимостью для колонки СкидкаПоДисконтнойКарте будет следующим:
 
Вторая часть когда - это функции, которые отвечают за формирование списков доступности. Они располагаются непосредственно в форме и являются экспортируемыми. Я немного отошел от стандарта 1С и заменил метод ПолучитьСписокДоступаКУправлениюВидимостью() на ПолучитьСписокУправлениеРедактированиемТекста(). Просто мне кажется, что так удобнее и логичнее. Ниже приведен шаблон кода с этими функциями:
////////////////////////////////////////////////////////////////////////////////
// ЭКСПОРТНЫЕ ПРОЦЕДУРЫ И ФУНКЦИИ

Функция ПолучитьСписокУправлениеВидимостью() Экспорт
  
    СписокУправлениеВидимостью = Новый СписокЗначений;
  
    Возврат СписокУправлениеВидимостью;
  
КонецФункции

Функция ПолучитьСписокУправлениеДоступностью() Экспорт
  
    СписокУправлениеДоступностью = Новый СписокЗначений;
  
    Возврат СписокУправлениеДоступностью;
  
КонецФункции

Функция ПолучитьСписокУправлениеРедактированиемТекста() Экспорт
  
    СписокУправлениеРедактированиемТекста = Новый СписокЗначений;
  
    Возврат СписокУправлениеРедактированиемТекста;
  
КонецФункции  

Функция ПолучитьСписокУправлениеТолькоПросмотр() Экспорт
  
    СписокУправлениеТолькоПросмотр = Новый СписокЗначений;
  
    Возврат СписокУправлениеТолькоПросмотр;
  
КонецФункции

И, наконец, третья часть - это процедура УстановитьДоступ(), которая тоже расположена в модуле формы. Именно эту процедуру мы вызываем в любом месте кода нашей формы, чтобы переопределить доступность элементов формы.

////////////////////////////////////////////////////////////////////////////////
// ПРОЦЕДУРЫ И ФУНКЦИИ ОБЩЕГО НАЗНАЧЕНИЯ

Процедура УстановитьДоступ()

    УправлениеДоступом.УстановитьДоступ(ЭтаФорма);

КонецПроцедуры
Чтобы было все нагляднее и понятнее, давайте рассмотрим следующий пример. Допустим, что у нас есть форма. На ней расположен флажок ЭтоНаличнаяПродажа (булево), флажок ПробиватьФискальныйЧек (булево), поле ввода ДисконтнаяКарта (ссылка на справочник ДисконтныеКарты), поле ввода Комментарий (строка) и табличное поле Товары. Все связаны с одноименными реквизитами. У табличного поля есть колонка с именем СкидкаПоДисконтнойКарте (число). Кроме этого, есть командная панель ОсновныеДействияФормы, на которой размещена кнопка ПробитьЧек. Определим некоторые условия:
 
  1. Если установлен флажок ЭтоНаличнаяПродажа, флажок ПробиватьФискальныйЧек вИдим и поле ДисконтнаяКарта доступно для ввода.
  2. Если стоит флажок ПробиватьФискальныйЧек, кнопка ПробитьЧек доступна.
  3. Если поле ДисконтнаяКарта заполнено, то видна колонка СкидкаПоДисконтнойКарте табличной части Товары и поле ввода Комментарий доступно для редактирования.
Тогда для нашего примера функции определения списков примут следующий вид:
Функция ПолучитьСписокУправлениеВидимостью() Экспорт

    СписокУправлениеВидимостью = Новый СписокЗначений;

    ЗначениеВидимость = ЭтоНаличнаяПродажа;
    СписокУправлениеВидимостью.Добавить(ЗначениеВидимость, "ПробиватьФискальныйЧек");

    ЗначениеВидимость = НЕ ДисконтнаяКарта.Пустая();
    СписокУправлениеВидимостью.Добавить(ЗначениеВидимость, "Товары.Колонки.СкидкаПоДисконтнойКарте");

    Возврат СписокУправлениеВидимостью;

КонецФункции

Функция ПолучитьСписокУправлениеДоступностью() Экспорт

    СписокУправлениеДоступностью = Новый СписокЗначений;

    ЗначениеДоступность = ПробиватьФискальныйЧек;
    СписокУправлениеДоступностью.Добавить(ЗначениеДоступность, "ОсновныеДействияФормы.Кнопки.ПробитьЧек");

    Возврат СписокУправлениеДоступностью;

КонецФункции

Функция ПолучитьСписокУправлениеРедактированиемТекста() Экспорт

    СписокУправлениеРедактированиемТекста = Новый СписокЗначений;

    ЗначениеРедактированиеТекста = ЭтоНаличнаяПродажа И НЕ ДисконтнаяКарта.Пустая();
    СписокУправлениеРедактированиемТекста.Добавить(ЗначениеРедактированиеТекста, "Комментарий");

    Возврат СписокУправлениеРедактированиемТекста;

КонецФункции

Функция ПолучитьСписокУправлениеТолькоПросмотр() Экспорт

    СписокУправлениеТолькоПросмотр = Новый СписокЗначений;

    ЗначениеТолькоПросмотр = ЭтоНаличнаяПродажа;
    СписокУправлениеТолькоПросмотр.Добавить(ЗначениеТолькоПросмотр, "ДисконтнаяКарта");

    Возврат СписокУправлениеТолькоПросмотр;

КонецФункции
Теперь нам достаточно вызвать процедуру формы УстановитьДоступ(), и мы получим то состояние элементов, которые задали.

Хочется выделить следующий момент. В списки можно можно добавлять пути к элементам формы. Например, для вышеприведенного примера с таблицей Товары имя элемента определяем как "Товары.Колонки.СкидкаПоДисконтнойКарте". Или путь к кнопке ПробитьЧек. Можно использовать множественные вложения, вроде "ИмяКоманднойПанели.Кнопки.ИмяПодменю.Кнопки.ИмяКнопки".

Надеюсь, что моя статья вам была интересна и полезна. Сам я использую вышеописанное практически во всех своих решениях, где присутствуют обычные формы "1С:Предприятия". Конечно, многое можно доработать, но это уже надо делать под конкретные нужды.

См. также

Работа с интерфейсом Рабочее место Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Платные (руб)

Богатый редактор картинок 1С предназначен для обработки изображений в режиме «Предприятие», с возможностью РИСОВАТЬ на них. Поддерживается работа как в обычных формах (толстый клиент) так и на управляемых формах (тонкий клиент). Обработка позволяет редактировать как картинки, хранимые в базе, так и графические файлы с диска на файловой системе. Помимо базовых функций (изменение размеров, преобразование формата, обрезание картинки, повороты и т.п.) – редактор имеет богатый набор инструментов для рисования. Доступна функция вставки изображения из буфера обмена. Объект может быть использован: на стороне клиента, на стороне сервера, из внешнего соединения. Обработка будет особенно полезна тем, кто вносит картинки в базу (изображения номенклатуры, фотографии физических лиц и т.п.). Функционал реализуется с использованием JavaScript и бесплатного ПО ImageMagick (без использования внешних компонент).

6000 руб.

16.01.2015    62986    44    59    

82

Работа с интерфейсом Программист Платформа 1С v8.3 Конфигурации 1cv8 1С:ERP Управление предприятием 2 Платные (руб)

Обработка предназначена для создания и управления дашбордами.

2400 руб.

29.06.2020    18855    26    6    

41

Работа с интерфейсом Программист Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Россия Платные (руб)

Редактор графов в 1С - внешний отчет, который формирует графы на основе таблицы значений, используя рисунки табличного документа. Есть возможность добавления, редактирования объектов графа и выгрузки результата в таблицу значений.

1500 руб.

06.10.2020    10224    7    7    

10

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    14732    YA_418728146    7    

166

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    3580    56    progmaster    8    

4

Работа с интерфейсом Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

"MVC плохо применима в 1С" - познакомьтесь с моделью состояния и, возможно, ваше мнение поменяется! Представленное решение является эволюционным развитием идеи реализации MVC для 1С. В новой версии добавлены DSL для описания модели состояния, а также параметризация свойств параметров и элементов формы.

1 стартмани

05.07.2022    5751    kalyaka    6    

33
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. d0dger 84 05.03.14 10:46 Сейчас в теме
Хорошая идея. Видел подобное в одной нетиповой конфигурации. Там так права на реквизиты для пользователей раздавались. Списки получались из регистра сведений с отбором по текущему пользователю...
Оставьте свое сообщение