Фокус, доступность и видимость поля управляемой формы: что писать в модуле

· 9 мин

Содержание

Чтобы активировать элемент формы в 1С, то есть поставить на него курсор, присвойте его свойству формы ТекущийЭлемент: ЭтаФорма.ТекущийЭлемент = Элементы.Контрагент;. Если «активировать» значит «сделать доступным для ввода», меняйте свойства самого элемента: Доступность, ТолькоПросмотр и Видимость.

Типичная ситуация: бухгалтер жалуется, что после выбора вида операции курсор остаётся на шапке, а поле «Договор» серое до перезаписи документа. Обе проблемы решаются в модуле формы за несколько строк. Ниже код для управляемых форм платформы 8.3, интерфейс «Такси».

Свойства, которые управляют состоянием элемента

У каждого поля управляемой формы есть набор свойств, задающих, можно ли с ним работать. Их видно в палитре свойств элемента в Конфигураторе и в коде через коллекцию Элементы.

СвойствоЧто делаетМожно ли поставить курсор
ВидимостьСкрывает элемент целикомНет
ДоступностьДелает элемент серым, ввод и выбор запрещеныНет
ТолькоПросмотрЗначение видно и копируется, но не меняетсяДа
АктивизироватьПоУмолчаниюПоле получает фокус при открытии формыДа
ПропускатьПриВводеПоле пропускается при переходе по EnterДа, мышью
АвтоОтметкаНезаполненногоПодчёркивает пустое поле краснымДа

Разница между Доступность и ТолькоПросмотр важна для пользователя. Недоступное поле нельзя даже выделить, чтобы скопировать номер договора. Поле «только просмотр» позволяет скопировать текст и открыть ссылку на объект.

💡 Если нужно запретить правку, но оставить возможность открыть карточку контрагента из поля, ставьте ТолькоПросмотр, а не Доступность = Ложь.

Порядок перехода по Enter

Когда пользователь вводит документ с клавиатуры, курсор идёт по полям в порядке их расположения в дереве элементов формы. Поменять маршрут можно двумя способами:

  1. Перетащить элемент в дереве выше или ниже, порядок обхода изменится вместе с расположением.
  2. Включить у второстепенных полей ПропускатьПриВводе, чтобы Enter их проскакивал. Мышью такое поле остаётся доступным.

Для документа с длинной шапкой это ускоряет ввод заметнее любого кода: оператор проходит только те поля, которые меняет каждый раз.

Свойства есть и у групп. Если сделать недоступной группу, недоступными становятся все её вложенные элементы, хотя их собственное свойство Доступность остаётся Истина. Это частый источник путаницы, о нём ниже.

Активация элемента формы из кода модуля

Поставить курсор на поле

Фокус задаётся свойством формы ТекущийЭлемент. Его можно установить при открытии и в любом клиентском обработчике.

&НаКлиенте
Процедура ВидОперацииПриИзменении(Элемент)
	ВидОперацииПриИзмененииНаСервере();
	ЭтаФорма.ТекущийЭлемент = Элементы.Договор;
КонецПроцедуры

Чтобы поле было активно сразу при открытии, проще всего включить у него флажок «Активизировать по умолчанию» в палитре свойств. Код не нужен. Если выбор поля зависит от данных, установите ТекущийЭлемент в ПриСозданииНаСервере или ПриОткрытии:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	Если ЗначениеЗаполнено(Объект.Контрагент) Тогда
		ТекущийЭлемент = Элементы.Товары;
	Иначе
		ТекущийЭлемент = Элементы.Контрагент;
	КонецЕсли;
КонецПроцедуры

Активировать колонку и строку таблицы

У табличной части фокус задаётся в два уровня: сначала сама таблица становится текущим элементом формы, затем у таблицы выбирается текущая колонка и строка.

&НаКлиенте
Процедура ПерейтиККоличеству(ИдентификаторСтроки)
	ЭтаФорма.ТекущийЭлемент = Элементы.Товары;
	Элементы.Товары.ТекущаяСтрока = ИдентификаторСтроки;
	Элементы.Товары.ТекущийЭлемент = Элементы.ТоварыКоличество;
	Элементы.Товары.ИзменитьСтроку();
КонецПроцедуры

ТекущаяСтрока принимает идентификатор строки данных формы, его получают методом ПолучитьИдентификатор() у строки коллекции. Номер строки сюда не подходит. ИзменитьСтроку() сразу открывает ячейку для ввода, как двойной щелчок.

Активировать страницу

Если нужное поле лежит на другой закладке, сначала переключите страницу:

Элементы.ГруппаСтраницы.ТекущаяСтраница = Элементы.СтраницаОплата;
ЭтаФорма.ТекущийЭлемент = Элементы.СуммаОплаты;

Фокус после закрытия другого окна

