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