Как программно создать документ и открыть его форму в 1С:Управляемые формы

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

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

Разделение контекста: Клиент и Сервер

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

Типичная ошибка, которую мы часто видим на форумах, — попытка получить форму или выполнить интерактивный выбор (например, ПолучитьФормуВыбора) внутри серверной функции. Это невозможно, так как сервер «не видит» интерфейс пользователя. Разберем правильный алгоритм взаимодействия:

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

Способ 1. Создание, запись и открытие по ссылке

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

Серверная часть:


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

Клиентская часть:


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

Способ 2. Открытие формы нового (незаписанного) документа

Иногда требуется открыть форму документа, который еще не записан в базу. Это «чистый» подход: пользователь видит заполненные поля, может их отредактировать и решить — сохранять документ или просто закрыть форму без создания «мусорной» записи в базе. Для этого используется параметр ЗначенияЗаполнения.

Выясним причину, почему это удобно: в модуле объекта документа существует предопределенная процедура ОбработкаЗаполнения. Когда мы передаем данные через параметры формы, 1С автоматически вызывает эту процедуру.

Пример вызова на клиенте:


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

Способ 3. Использование ДанныеФормыВЗначение и ЗначениеВДанныеФормы

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

Реализация на сервере и клиенте:


&НаКлиенте
Процедура СоздатьСложныйДокумент(Команда)
    
    // 1. Получаем форму нового документа
    ФормаДокумента = ПолучитьФорму("Документ.рбсДоговор.ФормаОбъекта");
    
    // 2. Извлекаем данные формы (это программная копия объекта в форме)
    ОбъектФормы = ФормаДокумента.Объект;
    
    // 3. Передаем данные на сервер для сложного заполнения
    ЗаполнитьНаСервере(ОбъектФормы);
    
    // 4. Копируем измененные данные обратно в форму
    КопироватьДанныеФормы(ОбъектФормы, ФормаДокумента.Объект);
    
    // 5. Открываем готовую форму пользователю
    ФормаДокумента.Открыть();
    
КонецПроцедуры

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

Важные нюансы и рекомендации

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

  1. Параметр «Ключ»: Это самый важный параметр. Если вы передаете в ОткрытьФорму структуру с ключом Ключ, содержащим ссылку, 1С всегда будет открывать существующий объект. Если Ключ пустой или отсутствует — будет создана форма нового объекта.
  2. Использование ОткрытьЗначение: Простейший способ открыть форму — метод ОткрытьЗначение(Ссылка). Он работает быстро, но не позволяет передавать дополнительные параметры в форму или управлять уникальностью окна.
  3. Отказ от модальности: Старайтесь не использовать ОткрытьМодально. В современном интерфейсе «Такси» и веб-клиенте это может привести к ошибкам. Используйте ОткрытьФорму или ОписаниеОповещения для асинхронной работы.
  4. Права доступа: Помните, что создание документа на сервере через Документы.Имя.СоздатьДокумент() не всегда проверяет права текущего пользователя в момент вызова метода. Проверка прав (на чтение или изменение) произойдет в момент вызова ОткрытьФорму. Если прав недостаточно, форма просто не откроется, даже если объект был успешно записан кодом.
  5. Уникальность формы: Если вам нужно, чтобы при повторном нажатии кнопки не открывалось второе окно с тем же документом, используйте третий параметр метода ОткрытьФорму — ключ уникальности. Обычно туда передается ссылка на документ.

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

← На главную