При разработке конфигураций на платформе 1С:Предприятие 8.3 часто возникает задача: при создании одного документа на основании другого необходимо уточнить у пользователя параметры заполнения. Например, это может быть выбор типа операции, режима расчета цен или состава переносимых данных. Сложность заключается в том, что стандартный механизм платформы ОбработкаЗаполнения выполняется в модуле объекта на стороне сервера, где интерактивные действия (вызов окон, вопросов или форм) технически невозможны.
В этой статье мы подробно разберем, как правильно обойти это ограничение, используя возможности БСП 3.0 и стандартные механизмы платформы. Мы рассмотрим несколько эффективных способов реализации этой задачи: от использования подключаемых команд до перехвата события получения формы.
Для начала проанализируем ситуацию с технической точки зрения. Когда пользователь нажимает кнопку «Создать на основании», платформа выполняет следующий цикл действий:
ОбработкаЗаполнения в модуле этого объекта.Поскольку процедура ОбработкаЗаполнения выполняется в контексте сервера, попытка вызвать метод ПоказатьВопрос или ОткрытьФорму приведет к ошибке, так как на сервере нет интерфейса пользователя. Следовательно, логику взаимодействия с пользователем нужно переносить на этап, предшествующий инициализации объекта.
Если ваша конфигурация построена на базе Библиотеки стандартных подсистем (БСП), наиболее правильным и современным методом будет использование механизма подключаемых команд. Это позволяет заменить стандартную кнопку платформы на программную команду, которая сначала выполнит код на клиенте.
Рассмотрим по шагам, как это реализовать:
1. В модуле менеджера создаваемого (подчиненного) документа найдем или создадим процедуру ДобавитьКомандыСозданияНаОсновании. Здесь мы опишем нашу команду, указав, что она должна вызывать клиентский метод.
Процедура ДобавитьКомандыСозданияНаОсновании(КомандыСозданияНаОсновании, Параметры) Экспорт
Команда = КомандыСозданияНаОсновании.Добавить();
Команда.Менеджер = "Документ.НашПодчиненныйДокумент";
Команда.Идентификатор = "СоздатьСВопросом";
Команда.Представление = НСтр("ru = 'Наш документ (с выбором параметров)'");
Команда.ТипВызова = "ВызовКлиентскогоМетода"; // Это ключевой момент
Команда.Порядок = 1;
КонецПроцедуры
2. Теперь нам необходимо прописать сам обработчик в модуле формы или в общем модуле (в зависимости от настроек БСП). Проанализируем пример клиентской логики, где мы задаем вопрос:
&НаКлиенте
Процедура ОбработчикКоманды(ПараметрыКоманды, ДополнительныеПараметры) Экспорт
ТекстВопроса = "Выберите режим заполнения документа: Заполнять цены из основания?";
Оповещение = Новый ОписаниеОповещения("ПослеВопросаОЗаполнении", ЭтотОбъект, ПараметрыКоманды);
ПоказатьВопрос(Оповещение, ТекстВопроса, РежимДиалогаВопрос.ДаНет);
КонецПроцедуры
&НаКлиенте
Процедура ПослеВопросаОЗаполнении(Результат, ПараметрыКоманды) Экспорт
Если Результат = КодВозвратаДиалога.Да Тогда
ОтветПользователя = Истина;
Иначе
ОтветПользователя = Ложь;
КонецЕсли;
// Подготавливаем параметры для открытия формы
ПараметрыЗаполнения = Новый Структура;
ПараметрыЗаполнения.Вставить("Основание", ПараметрыКоманды.Источник[0]);
ПараметрыЗаполнения.Вставить("ПереноситьЦены", ОтветПользователя);
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ЗначенияЗаполнения", ПараметрыЗаполнения);
ОткрытьФорму("Документ.НашПодчиненныйДокумент.ФормаОбъекта", ПараметрыФормы);
КонецПроцедуры
3. На заключительном этапе перейдем в модуль объекта подчиненного документа и обработаем переданную структуру в событии ОбработкаЗаполнения.
Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)
Если ТипЗнч(ДанныеЗаполнения) = Тип("Структура") И ДанныеЗаполнения.Свойство("Основание") Тогда
ДокументОснование = ДанныеЗаполнения.Основание;
НужноЛиЗаполнятьЦены = Ложь;
ДанныеЗаполнения.Свойство("ПереноситьЦены", НужноЛиЗаполнятьЦены);
// Логика заполнения на основе полученного ответа
ЗаполнитьШапку(ДокументОснование);
Если НужноЛиЗаполнятьЦены Тогда
ЗаполнитьЦены(ДокументОснование);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Если вы не используете БСП или хотите оставить стандартную кнопку «Создать на основании», можно применить метод перехвата события получения формы в модуле менеджера подчиненного документа. Выясним причину выбора этого метода: он позволяет вмешаться в процесс открытия формы до того, как будет создан объект.
Рассмотрим алгоритм действий:
ОбработкаПолученияФормы.Параметры ключ Основание.СтандартнаяОбработка = Ложь.Пример кода в модуле менеджера:
Процедура ОбработкаПолученияФормы(ВидФормы, Параметры, ВыбраннаяФорма, СтандартнаяОбработка)
// Проверяем, что это ввод на основании и у нас еще нет ответа от пользователя
Если Параметры.Свойство("Основание") И НЕ Параметры.Свойство("ВопросРешен") Тогда
СтандартнаяОбработка = Ложь;
// Открываем специальную форму выбора операции
ВыбраннаяФорма = "ОбщаяФорма.ДиалогВыбораВариантаЗаполнения";
КонецЕсли;
КонецПроцедуры
Важный нюанс: В форме-диалоге после выбора варианта нужно программно вызвать открытие формы основного документа, передав в параметрах ссылку на основание и признак ВопросРешен = Истина, чтобы избежать бесконечной рекурсии в ОбработкаПолученияФормы.
Разберем ситуацию, когда документ создается пустым, и вопрос задается уже непосредственно в открытой форме. Этот способ проще в реализации, но менее эстетичен, так как пользователь сначала видит пустую форму, которая затем «магически» заполняется.
В модуле формы подчиненного документа в событии ПриОткрытии (на клиенте) выполняем проверку:
&НаКлиенте
Процедура ПриОткрытии(Отказ)
// Проверяем, что документ новый и еще не заполнен
Если Объект.Ссылка.Пустая() И Объект.Товары.Количество() = 0 Тогда
Оповещение = Новый ОписаниеОповещения("ЗаполнитьПослеВопроса", ЭтотОбъект);
ПоказатьВопрос(Оповещение, "Заполнить данные из основания?", РежимДиалогаВопрос.ДаНет);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ЗаполнитьПослеВопроса(Результат, ДополнительныеПараметры) Экспорт
Если Результат = КодВозвратаДиалога.Да Тогда
// Вызываем серверную процедуру для заполнения объекта
ЗаполнитьДокументНаСервере();
КонецЕсли;
КонецПроцедуры
Проанализировав все варианты, можно сделать вывод, что наиболее профессиональным решением для современных конфигураций является использование подключаемых команд БСП. Это обеспечивает чистоту кода и позволяет полностью контролировать процесс создания объекта. Если же конфигурация не использует БСП, стоит остановиться на методе ОбработкаПолученияФормы.
Помните основные правила:
ЗначенияЗаполнения для передачи ответов пользователя из клиентских процедур в серверную ОбработкаЗаполнения.ПоказатьВопрос) всегда применяйте ОписаниеОповещения.Применяя эти подходы, вы сможете создавать удобные и гибкие механизмы ввода на основании, которые значительно повысят удобство работы пользователей в системе. Для быстрой настройки переноса данных без ручного написания логики можно использовать обработку-конструктор для автоматического создания документов на основании.