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