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