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