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