Как выгрузить ТабличныйДокумент в ТаблицуЗначений с заданием фиксированной длины строк?

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

При разработке инструментов импорта данных или обработок, взаимодействующих с макетами, программисты часто сталкиваются с задачей конвертации ТабличногоДокумента в ТаблицуЗначений. Стандартный и наиболее быстрый способ — использование объекта ПостроительЗапроса. Однако у него есть существенный недостаток: при формировании таблицы-результата 1С автоматически вычисляет длину строковых колонок на основании самого длинного значения в текущем документе. Если в ячейках содержатся строки до 20 символов, то и в итоговой таблице колонка получит ограничение в 20 символов. Это создает проблемы, если в дальнейшем планируется программно дополнять эту таблицу более длинными строками или объединять её с данными из БД.

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

Метод 1: Использование ПостроителяЗапроса и «физической» типизации ячеек

Разберем ситуацию, когда ПостроительЗапроса игнорирует настройки ДоступныеПоля. Как правило, даже если мы вручную указываем ОписаниеТипов для колонки построителя, после вызова метода Выполнить() структура перестраивается на основе анализа данных источника. Чтобы заставить платформу «увидеть» нужную нам длину, мы можем воздействовать на сам ТабличныйДокумент.

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

  1. Установим для области ячеек свойство СодержитЗначение в значение Истина.
  2. Назначим ТипЗначения с нужным квалификатором строки.

Рассмотрим пример кода:


// Предположим, ТабДок уже заполнен данными
Для Каждого Колонка Из СписокКолонок Цикл
    Область = ТабДок.Область(1, НомерКолонки, ТабДок.ВысотаТаблицы, НомерКолонки);
    Область.СодержитЗначение = Истина;
    Область.ТипЗначения = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(200));
КонецЦикла;

Построитель = Новый ПостроительЗапроса;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабДок.Область());
Построитель.Выполнить();
ТЗ = Построитель.Результат.Выгрузить();

Хотя здесь присутствует цикл, он работает с областями ТабличногоДокумента, что зачастую быстрее, чем построчное заполнение ТаблицыЗначений вручную.

Метод 2: Использование «фиктивной» строки данных

Проанализируем самый простой «хитрый» способ, который часто применяют опытные разработчики. Поскольку ПостроительЗапроса определяет длину колонки по самому длинному значению, мы можем временно добавить в ТабличныйДокумент одну строку, заполненную пробелами нужной длины.

  1. Добавляем в конец таблицы строку.
  2. В каждую целевую ячейку записываем строку из N пробелов (например, 200).
  3. Выполняем выгрузку через построитель.
  4. Удаляем лишнюю строку из полученной ТаблицыЗначений.

Это решение позволяет избежать сложной настройки типов и работает максимально быстро, так как платформа задействует внутренние оптимизированные алгоритмы анализа данных.

Метод 3: Приведение типов через временные таблицы в Запросе

Если мы хотим получить результат с гарантированно точными типами и не желаем менять исходный ТабличныйДокумент, мы можем использовать механизм запросов 1С. Рассмотрим этот алгоритм подробнее:

Сначала мы выгружаем данные «как есть» (с короткими строками) в промежуточную ТаблицуЗначений. Затем передаем эту таблицу в запрос в качестве параметра. В самом запросе мы используем оператор ВЫРАЗИТЬ, который позволяет жестко задать тип и длину поля.


// 1. Получаем "короткую" ТЗ
Построитель = Новый ПостроительЗапроса;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабДок.Область());
Построитель.Выполнить();
ТЗ_Короткая = Построитель.Результат.Выгрузить();

// 2. Типизируем через запрос
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ВЫРАЗИТЬ(ТЗ.Артикул КАК СТРОКА(200)) КАК Артикул,
    |	ВЫРАЗИТЬ(ТЗ.Наименование КАК СТРОКА(500)) КАК Наименование
    |ПОМЕСТИТЬ ВтДанные
    |ИЗ
    |	&ТЗ КАК ТЗ
    |;
    |
    |ВЫБРАТЬ * ИЗ ВтДанные";

Запрос.УстановитьПараметр("ТЗ", ТЗ_Короткая);
ТЗ_Итоговая = Запрос.Выполнить().Выгрузить();

Важный момент: использование ВЫРАЗИТЬ для строк работает только при приведении к строке фиксированной длины. Это идеальный способ быстро перетипизировать весь массив данных без перебора строк в цикле Для каждого.

Метод 4: Использование Системы Компоновки Данных (СКД)

Выясним, как применить мощь СКД для решения нашей задачи. СКД позволяет описывать наборы данных с четко заданными типами. Если мы опишем Внешний набор данных, укажем для его полей нужные квалификаторы строк и загрузим в него нашу таблицу, полученную из ТабличногоДокумента, то при компоновке результата платформа сама приведет данные к нужным типам.

Этот метод считается наиболее «архитектурно правильным» в современной платформе 8.3, так как он отделяет описание структуры данных от процесса их получения. Рассмотрим шаги:

  1. Создаем схему компоновки данных программно.
  2. Добавляем НаборДанныхОбъект.
  3. Описываем поля набора данных, указывая для них ОписаниеТипов с нужной длиной.
  4. Загружаем в схему данные из исходной (даже «короткой») таблицы.
  5. Выводим результат в новую ТаблицуЗначений.

Сравнение подходов

Выбор метода зависит от контекста задачи:

Таким образом, несмотря на кажущееся ограничение ПостроителяЗапроса, платформа 1С предоставляет достаточно инструментов для гибкого управления типами данных при конвертации из визуальных форм в структуры памяти.

← На главную