К статье
Практический материал

Разработка и Конфигурация · 11 мин

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

Разбираем способы передачи таблицы значений в форму 1С: хранилище значений, временное хранилище, реквизит формы. Примеры кода, ошибки, FAQ.

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

Существует несколько рабочих подходов: через временное хранилище, через хранилище значений, через параметры формы с предварительной упаковкой и через реквизит формы типа «ТаблицаЗначений». Выбор зависит от того, откуда вызывается форма, нужно ли редактировать данные в форме и какой объём передаётся.

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

Почему таблицу значений нельзя передать напрямую

При открытии управляемой формы с параметрами платформа сериализует их — преобразует в формат, пригодный для передачи между клиентом и сервером. Таблица значений в этот список сериализуемых типов не входит: попытка передать её через структуру параметров ОткрытьФорму() приведёт к ошибке вида «Недопустимый тип параметра» или к потере данных.

Кроме того, таблица значений может содержать произвольные типы в колонках, включая объекты, которые сами не сериализуются. Платформа не может гарантировать корректное восстановление такой структуры на другой стороне, поэтому запрещает передачу целиком.

Из этого следует главный принцип: передавать нужно не саму таблицу, а либо ссылку на неё (адрес временного хранилища), либо сериализуемую обёртку (хранилище значения), либо набор простых данных, из которых таблица восстанавливается в форме.

Способ 1: передача через временное хранилище

Это самый универсальный и рекомендуемый способ для управляемых форм. Идея: таблица помещается во временное хранилище, а в форму передаётся только адрес (строка). В форме таблица извлекается по этому адресу и загружается в реквизит формы.

Код в месте вызова формы:

АдресХранилища = ПоместитьВоВременноеХранилище(ТаблицаДанных, Новый УникальныйИдентификатор);

ПараметрыФормы = Новый Структура;

ПараметрыФормы.Вставить("АдресТаблицы", АдресХранилища);

ОткрытьФорму("Обработка.ПодборСтрок.Форма.ФормаПодбора", ПараметрыФормы);

Код в форме-получателе:

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

Если Параметры.Свойство("АдресТаблицы") Тогда

ТаблицаДанных = ПолучитьИзВременногоХранилища(Параметры.АдресТаблицы);

ТаблицаФормы.Загрузить(ТаблицаДанных);

КонецЕсли;

КонецПроцедуры

Здесь ТаблицаФормы — реквизит формы с типом «ТаблицаЗначений», созданный в конфигураторе. Метод Загрузить() копирует строки и структуру колонок. Второй параметр ПоместитьВоВременноеХранилище() — идентификатор формы — определяет время жизни данных: пока жива форма с этим идентификатором, хранилище не очищается.

Порядок действий
  1. 1
    Создайте в форме-получателе реквизит с типом ТаблицаЗначений и нужными колонками
  2. 2
    В месте вызова поместите таблицу во временное хранилище и получите адрес
  3. 3
    Передайте адрес через структуру параметров ОткрытьФорму()
  4. 4
    В ПриСозданииНаСервере извлеките таблицу по адресу и загрузите в реквизит формы
  5. 5
    Проверьте: данные отображаются в табличной части формы после открытия

Способ 2: упаковка в хранилище значений

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

ПараметрыФормы = Новый Структура;

ПараметрыФормы.Вставить("ТаблицаУпакованная", Новый ХранилищеЗначения(ТаблицаДанных));

ОткрытьФорму("Обработка.ПодборСтрок.Форма.ФормаПодбора", ПараметрыФормы);

В форме:

Если Параметры.Свойство("ТаблицаУпакованная") Тогда

ТаблицаДанных = Параметры.ТаблицаУпакованная.Получить();

ТаблицаФормы.Загрузить(ТаблицаДанных);

КонецЕсли;

Способ удобен, когда форма открывается из контекста, где временное хранилище недоступно или неудобно — например, при программном создании формы через ПолучитьФорму(). Ограничение: упаковка и распаковка создают полные копии данных, поэтому для очень больших таблиц (десятки тысяч строк и более) это медленнее и тяжелее по памяти, чем хранилище.

Способ 3: заполнение реквизита формы напрямую

Если форма доступна как объект до открытия (через ПолучитьФорму()) или таблица передаётся между формами одного объекта, можно обойтись без параметров: заполнить реквизит формы-получателя напрямую из вызывающего кода.

ФормаПодбора = ПолучитьФорму("Обработка.ПодборСтрок.Форма.ФормаПодбора");

ФормаПодбора.ТаблицаФормы.Загрузить(ТаблицаДанных);

ФормаПодбора.Открыть();

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

Этот подход часто используется при передаче данных между основной формой обработки и её дополнительными формами, а также при возврате результата из модальной формы через ОповеститьОВыборе() — там таблицу тоже передают как адрес хранилища или упакованное значение.

Возврат таблицы из формы обратно

Симметричная задача — получить отредактированную таблицу после закрытия формы. Стандартный приём: при закрытии форма помещает таблицу во временное хранилище и возвращает адрес через Закрыть() или оповещение.

&НаКлиенте

Процедура КомандаВыбрать(Команда)

АдресРезультата = ПоместитьТаблицуВХранилище();

ОповеститьОВыборе(АдресРезультата);

КонецПроцедуры

&НаСервере

Функция ПоместитьТаблицуВХранилище()

Возврат ПоместитьВоВременноеХранилище(ТаблицаФормы.Выгрузить(), УникальныйИдентификатор);

КонецФункции

Вызывающая форма открывает подбор через ОткрытьФорму() с указанием владельца и обрабатывает результат в ОбработкаВыбора() или через описание оповещения в ПоказатьОткрытьФорму-подобных механизмах. Полученный адрес используется для извлечения таблицы и дальнейшей обработки.

Сравнение вариантов

Временное хранилище

Универсальный способ для управляемых форм; данные живут на сервере, передаётся только адрес. Требует управления временем жизни хранилища.

Хранилище значений

Простая передача прямо в параметрах формы. Создаёт полную копию данных — не подходит для очень больших таблиц.

Прямое заполнение реквизита

Быстро и без сериализации, но работает только когда форма доступна как объект до открытия.

Массив структур

Сериализуется без обёрток, но теряется типизация колонок и не поддерживаются сложные типы в ячейках.

Типичные ошибки и ограничения

Самая частая ошибка — попытка передать таблицу значений напрямую в структуре параметров. Платформа либо выдаст ошибку, либо молча потеряет данные, и форма откроется пустой. Второе место занимает обращение к методам Загрузить()/Выгрузить() на клиенте: реквизит формы там представлен как ДанныеФормыКоллекция, у которого этих методов нет, — вызов завершится ошибкой «Метод объекта не обнаружен».

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

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

Типичные ошибки
01
Передача таблицы значений напрямую в параметрах ОткрытьФорму — ошибка сериализации или пустая форма
02
Вызов Загрузить()/Выгрузить() на клиенте — методы доступны только в серверном контексте
03
Помещение во временное хранилище без идентификатора формы — данные удаляются до чтения
04
Несовпадение имён колонок при Загрузить() — часть данных теряется без сообщений
05
Передача большой таблицы через хранилище значений — лишние копии в памяти и замедление

Как проверить, что передача сработала

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

Полезно также проверить типы колонок: если в исходной таблице колонка имела тип «СправочникСсылка», а в форме колонка строковая, Загрузить() выполнит приведение, и ссылки превратятся в строки представления. Такие ошибки проявляются позже — при попытке использовать значение как ссылку.

Контрольные точки

Как проверить результат

Количество строк в форме
Норма

Совпадает с количеством строк исходной таблицы

Тревожный признак

Строк меньше или таблица пустая — данные не дошли или адрес хранилища недействителен

Типы значений в колонках
Норма

Ссылки остаются ссылками, даты — датами

Тревожный признак

Ссылки превратились в строки — несовпадение типов колонок

Повторное открытие формы
Норма

Данные читаются стабильно при каждом открытии

Тревожный признак

При повторном открытии таблица пустая — проблема со временем жизни хранилища

FAQ

Можно ли передать таблицу значений между разными сеансами или пользователями?

Нет, ни временное хранилище, ни параметры формы для этого не предназначены. Для межсеансовой передачи таблицу сохраняют в базу данных — например, в регистр сведений с ресурсом типа «ХранилищеЗначения» или в реквизит справочника, — а второй сеанс читает её оттуда.

Что делать, если таблица содержит колонки с типом «ТаблицаЗначений» (вложенные таблицы)?

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

Нужно ли очищать временное хранилище после использования?

Если адрес привязан к идентификатору формы, данные удалятся автоматически при её закрытии. Если привязки нет, хранилище живёт до конца сеанса и расходует память сервера — для больших таблиц стоит явно вызывать УдалитьИзВременногоХранилища() после чтения.

Можно ли передать таблицу в форму записи регистра или документа?

Да, механизм тот же: адрес временного хранилища передаётся через параметры, а в ПриСозданииНаСервере таблица загружается в табличную часть объекта. Для документов удобно заполнять движения или табличную часть в обработчике ОбработкаЗаполнения, если данные передаются как источник заполнения.

Почему после Загрузить() в форме пропали настройки колонок, заданные в конфигураторе?

Метод Загрузить() пересоздаёт колонки реквизита по структуре загружаемой таблицы, если колонки реквизита не были зафиксированы. Чтобы сохранить настройки, заранее создайте колонки реквизита с теми же именами и типами — тогда загрузятся только данные строк.

Итог

Что важно запомнить

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