К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как выгрузить табличную часть в массив в 1С

Способы выгрузить табличную часть документа в массив в 1С: Выгрузить(), ВыгрузитьКолонку(), обход строк. Примеры кода, ошибки, отличия толстого и тонкого клиента.

Табличная часть документа или справочника в 1С — это коллекция строк, и напрямую передать её как массив нельзя: типы «ТабличнаяЧасть» и «Массив» несовместимы. Чтобы получить массив, нужно либо выгрузить данные в таблицу значений и затем преобразовать её, либо обойти строки в цикле и собрать массив вручную.

Выбор способа зависит от задачи. Если нужен массив значений одной колонки (например, список номенклатуры для запроса) — используйте метод ВыгрузитьКолонку(). Если нужны полные строки с несколькими реквизитами — выгружайте в таблицу значений и обходите её, либо сразу обходите табличную часть циклом. Ниже разобраны все рабочие варианты с кодом.

Важно понимать контекст выполнения: на тонком клиенте недоступны серверные типы вроде «ТаблицаЗначений», поэтому часть приёмов работает только на сервере или в толстом клиенте. Это частая причина ошибок у начинающих разработчиков.

Что такое табличная часть и почему её нельзя присвоить массиву

Табличная часть — это объект типа «ТабличнаяЧасть» (в управляемом приложении на клиенте — «ДанныеФормыКоллекция»). Она поддерживает индексированный доступ к строкам, методы Добавить(), Найти(), Итог(), но не является массивом. Попытка передать её туда, где ожидается массив, приведёт к ошибке несоответствия типов.

Массив в 1С — это универсальная коллекция произвольных значений. В него можно поместить числа, строки, ссылки, структуры и даже другие массивы. Именно поэтому массив удобен как «транспортный» формат: его легко передать в параметр запроса, в процедуру общего модуля, сериализовать в JSON.

Способ 1. Выгрузить одну колонку через ВыгрузитьКолонку()

Самый короткий путь, когда нужен массив значений одного реквизита. Метод доступен у табличной части объекта на сервере:

// Объект документа получен на сервере

ДокОбъект = ДокументСсылка.ПолучитьОбъект();

МассивТоваров = ДокОбъект.Товары.ВыгрузитьКолонку("Номенклатура");

// Результат: Массив, каждый элемент — ссылка на номенклатуру

Для Каждого Товар Из МассивТоваров Цикл

Сообщить(Товар);

КонецЦикла;

У метода есть ограничение: он возвращает значения всех строк, включая дубликаты. Если нужен список уникальных значений, сверните результат или используйте запрос:

// Убрать дубликаты через соответствие

Уникальные = Новый Соответствие;

Для Каждого Элемент Из МассивТоваров Цикл

Уникальные.Вставить(Элемент, Истина);

КонецЦикла;

МассивУникальных = Новый Массив;

Для Каждого Ключ Из Уникальные Цикл

МассивУникальных.Добавить(Ключ.Ключ);

КонецЦикла;

Способ 2. Выгрузить всю табличную часть через Выгрузить()

Метод Выгрузить() возвращает таблицу значений со всеми строками и колонками табличной части. Дальше таблицу обходят в цикле и складывают нужные данные в массив — например, как структуры:

ТЗ = ДокОбъект.Товары.Выгрузить();

МассивСтрок = Новый Массив;

Для Каждого СтрокаТЗ Из ТЗ Цикл

ОписаниеСтроки = Новый Структура;

ОписаниеСтроки.Вставить("Номенклатура", СтрокаТЗ.Номенклатура);

ОписаниеСтроки.Вставить("Количество", СтрокаТЗ.Количество);

ОписаниеСтроки.Вставить("Сумма", СтрокаТЗ.Сумма);

МассивСтрок.Добавить(ОписаниеСтроки);

КонецЦикла;

Методу Выгрузить() можно передать параметры: отбор строк (структура с условием) и список выгружаемых колонок строкой через запятую. Это экономит память на больших табличных частях:

// Только строки с ненулевым количеством, только две колонки

Отбор = Новый Структура("ПометкаУдаленияСтроки", Ложь);

ТЗ = ДокОбъект.Товары.Выгрузить(Отбор, "Номенклатура,Количество");

Способ 3. Обход строк циклом без промежуточной таблицы

Если промежуточная таблица значений не нужна, строки можно обойти напрямую. Это единственный универсальный вариант, который работает и на тонком клиенте с данными формы:

МассивСтрок = Новый Массив;

Для Каждого СтрокаТЧ Из Объект.Товары Цикл

ОписаниеСтроки = Новый Структура("Номенклатура,Количество,Цена");

ЗаполнитьЗначенияСвойств(ОписаниеСтроки, СтрокаТЧ);

МассивСтрок.Добавить(ОписаниеСтроки);

КонецЦикла;

Приём с ЗаполнитьЗначенияСвойств() удобен тем, что не нужно перечислять присваивания вручную: значения копируются по совпадающим именам свойств. Следите, чтобы имена ключей структуры точно совпадали с именами реквизитов табличной части — иначе свойство останется незаполненным.

Цикл также позволяет на лету фильтровать и преобразовывать данные — например, пропускать строки с нулевым количеством или сразу вычислять дополнительные поля:

Для Каждого СтрокаТЧ Из Объект.Товары Цикл

Если СтрокаТЧ.Количество = 0 Тогда

Продолжить;

КонецЕсли;

МассивСтрок.Добавить(Новый Структура("Номенклатура,Сумма",

СтрокаТЧ.Номенклатура, СтрокаТЧ.Количество * СтрокаТЧ.Цена));

КонецЦикла;

Способ 4. Получить массив через запрос

