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

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

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

Способ 1: Создание колонки с произвольным типом данных

Самый простой и быстрый способ добавить колонку, в которой будет храниться вложенная таблица — это добавить колонку без явного указания типа. В 1С колонки таблицы значений по умолчанию имеют произвольный тип, что позволяет записывать в ячейку объект любого типа, включая другую ТаблицаЗначений.

Рассмотрим пример кода, где мы создаем основную таблицу и добавляем в нее колонку для вложенных данных:


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

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

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

Способ 2: Строгая типизация колонки через ОписаниеТипов

Если мы хотим следовать правилам хорошего тона в программировании и обеспечить самодокументируемость кода, следует использовать строгую типизацию. Несмотря на расхожее мнение, что типизировать колонку для ТЗ нет смысла, технически это возможно и иногда необходимо для работы определенных механизмов платформы.

Разберем по шагам, как задать тип ТаблицаЗначений для колонки:

  1. Создадим массив, содержащий нужный нам тип данных.
  2. На основе массива создадим объект ОписаниеТипов.
  3. Передадим это описание в метод Добавить() коллекции колонок.

Проанализируем пример реализации:


// Формируем массив типов
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("ТаблицаЗначений"));

// Создаем описание типов
ОписаниеТипаТЗ = Новый ОписаниеТипов(МассивТипов);

// Добавляем типизированную колонку
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("СоставОбъекта", ОписаниеТипаТЗ);

// Теперь в колонку "СоставОбъекта" можно помещать только таблицы значений
НоваяСтрока = ТЗ.Добавить();
НоваяСтрока.СоставОбъекта = Новый ТаблицаЗначений;

Использование ОписаниеТипов помогает избежать ошибок, когда в колонку по ошибке может быть записано строковое значение или число вместо ожидаемого объекта таблицы.

Особенности работы с вложенными таблицами на управляемых формах

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

Выясним основные нюансы визуализации:

Копирование и память при работе с вложенными структурами

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

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

Альтернативные способы хранения в базе данных

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

Посмотрим на доступные альтернативы:

  1. ХранилищеЗначения: Вы можете поместить вложенную таблицу в объект ХранилищеЗначения. Перед записью платформа сериализует таблицу в двоичные данные (обычно со сжатием). Это оптимальный способ для хранения "настроек" или "составов" внутри одного реквизита.
    
    // Пример записи в хранилище
    ОбъектСправочника.ДополнительныеДанные = Новый ХранилищеЗначения(ВложеннаяТЗ, Новый СжатиеДанных(9));
    
  2. Сериализация в XML/JSON: Если данные нужно передавать во внешние системы, таблицу можно преобразовать в строку XML или массив структур JSON. Помните, что метод ЗаписатьJSON не поддерживает ТЗ напрямую, поэтому предварительно ее нужно выгрузить в массив структур.
  3. Связанные таблицы (UID): Если данных много и по ним нужен поиск, создайте две плоские таблицы. В основной таблице храните уникальный идентификатор (UID), а во второй таблице — данные с привязкой к этому UID.

Ограничения в запросах

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

Если вам необходимо использовать данные из вложенной таблицы в конструкции ГДЕ ПОЛЕ В (&Параметр), вам придется сначала выгрузить нужную колонку вложенной таблицы в отдельный массив или создать отдельную временную таблицу, в которую будут помещены данные из всех вложенных таблиц, объединенных вместе.

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

← На главную