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

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

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

Разберем основные варианты реализации этой задачи в управляемых формах в зависимости от исходного контекста вызова.

Вариант 1. Модификация данных уже открытого документа (внутри формы)

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

  1. Вызываем серверную процедуру без сохранения данных в базу.
  2. Преобразуем данные формы в прикладной объект типа ДокументОбъект с помощью метода РеквизитФормыВЗначение.
  3. Выполняем все необходимые изменения, расчеты или заполнение табличных частей.
  4. Возвращаем измененный объект обратно в структуру данных формы через метод ЗначениеВРеквизитФормы.

Посмотрим на пример реализации в модуле формы документа:


&НаКлиенте
Процедура ВыполнитьСложноеЗаполнение(Команда)
    ЗаполнитьДокументНаСервере();
    ОповеститьОбИзменении(Объект.Ссылка);
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьДокументНаСервере()
    // Преобразуем данные формы в полноценный прикладной объект
    ДокОбъект = РеквизитФормыВЗначение("Объект");
    
    // Выполняем алгоритмы заполнения или вызываем методы модуля объекта
    ДокОбъект.ЗаполнитьПоСложномуАлгоритму();
    
    // Загружаем измененные данные обратно в форму без записи в базу данных
    ЗначениеВРеквизитФормы(ДокОбъект, "Объект");
КонецПроцедуры

Если сложная логика не требует методов модуля объекта, а оперирует лишь реквизитами и табличными частями, достаточно выполнить обычный контекстный вызов &НаСервере и напрямую обращаться к реквизиту Объект формы — платформа 1С автоматически передаст изменения обратно на клиент при завершении серверного вызова.

Вариант 2. Открытие нового документа с передачей параметров заполнения

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

Разберем по шагам, как открыть форму нового документа с заполненными на сервере данными:

  1. Формируем на клиенте или сервере структуру параметров с ключом ЗначенияЗаполнения или произвольными флагами.
  2. Вызываем метод ОткрытьФорму, передавая подготовленную структуру.
  3. В модуле открываемого документа отрабатывает стандартная ОбработкаЗаполнения или обработчик ПриСозданииНаСервере.

Пример вызова из внешней формы:


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

В модуле формы открываемого документа перехватываем переданные параметры:


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

Вариант 3. Передача больших объемов данных через Временное хранилище

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

Разберем данный алгоритм:

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

Пример кода формирования данных:


&НаКлиенте
Процедура СформироватьИОткрыть(Команда)
    АдресВХ = ПодготовитьДанныеНаСервере();
    
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("АдресДанныхЗаполнения", АдресВХ);
    
    ОткрытьФорму("Документ.ЗаказКлиента.ФормаОбъекта", ПараметрыФормы);
КонецПроцедуры

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

Пример приема данных в форме документа:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Если Параметры.Свойство("АдресДанныхЗаполнения") И ЭтоАдресВременногоХранилища(Параметры.АдресДанныхЗаполнения) Тогда
        ТаблицаДанных = ПолучитьИзВременногоХранилища(Параметры.АдресДанныхЗаполнения);
        Объект.Товары.Загрузить(ТаблицаДанных);
        УдалитьИзВременногоХранилища(Параметры.АдресДанныхЗаполнения);
    КонецЕсли;
КонецПроцедуры

Ограничения при работе с незаписанными документами

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

  1. Отсутствие ссылки в базе данных: У незаписанного документа свойство Объект.Ссылка возвращает пустую ссылку (ДокументСсылка.<ИмяДокумента>.ПустаяСсылка). Любые механизмы, завязанные на запросы к данным текущего документа по ссылке, работать не будут до момента первой интерактивной или программной записи.
  2. Оптимизация трафика: Частое преобразование РеквизитФормыВЗначение и ЗначениеВРеквизитФормы на объемных документах создает дополнительную нагрузку на серверную память и сериализацию данных, поэтому применять данные методы следует только при реальной необходимости обращения к функционалу модуля объекта.
← На главную