Как программно изменить существующий документ и открыть его форму без записи в управляемом приложении 1С

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

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

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

Метод 1: Прямая модификация реквизита формы «Объект»

Это самый быстрый способ, наиболее близкий к логике обычных форм. Суть заключается в том, что мы сначала получаем форму существующего документа на клиенте, затем на сервере модифицируем её данные и возвращаем управление клиенту для открытия окна.

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

Шаг 1. Код на стороне клиента

На клиенте нам нужно получить форму документа по его ссылке. Для этого используется функция ПолучитьФорму с передачей параметра Ключ.


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

Шаг 2. Код на стороне сервера

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


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

Метод 2: Использование параметров формы и обработчика ПриСозданииНаСервере

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

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

  1. В вызывающей обработке мы помещаем данные во Временное хранилище.
  2. Передаем адрес этого хранилища в параметрах открытия формы.
  3. В форме документа в событии ПриСозданииНаСервере считываем данные и заполняем объект.

Пример кода в обработке:


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

Затем в расширении или модуле формы документа добавим обработку этих параметров:


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

Важные нюансы работы в управляемом режиме

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

1. Объект vs ДанныеФормы

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

2. Уникальность формы

Если документ уже открыт у пользователя, вызов ПолучитьФорму вернет ссылку на уже открытое окно. Если вы начнете менять его данные программно, пользователь может увидеть неожиданное обновление таблиц. Чтобы всегда работать с конкретным экземпляром, внимательно следите за параметром УникальныйИдентификатор.

3. Модифицированность

Когда вы программно меняете Объект формы, система не всегда автоматически понимает, что данные стали "грязными" (измененными). Чтобы при закрытии формы 1С спросила пользователя: "Сохранить изменения?", не забывайте устанавливать ЭтаФорма.Модифицированность = Истина;.

4. Использование БСП

Если вы разрабатываете в современной типовой конфигурации (УТ 11, ERP, БП 3.0), рекомендуется использовать механизмы Библиотеки Стандартных Подсистем (БСП). В частности, для внешних обработок заполнения предусмотрены готовые интерфейсы, которые берут на себя всю сложность взаимодействия контекстов.

Выяснив причину сложности — разделение контекстов — мы видим, что решение остается простым, если понимать механику преобразования данных формы в объект и обратно. Используйте Метод 1 для быстрых правок «извне» и Метод 2 для более надежной и чистой архитектуры вашего кода.

← На главную