Нередко перед разработчиком в 1С 7.7 встает задача ограничить видимость определенных элементов справочника для конкретных пользователей или ролей. Например, требуется скрыть некоторые типы цен у номенклатуры для сотрудников филиала. При этом разработчики часто пытаются перебрать элементы прямо на форме списка или модифицировать реквизиты объектов «на лету» в процедуре ПриОткрытии(), чтобы затем применить штатный отбор.
Разберем, почему перебор формы списка напрямую невозможен, как правильно обращаться к выборке подчиненного справочника и какие способы фильтрации являются архитектурно верными и безопасными для многопользовательской работы.
Форма списка в 1С 7.7 — это лишь визуальный элемент интерфейса, динамически отображающий срез данных из базы. В ней нет коллекции строк, доступной для прямого поэлементного перебора через цикл. Попытка обратиться к элементам формы как к массиву строк не увенчается успехом.
Для работы с записями необходимо создать программную выборку данных через объект Справочник. Если справочник является подчиненным (как справочник цен, подчиненный номенклатуре), выборка должна быть обязательно спозиционирована на владельце.
Выясним, как правильно обойти элементы подчиненного справочника в модуле формы списка при ее открытии. В контексте формы подчиненного справочника доступна функция ИспользоватьВладельца() без параметров, которая возвращает текущего владельца открытого списка.
Посмотрим на пример правильного позиционирования и обхода подчиненного справочника:
Спр = СоздатьОбъект("Справочник." + Вид());
Спр.ИспользоватьВладельца(ИспользоватьВладельца());
Спр.ВыбратьЭлементы();
Пока Спр.ПолучитьЭлемент() = 1 Цикл
// Обработка текущего элемента подчиненного справочника
Сообщить("Найден элемент: " + Спр.ТекущийЭлемент());
КонецЦикла;
Обратите внимание на распространенную избыточную ошибку: попытку выполнить поиск владельца через конструкцию Н.НайтиЭлемент(ИспользоватьВладельца()). Метод ИспользоватьВладельца() уже возвращает готовую ссылку на элемент-владелец, поэтому дополнительный поиск через НайтиЭлемент не требуется.
Иногда для фильтрации прибегают к подходу, когда в цикле обхода реквизиту элемента присваивается признак видимости (например, Показать = 1), вызывается метод Записать(), а затем накладывается штатный УстановитьОтбор("Показать", 1). Рассмотрим подробнее, почему такой подход категорически не рекомендуется использовать в реальных рабочих базах:
Записать() при простом просмотре списка провоцирует блокировки таблиц. Если несколько пользователей откроют справочник одновременно, возникнут взаимоблокировки и падение скорости работы.Записать() вызовет аварийное завершение с ошибкой прав доступа.Штатным и безопасным способом динамического ограничения видимости элементов в форме списка 1С 7.7 является использование метода ИспользоватьСписокЭлементов(). Он не требует изменения реквизитов и записи объектов в базу данных.
Разберем по шагам реализацию этого метода в процедуре ПриОткрытии() формы списка подчиненного справочника:
ДобавитьЗначение().ИспользоватьСписокЭлементов().Посмотрим на практический пример кода:
Процедура ПриОткрытии()
Если НазваниеНабораПрав() = "Филиал" Тогда
СпРазрешенных = СоздатьОбъект("СписокЗначений");
Цены = СоздатьОбъект("Справочник.Цены");
Цены.ИспользоватьВладельца(ИспользоватьВладельца());
Цены.ВыбратьЭлементы();
Пока Цены.ПолучитьЭлемент() = 1 Цикл
// Проверяем доступность типа цены для филиала
Если Цены.ТипЦен.ДоступноУве = 1 Тогда
СпРазрешенных.ДобавитьЗначение(Цены.ТекущийЭлемент());
КонецЕсли;
КонецЦикла;
// Устанавливаем фильтр списка
ИспользоватьСписокЭлементов(СпРазрешенных);
// Скрываем ненужные элементы интерфейса
Форма.Процент.Видимость(0);
КонецЕсли;
КонецПроцедуры
Важное замечание: метод ИспользоватьСписокЭлементов() отлично работает при небольшом и среднем количестве строк (в пределах десятков или сотен записей подчиненного справочника). Если список содержит тысячи элементов, навигация по форме списка может замедлиться.
Если требуется полностью изолировать интерфейс просмотра и редактирования от стандартных механизмов справочника, наиболее надежным решением является отказ от стандартной формы списка в пользу элемента формы ТаблицаЗначений.
Проанализируем преимущества такого подхода: