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

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

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

Как поместить таблицу значений во временное хранилище 1С: ПоместитьВоВременноеХранилище, адрес хранения, передача на клиент, сериализация и типичные ошибки.

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

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

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

Базовый код: поместить таблицу и получить адрес

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

&НаСервере

Функция ПолучитьАдресТаблицы()

Таблица = Новый ТаблицаЗначений;

Таблица.Колонки.Добавить("Номенклатура");

Таблица.Колонки.Добавить("Количество");

НоваяСтрока = Таблица.Добавить();

НоваяСтрока.Номенклатура = "Товар 1";

НоваяСтрока.Количество = 5;

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

Возврат Адрес;

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

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

Получение таблицы обратно из хранилища

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

&НаСервере

Процедура ЗагрузитьТаблицуНаСервере(Адрес)

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

Если ТипЗнч(Таблица) = Тип("ТаблицаЗначений") Тогда

ТаблицаНаФорме.Загрузить(Таблица);

КонецЕсли;

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

Обратите внимание на проверку типа. Если адрес устарел (форма была закрыта и открыта заново, сеанс перезапущен), метод вернёт Неопределено, и обращение к методам таблицы вызовет ошибку. Проверка типа перед использованием — обязательная практика.

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

Порядок действий
  1. 1
    Сформируйте таблицу значений в серверной процедуре
  2. 2
    Вызовите ПоместитьВоВременноеХранилище с УникальныйИдентификатор формы
  3. 3
    Сохраните или передайте полученный адрес
  4. 4
    Извлеките таблицу через ПолучитьИзВременногоХранилища с проверкой типа
  5. 5
    Удалите данные через УдалитьИзВременногоХранилища, если они больше не нужны

Передача таблицы между формами

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

&НаКлиенте

Процедура ЗавершитьПодбор(Команда)

Адрес = СформироватьТаблицуПодбора();

ОповеститьОВыборе(Адрес);

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

&НаСервере

Функция СформироватьТаблицуПодбора()

// Адрес привязываем к форме-владельцу

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

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

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

Типичные ошибки
01
Привязка хранилища к закрывающейся форме — после закрытия адрес становится недействительным, и ПолучитьИзВременногоХранилища возвращает Неопределено
02
Попытка передать саму таблицу значений как параметр между клиентом и сервером в управляемой форме — платформа не сериализует этот тип напрямую
03
Отсутствие удаления больших таблиц из хранилища — память сервера растёт до перезапуска сеанса

Работа с фоновыми заданиями

В длительных операциях (загрузка из файла, обмен, массивный расчёт) таблицу формирует фоновое задание. У фонового задания нет формы, поэтому адрес хранилища передаётся в параметрах метода ДлительныеОперации.ВыполнитьФункцию или классического ФоновыеЗадания.Выполнить.

&НаСервере

Функция ЗапуститьЗагрузку()

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

ПараметрыПроцедуры = Новый Массив;

ПараметрыПроцедуры.Добавить(Адрес);

ФоновыеЗадания.Выполнить("МойМодуль.ЗагрузитьДанные", ПараметрыПроцедуры);

Возврат Адрес;

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

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

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

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

Тип значения по адресу
Норма

ТипЗнч возвращает ТаблицаЗначений

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

Неопределено — адрес устарел или хранилище очищено

Количество строк после извлечения
Норма

Совпадает с количеством при помещении

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

Пустая таблица — вероятно, помещён другой объект или адрес перезаписан

Память после обработки
Норма

Хранилище удалено или привязано к форме

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

Адреса без владельца накапливаются в сеансе

Ограничения и альтернативы

Временное хранилище сериализует данные, поэтому помещать можно только сериализуемые значения. Таблица значений сериализуется полностью, вместе со структурой колонок и типами. Однако если в ячейках таблицы лежат несериализуемые объекты (например, COM-объекты), помещение завершится ошибкой.

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

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

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

Подходит для передачи между формами и фоновыми заданиями; требует контроля времени жизни адреса

Реквизит формы ТаблицаЗначений

Проще внутри одной формы, платформа сама передаёт данные; не работает вне формы

Сериализация в JSON через ЗаписьJSON

Подходит для обмена с внешними системами; требует ручного описания структуры и потери типов 1С

Ещё одна альтернатива — метод ЗначениеВСтрокуВнутр, который превращает таблицу во внутреннее строковое представление. Оно компактнее адреса хранилища при передаче во внешние системы, но нечитаемо и зависит от версии платформы, поэтому для обмена с внешними сервисами предпочтительнее JSON.

Очистка хранилища и производительность

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

&НаСервере

Процедура ОбработатьИОчистить(Адрес)

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

Если ТипЗнч(Таблица) = Тип("ТаблицаЗначений") Тогда

// обработка таблицы

КонецЕсли;

УдалитьИзВременногоХранилища(Адрес);

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

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

FAQ

Почему ПолучитьИзВременногоХранилища возвращает Неопределено?

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

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

Да, если не передавать второй параметр или передать свой адрес-строку. Но тогда хранилище живёт до конца сеанса, и удалять данные придётся вручную через УдалитьИзВременногоХранилища, иначе память сервера будет расходоваться впустую.

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

Создайте адрес заранее с привязкой к УникальныйИдентификатор формы, передайте его в параметры фонового задания, а внутри задания вызовите ПоместитьВоВременноеХранилище с этим адресом. После завершения задания форма забирает таблицу по тому же адресу.

Сохраняются ли типы колонок при помещении в хранилище?

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

Что лучше для обмена с внешним веб-сервисом — хранилище или JSON?

Для внешних систем используйте JSON: адрес временного хранилища существует только внутри сеанса 1С и недоступен извне. Таблицу сериализуют через ЗаписьJSON, а на приёмной стороне восстанавливают по описанной структуре.

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

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

Итог

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

Таблица значений помещается через ПоместитьВоВременноеХранилище с привязкой к УникальныйИдентификатор формы, извлекается через ПолучитьИзВременногоХранилища с проверкой типа, а неиспользуемые адреса удаляются вручную. Для фоновых заданий адрес создаётся заранее и передаётся в параметрах.