Контроль прав пользователей при изменении категорий объектов

30.09.12

Разработка - Инструментарий разработчика

Вариант решения задачи контроля прав пользователей при изменении категорий объектов или сказ о том, как добавить флажок "Оригинал получен" для отслеживания того, что бухгалтерия получила бумажные оригиналы документов, но не давать этот флажок устанавливать кому ни попадя.

Файлы

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование Скачано Купить файл
ПраваНаКатегории.zip
.zip 15,29Kb
22 2 500 руб. Купить

Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний

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

Оформить подписку и скачать решение со скидкой

Вы можете заказать платную доработку или адаптацию этой разработки под вашу конфигурацию на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

Предисловие

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

Задача

Обеспечить возможность разграничения прав пользователей для работы с категориями объектов в 1С: УПП.

Шаг 1. Добавляем регистр для хранения сведений о правах пользователей и код для работы с ним.

Вообще таких велосипедов, как регистр сведений, хранящий права пользователей, наделано уже великое множество. И каждый волен выбрать себе тот велосипед, который ему больше по душе. Для нашей задачи главное чтобы имелась в наличии экспортная функция общего модуля Функция ПолучитьРазрешенныеСвойстваИКатегории(Пользователь, СписокСвойствИКатегорий = Неопределено) Экспорт, которая будет возвращать массив категорий, которые Пользователь имеет право изменять (в параметре СписокСвойствИКатегорий передаётся интересующая нас категория или массив категорий; Неопределено в этом параметре означает что нас интересуют права на все категории). Если такая функция у вас уже есть - можно переходить к шагу 2.

Мой "велосипед" таков (в моём регистре помимо прав на изменение категорий можно также задавать права на изменение свойств объектов - это задел на будущее когда понадобится ещё разграничивать права пользователей на установку свойств объектов):


1. Непериодический независимый регистр сведений Префикс_ПраваДоступаДляДопСвойств ("Префикс" замените на свой префикс разработчика), имеющий
Измерения

- Субъект - тип {СправочникСсылка.Пользователи, СправочникСсылка.ГруппыПользователей}, Ведущее, Основной отбор;
- ОбъектДоступа - тип {СправочникСсылка.КатегорииОбъектов, ПланВидовХарактеристикСсылка.СвойстваОбъектов}, Ведущее, Основной отбор, Запрет незаполненных значений;

Ресурсы

- ДоступРазрешен - тип Булево.

Определение прав пользователя осуществляется следующим образом. Самым высоким приоритетом обладает право установленное для конкретного пользователя, более низким приоритетом обладает право установленное для группы, в которую входит данный пользователь, и, наконец, самым низким приоритетом обладает право установленное для всех пользователей (в качестве Субъекта указана предопределённая группа "Все пользователи" или Субъект не заполнен). В качестве права пользователя берётся право с максимальным приоритетом (пользователь->группа->все). Если право для пользователя не найдено, то считается что доступ пользователю запрещён.

 

В приведённом примере Пользователь1 не имеет прав на изменение категории "Категория1" (запрет задан явно для этого пользователя), хотя все остальные пользователи имеют право на изменение этой категории (право дано через группу "Все пользователи"). Пользователь1 имеет право на изменение категории "Категория3" (право дано всем пользователям, т.к. не указан Субъект) и изменение свойства "Торговая марка" (право задано явно для этого пользователя). Все пользователи группы Группа1 имеют право изменять категорию "Категория2".

2. Функция ПолучитьРазрешенныеСвойстваИКатегории() для получения массива категорий, которые пользователь имеет право изменять:

