Как выгрузить одну строку из табличной части в таблицу значений в 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В практике разработчика 1С часто возникает задача изолировать конкретную строку табличной части (ТЧ) для последующей обработки, передачи во временное хранилище или использования в других алгоритмах. Несмотря на кажущуюся простоту, метод Выгрузить() часто вызывает ошибки у начинающих программистов. В этой статье мы подробно разберем, как правильно реализовать эту задачу, проанализируем типичные ошибки и рассмотрим альтернативные подходы.

Разбор основной ошибки при использовании метода Выгрузить

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


МассивСтрок = Новый Массив;
МассивСтрок.Добавить(НомерСтроки + 1); // Ошибка: добавляется число (индекс), а не строка
ТЗ = Объект.Товары.Выгрузить(МассивСтрок); 

Причина ошибки: Методы Выгрузить() (у объекта ТабличнаяЧасть) и Скопировать() (у объекта ТаблицаЗначений) ожидают в качестве первого параметра массив, содержащий именно объекты строк данной коллекции, а не их порядковые номера. Когда платформа встречает в массиве число вместо ссылки на строку, она генерирует ошибку контекста.

Правильный способ выгрузки через массив строк

Для того чтобы метод отработал корректно, нам необходимо сначала получить саму строку по её индексу и добавить её в массив. Рассмотрим правильный алгоритм действий:

  1. Определяем индекс нужной строки (помните, что индексация в 1С начинается с 0).
  2. Получаем объект строки из табличной части по индексу.
  3. Помещаем этот объект в массив.
  4. Вызываем метод Выгрузить() у табличной части, передавая этот массив.

Реализуем это в коде:


// Предположим, нам нужна первая строка (индекс 0)
МассивСтрок = Новый Массив;
СтрокаТЧ = Объект.Товары[0]; // Получаем саму строку
МассивСтрок.Добавить(СтрокаТЧ);

// Теперь выгружаем. В результате получим ТЗ с одной строкой и всеми колонками ТЧ
ТЗ = Объект.Товары.Выгрузить(МассивСтрок);

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

Альтернативный метод: Использование ЗаполнитьЗначенияСвойств

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

Рассмотрим по шагам этот процесс:

  1. Сначала создаем пустую таблицу значений с нужной структурой. Проще всего это сделать, выгрузив пустой массив из ТЧ.
  2. Добавляем в новую ТЗ пустую строку.
  3. Используем функцию ЗаполнитьЗначенияСвойств() для переноса данных.

// 1. Создаем структуру (колонки) без данных
ТЗ = Объект.Товары.Выгрузить(Новый Массив); 

// 2. Получаем нужную строку-источник
Индекс = 0; // Нужная нам строка
Источник = Объект.Товары[Индекс];

// 3. Добавляем новую строку в приемник и заполняем её
НоваяСтр = ТЗ.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтр, Источник);

Этот метод удобен тем, что позволяет выборочно копировать данные, если названия колонок в ТЧ и вашей ТЗ совпадают лишь частично.

Важные нюансы работы с контекстом: ТабличнаяЧасть vs ДанныеФормыКоллекция

Выясним причину, почему код может работать в модуле объекта, но выдавать ошибки в модуле формы. В управляемом приложении Объект.Товары на клиенте и сервере формы имеет тип ДанныеФормыКоллекция.

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


&НаСервере
Процедура ВыгрузитьСтрокуНаСервере()
    // Преобразуем коллекцию формы в реальную ТаблицуЗначений
    ТаблицаОбъекта = ДанныеФормыВЗначение(Объект.Товары, Тип("ТаблицаЗначений"));
    
    МассивДляКопирования = Новый Массив;
    МассивДляКопирования.Добавить(ТаблицаОбъекта[0]);
    
    РезультатТЗ = ТаблицаОбъекта.Скопировать(МассивДляКопирования);
КонецПроцедуры

Методы Скопировать() и ВыгрузитьКолонки()

Проанализируем сообщения форума касательно ошибки Метод объекта не обнаружен (ВыгрузитьКолонки). Это происходит потому, что программисты часто путают методы объектов ТаблицаЗначений и ТабличнаяЧасть.

Использование поиска для получения строк

Если вам нужно выгрузить строку не по индексу, а по определенному условию (например, по конкретной Номенклатуре), воспользуйтесь методом НайтиСтроки(). Обратите внимание, что этот метод возвращает Массив, который идеально подходит для передачи в метод Скопировать() или Выгрузить().


Отбор = Новый Структура;
Отбор.Вставить("Номенклатура", ВыбраннаяНоменклатура);

// Получаем массив строк, подходящих под условие
НайденныеСтроки = Объект.Товары.НайтиСтроки(Отбор);

Если НайденныеСтроки.Количество() > 0 Тогда
    // Выгружаем только найденные строки в новую ТЗ
    ТЗ = Объект.Товары.Выгрузить(НайденныеСтроки);
КонецЕсли;

Рекомендации по оптимизации

В завершение рассмотрим несколько советов по производительности:

  1. Проверка на пустоту: Перед обращением по индексу (например, Объект.Товары[0]), всегда проверяйте количество строк методом Количество(), чтобы избежать аварийного завершения программы при пустой таблице.
  2. Запросы: Если документ уже записан в базе данных, а вам нужно получить лишь одну строку для анализа на сервере, зачастую быстрее и правильнее использовать Запрос к табличной части документа. Это позволит не считывать весь объект документа в память целиком, что критично для документов с тысячами строк.
  3. Типизация: При создании ТЗ вручную (через Новый ТаблицаЗначений) старайтесь явно определять типы колонок, если планируете передавать эту таблицу в СКД или использовать в сложных расчетах.

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

← На главную