Фокус, доступность и видимость поля управляемой формы: что писать в модуле
Содержание
Чтобы активировать элемент формы в 1С, то есть поставить на него курсор, присвойте его свойству формы ТекущийЭлемент: ЭтаФорма.ТекущийЭлемент = Элементы.Контрагент;. Если «активировать» значит «сделать доступным для ввода», меняйте свойства самого элемента: Доступность, ТолькоПросмотр и Видимость.
Типичная ситуация: бухгалтер жалуется, что после выбора вида операции курсор остаётся на шапке, а поле «Договор» серое до перезаписи документа. Обе проблемы решаются в модуле формы за несколько строк. Ниже код для управляемых форм платформы 8.3, интерфейс «Такси».
Свойства, которые управляют состоянием элемента
У каждого поля управляемой формы есть набор свойств, задающих, можно ли с ним работать. Их видно в палитре свойств элемента в Конфигураторе и в коде через коллекцию Элементы.
| Свойство | Что делает | Можно ли поставить курсор |
|---|---|---|
Видимость | Скрывает элемент целиком | Нет |
Доступность | Делает элемент серым, ввод и выбор запрещены | Нет |
ТолькоПросмотр | Значение видно и копируется, но не меняется | Да |
АктивизироватьПоУмолчанию | Поле получает фокус при открытии формы | Да |
ПропускатьПриВводе | Поле пропускается при переходе по Enter | Да, мышью |
АвтоОтметкаНезаполненного | Подчёркивает пустое поле красным | Да |
Разница между Доступность и ТолькоПросмотр важна для пользователя. Недоступное поле нельзя даже выделить, чтобы скопировать номер договора. Поле «только просмотр» позволяет скопировать текст и открыть ссылку на объект.
💡 Если нужно запретить правку, но оставить возможность открыть карточку контрагента из поля, ставьте ТолькоПросмотр, а не Доступность = Ложь.
Порядок перехода по Enter
Когда пользователь вводит документ с клавиатуры, курсор идёт по полям в порядке их расположения в дереве элементов формы. Поменять маршрут можно двумя способами:
- Перетащить элемент в дереве выше или ниже, порядок обхода изменится вместе с расположением.
- Включить у второстепенных полей
ПропускатьПриВводе, чтобы Enter их проскакивал. Мышью такое поле остаётся доступным.
Для документа с длинной шапкой это ускоряет ввод заметнее любого кода: оператор проходит только те поля, которые меняет каждый раз.
Свойства есть и у групп. Если сделать недоступной группу, недоступными становятся все её вложенные элементы, хотя их собственное свойство Доступность остаётся Истина. Это частый источник путаницы, о нём ниже.
Активация элемента формы из кода модуля
Поставить курсор на поле
Фокус задаётся свойством формы ТекущийЭлемент. Его можно установить при открытии и в любом клиентском обработчике.
&НаКлиенте
Процедура ВидОперацииПриИзменении(Элемент)
ВидОперацииПриИзмененииНаСервере();
ЭтаФорма.ТекущийЭлемент = Элементы.Договор;
КонецПроцедуры
Чтобы поле было активно сразу при открытии, проще всего включить у него флажок «Активизировать по умолчанию» в палитре свойств. Код не нужен. Если выбор поля зависит от данных, установите ТекущийЭлемент в ПриСозданииНаСервере или ПриОткрытии:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если ЗначениеЗаполнено(Объект.Контрагент) Тогда
ТекущийЭлемент = Элементы.Товары;
Иначе
ТекущийЭлемент = Элементы.Контрагент;
КонецЕсли;
КонецПроцедуры
Активировать колонку и строку таблицы
У табличной части фокус задаётся в два уровня: сначала сама таблица становится текущим элементом формы, затем у таблицы выбирается текущая колонка и строка.
&НаКлиенте
Процедура ПерейтиККоличеству(ИдентификаторСтроки)
ЭтаФорма.ТекущийЭлемент = Элементы.Товары;
Элементы.Товары.ТекущаяСтрока = ИдентификаторСтроки;
Элементы.Товары.ТекущийЭлемент = Элементы.ТоварыКоличество;
Элементы.Товары.ИзменитьСтроку();
КонецПроцедуры
ТекущаяСтрока принимает идентификатор строки данных формы, его получают методом ПолучитьИдентификатор() у строки коллекции. Номер строки сюда не подходит. ИзменитьСтроку() сразу открывает ячейку для ввода, как двойной щелчок.
Активировать страницу
Если нужное поле лежит на другой закладке, сначала переключите страницу:
Элементы.ГруппаСтраницы.ТекущаяСтраница = Элементы.СтраницаОплата;
ЭтаФорма.ТекущийЭлемент = Элементы.СуммаОплаты;
Фокус после закрытия другого окна
Когда пользователь закрывает форму выбора или вопрос, платформа сама возвращает фокус туда, откуда окно открыли. Если в обработчике оповещения нужно поставить курсор на другое поле, установка может не сработать. Рабочий приём — отложить её обработчиком ожидания:
&НаКлиенте
Процедура ПослеВыбораВарианта(Результат, ДополнительныеПараметры) Экспорт
ПодключитьОбработчикОжидания("АктивироватьСумму", 0.1, Истина);
КонецПроцедуры
&НаКлиенте
Процедура АктивироватьСумму()
ЭтаФорма.ТекущийЭлемент = Элементы.СуммаДокумента;
КонецПроцедуры
Третий параметр Истина означает однократный вызов, повторять отключение не нужно.
Программное изменение доступности и видимости
Правило, которое снимает половину вопросов: вся логика доступности должна жить в одной процедуре. Её вызывают при создании формы, при чтении объекта и после изменения реквизитов, от которых зависит состояние.
&НаСервере
Процедура УправлениеФормой()
ЭтоПоставка = (Объект.ВидОперации = Перечисления.ВидыОпераций.Поставка);
Элементы.Договор.Доступность = ЗначениеЗаполнено(Объект.Контрагент);
Элементы.ГруппаДоставка.Видимость = ЭтоПоставка;
Элементы.Сумма.ТолькоПросмотр = Объект.Проведен;
КонецПроцедуры
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
УправлениеФормой();
КонецПроцедуры
&НаКлиенте
Процедура КонтрагентПриИзменении(Элемент)
КонтрагентПриИзмененииНаСервере();
КонецПроцедуры
&НаСервере
Процедура КонтрагентПриИзмененииНаСервере()
УправлениеФормой();
КонецПроцедуры
Имя перечисления и его значения здесь условные, подставьте свои. Если условие простое и не требует данных из базы, процедуру можно сделать клиентской &НаКлиенте и не делать серверный вызов. Свойства Видимость, Доступность и ТолькоПросмотр меняются и на клиенте, и на сервере.
ПриСозданииНаСервере или ПриЧтенииНаСервере
Для формы объекта ПриЧтенииНаСервере вызывается только при открытии существующего объекта. Для нового документа она не сработает. Поэтому общий вызов ставят в ПриСозданииНаСервере, а ПриЧтенииНаСервере используют, если состояние зависит от данных, прочитанных из базы, например при перечитывании после записи.
Вся форма только для просмотра
У формы тоже есть свойство ТолькоПросмотр. Его ставят, например, для закрытого периода:
ТолькоПросмотр = (Объект.Дата <= ДатаЗапрета);
Отдельные кнопки командной панели при этом остаются нажимаемыми, если не отключить их явно.
Параметры формы, функциональные опции и отчёты на СКД
Передача режима через параметры
Состояние элементов часто зависит от того, откуда открыли форму. Добавьте параметр формы на закладке «Параметры» редактора формы и передайте его при открытии:
ПараметрыФормы = Новый Структура("Ключ, РежимПроверки", Ссылка, Истина);
ОткрытьФорму("Документ.ПоступлениеТоваров.ФормаОбъекта", ПараметрыФормы);
В ПриСозданииНаСервере значение читается через Параметры.РежимПроверки. Стандартный параметр Ключ открывает конкретный объект. Свойство формы ТолькоПросмотр тоже можно передать в структуре параметров, и форма откроется закрытой для правки.
Функциональные опции
Если элемент нужен только при включённой настройке учёта, не пишите для него код. Укажите функциональную опцию в свойстве элемента или связанного реквизита. Когда опция выключена, платформа сама скрывает элемент. Программная установка Видимость = Истина такой элемент не покажет: опция главнее.
Условное оформление
Для колонок таблицы код по строкам не работает
: свойство ТолькоПросмотр колонки действует на все строки сразу. Чтобы закрыть ячейку только в некоторых строках, используйте условное оформление формы. Это настройка в редакторе формы и в коде через УсловноеОформление: задаётся условие отбора, оформляемое поле и параметр оформления ТолькоПросмотр.
Элемент = УсловноеОформление.Элементы.Добавить();
Поле = Элемент.Поля.Элементы.Добавить();
Поле.Поле = Новый ПолеКомпоновкиДанных("ТоварыЦена");
Отбор = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
Отбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.Товары.ЦенаЗафиксирована");
Отбор.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
Отбор.ПравоеЗначение = Истина;
Элемент.Оформление.УстановитьЗначениеПараметра("ТолькоПросмотр", Истина);
Здесь ТоварыЦена — имя элемента колонки, а ЦенаЗафиксирована — булев реквизит табличной части. Оба имени примера ваши.
Отчёты на СКД
В форме отчёта на СКД поля отбора и параметры создаются по настройкам компоновщика, а не вручную. Какие параметры видит пользователь в шапке, задаёт режим отображения элемента настроек: «Быстрый доступ», «Обычный» или «Недоступный». Меняется это в настройках варианта отчёта. Пытаться скрывать такие поля через Элементы ненадёжно: форма перестраивает их при смене варианта.
Роли и права: кто видит поле
Доступность поля для конкретного пользователя лучше задавать декларативно, а не кодом.
- 🔐 Права на реквизит. Если у роли нет права на просмотр реквизита объекта, поле на форме не показывается. Нет права на редактирование — поле доступно только для чтения.
- 👥 Пользовательская видимость по ролям. В свойствах элемента формы можно задать видимость отдельно для каждой роли. Это удобно, когда реквизит виден всем, а поле на конкретной форме нужно не всем.
- 🧩 Проверка в коде. Когда условие сложнее роли, проверяйте право на сервере:
Элементы.Себестоимость.Видимость = РольДоступна("ПросмотрСебестоимости");. Имя роли здесь пример. В конфигурациях на БСП вместоРольДоступнаиспользуют функции подсистемы пользователей, они учитывают профили групп доступа.
Скрытие поля на форме — не защита данных. Значение реквизита можно получить отчётом или через другую форму. Если данные секретны, закрывайте их правами роли и ограничением доступа на уровне записей (RLS).
RLS при этом ограничивает записи, а не поля. Она решает, какие документы и элементы справочников пользователь видит вообще. За конкретное поле отвечают права на реквизит и видимость по ролям.
События, проверка заполнения и переход к ошибочному полю
Обработчики, которые меняют состояние
- 🔄
ПриИзменении— пересчитать доступность после смены значения. - 📋
НачалоВыбора— подменить форму выбора или отказаться от стандартной (СтандартнаяОбработка = Ложь). - ✅
ОбработкаПроверкиЗаполненияНаСервере— проверить данные перед записью. - 💾
ПослеЗаписиНаСервере— обновить состояние после записи, например закрыть сумму для проведённого документа.
Активировать поле с ошибкой
Самый полезный приём для пользователя: при ошибке сообщение привязывается к полю. Щелчок по сообщению ставит курсор в нужное место.
&НаСервере
Процедура ОбработкаПроверкиЗаполненияНаСервере(Отказ, ПроверяемыеРеквизиты)
Если Объект.Сумма <= 0 Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Сумма должна быть больше нуля";
Сообщение.Поле = "Сумма";
Сообщение.ПутьКДанным = "Объект";
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
Для строки табличной части путь к полю указывает индекс строки: Сообщение.Поле = "Товары[2].Количество";. Индекс в коллекции начинается с нуля, поэтому [2] — третья строка. В конфигурациях на БСП то же делает ОбщегоНазначения.СообщитьПользователю(Текст, , Поле, ПутьКДанным, Отказ).
Если поле обязательно всегда, не пишите проверку руками. Поставьте у реквизита «Проверка заполнения: Выдавать ошибку», и платформа сама подсветит поле и привяжет к нему сообщение.
Ошибки при активации элементов и как их исправить
Элементы. Имя элемента формы и имя реквизита часто различаются, например ТоварыКоличество вместо Количество. Посмотрите имя в дереве элементов формы.ТекущаяСтраница, затем задайте ТекущийЭлемент.ПослеЗаписиНаСервере.Ещё одна ловушка — пользовательские настройки формы. Если пользователь скрыл поле через «Изменить форму», платформа запоминает это. Код с Видимость = Истина поле покажет, но при следующем открытии сохранённая настройка может снова вмешаться. Сбросить настройки пользователь может сам в том же окне командой стандартных настроек.
Для доработки типовой конфигурации меняйте форму через расширение, а не правкой конфигурации поставщика. В расширении заимствуют форму и добавляют свой обработчик ПриСозданииНаСервере с директивой &После, где меняют свойства нужных элементов. Тогда изменения не потеряются при обновлении релиза.
Частые вопросы
Чем ТекущийЭлемент отличается от АктивизироватьПоУмолчанию?
АктивизироватьПоУмолчанию — флажок в свойствах поля, действует только при открытии формы. ТекущийЭлемент задаётся в коде и переводит фокус в любой момент.Как оставить только выбор из списка, без ввода с клавиатуры?
РедактированиеТекста. Кнопка выбора продолжит работать, а набрать значение вручную будет нельзя.Можно ли менять доступность в обычной форме 8.2 тем же кодом?
ЭлементыФормы, например ЭлементыФормы.Договор.Доступность = Ложь.Почему свойства элементов нельзя менять в модуле объекта?
Как узнать, какой элемент сейчас активен?
ТекущийЭлемент в клиентском коде и сравните его с нужным: Если ТекущийЭлемент = Элементы.Контрагент Тогда.