Функция ПолучитьРазрешенныеСвойстваИКатегории(Пользователь, СписокСвойствИКатегорий = Неопределено) Экспорт
	
	// 
	Запрос = Новый Запрос;
	Запрос.УстановитьПараметр("Пользователь", Пользователь);
	Запрос.УстановитьПараметр("СписокСвойствИКатегорий", СписокСвойствИКатегорий);

	ВсеСубъекты = Новый Массив; // через этих субъектов устанавливаются права вообще всем пользователям
	ВсеСубъекты.Добавить(Неопределено);
	ВсеСубъекты.Добавить(Справочники.Пользователи.ПустаяСсылка());
	ВсеСубъекты.Добавить(Справочники.ГруппыПользователей.ПустаяСсылка());
	ВсеСубъекты.Добавить(Справочники.ГруппыПользователей.ВсеПользователи);	
	Запрос.УстановитьПараметр("ВсеСубъекты", ВсеСубъекты);
	
	Запрос.Текст =
	"ВЫБРАТЬ
 | ГруппыПользователейПользователиГруппы.Ссылка
 |ПОМЕСТИТЬ ВТ_ГруппыПользователя
 |ИЗ
 | Справочник.ГруппыПользователей.ПользователиГруппы КАК ГруппыПользователейПользователиГруппы
 |ГДЕ
 | ГруппыПользователейПользователиГруппы.Пользователь = &Пользователь
 |;
 |
 |////////////////////////////////////////////////////////////////////////////////
 |ВЫБРАТЬ
 | ВЫБОР
 | КОГДА ПраваДоступаДляДопСвойств.Субъект = &Пользователь
 | ТОГДА 3
 | КОГДА ПраваДоступаДляДопСвойств.Субъект ССЫЛКА Справочник.ГруппыПользователей
 | И НЕ ПраваДоступаДляДопСвойств.Субъект В (&ВсеСубъекты)
 | ТОГДА 2
 | ИНАЧЕ 1
 | КОНЕЦ КАК Приоритет,
 | ПраваДоступаДляДопСвойств.ОбъектДоступа КАК ОбъектДоступа,
 | ПраваДоступаДляДопСвойств.ДоступРазрешен КАК ДоступРазрешен
 |ПОМЕСТИТЬ ВТ_ПраваДоступаСПриоритетами
 |ИЗ
 | РегистрСведений.Префикс_ПраваДоступаДляДопСвойств КАК ПраваДоступаДляДопСвойств
 |ГДЕ
 | (ПраваДоступаДляДопСвойств.Субъект = &Пользователь
 | ИЛИ ПраваДоступаДляДопСвойств.Субъект В
 | (ВЫБРАТЬ
 | ВТ_ГруппыПользователя.Ссылка
 | ИЗ
 | ВТ_ГруппыПользователя)
 | ИЛИ ПраваДоступаДляДопСвойств.Субъект В (&ВсеСубъекты))
 | И &УсловиеСписокСвойствИКатегорий
 |;
 |
 |////////////////////////////////////////////////////////////////////////////////
 |ВЫБРАТЬ
 | ВТ_ПраваДоступаСПриоритетами.ОбъектДоступа КАК ОбъектДоступа
 |ИЗ
 | ВТ_ПраваДоступаСПриоритетами КАК ВТ_ПраваДоступаСПриоритетами
 | ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
 | ВТ_ПраваДоступаСПриоритетами.ОбъектДоступа КАК ОбъектДоступа,
 | МАКСИМУМ(ВТ_ПраваДоступаСПриоритетами.Приоритет) КАК Приоритет
 | ИЗ
 | ВТ_ПраваДоступаСПриоритетами КАК ВТ_ПраваДоступаСПриоритетами
 | 
 | СГРУППИРОВАТЬ ПО
 | ВТ_ПраваДоступаСПриоритетами.ОбъектДоступа) КАК ВложенныйЗапрос
 | ПО ВТ_ПраваДоступаСПриоритетами.ОбъектДоступа = ВложенныйЗапрос.ОбъектДоступа
 | И ВТ_ПраваДоступаСПриоритетами.Приоритет = ВложенныйЗапрос.Приоритет
 |ГДЕ
 | ВТ_ПраваДоступаСПриоритетами.ДоступРазрешен";
	
	
	УсловиеСписокСвойствИКатегорий = ?(СписокСвойствИКатегорий = Неопределено, 
				"ИСТИНА", 
				"ПраваДоступаДляДопСвойств.ОбъектДоступа В (&СписокСвойствИКатегорий)");
	Запрос.Текст = СтрЗаменить(Запрос.Текст, "&УсловиеСписокСвойствИКатегорий", УсловиеСписокСвойствИКатегорий);
	
	Возврат Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("ОбъектДоступа");
	
КонецФункции

Шаг 2. Добавляем подписку на событие ПередЗаписью для регистра сведений КатегорииОбъектов.

Сам контроль прав будем осуществлять через подписку на событие ПередЗаписью для регистра сведений КатегорииОбъектов (Источник события РегистрСведенийНаборЗаписей.КатегорииОбъектов):

Обработчик события такой:

