Публикация написана новичком для новичков, гуру 1С просьба не судить строго.
Введение
Пару дней ваш покорный слуга бродил по Сети в поисках решения своей задачи. Задача заключалась в возможности программно, на лету, менять состав форм рабочего стола, ориентируясь на роли пользователей. На лету означает, что буде в системе суперпользователь, он мог бы менять свой интерфейс не отходя от кассы. Предлагаемые решения не удовлетворяли меня совсем своею громоздкостью и костыльностью.
Как правило, это были варианты с программным добавлением одной необходимой формы на рабочий стол подобным кодом:
Окна = ПолучитьОкна()[0]; ;
ОткрытьФорму(«ОбщаяФорма.ФормаСпискаПринятые», , , , ПолучитьОкна()[0]);
Либо вариация на тему добавления единой формы на рабочий стол, для которой уже создавались вкладки, управляемые вручную. Способ имеет недостаток в именовании элементов формы и скорости работы. Ознакомиться с решением можно вот здесь //infostart.ru/public/82615/
И тогда, Аз грешен, поправ древние заповеди 1С програмёров, открыл Запретную книгу, имя которой не произносят вслух. Однако Вам я всё же открою эту страшную тайну. Руководство разработчика ч.1 её имя. Берегитесь этой книги! Ладно, посмеялись и будет. К делу.
Описание
Задача решается при помощи объектов конфигурации Общая форма и Функциональные опции. Про них как раз подробно написано в Запретной книге. Вкратце: объекты класса Функциональная опция управляют ограничением доступа к данным. На входе эти объекты получают булево значение из константы, справочника или регистра сведений (можно многомерного), на выходе — мягко вырезают из интерфейса и запросов всё, что пользователю видеть и трогать нельзя.
Устанавливать функциональные опции для отдельных форм, например документа, невозможно. Если сделать это для всего документа или справочника, полагаю, можно поиметь множественные траблы в алгоритмах с обращением к данным. Вот тут-то как раз и пригодятся общие формы. Для них и функциональные опции устанавливаются прекрасно и проблемы с доступом к документам, справочникам и т.п. будут исключены.
Механизм следующий: на рабочую область рабочего стола помещаются все формы, которые когда-либо потребуется отображать. Формы — общие. Для каждой формы / группы форм создается и настраивается функциональная опция. На рабочем же столе требуется разместить управляющий элемент. Этот элемент обращается к функциональной опции (либо её хранилищу), и, выставляя значение булевой переменной запрещает к отображению требуемые формы. После чего интерфейс обновляется соответствующей командой.
Порядок действий при управлении ФО при помощи констант:
- Нам нужны аналоги требуемых для отображения форм документов, справочников и т.п. Создаем их простым перетаскиванием в окошке Конфигурация. Тащим в список Общие формы.
- Создаем константы, посредством которых будем управлять функциональными опциями. Тип — Булево.
- Создаем функциональные опции по количеству необходимых ролей, подсистем, чемоданов с деньгами (ненужное зачеркнуть). Для каждой опции указываем свою константу в поле Хранение , а на закладке Состав — подлежащие для скрытия общие формы.
- Создаем обработку, с формы которой мы будем управлять функциональными опциями. На обработку добавляем управляющий элемент, у меня это — простая кнопка. Кто захочет — может сделать неотличимую копию стандартных закладок подсистем.
Скриншотов, надеюсь, не надо?
Дело осталось за малым. Пишем вот такой незатейливый код:
В обработке…
//Обработчик нажатия кнопки Переключить.
&НаКлиенте
Процедура Переключить(Команда)
УправлениеИнтерфейсомСервер.СменитьРоль();
ОбновитьИнтерфейс();
КонецПроцедуры
И в общем модуле (его тоже нужно создать ; ) ). Модуль серверный, с установленным свойством Вызов сервера.
//Сменим значение функциональной опции на противоположное
Процедура СменитьРоль() Экспорт
//Получаем значение функциональной опции. По сути — управляющей ею константы РольНачальника
ЗначениеФОпции = ПолучитьФункциональнуюОпцию(«РабочийСтолНачальника»);
Константы.РольНачальника.Установить(НЕ ЗначениеФОпции);
КонецПроцедуры
В обработчике события УстановкаПараметровСеанса, что в Модуле сеанса, значения констант инициализируются по требуемому Вам алгоритму.
Порядок действий при управлении ФО при помощи регистра сведений:
- Нам нужны аналоги требуемых для отображения форм документов, справочников и т.п. Создаем их простым перетаскиванием в окошке Конфигурация. Тащим в список Общие формы.
- Создаем регистр сведений, посредством которого будем управлять функциональными опциями. Задаем для регистра измерение или набор измерений и ресурс с типом — Булево.
- Создаем требуемые функциональные опции. Для каждой опции в поле Хранение указываем ресурс регистра сведений, а на закладке Состав — подлежащие для скрытия общие формы.
- По числу измерений регистра сведений создаем параметры функциональных опций (ветвь конфигурации Общие). В свойства объекта заполняем поле Использование — измерением ресурса сведений разумеется. Один параметр — одно измерение — любое количество ФО управляется.
- Создаем обработку, с формы которой мы будем управлять функциональными опциями. На обработку добавляем управляющий элемент, в моем случае — список элементов справочника.
Код для управления всем этим хозяйством примерно следующий.
Общий клиентский модуль:
Процедура УстановитьРольПользователя(РольПользователя) Экспорт
//Получаем элемент справочника РолиПользователей, устанавливаем новое значение ФО
РольПользователя = УправлениеИнтерфейсомСервер.ПолучитьРоль(«Менеджер»);
УстановитьПараметрыФункциональныхОпцийИнтерфейса(Новый Структура(«РольПользователя», РольПользователя));
КонецПроцедуры
Общий серверный модуль (УправлениеИнтерфейсомСервер):
Функция ПолучитьРоль(ИмяРоли) Экспорт
Возврат Справочники.РолиПользователей.НайтиПоНаименованию(ИмяРоли);
КонецФункции
Прилагаемая демонстраионная база содержит механизмы управления формами рабочего стола как при помощи констант, так и посредством регистра сведений. Инициализация константы находится в модуле сеанса, инициализация через регистр сведений — в модуле управляемого приложения.
Вот, собственно, и всё.
Благодарю за внимание, надеюсь это сэкономит кому—нибудь время
О. Очень нужная штука. Я это давно искал. Спасибо автору что поделился.
не понял, как набор констант заменяет функцию «УстановитьПараметрыФункциональныхОпцийИнтерфейса()». Если я правильно понимаю, функция позволяет в каждом отдельном сеансе использовать свое значение функциональной опции т.е. для иванова опция «показывать заказы» будет получаться из одной строки регистра, а у петрова — из другой. Таким образом у иванова с петровым будет разный интерфейс (рабочий стол, например). А как этого добиться, если использовать набор опций и набор констант к ним?
А очень просто. Он не заменяет. Если Ивановых и Петровых много, если доступ настраивается для каждого персонально — лучше сделать через функцию «УстановитьПараметрыФункциональныхОпцийИнтерфейса() и регистр сведений соответственно. Статью и пример я доработал. Если у вас две роли железно: техник да менеджер, можно обойтись разединственной константой, которая будет выставляться в нужное значение в зависимости от роли пользователя. Больше ролей — значит и констант больше. Управлять набором констант едва ли сложнее, чем одной. В общем — дело вкуса и требуемого функционала.
Я возможно туплю, но функциональная опция, привязанная к константе одинакова во всех сеансах пользователей и значит, при ее смене в одном сеансе, она изменит интефейс всех пользователей. Нет?
Забавно, но — нет. Константа одна, а вот ФО у каждого своя. На том прием и основан. Значение функциональной опции не изменится пока не вызвать функцию ОбновитьИнтерфейс(), даже если значение константы вдруг изменилось. Таким образом, пользователь в начале сеанса «инициализирует» константу, которая настраивает ему рабочий стол. В дальнейшем как бы константа не менялась, рабочий стол останется прежним до вызова этой функции.
Лично я считаю, что решение с константами не самое лучшее, но оно работает и наглядно демонстрирует принцип. Для чего статья и писалась. Где хранить значение ФО и как им управлять — личное дело каждого.
1) в какой базе тестировалось — файловой или серверной?
2) проверялось только наличие кнопок в интерфейсе или и их доступность?
Поясню: мы пробовали использовать функц.опции с хранением в регистре + установка параметров ОП при начале работы системы. В файловой базе работает нормально, а в серверной нет: 1. заходит пользователь с нормальными правами — у него все норм 2. заходит пользователь с обрезанными правами у него все норм, а вот у первого пользователя кнопки все на месте, но нажатие тех, которых нет в обрезанном интерфейсе, приводит к ошибке «неверная навигационная ссылка» (или типа того).
Что за сервер используется, каков режим блокировок? Наверняка сервер какую-то свою блокировку накладывает дополнительно.
Еще до появления функциональных опций в платформе 1с, эта проблема решалась настройкой видимости по ролям. Т.е. заходит пользователь с одним набором ролей — видит одни формы, заходит с другим набором ролей — другие. По-моему, так было легче. Во всяком случае, у меня в свое время не вызвало больших затруднений. И кода не надо писать.
Изначально свою проблему именно так я и собирался решить. Но у меня пользователь должен иметь возможность работать и со столом менеджера и со столом техника, при этом переключаться он должен динамически, без выхода из программы. Если знаете как это реализовать на ролях, поделитесь пожалуйста.
Грамотный подход. Прежде чем изобретать велосипед, посмотри в «запретную» книгу.
Понимаю, что код в статье дан в качестве примера, но тем не менее, такая реализация (для варианта с константами) будет поуниверсальнее
Подход правильный, но если форма сложная, то простого копирования формы в общие недостаточно. Например падает общая форма на таком коде
УправлениеПечатью.ПриСозданииНаСервере(ЭтаФорма, Элементы.ГруппаПечать)
Извините, что поднимаю древнюю тему, но я с этой задачей столкнулся только сейчас
Реализовап — работает во всех клиентах, кроме веб-клиента — у того какие то проблемы с обновлением интерфейса
На рабочем столе преспокойно присутствуют формы, «закрытые» функциональными опциями, притом при открытии стандартного «Настройка рабочего стола…» формы эти в доступных отсутствуют (ибо запрещены ф.о.) Нажимаем «ОК» — интерфейс перерисовывается как надо. программные «ОбновитьИнтерфейс()» не помогают
Подскажите, есть какие то ньюансы? Или, может, наконец то, сделали «штатный» способ программного изменения состава рабочего стола?
платформа 8.3.13.1513, тестировал через Firefox