Разработка и Конфигурация · 10 мин
Как сохранить табличный документ во временное хранилище в 1С
Как поместить табличный документ во временное хранилище 1С: ПоместитьВоВременноеХранилище, передача на сервер, срок жизни, типичные ошибки и примеры кода.
Временное хранилище в 1С — это механизм платформы, который позволяет передать данные между клиентом и сервером или между сеансами без записи в базу данных. Табличный документ при этом нельзя поместить в хранилище «как есть»: сначала его преобразуют в двоичные данные (например, через запись в поток или временный файл), а уже результат помещают в хранилище.
Типовая задача выглядит так: на сервере сформирован табличный документ (отчёт, печатная форма, файл Excel), его нужно отдать на клиент для сохранения на диск, отправки по почте или отображения без повторного формирования. Для этого документ записывается методом Записать() в поток в памяти или во временный файл, затем вызывается ПоместитьВоВременноеХранилище(), которая возвращает адрес — строку-идентификатор, по которому данные доступны на сервере.
Ниже разобраны рабочие варианты кода для управляемых форм и внешних вызовов, ограничения по сроку жизни данных, способы проверить результат и ошибки, из-за которых адрес оказывается пустым или данные теряются.
Как работает временное хранилище и почему документ нельзя поместить напрямую
Временное хранилище — это область памяти на сервере 1С, доступная по уникальному адресу (строке вида GUID внутри специального URL). В него можно поместить значения, сериализуемые платформой: примитивные типы, структуры, таблицы значений, двоичные данные. Объект ТабличныйДокумент в хранилище напрямую не помещается в большинстве сценариев передачи между клиентом и сервером, поэтому стандартная практика — сериализовать его в файл.
Последовательность всегда одинаковая: сформировать или получить табличный документ → записать его в поток или файл с указанием типа файла (MXL, XLSX, PDF, HTML и др.) → прочитать двоичные данные → поместить их в хранилище → передать адрес туда, где данные будут использованы.
Базовый способ: запись в поток в памяти
Самый чистый вариант — обойтись без файлов на диске и записать документ в поток в памяти. Это быстрее и не требует прав на файловую систему сервера.
&НаСервере
Функция ПоместитьТабличныйДокументВХранилище(ТабДок)
Поток = Новый ПотокВПамяти();
ТабДок.Записать(Поток, ТипФайлаТабличногоДокумента.XLSX);
ДвоичныеДанные = Поток.ЗакрытьИПолучитьДвоичныеДанные();
Адрес = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификаторФормы);
Возврат Адрес;
КонецФункции
Второй параметр ПоместитьВоВременноеХранилище() — идентификатор формы. Если его передать, данные живут, пока жива форма, что удобно: при закрытии формы хранилище очищается автоматически. Если идентификатор не указан, данные живут до конца сеанса или до первого получения — в зависимости от контекста вызова.
Тип файла выбирайте по дальнейшему сценарию: XLSX — для передачи пользователю в Excel, PDF — для печати и отправки, MXL — если документ потом нужно снова открыть как табличный документ в 1С с сохранением всех свойств, HTML — для показа в браузере или письме.
Вариант через временный файл
Если по какой-то причине поток недоступен (старая версия платформы, особенности окружения), документ записывают во временный файл, читают его в двоичные данные и удаляют файл.
&НаСервере
Функция ПоместитьЧерезФайл(ТабДок)
ИмяФайла = ПолучитьИмяВременногоФайла("xlsx");
ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
ДвоичныеДанные = Новый ДвоичныеДанные(ИмяФайла);
Адрес = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификаторФормы);
УдалитьФайлы(ИмяФайла);
Возврат Адрес;
КонецФункции
Обязательно удаляйте временный файл после чтения. На сервере с активными пользователями накопление таких файлов в каталоге временных файлов — реальная причина переполнения диска. Удаление лучше обернуть в попытку/исключение, чтобы ошибка удаления не прерывала основную логику.
Получение данных на клиенте и сохранение на диск
После того как адрес получен, типовой сценарий на клиенте — забрать двоичные данные и предложить пользователю сохранить файл. В тонком клиенте это делается через ПолучитьФайл() или НачатьПолучениеФайлов().
&НаКлиенте
Процедура СохранитьФайл(Команда)
Адрес = ПоместитьТабличныйДокументВХранилище(ТабличныйДокумент);
Если Не ЭтоАдресВременногоХранилища(Адрес) Тогда
Возврат;
КонецЕсли;
ПолучитьФайл(Адрес, "ПечатнаяФорма.xlsx", Истина);
КонецПроцедуры
Метод ПолучитьФайл() с третьим параметром Истина открывает диалог сохранения. В веб-клиенте файл уйдёт в стандартную загрузку браузера. Если данные нужны не пользователю, а другому серверному вызову (например, фоновое задание сформировало документ, а основной сеанс отправляет его по почте), адрес просто передаётся как параметр, а данные извлекаются через ПолучитьИзВременногоХранилища(Адрес).
- 1Сформируйте или получите табличный документ на сервере
- 2Запишите его в поток в памяти с нужным типом файла
- 3Получите двоичные данные из потока
- 4Вызовите ПоместитьВоВременноеХранилище() с идентификатором формы
- 5Передайте адрес на клиент или в другой вызов
- 6Заберите данные через ПолучитьИзВременногоХранилища() или ПолучитьФайл()
- 7Проверьте, что файл открывается и содержит ожидаемые данные
Срок жизни данных и область видимости адреса
Главная причина «пропадающих» данных — непонимание срока жизни хранилища. Правила зависят от способа помещения:
- с идентификатором формы — данные живут, пока открыта форма; после её закрытия адрес становится недействительным;
- без идентификатора при вызове с клиента — данные обычно живут до конца сеанса;
- при помещении в фоновом задании — данные доступны, пока живо задание или родительский сеанс, в зависимости от контекста; надёжнее передавать результат через параметры задания или помещать в хранилище уже в вызывающем сеансе.
Для длительных сценариев (файл нужен через час, ссылка на скачивание из письма) временное хранилище не подходит в принципе — сохраняйте файл в базу как присоединённый файл или в регистр сведений с двоичными данными.
Типичные ошибки и как их диагностировать
Первая частая ошибка — попытка поместить сам табличный документ и передать адрес на клиент. На тонком клиенте объект ТабличныйДокумент из хранилища не восстановится: получите либо ошибку сериализации, либо непригодное значение. Всегда сериализуйте в файл.
Вторая ошибка — вызов ПоместитьВоВременноеХранилище() в контексте, где нет УникальныйИдентификаторФормы (например, в модуле объекта или общем модуле без параметра). Решение — передавать идентификатор формы параметром из формы или помещать данные без привязки, понимая ограничения по сроку жизни.
Третья — потеря данных между серверными вызовами. Каждый вызов &НаСервере из формы — отдельное обращение; если адрес сформирован в фоновом задании, а задание завершилось, хранилище могло очиститься. Проверяйте адрес функцией ЭтоАдресВременногоХранилища() и не полагайтесь на адрес, полученный давно.
Проверка результата
Минимальная проверка — убедиться, что адрес валиден и данные читаются:
Если ЭтоАдресВременногоХранилища(Адрес) Тогда
Данные = ПолучитьИзВременногоХранилища(Адрес);
Если ТипЗнч(Данные) = Тип("ДвоичныеДанные") Тогда
// данные на месте
КонецЕсли;
КонецЕсли;
Функциональная проверка — открыть полученный файл. XLSX должен открыться в Excel без предупреждений о повреждении, PDF — отобразиться в просмотрщике. Если Excel сообщает о неверном формате, чаще всего документ записан с несовпадающим типом файла и расширением (например, записан как MXL, а сохранён с расширением .xlsx).
Как проверить результат
ЭтоАдресВременногоХранилища() возвращает Истина
Пустая строка или Ложь — данные не помещены
ПолучитьИзВременногоХранилища() возвращает ДвоичныеДанные
Неопределено — срок жизни истёк или адрес чужой
Файл открывается без ошибок формата
Ошибка повреждения — неверный тип файла при записи
FAQ
Можно ли поместить табличный документ в хранилище без преобразования в файл?
Технически ПоместитьВоВременноеХранилище() принимает и другие типы, но при передаче между клиентом и сервером объект ТабличныйДокумент не сериализуется корректно. Надёжный и общепринятый путь — записать документ в поток или файл и поместить двоичные данные.
Сколько времени данные живут во временном хранилище?
Если при помещении указан идентификатор формы — до закрытия формы. Без него — как правило, до конца сеанса, но в ряде сценариев данные удаляются после первого чтения. Для долгого хранения используйте присоединённые файлы или реквизиты с двоичными данными.
Почему ПолучитьИзВременногоХранилища() возвращает Неопределено?
Чаще всего истёк срок жизни: форма закрыта, фоновое задание завершено или данные уже были прочитаны. Также проверьте, что адрес не потерян при сериализации параметров и что чтение происходит в том же сеансе, где данные помещены.
Как передать сформированный в фоновом задании документ в форму?
Помещайте двоичные данные в хранилище внутри фонового задания с адресом, привязанным к форме, либо возвращайте адрес через результат задания и сразу забирайте данные в обработчике ожидания. Не храните адрес долго — после завершения задания данные могут быть очищены.
Какой тип файла выбрать при записи табличного документа?
XLSX — если пользователь будет работать с файлом в Excel; PDF — для печати и отправки; MXL — если документ позже нужно открыть в 1С как табличный документ со всеми свойствами; HTML — для отображения в браузере или теле письма.
Работает ли этот подход в веб-клиенте?
Да. Серверная часть идентична, а на клиенте ПолучитьФайл() инициирует скачивание через браузер. Ограничение — нет прямого доступа к файловой системе пользователя, поэтому сохранение идёт через стандартный диалог загрузки.
Что важно запомнить
Табличный документ сначала сериализуется в поток или файл, затем двоичные данные помещаются во временное хранилище с идентификатором формы. Адрес проверяется через ЭтоАдресВременногоХранилища(), данные забираются оперативно — срок жизни ограничен. Временные файлы на сервере удаляйте сразу после чтения.