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

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

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

Метод 1. Использование стандартного обработчика «ОбработкаЗаполнения»

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

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


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

Теперь разберем, что должно происходить на стороне создаваемого документа. В модуле объекта необходимо прописать логику обработки этого массива:


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

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

Метод 2. Использование команд с типом параметра «Массив»

Если мы хотим использовать стандартный механизм «Создать на основании», нам следует создать общую команду или команду объекта. Выясним причину, по которой команды часто не отображаются в интерфейсе: это происходит из-за неверной настройки свойств команды.

Рассмотрим по шагам настройку такой команды:

  1. Создаем новую Команду в дереве метаданных документа.
  2. В свойстве Тип параметра команды выбираем типы документов, которые могут быть основаниями.
  3. Устанавливаем свойство Режим использования параметра в значение Множественный. Это позволит платформе передавать в команду массив ссылок, если в списке выделено несколько строк.
  4. В свойстве Группа выбираем Командная панель формы.Создать на основании.

После этого в модуле команды пишем код вызова формы, аналогичный примеру выше. Важный нюанс: если команда все равно не видна, проверьте Тип параметра. Если он не задан или задан неверно для текущего контекста, кнопка не появится в командной панели.

Метод 3. Программное создание объекта и использование КопироватьДанныеФормы()

Иногда логика заполнения настолько сложна, что её удобнее выполнить целиком на сервере, получить готовый объект, а затем «подсунуть» его в открывающуюся форму. Рассмотрим этот продвинутый вариант. Мы не можем передать целый объект с сервера на клиент напрямую для открытия формы, так как ДанныеФормыСтруктура (которым является реквизит Объект) требует особого обращения.

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

  1. На сервере создаем экземпляр документа через Документы.НужныйТип.СоздатьДокумент().
  2. Заполняем его всеми необходимыми данными.
  3. В форме документа, которую мы открываем, в обработчике ПриСозданииНаСервере используем метод КопироватьДанныеФормы().

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


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

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

Метод 4. Передача данных через параметры «ЗначенияЗаполнения»

Если нам нужно заполнить только простые реквизиты шапки (например, Организация, Склад, Контрагент), можно воспользоваться параметром формы ЗначенияЗаполнения. Это структура, ключи которой соответствуют именам реквизитов документа.

Проанализируем пример:


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

Платформа сама подставит эти значения в соответствующие поля при инициализации формы. Это работает максимально быстро и не требует написания кода в модуле объекта.

Рекомендации и важные моменты

При реализации создания документов без записи следует учитывать несколько технических аспектов:

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

← На главную