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

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

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

Проблема передачи объекта между сервером и клиентом (Ошибка XDTO)

Разберем ситуацию, представленную в одном из сообщений форума. Разработчик пытается создать функцию на сервере, которая возвращает ДокументОбъект, и вызвать её на клиенте для открытия формы. Это приводит к критической ошибке: "Ошибка преобразования данных XDTO: НачалоСвойства: ret... Тип: {http://www.w3.org/2001/XMLSchema}anyType".

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

Решение 1: Использование параметра «ЗначенияЗаполнения» (для новых документов)

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

Рассмотрим пример кода:


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

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

Решение 2: Использование метода «КопироватьДанныеФормы»

Если задача сложнее (например, нужно заполнить не только простые реквизиты, но и табличные части), или мы работаем с существующим документом, который нужно изменить «на лету» перед показом, нам потребуется метод КопироватьДанныеФормы. Этот метод позволяет перенести данные из прикладного объекта в структуру данных формы.

Разберем алгоритм действий по шагам:

  1. Получаем форму документа программно (без открытия).
  2. На сервере модифицируем данные объекта.
  3. Копируем измененные данные в реквизит формы Объект.
  4. Открываем форму пользователю.

Посмотрим на пример реализации этой логики:


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

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

Важный момент: использование ДанныеФормыВЗначение и КопироватьДанныеФормы позволяет работать с объектом на сервере привычными методами, сохраняя при этом интерактивность — пользователь увидит все изменения, но кнопка «Записать» в базе еще не будет нажата.

Решение 3: Передача данных через временное хранилище

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

Схема работы будет следующей:

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

Посмотрим, как реализовать извлечение данных в модуле формы открываемого документа:


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

Резюме и рекомендации

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

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

← На главную