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