Ограничение доступа к контрагентам для конфигурации, в которой функционал ограничения отсутствует по умолчанию
Добрый день, читатель! Я покажу тебе, как в конфигурации (в которой функционал ограничения отсутствует по умолчанию) ограничить сотрудников компании (менеджеров) при работе в 1С только определенными контрагентами.
Например, при заведении Заказа Покупателя (или Поставщика) менеджер может видеть и создавать документы только по определенным Контрагентам. Это сделано для удобства работы отдела продаж, когда за каждым Менеджером в отделе закреплен определенный круг Клиентов. Другие менеджеры не могут видеть и менять чужие заказы, так как в них указаны не их Контрагенты (не закрепленные за ними).
Думаю, я понятно объяснил, что я хочу вам показать.
- Описание
- Подробнее
Описание
Проблемы организации работы в 1С на Предприятии и путь решения
Первоначально такая задача возникла у одного моего клиента, которому понадобилось оптимизировать работу отдела продаж. В его отделе возникали конфликты и даже потасовки между Менеджерами. Возникали ситуации, когда один менеджер редактировал чужие Заказы. Еще были ситуации, когда клиент звонил другому менеджеру, а тот, не зная договоренностей, ставил неправомерную скидку. Ситуаций много, но корень один. Я предложил клиенту изменить работу в 1С таким образом, что у Менеджера в 1С вообще не было возможности работать не со своим Контрагентом. Права на Контрагентов назначает начальник отдела продаж. У Менеджера нет вообще никакой возможности, ни одной лазейки работать не со своим Контрагентом. Ну разве что на уровне СУБД, но туда его никто не пустит. Итак, для тех, кто не в курсе, есть такая возможность в 1С — «Права на уровне записей».
Пример для понимания, что такое Права на уровне записей
Например, у нас есть Заказ №1, в котором указан Контрагент №1, закрепленный за Менеджером №1. В этом случае Менеджер №2, за которым Контрагент №1 НЕ ЗАКРЕПЛЕН, не сможет не только открыть и посмотреть Контрагента как справочник, или увидеть его в списке, он не сможет даже открыть ЗАКАЗ №1, в котором указан Контрагент №1.Это достигается с помощью механизма доступа на уровне записей.
Начнем внедрение в 1С!
Начнем изменение 1С УТ (Управление Торговлей), редакция 10.3, чтобы у нас все вышеперечисленное заработало. Итак, начнем!
![]() | 1.1. Ограничение доступа к Контрагентам на уровне записей у Менеджера при заведении Заказа Покупателя |
На скриншоте показана ситуация, когда Менеджер в 1С открывает список Заказов, создает новый документ и открывает список Контрагентов из документа. В списке Контрагентов видно, что он может видеть и выбирать в Заказ только Контрагентов из своего круга. Круг Контрагентов закрепляется за каждым Менеджером руководителем отдела Продаж.
![]() | 2.1. Роль Менеджер По Продажам |
В роли МенеджерПоПродажам, которая закреплена за каждым пользователем Менеджер, видно, что у Заказов в настройках чтения, добавления, изменения создан шаблон, по которому определяется правомочность доступа на уровне записи. Таким образом, если в Заказе указан чужой, не закрепленный за Менеджером Контрагент, то Менеджер не сможет увидеть и открыть данный Заказ!
![]() | 2.2. Роль Менеджер По Продажам доступ к Контрагентам |
Интересная фишка! Я такое решение нашел, не додумался самостоятельно! Права на справочник Контрагенты ВООБЩЕ СНЯТ! Т.е. чтобы у Менеджера был доступ к Контрагентам, надо это прописать программно. Таким образом все лазейки Менеджеру закрыты. Это сделано для гарантии. Потому что менеджеры — народ ушлый! они ищут лазейки в 1С и находят неожиданные дыры в безопасности. Чтобы Программисту не влетело по шапке, надо все эти лазейки на корню пресечь! Теперь Программист имеет ПОЛНЫЙ контроль над доступом к Контрагентам. Если не прописать доступ программно, то его не будет!Этим мы и займемся!
![]() | 3. Настраиваем регистр Сведений Настройки Прав доступа пользователей в режиме 1с Предприятие |
Добавим записи в регистр у каждого Менеджера. В объекте Доступа Выберем созданный элемент справочника «Группы доступа к контрагентам». Назовем созданный элемент по имени пользователя. В качестве пользователя выберем (создадим, если нет) элемент справочника «Группы пользователей» с наименованием Пользователя
![]() | 4. Вносим изменения в код обработки НастройкаПравДоступа. |
В фукцию ПолучитьСписокОбластейДанных(ТипДанных) и процедуру ПередОткрытием(Отказ, СтандартнаяОбработка) вносим строки, как показано на скриншоте. Вот код функции и процедуры с изменениями:
// Функция определяет список областей данных,
// которые соответствуют переданному типу данных
//
// Параметры
// ТИпДанных - Тип, Анализируемый тип
//
// Возвращаемое значение:
// СписокЗначений
//
Функция ПолучитьСписокОбластейДанных(ТипДанных)
СписокОбластей = Новый СписокЗначений;
Если ТипДанных = Тип("СправочникСсылка.Организации") Тогда
СписокОбластей.Добавить(Перечисления.ВидыОбъектовДоступа.Организации);
ИначеЕсли ТипДанных = Тип("СправочникСсылка.ГруппыДоступаККонтрагентам") Тогда
СписокОбластей.Добавить(Перечисления.ОбластиДанныхОбъектовДоступа.КонтрагентыСписок);
ИначеЕсли ТипДанных = Тип("СправочникСсылка.ГруппыПользователей") Тогда
// Добавим только те виды объектов доступа, для которых нет областей данных
СписокОбластей.Добавить(Перечисления.ВидыОбъектовДоступа.Организации);
// Добавим все области данных
Для каждого Перечисление Из Перечисления.ОбластиДанныхОбъектовДоступа Цикл
СписокОбластей.Добавить(Перечисление);
КонецЦикла;
КонецЕсли;
Возврат СписокОбластей;
КонецФункции
Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
Если НЕ ПараметрыСеанса.ИспользоватьОграниченияПравДоступаНаУровнеЗаписей Тогда
Предупреждение("В конфигурации отключено использование ограничения прав доступа не уровне записей.");
Отказ = Истина;
Возврат;
КонецЕсли;
ТипыОбъектовДоступа = Новый Структура;
ТипыОбъектовДоступа.Вставить("Организации", Тип("СправочникСсылка.Организации"));
ТипыОбъектовДоступа.Вставить("Контрагенты", Тип("СправочникСсылка.ГруппыДоступаККонтрагентам"));
СсылкаОбъекта = ЭтаФорма.КлючУникальности;
МетаданныеОбъекта = СсылкаОбъекта.Метаданные(); ![]() | 4.1. Вносим изменения в общий модуль НастройкаПравДоступа |
Во код с изменениями:
Функция ПолучитьВидОбъектаДоступа(ОбъектДоступа) Экспорт
Если ТипЗнч(ОбъектДоступа) = Тип("СправочникСсылка.Организации") Тогда
Возврат Перечисления.ВидыОбъектовДоступа.Организации;
ИначеЕсли ТипЗнч(ОбъектДоступа) = Тип("СправочникСсылка.ГруппыДоступаККонтрагентам") Тогда
Возврат Перечисления.ВидыОбъектовДоступа.Контрагенты;
Иначе
Возврат Перечисления.ВидыОбъектовДоступа.ПустаяСсылка();
КонецЕсли;
КонецФункции![]() | 5. Для роли в доступе добавляем шаблон ограничений |
![]() | 5.1. Для роли в доступе добавляем шаблон ограничений |
![]() | 5.2. Для роли в доступе добавляем шаблон ограничений |
![]() | 5.3. Для роли в закладке «Шаблоны доступа» добавляем описание шаблонов |
Вот код шаблона «ОрганизацияВШапкеКонтрагентВШапке»
##Если &ИспользоватьОграниченияПравДоступаНаУровнеЗаписей ##Тогда
ТекущаяТаблица ИЗ #ТекущаяТаблица КАК ТекущаяТаблица
ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ РАЗЛИЧНЫЕ
СоставГруппы.Ссылка КАК ГруппаПользователей
ИЗ
Справочник.ГруппыПользователей.ПользователиГруппы КАК СоставГруппы
ГДЕ
СоставГруппы.Пользователь = &ТекущийПользователь) КАК ГруппыПользователей
ПО (&ИспользоватьОграниченияПравДоступаНаУровнеЗаписей)
ГДЕ (&ИспользоватьОграниченияПравДоступаНаУровнеЗаписей = ЛОЖЬ
ИЛИ (НЕ 1 В
(ВЫБРАТЬ ПЕРВЫЕ 1
1 КАК ПолеОтбора
ИЗ
РегистрСведений.НазначениеВидовОбъектовДоступа КАК НазначениеВидовОбъектовДоступа
ГДЕ
НазначениеВидовОбъектовДоступа.ГруппаПользователей = ГруппыПользователей.ГруппаПользователей
И ВЫБОР
КОГДА НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Организации)
И ТекущаяТаблица.#Параметр(1) ССЫЛКА Справочник.Организации
И НЕ ТекущаяТаблица.#Параметр(1) = ЗНАЧЕНИЕ(Справочник.Организации.ПустаяСсылка)
ТОГДА ВЫБОР
КОГДА 1 В
(ВЫБРАТЬ ПЕРВЫЕ 1
1
ИЗ
(ВЫБРАТЬ
1 КАК ПолеОтбора
) КАК Оптмизация ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиПравДоступаПользователей КАК НастройкиПравДоступаПользователей
ПО
НастройкиПравДоступаПользователей.ОбъектДоступа = ТекущаяТаблица.#Параметр(1)
И НастройкиПравДоступаПользователей.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Организации)
И (НастройкиПравДоступаПользователей.Пользователь = НазначениеВидовОбъектовДоступа.ГруппаПользователей
ИЛИ НастройкиПравДоступаПользователей.Пользователь = ЗНАЧЕНИЕ(Справочник.ГруппыПользователей.ВсеПользователи)))
ТОГДА ИСТИНА
ИНАЧЕ ЛОЖЬ
КОНЕЦ
КОГДА НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Контрагенты)
И ТекущаяТаблица.#Параметр(2) ССЫЛКА Справочник.Контрагенты
И НЕ ТекущаяТаблица.#Параметр(2) = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
ТОГДА ВЫБОР
КОГДА 1 В
(ВЫБРАТЬ ПЕРВЫЕ 1
1
ИЗ
Справочник.Контрагенты КАК Контрагенты ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиПравДоступаПользователей КАК НастройкиПравДоступаПользователей
ПО
НастройкиПравДоступаПользователей.ОбъектДоступа = Контрагенты.ГруппаДоступаККонтрагенту
И НастройкиПравДоступаПользователей.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Контрагенты)
И (НастройкиПравДоступаПользователей.Пользователь = НазначениеВидовОбъектовДоступа.ГруппаПользователей
ИЛИ НастройкиПравДоступаПользователей.Пользователь = ЗНАЧЕНИЕ(Справочник.ГруппыПользователей.ВсеПользователи))
ГДЕ
Контрагенты.Ссылка = ТекущаяТаблица.#Параметр(2))
ТОГДА ИСТИНА
ИНАЧЕ ЛОЖЬ
КОНЕЦ
ИНАЧЕ ИСТИНА
КОНЕЦ = ЛОЖЬ))
И НЕ ГруппыПользователей.ГруппаПользователей ЕСТЬ NULL)
##КонецЕсли
Вот код шаблона "ОрганизацияВШапкеКонтрагентВШапке_Запись"
##Если &ИспользоватьОграниченияПравДоступаНаУровнеЗаписей ##Тогда
ТекущаяТаблица ИЗ #ТекущаяТаблица КАК ТекущаяТаблица
ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ РАЗЛИЧНЫЕ
СоставГруппы.Ссылка КАК ГруппаПользователей
ИЗ
Справочник.ГруппыПользователей.ПользователиГруппы КАК СоставГруппы
ГДЕ
СоставГруппы.Пользователь = &ТекущийПользователь) КАК ГруппыПользователей
ПО (&ИспользоватьОграниченияПравДоступаНаУровнеЗаписей)
ГДЕ (&ИспользоватьОграниченияПравДоступаНаУровнеЗаписей = ЛОЖЬ
ИЛИ (НЕ 1 В
(ВЫБРАТЬ ПЕРВЫЕ 1
1 КАК ПолеОтбора
ИЗ
РегистрСведений.НазначениеВидовОбъектовДоступа КАК НазначениеВидовОбъектовДоступа
ГДЕ
НазначениеВидовОбъектовДоступа.ГруппаПользователей = ГруппыПользователей.ГруппаПользователей
И ВЫБОР
КОГДА НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Организации)
И ТекущаяТаблица.#Параметр(1) ССЫЛКА Справочник.Организации
И НЕ ТекущаяТаблица.#Параметр(1) = ЗНАЧЕНИЕ(Справочник.Организации.ПустаяСсылка)
ТОГДА ВЫБОР
КОГДА 1 В
(ВЫБРАТЬ ПЕРВЫЕ 1
1
ИЗ
(ВЫБРАТЬ
1 КАК ПолеОтбора
) КАК Оптмизация ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиПравДоступаПользователей КАК НастройкиПравДоступаПользователей
ПО
НастройкиПравДоступаПользователей.ОбъектДоступа = ТекущаяТаблица.#Параметр(1)
И НастройкиПравДоступаПользователей.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Организации)
И (НастройкиПравДоступаПользователей.Пользователь = НазначениеВидовОбъектовДоступа.ГруппаПользователей
ИЛИ НастройкиПравДоступаПользователей.Пользователь = ЗНАЧЕНИЕ(Справочник.ГруппыПользователей.ВсеПользователи))
И НастройкиПравДоступаПользователей.Запись = ИСТИНА)
ТОГДА ИСТИНА
ИНАЧЕ ЛОЖЬ
КОНЕЦ
КОГДА НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Контрагенты)
И ТекущаяТаблица.#Параметр(2) ССЫЛКА Справочник.Контрагенты
И НЕ ТекущаяТаблица.#Параметр(2) = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
ТОГДА ВЫБОР
КОГДА 1 В
(ВЫБРАТЬ ПЕРВЫЕ 1
1
ИЗ
Справочник.Контрагенты КАК Контрагенты ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиПравДоступаПользователей КАК НастройкиПравДоступаПользователей
ПО
НастройкиПравДоступаПользователей.ОбъектДоступа = Контрагенты.ГруппаДоступаККонтрагенту
И НастройкиПравДоступаПользователей.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Контрагенты)
И (НастройкиПравДоступаПользователей.Пользователь = НазначениеВидовОбъектовДоступа.ГруппаПользователей
ИЛИ НастройкиПравДоступаПользователей.Пользователь = ЗНАЧЕНИЕ(Справочник.ГруппыПользователей.ВсеПользователи))
И НастройкиПравДоступаПользователей.Запись = ИСТИНА
ГДЕ
Контрагенты.Ссылка = ТекущаяТаблица.#Параметр(2))
ТОГДА ИСТИНА
ИНАЧЕ ЛОЖЬ
КОНЕЦ
ИНАЧЕ ИСТИНА
КОНЕЦ = ЛОЖЬ))
И НЕ ГруппыПользователей.ГруппаПользователей ЕСТЬ NULL)
##КонецЕслиВот и все! Все настроено и прекрасно работает! Если у вас будут вопросы, пишите, постараюсь ответить! На этом все, счастливо!










