Работа с табличными частями документов и справочников в 1С:Предприятие — одна из самых частых задач для разработчиков. Часто данные из табличных частей требуется преобразовать в массивы для дальнейшей обработки: фильтрации, сортировки, передачи в другие системы или просто для удобства работы в коде. Однако не все знают, что существует несколько способов выгрузки — от элементарных до оптимизированных для больших объёмов данных.

В этой статье мы разберём 5 основных методов выгрузки табличной части в массив, их плюсы и минусы, а также нюансы, которые помогут избежать типичных ошибок. Особое внимание уделим работе с Управляемыми формами (где табличные части представлены как ДинамическийСписок) и Обычными формами (где используется ТаблицаФормы). Также рассмотрим, как правильно обрабатывать пустые строки, отборы и производительность при работе с большими таблицами.

Если вы только начинаете осваивать программирование в 1С, советуем сначала прочитать раздел о базовых методах. Опытные разработчики могут сразу перейти к оптимизированным решениям или разделу про работу с динамическими списками.

1. Базовый метод: Выгрузка через цикл Для Каждого

Самый простой и интуитивно понятный способ — это перебор строк табличной части в цикле и добавление их в массив. Этот метод подходит для небольших таблиц (до 1000 строк) и часто используется в учебных примерах.

Пример кода для Обычной формы:

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

Для Каждого СтрокаТаблицы Из ТабличнаяЧасть Цикл

МассивСтрок.Добавить(СтрокаТаблицы.Ссылка); // или другие поля

КонецЦикла;

Для Управляемой формы код будет аналогичным, но вместо ТабличнаяЧасть используется Объект.ТабличнаяЧасть:

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

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

МассивСтрок.Добавить(Строка.Номенклатура);

КонецЦикла;

Плюсы:

  • 🔹 Простота реализации — подходит для новичков.
  • 🔹 Не требует дополнительных функций или методов.
  • 🔹 Легко модифицировать под конкретные задачи.

Минусы:

  • ⚠️ Низкая производительность при большом количестве строк (более 1000).
  • ⚠️ Не учитывает отборы и фильтры, если они не применены заранее.
💡

Если вам нужно выгрузить только определенные поля, укажите их явно в цикле: МассивСтрок.Добавить(Строка.Номенклатура + " | " + Строка.Количество). Это сэкономит память.

2. Метод Выгрузить(): быстрая выгрузка без цикла

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

Пример использования:

МассивСтрок = Объект.ТабличнаяЧасть.Выгрузить();

Метод возвращает массив структур, где каждая структура соответствует строке табличной части, а ключи структуры — это имена колонок. Например:

// Пример содержимого массива:

МассивСтрок[0].Номенклатура // значение из первой строки, колонки "Номенклатура"

МассивСтрок[0].Количество // значение из первой строки, колонки "Количество"

🔹 Особенности метода:

  • 📌 Выгружает все колонки, даже если они не отображаются в форме.
  • 📌 Сохраняет порядок строк, но не учитывает сортировку, применённую пользователем.
  • 📌 Работает значительно быстрее цикла Для Каждого (в 5-10 раз для больших таблиц).
Что делать, если метод Выгрузить() не работает?

Если при вызове Выгрузить() возникает ошибка, проверьте:

1. Версию платформы (метод доступен с 8.3.6 и выше).

2. Права доступа к табличной части (может требоваться режим ЧтениеИЗапись).

3. Наличие несохранённых изменений в документе (иногда требуется сначала сохранить объект).

3. Выгрузка с отбором: как выгрузить только нужные строки

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

Способ 1: Отбор до выгрузки

Отбор = Новый Структура();

Отбор.Вставить("Номенклатура", Справочники.Номенклатура.НайтиПоНаименованию("Товар 1"));

Объект.ТабличнаяЧасть.Отбор.Установить(Отбор);

МассивСтрок = Объект.ТабличнаяЧасть.Выгрузить();

Способ 2: Фильтрация после выгрузки (если отбор сложный или динамический):

МассивСтрок = Объект.ТабличнаяЧасть.Выгрузить();

ОтфильтрованныйМассив = МассивСтрок.Найти(Функция(Строка) Возврат Строка.Количество > 10 КонецФункции);

⚠️ Внимание: Если вы используете отбор в Управляемой форме, не забывайте сбрасывать его после выгрузки, иначе он останется активным для пользователя:

Объект.ТабличнаяЧасть.Отбор.Очистить();
Метод отбора Производительность Когда использовать
Отбор.Установить() ⚡ Высокая Для статических условий (например, фильтр по справочнику)
НайтиСтроки() ⚡⚡ Средняя Для динамических условий (например, фильтр по дате)
Фильтрация после выгрузки ⚡⚡⚡ Низкая Только для небольших массивов (до 500 строк)

4. Работа с динамическими списками в Управляемых формах

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

Пример выгрузки из динамического списка:

ЭлементыФормы.ТабличнаяЧасть.ВыгрузитьДанные(МассивСтрок, Ложь);

Параметры метода:

  • МассивСтрок — целевой массив для выгрузки.
  • Ложь — не выгружать служебные колонки (например, ПометкаУдаления).

🔹 Важные моменты:

  • 📌 Динамический список может содержать несохранённые изменения. Если нужно выгрузить актуальные данные, сначала сохраните объект:
  • Объект.Записать();
  • 📌 Для вычисляемых колонок (например, Сумма = Количество * Цена) значения будут актуальны только на момент выгрузки.
