Передача сложных объектов, таких как ТабличныйДокумент, между двумя формами — это стандартная задача в разработке на платформе 1С:Предприятие 8.3. Однако начинающие разработчики часто сталкиваются с трудностями при использовании механизма временного хранилища. Разберем типичные ошибки, проанализируем причины их возникновения и рассмотрим два способа решения задачи: «быстрый» (через параметры) и «правильный» (через временное хранилище).
Рассмотрим ситуацию, с которой столкнулся автор темы. Попытка поместить данные в хранилище и получить их по УникальныйИдентификатор формы часто приводит к ошибке: «Ошибка получения значения из временного хранилища по причине: Неправильный путь к файлу...». Выясним причину этой проблемы.
Многие полагают, что второй параметр функции ПоместитьВоВременноеХранилище — это и есть адрес, по которому данные будут доступны. На самом деле это не так. Рассмотрим пример ошибочного кода:
&НаСервере
Процедура ОшибочныйМетод()
// ОШИБКА: Мы создаем новый GUID, но не сохраняем адрес хранилища
ПоместитьВоВременноеХранилище(Реквизит1, Новый УникальныйИдентификатор);
КонецПроцедуры
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// ОШИБКА: Попытка получить данные по идентификатору формы,
// в которую ничего не помещалось
Данные = ПолучитьИзВременногоХранилища(ЭтаФорма.УникальныйИдентификатор);
КонецПроцедуры
В чем здесь кроется подвох? Функция ПоместитьВоВременноеХранилище возвращает строку — уникальный адрес во временном хранилище (вида e1cib/tempstorage/UUID). Именно эту строку нужно передать во вторую форму. Если же мы пытаемся использовать просто УникальныйИдентификатор формы-получателя, платформа сообщает, что по такому пути ничего не найдено, так как адрес хранилища — это специальный строковый путь, а не просто набор символов идентификатора.
Этот способ подходит для передачи небольших объектов или когда производительность не является критическим фактором. В этом случае мы помещаем объект непосредственно в структуру параметров при открытии формы.
Посмотрим на пример реализации, который применил автор во втором сообщении:
&НаКлиенте
Процедура ПоказатьФорму(Команда)
// Формируем параметры, передавая сам объект (например, ТабличныйДокумент)
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Параметр1", Реквизит1);
ПараметрыФормы.Вставить("Параметр2", Реквизит2);
ОткрытьФорму("Обработка.ПробаМетодаСЛистом.Форма.ФормаНаша",
ПараметрыФормы,
,,,,
РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
КонецПроцедуры
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Извлекаем данные напрямую из коллекции Параметры
Если Параметры.Свойство("Параметр1") Тогда
РеквизитНаВторойФорме.Вывести(Параметры.Параметр1);
КонецЕсли;
КонецПроцедуры
Важное замечание: При таком подходе 1С выполняет сериализацию объекта в XML на стороне сервера первой формы, передает его на клиент, а затем снова десериализует на сервере второй формы. Для огромных табличных документов это может привести к заметным задержкам в интерфейсе.
Для оптимизации работы и передачи «тяжелых» данных рекомендуется использовать временное хранилище. В этом случае между формами передается только короткая строка-адрес, а сами данные остаются в оперативной памяти сервера.
Разберем этот процесс по шагам:
Шаг 1. Помещение данных в хранилище на первой форме. Нам необходимо привязать данные к идентификатору текущей формы, чтобы они жили столько же, сколько открыта форма-владелец.
&НаСервере
Функция ПодготовитьАдресДанных()
// Возвращаем адрес строки, привязанный к текущей форме
Возврат ПоместитьВоВременноеХранилище(Реквизит1, ЭтаФорма.УникальныйИдентификатор);
КонецФункции
&НаКлиенте
Процедура ОткрытьВторуюФорму(Команда)
АдресХранилища = ПодготовитьАдресДанных();
ПараметрыОткрытия = Новый Структура("АдресДанных", АдресХранилища);
ОткрытьФорму("Обработка.МояОбработка.Форма.ВтораяФорма", ПараметрыОткрытия);
КонецПроцедуры
Шаг 2. Получение данных на второй форме. В процедуре ПриСозданииНаСервере мы обращаемся к адресу, переданному через параметры.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Параметры.Свойство("АдресДанных") Тогда
// Получаем объект по переданному адресу
ОбъектИзХранилища = ПолучитьИзВременногоХранилища(Параметры.АдресДанных);
Если ТипЗнч(ОбъектИзХранилища) = Тип("ТабличныйДокумент") Тогда
РеквизитВторойФормы.Вывести(ОбъектИзХранилища);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Проанализируем ситуацию с точки зрения управления ресурсами. Временное хранилище требует внимательного отношения к времени жизни данных:
ЭтаФорма.УникальныйИдентификатор, данные будут автоматически удалены при закрытии формы. Это наиболее безопасный вариант.УдалитьИзВременногоХранилища(Параметры.АдресДанных), чтобы не ждать закрытия формы для освобождения памяти.Подведем итог: использование УникальныйИдентификатор — это не способ «назвать» ячейку в хранилище, а способ указать «владельца» данных. Чтобы передать информацию, всегда нужно оперировать результатом функции ПоместитьВоВременноеХранилище, который является строковым адресом. Выбирайте способ передачи в зависимости от объема данных: параметры — для простых значений, хранилище — для отчетов и таблиц.