Процедура Префикс_ПередЗаписьюКатегорийОбъекта(Источник, Отказ, Замещение) Экспорт
	
	Если Источник.ОбменДанными.Загрузка Тогда
		Возврат;
	КонецЕсли;
	
	Заголовок = "Запись регистра сведений " + Источник.Метаданные().Имя + ":";
	
	ОтборИсточника = Источник.Отбор;
	Если НЕ ОтборИсточника.Категория.Использование Тогда
		ТекстСообщения = "Не установлен отбор по измерению ""Категория""!";
		ОбщегоНазначения.СообщитьОбОшибке(ТекстСообщения, Отказ, Заголовок);
		Возврат;
	КонецЕсли;
	
	ТекПользователь		= глЗначениеПеременной("глТекущийПользователь");
	Категория			= ОтборИсточника.Категория.Значение;
	РазрешенныеКатегории	= ПолучитьРазрешенныеСвойстваИКатегории(ТекПользователь, Категория);
	Если РазрешенныеКатегории.Найти(Категория) = Неопределено Тогда
		ТекстСообщения = "Недостаточно прав для изменения категории """ + Категория + """!";
		ОбщегоНазначения.СообщитьОбОшибке(ТекстСообщения, Отказ, Заголовок);
		Возврат;
	КонецЕсли;
	
КонецПроцедуры

Шаг 3. Модифицируем штатную обработку КатегорииОбъектов.

К сожалению, совсем обойтись без изменения штатных объектов не удалось. Дело в том, что штатная обработка КатегорииОбъектов, которая вызывается из форм справочников и документов по соответствующей кнопке, записывает регистр сведений КатегорииОбъектов набором записей с отбором только по Объекту. Если в записываемом наборе записей будут категории, которые пользователь не имеет права изменять и одновременно с этим в нём будут категории, которые пользователь изменять может, то мы не сможем ни записать такой набор, ни отказаться от его записи. Да, конечно можно просмотреть записываемый набор записей, найти в нём те категории, которые пользователь изменять не имеет права, прочитать значения этих категорий из базы и если прочитанные из базы значения отличаются от значений в наборе записей, то подменить значения изменённых категорий в наборе на значения  из базы, а пользователю сказать  "Ай-яй-яй!", но по-моему это излишне усложнит алгоритм. Тем более что другие обработки (в частности, "Групповая обработка ..."), пишут наборы записей с полным отбором по Объект+Категория.

Для исправления ситуации в модуле обработки КатегорииОбъектов была модифицирована Функция ЗаписатьКатегорииОбъекта() Экспорт так, чтобы запись регистра сведений осуществлялась с отбором по Объект+Категория.

// Функция записывеет категории объекта в информационную базу.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Истина - если категории объекта были записаны, или их не требуется записывать
// Ложь - если категории объекта не удалось записать.
//
Функция ЗаписатьКатегорииОбъекта() Экспорт

	// *** Разграничение прав пользователей на установку категорий объектов
	//НаборЗаписейКатегорииОбъекта = РегистрыСведений.КатегорииОбъектов.СоздатьНаборЗаписей();

	//Для каждого Строка Из КатегорииОбъекта Цикл
	// Если Строка.Принадлежность Тогда
	// Запись = НаборЗаписейКатегорииОбъекта.Добавить();

	// Запись.Объект = ОбъектОтбораКатегорий;
	// Запись.Категория = Строка.Категория;
	// КонецЕсли;
	//КонецЦикла;

	//НаборЗаписейКатегорииОбъекта.Отбор.Объект.Установить(ОбъектОтбораКатегорий);

	//Попытка
	// НаборЗаписейКатегорииОбъекта.Записать();
	//Исключение
	// #Если Клиент Тогда
	// Предупреждение("Не удалось записать категории объекта:" + Символы.ПС + ОписаниеОшибки());
	// #КонецЕсли
	// Возврат Ложь;
	//КонецПопытки;
	
	// ---------- заменено на:
	
	НачатьТранзакцию();
	
	// Прочитаем категории из БД
	НаборЗаписейБД = РегистрыСведений.КатегорииОбъектов.СоздатьНаборЗаписей();
	НаборЗаписейБД.Отбор.Объект.Установить(ОбъектОтбораКатегорий);
	НаборЗаписейБД.Прочитать();
	УстановленныеКатегорииБД = НаборЗаписейБД.ВыгрузитьКолонку("Категория");
	
	// Получим разрешенные категории
	ТекПользователь			= глЗначениеПеременной("глТекущийПользователь");
	РазрешенныеКатегории	= Префикс_ПраваДоступаДляДопСвойств.ПолучитьРазрешенныеСвойстваИКатегории(ТекПользователь, КатегорииОбъекта.ВыгрузитьКолонку("Категория"));
	
	Для каждого Строка Из КатегорииОбъекта Цикл
	
		ПринадлежностьПоДаннымБД = (УстановленныеКатегорииБД.Найти(Строка.Категория) <> Неопределено);
		
		Если ПринадлежностьПоДаннымБД = Строка.Принадлежность Тогда
			// значение данной категории не изменилась
			Продолжить;
		ИначеЕсли РазрешенныеКатегории.Найти(Строка.Категория) = Неопределено Тогда
			// у пользователя нет прав
			ОтменитьТранзакцию();
			ТекстСообщения = "Недостаточно прав для изменения категории """ + Строка.Категория + """!";
 #Если Клиент Тогда
				Предупреждение(ТекстСообщения);
 #Иначе
				Сообщить(ТекстСообщения, СтатусСообщения.Важное);
 #КонецЕсли
			Возврат Ложь;
		КонецЕсли;
		
		НаборЗаписейКатегорииОбъекта = РегистрыСведений.КатегорииОбъектов.СоздатьНаборЗаписей();

		НаборЗаписейКатегорииОбъекта.Отбор.Объект.Установить(ОбъектОтбораКатегорий);
		НаборЗаписейКатегорииОбъекта.Отбор.Категория.Установить(Строка.Категория);
		
		Если Строка.Принадлежность Тогда
			Запись = НаборЗаписейКатегорииОбъекта.Добавить();

			Запись.Объект    = ОбъектОтбораКатегорий;
			Запись.Категория = Строка.Категория;
		КонецЕсли;		
		
		Попытка
			НаборЗаписейКатегорииОбъекта.Записать();
		Исключение
			ОтменитьТранзакцию();
			Сообщить("Не удалось записать категории объекта:" + Символы.ПС + ОписаниеОшибки(), СтатусСообщения.Важное);
			Возврат Ложь;
		КонецПопытки;
		
	КонецЦикла;
	
	ЗафиксироватьТранзакцию();
	
	Возврат Истина;
	// Разграничение прав пользователей на установку категорий объектов ***
	
КонецФункции

Заключение

В прилагаемом архиве текстовые файлы с кодом процедур и функций, приведённых выше, а также модифицированная обработка КатегорииОбъектов с изменённиями в функции ЗаписатьКатегорииОбъекта(), описанными в разделе "Шаг 3".

Буду рад дельным замечаниям и предложениям по теме в комментариях (если кто знает как более просто и изящно решить задачу с добавлением признака "Оригинал получен" - обязательно поделитесь опытом).

Все права на код обработки КатегорииОбъектов принадлежат фирме 1С.

Весь остальной код - под GPLv3, а текст под CC-BY.

P.S. Возможно, обработку КатегорииОбъектов имеет смысл ещё немного допилить чтобы в табличную часть КатегорииОбъекта выводились только те категории, которые пользователь имеет право изменять (ну или выводить все, но строки с запрещёнными для изменения категориями делать недоступными для редактирования).

Вступайте в нашу телеграмм-группу Инфостарт

См. также

Инструментарий разработчика Роли и права Запросы СКД Программист Руководитель проекта 1С:Предприятие 8 Платные (руб)

Инструменты для разработчиков 1С 8.3: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

16500 руб.

02.09.2020    267448    1488    421    

1178

Инструментарий разработчика Чистка данных Свертка базы Инструменты администратора БД Системный администратор Программист Руководитель проекта 1С:Предприятие 8 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 Россия Платные (руб)

Инструмент представляет собой обработку для проведения свёртки или обрезки баз данных. Работает на ЛЮБЫХ конфигурациях (УТ, БП, ERP, УНФ, КА и т.д.). Поддерживаются серверные и файловые базы, управляемые и обычные формы, интерфейс 8.5. Может выполнять свертку одновременно в несколько потоков, а также без непосредственного участия пользователя. Решение в Реестре отечественного ПО.

24900 руб.

20.08.2024    74667    377    170    

322

Пакетная печать Печатные формы Инструментарий разработчика Программист 1С:Предприятие 8 Платные (руб)

Расширение для создания и редактирования печатных форм в системе 1С:Предприятие 8.3. Благодаря конструктору можно значительно снизить затраты времени на разработку печатных форм, повысить качество и прозрачность разработки, а также навести порядок в многообразии корпоративных печатных форм. Обновление версии от 21.04.26

22570 руб.

06.10.2023    39986    112    54    

126

Инструментарий разработчика Нейросети Платные (руб)

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

15250 руб.

25.08.2025    63037    130    36    

136

Инструментарий разработчика Разработка Администрирование веб-серверов Системный администратор Программист Бизнес-аналитик Руководитель проекта 1С 8.3 Платные (руб)

Analyzer 1C сводит выгрузку 1С — основную конфигурацию и все расширения — в единый граф знаний. Любой запрос по связям за доли секунды, с пометками «Доб.» / «Заимств.» / «Переопределено». Новое в 2.0 — обновление поставки: сравнение и объединение версий деревом «как в Конфигураторе» с выгрузкой плана решений; поиск конфликтов из-за перехватов расширений и висячих ссылок; загрузка из бинарных .cf/.cfe; циклические зависимости. Плюс анализ влияния, запросы BSL, роли и RLS, граф вызовов. Минута на развёртывание через Docker без необходимости подключения к Интернет. Любая 1С:Предприятие 8.3+.

14000 руб.

17.04.2026    8616    36    46    

51

Инструменты администратора БД Инструментарий разработчика Роли и права Программист 1С:Предприятие 8 1C:Бухгалтерия Россия Платные (руб)

Расширение позволяет без изменения кода конфигурации выполнять проверки при вводе данных, скрывать от пользователя недоступные ему данные, выполнять код в обработчиках. Не изменяет данные конфигурации, легко устанавливается практически на любую конфигурацию на управляемых формах.

17000 руб.

10.11.2023    26313    98    46    

104

Мастера заполнения Поиск данных Инструментарий разработчика Подбор и обработка объектов 1С 8.3 1С 8.5 Платные (руб)

Infostart MagicInput улучшает подбор в полях ввода 1С: ищет по любой части названия и по нескольким ключевым фрагментам, распознаёт ввод в другой раскладке и показывает иконки/статусы объектов прямо в списке. Поддерживает вставку навигационной ссылки/представления документа для автоподбора; для разработчиков доступны поиск по GUID и полному имени предопределённого. Работает в управляемых формах и подключается в большинстве конфигураций 1С 8.3/8.5.

6000 руб.

25.02.2026    4738    16    1    

20

Информационная безопасность Инструменты администратора БД Инструментарий разработчика Учет документов Системный администратор Программист Бизнес-аналитик Бухгалтер Пользователь Руководитель проекта 1С 8.3 1С 8.5 Розничная и сетевая торговля (FMCG) Платные (руб)

Контроль ввода данных в 1С: проверка заполнения реквизитов, обязательные поля, контроль перед записью и проведением, запрет проведения документа. Позволяет настраивать любые проверки данных в 1С 8.3/8.5 от обязательных полей до сложных условий – без открытия конфигуратора и написания кода. Готовое расширение, которое подключается и работает сразу.

6000 руб.

15.04.2026    2520    6    0    

21
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. iov 408 30.09.12 22:54 Сейчас в теме
А тоже самое без вмешательства в штатный код?
2. q_i 587 30.09.12 23:08 Сейчас в теме
(1) iov, с удовольствием бы, но пока увы. есть идеи? ;)
3. iov 408 30.09.12 23:21 Сейчас в теме
(2) Есть - но не поделюсь... Ибо последствия решения задачи разными способами - на совести "решателя".
Просто хотел натолкнуть на мысль решения проблемы с минимальным изменением конфы.
4. q_i 587 30.09.12 23:43 Сейчас в теме
(3) iov,
Есть - но не поделюсь...
Просто хотел натолкнуть на мысль решения проблемы с минимальным изменением конфы.

Ну теперь даже и не знаю стоит ли мне браться за решение данной задачи - вдруг тоже решу, а потом делиться не захочется. ))
5. iov 408 30.09.12 23:50 Сейчас в теме
(5) Нет я не за жадность - просто я не считаю это чем-то что поможет кому-то и потому нет желания захламлять ресурс... Так что если Вы не захотите делится - это вполне нормально... Не все мысли должны покидать голову.
6. q_i 587 01.10.12 11:22 Сейчас в теме
(5) iov, успокоили. спасибо!
7. iov 408 01.10.12 15:21 Сейчас в теме
(6) За успокоительное 50 руб - в кассу :)
8. q_i 587 02.10.12 11:40 Сейчас в теме
(7) iov, держите:
Дт 50 Кт 66 Сумма 50 руб.
(мог бы конечно оформить как безвозмездную передачу, но "я не за жадность - просто я не считаю это чем-то что поможет кому-то" (с))
9. iov 408 02.10.12 13:04 Сейчас в теме
(8) А можно акт сверочки? А то у меня бухгалтерия не готова для приема не национальной валюты (плюсы в карму). :)
Для отправки сообщения требуется регистрация/авторизация