Когда данные нужны без открытия объекта, эффективнее выполнить запрос к табличной части и выгрузить результат. Запрос не создаёт объект документа в памяти и работает быстрее на больших объёмах:

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Товары.Номенклатура КАК Номенклатура,

| Товары.Количество КАК Количество

|ИЗ

| Документ.РеализацияТоваровУслуг.Товары КАК Товары

|ГДЕ

| Товары.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", ДокументСсылка);

ТЗ = Запрос.Выполнить().Выгрузить();

МассивТоваров = ТЗ.ВыгрузитьКолонку("Номенклатура");

У результата запроса метод ВыгрузитьКолонку() тоже доступен, поэтому связка «запрос → таблица значений → массив колонки» — рабочий шаблон для получения списков значений по одному или нескольким документам сразу.

Сравнение способов

ВыгрузитьКолонку()

Быстрее всего для одной колонки. Только на сервере, у объекта. Возвращает дубликаты.

Выгрузить() + обход ТЗ

Подходит для строк целиком и отбора. Требует память под таблицу значений, только сервер/толстый клиент.

Обход циклом

Универсален, работает на тонком клиенте. Код длиннее, но гибче: фильтрация и расчёты на лету.

Запрос

Лучший вариант без открытия объекта и для нескольких документов. Только сервер, требует текста запроса.

Особенности управляемого приложения и тонкого клиента

В управляемых формах табличная часть на клиенте представлена типом «ДанныеФормыКоллекция». У неё нет методов Выгрузить() и ВыгрузитьКолонку() — попытка вызвать их приведёт к ошибке «Метод объекта не обнаружен».

Стандартный приём — вынести выгрузку в серверную процедуру. Данные формы передаются на сервер через РеквизитФормыВЗначение() или обрабатываются в серверном контексте формы:

&НаСервере

Функция ПолучитьМассивТоваров()

ДокОбъект = РеквизитФормыВЗначение("Объект");

Возврат ДокОбъект.Товары.ВыгрузитьКолонку("Номенклатура");

КонецФункции

&НаКлиенте

Процедура КомандаВыгрузить(Команда)

МассивТоваров = ПолучитьМассивТоваров();

// дальше работаем с массивом на клиенте

КонецПроцедуры

Альтернатива без серверного вызова — обход коллекции на клиенте циклом, как в способе 3. Для небольших табличных частей это проще и не требует лишнего обращения к серверу.

Проверка результата и типичные ошибки

После выгрузки проверьте результат простыми средствами: количество элементов массива должно совпадать с числом строк табличной части (или с числом строк после отбора), типы элементов должны соответствовать ожиданиям.

Если МассивСтрок.Количество() <> Объект.Товары.Количество() Тогда

// где-то потерялись строки — проверить отбор и условия в цикле

КонецЕсли;

Контрольные точки

Как проверить результат

Количество элементов массива
Норма

Равно числу строк табличной части (или отобранных строк)

Тревожный признак

Меньше — сработал лишний фильтр; больше — дубли при объединении

Тип элементов
Норма

Ссылки, числа или структуры — как задумано

Тревожный признак

Неопределено в элементах — не совпали имена свойств при ЗаполнитьЗначенияСвойств

Поведение на тонком клиенте
Норма

Код выполняется без ошибок

Тревожный признак

Ошибка «Метод объекта не обнаружен: Выгрузить» — метод вызван у данных формы

Типичные ошибки
01
Вызов Выгрузить() у данных формы на тонком клиенте — ошибка «метод не обнаружен». Решение: серверная процедура или обход циклом.
02
Опечатка в имени колонки у ВыгрузитьКолонку() — исключение в момент выполнения. Имя проверяйте по конфигуратору.
03
Ожидание уникальных значений от ВыгрузитьКолонку() — метод возвращает все строки с дубликатами, сворачивайте отдельно.
04
Выгрузка в массив вместо передачи таблицы значений там, где массив не нужен — лишний расход памяти и кода.

FAQ

Можно ли передать табличную часть между клиентом и сервером напрямую?

Нет, табличная часть объекта не сериализуется. Передавайте массив структур с простыми типами, либо работайте с данными через реквизит формы. Таблицу значений с сервера на клиент тоже нельзя вернуть напрямую — её преобразуют в массив структур.

Как выгрузить табличную часть в массив, если документ ещё не записан?

Если работа идёт в форме документа, данные уже в реквизите формы — обходите их циклом или используйте серверную процедуру с РеквизитФормыВЗначение(). Ссылка и запрос в этом случае не подходят: в базе данных ещё нет актуальных строк.

Что быстрее: Выгрузить() или обход циклом?

На сервере Выгрузить() обычно быстрее, так как выполняется целиком на уровне платформы. Разница заметна на тысячах строк. Для десятков строк выбирайте вариант по читаемости кода, а не по скорости.

Как получить массив только по отобранным строкам?

Три варианта: передать отбор в метод Выгрузить(Отбор, Колонки), добавить условие ЕСЛИ внутрь цикла обхода, либо задать условие ГДЕ в запросе. Запрос предпочтительнее, если отбирать нужно по данным других таблиц.

Можно ли выгрузить табличную часть сразу в JSON?

Напрямую — нет. Сначала соберите массив структур обходом строк, затем сериализуйте его через ЗаписьJSON. Учтите, что ссылки в JSON превращаются в строковые представления — для обмена лучше выгружать уникальные идентификаторы.

Итог

Что важно запомнить

Для одной колонки используйте ВыгрузитьКолонку(), для полных строк — Выгрузить() в таблицу значений или обход циклом со структурами. На тонком клиенте методы Выгрузить недоступны — выносите логику на сервер. Для данных без открытия объекта применяйте запрос.