Когда пользователь закрывает форму выбора или вопрос, платформа сама возвращает фокус туда, откуда окно открыли. Если в обработчике оповещения нужно поставить курсор на другое поле, установка может не сработать. Рабочий приём — отложить её обработчиком ожидания:

&НаКлиенте
Процедура ПослеВыбораВарианта(Результат, ДополнительныеПараметры) Экспорт
	ПодключитьОбработчикОжидания("АктивироватьСумму", 0.1, Истина);
КонецПроцедуры

&НаКлиенте
Процедура АктивироватьСумму()
	ЭтаФорма.ТекущийЭлемент = Элементы.СуммаДокумента;
КонецПроцедуры

Третий параметр Истина означает однократный вызов, повторять отключение не нужно.

Программное изменение доступности и видимости

Правило, которое снимает половину вопросов: вся логика доступности должна жить в одной процедуре. Её вызывают при создании формы, при чтении объекта и после изменения реквизитов, от которых зависит состояние.

&НаСервере
Процедура УправлениеФормой()
	ЭтоПоставка = (Объект.ВидОперации = Перечисления.ВидыОпераций.Поставка);

	Элементы.Договор.Доступность = ЗначениеЗаполнено(Объект.Контрагент);
	Элементы.ГруппаДоставка.Видимость = ЭтоПоставка;
	Элементы.Сумма.ТолькоПросмотр = Объект.Проведен;
КонецПроцедуры

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	УправлениеФормой();
КонецПроцедуры

&НаКлиенте
Процедура КонтрагентПриИзменении(Элемент)
	КонтрагентПриИзмененииНаСервере();
КонецПроцедуры

&НаСервере
Процедура КонтрагентПриИзмененииНаСервере()
	УправлениеФормой();
КонецПроцедуры

Имя перечисления и его значения здесь условные, подставьте свои. Если условие простое и не требует данных из базы, процедуру можно сделать клиентской &НаКлиенте и не делать серверный вызов. Свойства Видимость, Доступность и ТолькоПросмотр меняются и на клиенте, и на сервере.

ПриСозданииНаСервере или ПриЧтенииНаСервере

Для формы объекта ПриЧтенииНаСервере вызывается только при открытии существующего объекта. Для нового документа она не сработает. Поэтому общий вызов ставят в ПриСозданииНаСервере, а ПриЧтенииНаСервере используют, если состояние зависит от данных, прочитанных из базы, например при перечитывании после записи.

Вся форма только для просмотра

У формы тоже есть свойство ТолькоПросмотр. Его ставят, например, для закрытого периода:

ТолькоПросмотр = (Объект.Дата <= ДатаЗапрета);

Отдельные кнопки командной панели при этом остаются нажимаемыми, если не отключить их явно.

Параметры формы, функциональные опции и отчёты на СКД

Передача режима через параметры

Состояние элементов часто зависит от того, откуда открыли форму. Добавьте параметр формы на закладке «Параметры» редактора формы и передайте его при открытии:

ПараметрыФормы = Новый Структура("Ключ, РежимПроверки", Ссылка, Истина);
ОткрытьФорму("Документ.ПоступлениеТоваров.ФормаОбъекта", ПараметрыФормы);

В ПриСозданииНаСервере значение читается через Параметры.РежимПроверки. Стандартный параметр Ключ открывает конкретный объект. Свойство формы ТолькоПросмотр тоже можно передать в структуре параметров, и форма откроется закрытой для правки.

Функциональные опции

Если элемент нужен только при включённой настройке учёта, не пишите для него код. Укажите функциональную опцию в свойстве элемента или связанного реквизита. Когда опция выключена, платформа сама скрывает элемент. Программная установка Видимость = Истина такой элемент не покажет: опция главнее.

Условное оформление

Для колонок таблицы код по строкам не работает : свойство ТолькоПросмотр колонки действует на все строки сразу. Чтобы закрыть ячейку только в некоторых строках, используйте условное оформление формы. Это настройка в редакторе формы и в коде через УсловноеОформление: задаётся условие отбора, оформляемое поле и параметр оформления ТолькоПросмотр.

Элемент = УсловноеОформление.Элементы.Добавить();
Поле = Элемент.Поля.Элементы.Добавить();
Поле.Поле = Новый ПолеКомпоновкиДанных("ТоварыЦена");

Отбор = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
Отбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.Товары.ЦенаЗафиксирована");
Отбор.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
Отбор.ПравоеЗначение = Истина;

Элемент.Оформление.УстановитьЗначениеПараметра("ТолькоПросмотр", Истина);

Здесь ТоварыЦена — имя элемента колонки, а ЦенаЗафиксирована — булев реквизит табличной части. Оба имени примера ваши.

Отчёты на СКД

В форме отчёта на СКД поля отбора и параметры создаются по настройкам компоновщика, а не вручную. Какие параметры видит пользователь в шапке, задаёт режим отображения элемента настроек: «Быстрый доступ», «Обычный» или «Недоступный». Меняется это в настройках варианта отчёта. Пытаться скрывать такие поля через Элементы ненадёжно: форма перестраивает их при смене варианта.

