В практике разработчика 1С (пригодится набор MCP-серверов для разработки на 1С с ИИ) часто возникает задача извлечения данных из табличного документа (макета или результата отчета) для их дальнейшей программной обработки. Стандартный путь — перебор строк и колонок в цикле — на больших объемах данных (от нескольких тысяч строк) работает крайне медленно. В этой статье мы рассмотрим, как использовать объект ПостроительОтчета для мгновенной конвертации области ячеек в таблицу значений и проанализируем способы наложения условий на результат без потери производительности.
Для начала разберем классический способ получения данных — для этой задачи извлечения данных из табличного документа (макета или результата отчета) пригодится универсальная выгрузка документов с гибкой настройкой. Вместо того чтобы обходить каждую ячейку методом Область(), мы задействуем механизм ОписаниеИсточникаДанных. Этот объект выступает «мостом» между визуальным представлением макета и программной структурой.
Посмотрим на пример кода, который выполняет базовое преобразование:
// Определяем область, из которой нужно забрать данные
ОбластьЯчеек = Макет.Область(1, 1, Макет.ВысотаТаблицы, 10);
// Создаем построитель и описываем источник
ПО_данные = Новый ПостроительОтчета;
ПО_данные.ИсточникДанных = Новый ОписаниеИсточникаДанных(ОбластьЯчеек);
// Выполняем построение и выгружаем результат
ПО_данные.Выполнить();
ТЗ = ПО_данные.Результат.Выгрузить();
Этот метод работает на порядок быстрее, чем ручное заполнение таблицы значений через Добавить() и Установить() в цикле. Основная магия здесь заключается в том, что 1С на уровне платформы оптимизирует чтение ячеек памяти табличного документа.
Часто нам нужно получить из макета не все строки, а только те, что соответствуют определенному критерию (например, где значение в колонке равно 1) — в этом поможет управление печатными формами и макетами 1С. Автор темы интересовался, можно ли обойтись без перебора результата. Выясним, как это сделать правильно с помощью коллекции Отбор.
Рассмотрим подробнее, как добавить условие:
// Добавляем фильтр до выполнения метода Выполнить()
ЭлементОтбора = ПО_данные.Отбор.Добавить("ИмяКолонкиИзМакета");
ЭлементОтбора.Использование = Истина;
ЭлементОтбора.ВидСравнения = ВидСравнения.Равно;
ЭлементОтбора.Значение = 1;
ПО_данные.Выполнить();
ТЗ_С_Фильтром = ПО_данные.Результат.Выгрузить();
Важный нюанс: ПостроительОтчета автоматически определяет имена колонок по первой строке указанной области. Если в первой строке написано "Статус", то в отборе нужно обращаться именно к полю с именем Статус. Если заголовков нет, система может присвоить имена вида Поле1, Поле2.
Когда мы работаем с очень большими макетами, ПостроительОтчета тратит время на то, чтобы «угадать» тип данных в каждой колонке, анализируя содержимое ячеек. Мы можем ускорить процесс, если заранее укажем типы данных.
Проанализируем ситуацию, когда нам нужны не все 100 колонок макета, а только 2 конкретных. Для этого в объекте ОписаниеИсточникаДанных есть коллекция Колонки. Разберем по шагам процесс оптимизации:
ОписаниеИсточника = Новый ОписаниеИсточникаДанных(ОбластьЯчеек);
ОписаниеИсточника.ЗаполнятьАвтоматически = Ложь;
// Добавляем только нужную колонку и задаем ей тип
НоваяКолонка = ОписаниеИсточника.Колонки.Добавить("Цена");
НоваяКолонка.ТипЗначения = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2));
ПО_данные.ИсточникДанных = ОписаниеИсточника;
ПО_данные.Выполнить();
ТЗ_Оптимизированная = ПО_данные.Результат.Выгрузить();
Такой подход позволяет избежать лишнего потребления памяти, так как 1С не будет создавать в итоговой ТаблицаЗначений лишние столбцы и пытаться обработать ненужные данные.
В исходном вопросе звучала задача: «значение колонки результата = ?(значение исх колонки = 1, Истина, Ложь)». ПостроительОтчета не поддерживает вычисляемые поля напрямую в своем тексте, когда источником является макет. Однако мы можем элегантно решить эту задачу, объединив скорость построителя и мощь языка запросов 1С, что является ключевым навыком для быстрого анализа данных.
Рассмотрим комбинированный алгоритм:
ПостроительОтчета.Запрос как внешний источник данных.ВЫБОР для преобразования данных.
// Шаг 1: Быстрая выгрузка
ПО = Новый ПостроительОтчета;
ПО.ИсточникДанных = Новый ОписаниеИсточникаДанных(ОбластьЯчеек);
ПО.Выполнить();
ТЗ_Сырая = ПО.Результат.Выгрузить();
// Шаг 2: Обработка запросом
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВТ.Колонка1 КАК ИсходноеЗначение,
| ВЫБОР
| КОГДА ВТ.Колонка1 = 1 ТОГДА ИСТИНА
| ИНАЧЕ ЛОЖЬ
| КОНЕЦ КАК РезультатЛогики
|ПОМЕСТИТЬ ВТ_Данные
|ИЗ
| &ТЗ КАК ВТ
|;
|ВЫБРАТЬ * ИЗ ВТ_Данные";
Запрос.УстановитьПараметр("ТЗ", ТЗ_Сырая);
ТЗ_Финальная = Запрос.Выполнить().Выгрузить();
Этот метод кажется более длинным по коду, но на практике он работает в десятки раз быстрее, чем цикл Для Каждого СтрокаТЗ Из ТЗ_Сырая, особенно если строк больше 10 000. Вся обработка происходит в оперативной памяти с использованием высокооптимизированных механизмов платформы.
Выясним причину, по которой опытные разработчики предпочитают именно этот метод. При ручном переборе каждой ячейки (Область(стр, кол).Текст или Область(стр, кол).Значение) происходит обращение к визуальному слою табличного документа. Это крайне ресурсоемкая операция. Каждое обращение к ячейке — это отдельный вызов к внутренним структурам данных, который включает в себя проверку прав, форматов, стилей и прочего.
ПостроительОтчета же обращается к данным «пакетом». Он считывает всю область целиком, минимизируя количество переключений контекста. Как показывают замеры производительности, для области в 50 000 строк выигрыш во времени может составлять 80-90%.
При работе с этим методом нужно учитывать несколько важных моментов, которые мы проанализируем ниже:
Значение ячейки. Если вы программно заполнили только Текст, а свойство Значение осталось пустым, в итоговой таблице вы получите NULL или неопределено.ТЗ через отладчик.Подведем итог: использование ПостроительОтчета — это профессиональный стандарт для быстрой обработки данных макета, хотя для более сложных задач сегодня чаще применяют объектную модель схемы компоновки данных, работу с которой можно упростить с помощью инструментов вроде СКДБилдера. Комбинируя его с объектом Запрос и коллекцией Отбор, мы получаем мощный инструмент, позволяющий обрабатывать огромные объемы данных без зависания интерфейса и перегрузки системы.