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