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