📊 Какой тип форм вы чаще используете в 1С?
Управляемые формы
Обычные формы
Оба типа примерно одинаково
Не работаю с формами

5. Оптимизированная выгрузка для больших таблиц (10 000+ строк)

При работе с большими табличными частями (от 10 000 строк) стандартные методы могут приводить к зависаниям интерфейса или переполнению памяти. В таких случаях рекомендуется использовать:

Способ 1: Постраничная выгрузка

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

Позиция = 0;

Пока Истина Цикл

ПачкаСтрок = Объект.ТабличнаяЧасть.Выгрузить(Позиция, 1000); // выгружаем по 1000 строк

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

Прервать;

КонецЕсли;

МассивСтрок.Добавить(ПачкаСтрок);

Позиция = Позиция + 1000;

КонецЦикла;

Способ 2: Прямой запрос к базе данных (для опытных разработчиков):

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

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

"ВЫБРАТЬ

| ТабличнаяЧастьДокумента.Номенклатура КАК Номенклатура,

| ТабличнаяЧастьДокумента.Количество КАК Количество

|ИЗ

| Документ.ВашДокумент.ТабличнаяЧасть КАК ТабличнаяЧастьДокумента

|ГДЕ

| ТабличнаяЧастьДокумента.Ссылка = &Ссылка";

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

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

МассивСтрок = Результат.Выгрузить();

⚠️ Внимание: Прямые запросы к базе данных обходят механизмы блокировок 1С. Используйте их только в фоновых заданиях или когда уверены, что данные не изменяются другими пользователями.

Использовать постраничную выгрузку (по 500-1000 строк)|Отключить ненужные колонки перед выгрузкой|Применить отбор на уровне запроса, а не после выгрузки|Для критических операций использовать фоновые задания-->

6. Типичные ошибки и как их избежать

Даже опытные разработчики иногда сталкиваются с проблемами при выгрузке табличных частей. Рассмотрим самые распространённые ошибки и способы их решения.

Ошибка 1: Пустой массив при выгрузке

🔹 Причина: Табличная часть не сохранена или отбор слишком строгий.

🔹 Решение: Проверьте, что объект записан (Объект.Записать()) и отбор не исключает все строки.

Ошибка 2: Ошибка доступа при выгрузке

🔹 Причина: Недостаточно прав на чтение табличной части.

🔹 Решение: Используйте Попытка ... Исключение или проверьте права в конфигураторе.

Попытка

МассивСтрок = Объект.ТабличнаяЧасть.Выгрузить();

Исключение

Сообщить("Ошибка выгрузки: " + ОписаниеОшибки());

КонецПопытки;

Ошибка 3: Несовпадение типов данных

🔹 Причина: В массиве ожидается один тип (например, СправочникСсылка.Номенклатура), а приходит другой (например, Неопределённо).

🔹 Решение: Явно преобразуйте типы или используйте ЗначениеЗаполнено():

Если ЗначениеЗаполнено(Строка.Номенклатура) Тогда

МассивСтрок.Добавить(Строка.Номенклатура);

КонецЕсли;

💡

Всегда проверяйте результат выгрузки на пустоту, особенно если табличная часть может быть не заполнена. Используйте Если МассивСтрок.Количество() = 0 Тогда для обработки таких случаев.

⚠️ Внимание: При работе с Управляемыми формами в веб-клиенте некоторые методы (например, ВыгрузитьДанные()) могут работать медленнее, чем в толстом клиенте. Тестируйте производительность в целевой среде!

FAQ: Ответы на частые вопросы

Можно ли выгрузить табличную часть в массив без потери форматирования (цветов, шрифтов)?

Нет, методы выгрузки (Выгрузить(), цикл Для Каждого) работают только с данными, без сохранения визуального оформления. Если нужно сохранить форматирование, используйте Печать или экспорт в Excel через ЗначениеВФайл().

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

Используйте явное создание структуры в цикле:

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

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

НоваяСтруктура = Новый Структура();

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

НоваяСтруктура.Вставить("Колво", Строка.Количество);

МассивСтрок.Добавить(НоваяСтруктура);

КонецЦикла;

Почему при выгрузке в массив теряются ссылки на справочники?

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

  1. Объект записан (Объект.Записать()).
  2. Вы не используете Копировать() или Поместить() без явного указания типов.

Если проблема остаётся, проверьте, не сброшены ли ссылки в самой табличной части (например, после обмена данными).

Как выгрузить табличную часть в массив асинхронно, чтобы не блокировать интерфейс?

Для асинхронной выгрузки используйте ФоновоеЗадание:

ФоновоеЗадание = ФоновыеЗадания.СоздатьФоновоеЗадание(

"ВыгрузкаТабличнойЧасти",

Новый Структура("Объект, МассивСтрок", Объект, Новый Массив()),

Истина);

В модуле фонового задания реализуйте логику выгрузки, а результат получите через событие ПриЗавершении.

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

Да, но для этого сначала преобразуйте массив в JSON через ЗаписьJSON:

Запись = Новый ЗаписьJSON;

Запись.УстановитьСтроку();

ЗаписьJSON.Записать(Запись, МассивСтрок);

JSONСтрока = Запись.Закрыть();

Учтите, что сериализует справочники как строки (например, "Справочник.Номенклатура:123"). Для корректной обработки на стороне веб-сервиса может потребоваться дополнительное преобразование.