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