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