При работе с расширениями в 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда новый реквизит или колонка в таблице значений (ТЗ) добавлены в расширение, код по их заполнению написан и успешно выполняется на сервере, но при открытии формы в режиме «1С:Предприятие» колонка остается пустой. Рассмотрим эту проблему на примере типовой конфигурации «Управление торговлей 11.5» и обработки УправлениеОтгрузкой.
Проанализируем ситуацию: в расширение добавлена форма, в реквизит формы (таблицу РаспоряженияНаОтгрузку) добавлена колонка Вес. Разработчик программно заполняет эту колонку, обходя таблицу в цикле, однако данные не доходят до визуального интерфейса. Выясним основные причины и разберем по шагам правильные способы решения этой задачи.
Одной из наиболее распространенных ошибок является добавление колонки в таблицу значений без указания типа данных. Когда мы пишем ТЗ.Колонки.Добавить("Вес"), система по умолчанию присваивает этой колонке тип Произвольный. При передаче данных с сервера на клиент или при привязке такой таблицы к элементам управляемой формы платформа может некорректно интерпретировать данные, что приводит к отображению пустых значений.
Разберем, как правильно типизировать колонку при программном создании таблицы значений. Вместо простого добавления имени, мы должны создать объект ОписаниеТипов. Посмотрим на пример кода:
// Создаем описание типов для числа с заданной точностью
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("Число"));
КвалификаторыЧисла = Новый КвалификаторыЧисла(15, 3);
ОписаниеТипаВес = Новый ОписаниеТипов(МассивТипов, , , КвалификаторыЧисла);
// Добавляем колонку с явным указанием типа
ТЗ.Колонки.Добавить("Вес", ОписаниеТипаВес);
Важно: Если колонка уже добавлена в реквизиты формы в самом расширении (через дерево метаданных), то при выгрузке запроса в таблицу или загрузке данных в реквизит формы, типы должны строго совпадать. Если в реквизитах формы Вес — это Число, а в программной ТЗ это Произвольный тип, платформа может очистить данные при выполнении метода Загрузить().
Проанализируем способ получения данных. В сообщениях форума упоминается код: Вес = Стр["Распоряжение"].ЕП1_ВесПоДокументу. Здесь кроется критическая проблема производительности и доступности данных. Если этот код выполняется на стороне клиента, обращение через точку к реквизиту ссылки (Распоряжение) заставит систему выполнить неявный серверный вызов для получения значения. В некоторых случаях, если контекст формы ограничен или включен безопасный режим расширения, такие данные могут просто не вернуться.
Более того, если мы работаем в цикле, получение веса для каждой строки через обращение к ссылке создаст столько серверных вызовов, сколько строк в таблице. Это крайне неоптимально. Правильным подходом будет получение всех необходимых данных одним запросом на сервере.
При работе с расширениями стоит проверить свойства самого расширения в конфигураторе или в справочнике «Расширения» в пользовательском режиме. Если для расширения установлен флаг «Защищенный режим» или «Защита от опасных действий», работа с данными может быть ограничена. Это часто приводит к тому, что программные изменения структуры данных или специфические вызовы игнорируются платформой без вывода явных ошибок.
Рекомендуем временно снять эти флаги для проверки: если данные появились, значит, проблему нужно искать в правах доступа расширения к метаданным основной конфигурации.
В типовых конфигурациях, таких как УТ 11.5, данные в сложных обработках часто собираются внутренними механизмами, которые могут перезаписывать содержимое таблиц после вашего кода. Рассмотрим наиболее надежный метод решения, к которому пришел автор темы. Мы будем использовать расширение процедуры ЗаполнитьРаспоряженияНаОтгрузку с аннотацией &После.
Этот метод гарантирует, что основная логика типовой конфигурации уже отработала, таблица РаспоряженияНаОтгрузку заполнена стандартными данными, и нам остается лишь дополнить её нашими значениями. Разберем по шагам реализацию этого кода на сервере:
&НаСервере
&После("ЗаполнитьРаспоряженияНаОтгрузку")
Процедура ЕП1_ЗаполнитьРаспоряженияНаОтгрузку(ПроверятьИзменениеПараметров)
// В этот момент таблица РаспоряженияНаОтгрузку уже наполнена данными в основной конфигурации.
// Нам нужно обойти её и заполнить добавленную нами колонку "Вес".
Для Каждого Стр Из РаспоряженияНаОтгрузку Цикл
// Проверяем тип распоряжения, чтобы избежать ошибок при обращении к реквизитам
Если (ТипЗнч(Стр.Распоряжение) = Тип("ДокументСсылка.ЗаказКлиента"))
ИЛИ (ТипЗнч(Стр.Распоряжение) = Тип("ДокументСсылка.РеализацияТоваровУслуг")) Тогда
// Получаем вес из добавленного в расширение реквизита "ЕП1_ВесПоДокументу"
// Внимание: обращение через точку допустимо на сервере,
// но для оптимизации лучше использовать один запрос до цикла.
Стр.Вес = Стр.Распоряжение.ЕП1_ВесПоДокументу;
Иначе
// Для прочих типов документов устанавливаем значение по умолчанию
Стр.Вес = 0;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Проанализируем преимущества данного подхода:
&После гарантирует, что типовой механизм 1С не очистит вашу колонку в процессе формирования списка распоряжений.Вес в реквизите формы РаспоряженияНаОтгрузку с одноименным элементом (колонкой) на визуальной форме.Если даже после применения правильного кода колонка остается пустой, проверьте следующие моменты:
ПутьКДанным указано именно РаспоряженияНаОтгрузку.Вес. Иногда при копировании элементов пути сбиваются.ПриСозданииНаСервере можно принудительно установить Элементы.Вес.Видимость = Истина;.Таким образом, для успешного вывода данных в расширении необходимо соблюдать три условия: выполнять заполнение на сервере, обеспечивать типизацию данных и использовать правильные точки подключения к типовому коду (перехватчики процедур).