Работа с табличными частями документов и справочников в 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. Работа с динамическими списками в Управляемых формах
В Управляемых формах табличные части часто представлены как ДинамическийСписок. Выгрузка данных из него имеет свои нюансы, так как динамический список может содержать не только строки объекта, но и дополнительные колонки (например, вычисляемые поля).
Пример выгрузки из динамического списка:
ЭлементыФормы.ТабличнаяЧасть.ВыгрузитьДанные(МассивСтрок, Ложь);
Параметры метода:
МассивСтрок— целевой массив для выгрузки.Ложь— не выгружать служебные колонки (например,ПометкаУдаления).
🔹 Важные моменты:
- 📌 Динамический список может содержать несохранённые изменения. Если нужно выгрузить актуальные данные, сначала сохраните объект:
Объект.Записать();
Сумма = Количество * Цена) значения будут актуальны только на момент выгрузки.5. Оптимизированная выгрузка для больших таблиц (10 000+ строк)
При работе с большими табличными частями (от 10 000 строк) стандартные методы могут приводить к зависаниям интерфейса или переполнению памяти. В таких случаях рекомендуется использовать:
Способ 1: Постраничная выгрузка
МассивСтрок = Новый Массив();
Позиция = 0;
Пока Истина Цикл
ПачкаСтрок = Объект.ТабличнаяЧасть.Выгрузить(Позиция, 1000); // выгружаем по 1000 строк
Если ПачкаСтрок.Количество() = 0 Тогда
Прервать;
КонецЕсли;
МассивСтрок.Добавить(ПачкаСтрок);
Позиция = Позиция + 1000;
КонецЦикла;
Способ 2: Прямой запрос к базе данных (для опытных разработчиков):
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТабличнаяЧастьДокумента.Номенклатура КАК Номенклатура,
| ТабличнаяЧастьДокумента.Количество КАК Количество
|ИЗ
| Документ.ВашДокумент.ТабличнаяЧасть КАК ТабличнаяЧастьДокумента
|ГДЕ
| ТабличнаяЧастьДокумента.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", Объект.Ссылка);
Результат = Запрос.Выполнить();
МассивСтрок = Результат.Выгрузить();
⚠️ Внимание: Прямые запросы к базе данных обходят механизмы блокировок 1С. Используйте их только в фоновых заданиях или когда уверены, что данные не изменяются другими пользователями.
Использовать постраничную выгрузку (по 500-1000 строк)|Отключить ненужные колонки перед выгрузкой|Применить отбор на уровне запроса, а не после выгрузки|Для критических операций использовать фоновые задания-->
6. Типичные ошибки и как их избежать
Даже опытные разработчики иногда сталкиваются с проблемами при выгрузке табличных частей. Рассмотрим самые распространённые ошибки и способы их решения.
Ошибка 1: Пустой массив при выгрузке
🔹 Причина: Табличная часть не сохранена или отбор слишком строгий.
🔹 Решение: Проверьте, что объект записан (Объект.Записать()) и отбор не исключает все строки.
Ошибка 2: Ошибка доступа при выгрузке
🔹 Причина: Недостаточно прав на чтение табличной части.
🔹 Решение: Используйте Попытка ... Исключение или проверьте права в конфигураторе.
Попытка
МассивСтрок = Объект.ТабличнаяЧасть.Выгрузить();
Исключение
Сообщить("Ошибка выгрузки: " + ОписаниеОшибки());
КонецПопытки;
Ошибка 3: Несовпадение типов данных
🔹 Причина: В массиве ожидается один тип (например, СправочникСсылка.Номенклатура), а приходит другой (например, Неопределённо).
🔹 Решение: Явно преобразуйте типы или используйте ЗначениеЗаполнено():
Если ЗначениеЗаполнено(Строка.Номенклатура) Тогда
МассивСтрок.Добавить(Строка.Номенклатура);
КонецЕсли;
Всегда проверяйте результат выгрузки на пустоту, особенно если табличная часть может быть не заполнена. Используйте Если МассивСтрок.Количество() = 0 Тогда для обработки таких случаев.
⚠️ Внимание: При работе с Управляемыми формами в веб-клиенте некоторые методы (например, ВыгрузитьДанные()) могут работать медленнее, чем в толстом клиенте. Тестируйте производительность в целевой среде!
FAQ: Ответы на частые вопросы
Можно ли выгрузить табличную часть в массив без потери форматирования (цветов, шрифтов)?
Нет, методы выгрузки (Выгрузить(), цикл Для Каждого) работают только с данными, без сохранения визуального оформления. Если нужно сохранить форматирование, используйте Печать или экспорт в Excel через ЗначениеВФайл().
Как выгрузить табличную часть в массив структур с заданными именами полей?
Используйте явное создание структуры в цикле:
МассивСтрок = Новый Массив();
Для Каждого Строка Из Объект.ТабличнаяЧасть Цикл
НоваяСтруктура = Новый Структура();
НоваяСтруктура.Вставить("Товар", Строка.Номенклатура);
НоваяСтруктура.Вставить("Колво", Строка.Количество);
МассивСтрок.Добавить(НоваяСтруктура);
КонецЦикла;
Почему при выгрузке в массив теряются ссылки на справочники?
Это происходит, если вы используете неверный метод выгрузки или не сохраняете объект перед выгрузкой. Убедитесь, что:
- Объект записан (
Объект.Записать()). - Вы не используете
Копировать()илиПоместить()без явного указания типов.
Если проблема остаётся, проверьте, не сброшены ли ссылки в самой табличной части (например, после обмена данными).
Как выгрузить табличную часть в массив асинхронно, чтобы не блокировать интерфейс?
Для асинхронной выгрузки используйте ФоновоеЗадание:
ФоновоеЗадание = ФоновыеЗадания.СоздатьФоновоеЗадание(
"ВыгрузкаТабличнойЧасти",
Новый Структура("Объект, МассивСтрок", Объект, Новый Массив()),
Истина);
В модуле фонового задания реализуйте логику выгрузки, а результат получите через событие ПриЗавершении.
Можно ли выгрузить табличную часть в JSON для передачи в веб-сервис?
Да, но для этого сначала преобразуйте массив в JSON через ЗаписьJSON:
Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
ЗаписьJSON.Записать(Запись, МассивСтрок);
JSONСтрока = Запись.Закрыть();
Учтите, что 1С сериализует справочники как строки (например, "Справочник.Номенклатура:123"). Для корректной обработки на стороне веб-сервиса может потребоваться дополнительное преобразование.