Роли и права: кто видит поле

Доступность поля для конкретного пользователя лучше задавать декларативно, а не кодом.

  • 🔐 Права на реквизит. Если у роли нет права на просмотр реквизита объекта, поле на форме не показывается. Нет права на редактирование — поле доступно только для чтения.
  • 👥 Пользовательская видимость по ролям. В свойствах элемента формы можно задать видимость отдельно для каждой роли. Это удобно, когда реквизит виден всем, а поле на конкретной форме нужно не всем.
  • 🧩 Проверка в коде. Когда условие сложнее роли, проверяйте право на сервере: Элементы.Себестоимость.Видимость = РольДоступна("ПросмотрСебестоимости");. Имя роли здесь пример. В конфигурациях на БСП вместо РольДоступна используют функции подсистемы пользователей, они учитывают профили групп доступа.

Скрытие поля на форме — не защита данных. Значение реквизита можно получить отчётом или через другую форму. Если данные секретны, закрывайте их правами роли и ограничением доступа на уровне записей (RLS).

RLS при этом ограничивает записи, а не поля. Она решает, какие документы и элементы справочников пользователь видит вообще. За конкретное поле отвечают права на реквизит и видимость по ролям.

События, проверка заполнения и переход к ошибочному полю

Обработчики, которые меняют состояние

  • 🔄 ПриИзменении — пересчитать доступность после смены значения.
  • 📋 НачалоВыбора — подменить форму выбора или отказаться от стандартной (СтандартнаяОбработка = Ложь).
  • ✅ ОбработкаПроверкиЗаполненияНаСервере — проверить данные перед записью.
  • 💾 ПослеЗаписиНаСервере — обновить состояние после записи, например закрыть сумму для проведённого документа.

Активировать поле с ошибкой

Самый полезный приём для пользователя: при ошибке сообщение привязывается к полю. Щелчок по сообщению ставит курсор в нужное место.

&НаСервере
Процедура ОбработкаПроверкиЗаполненияНаСервере(Отказ, ПроверяемыеРеквизиты)
	Если Объект.Сумма <= 0 Тогда
		Сообщение = Новый СообщениеПользователю;
		Сообщение.Текст = "Сумма должна быть больше нуля";
		Сообщение.Поле = "Сумма";
		Сообщение.ПутьКДанным = "Объект";
		Сообщение.Сообщить();
		Отказ = Истина;
	КонецЕсли;
КонецПроцедуры

Для строки табличной части путь к полю указывает индекс строки: Сообщение.Поле = "Товары[2].Количество";. Индекс в коллекции начинается с нуля, поэтому [2] — третья строка. В конфигурациях на БСП то же делает ОбщегоНазначения.СообщитьПользователю(Текст, , Поле, ПутьКДанным, Отказ).

Если поле обязательно всегда, не пишите проверку руками. Поставьте у реквизита «Проверка заполнения: Выдавать ошибку», и платформа сама подсветит поле и привяжет к нему сообщение.

Поле не реагирует: проверьте по порядку
Выполнено: 0 / 5

Ошибки при активации элементов и как их исправить

Диагностика: выберите симптом

Ещё одна ловушка — пользовательские настройки формы. Если пользователь скрыл поле через «Изменить форму», платформа запоминает это. Код с Видимость = Истина поле покажет, но при следующем открытии сохранённая настройка может снова вмешаться. Сбросить настройки пользователь может сам в том же окне командой стандартных настроек.

Для доработки типовой конфигурации меняйте форму через расширение, а не правкой конфигурации поставщика. В расширении заимствуют форму и добавляют свой обработчик ПриСозданииНаСервере с директивой &После, где меняют свойства нужных элементов. Тогда изменения не потеряются при обновлении релиза.

Частые вопросы

Чем ТекущийЭлемент отличается от АктивизироватьПоУмолчанию?
АктивизироватьПоУмолчанию — флажок в свойствах поля, действует только при открытии формы. ТекущийЭлемент задаётся в коде и переводит фокус в любой момент.
Как оставить только выбор из списка, без ввода с клавиатуры?
Отключите у поля ввода свойство РедактированиеТекста. Кнопка выбора продолжит работать, а набрать значение вручную будет нельзя.
Можно ли менять доступность в обычной форме 8.2 тем же кодом?
Нет, синтаксис другой. В обычных формах элементы берут из коллекции ЭлементыФормы, например ЭлементыФормы.Договор.Доступность = Ложь.
Почему свойства элементов нельзя менять в модуле объекта?
Модуль объекта не знает о форме: объект может записываться без неё, например обработкой. Управляйте элементами только в модуле формы.
Как узнать, какой элемент сейчас активен?
Прочитайте ТекущийЭлемент в клиентском коде и сравните его с нужным: Если ТекущийЭлемент = Элементы.Контрагент Тогда.