Как во внешней обработке заполнения документа БСП открыть форму для ввода данных пользователем?

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

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

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

Шаг 1. Настройка экспортной функции регистрации обработки

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

В типовых конфигурациях для этого применяется тип "ОткрытиеФормы" (или вызов метода ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыОткрытиеФормы()). Посмотрим на пример формирования структуры регистрации:


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

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

Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = "")
    
    НоваяСтрока = ТаблицаКоманд.Добавить();
    НоваяСтрока.Представление = Представление;
    НоваяСтрока.Идентификатор = Идентификатор;
    НоваяСтрока.Использование = Использование;
    НоваяСтрока.ПоказыватьОповещение = ПоказыватьОповещение;
    НоваяСтрока.Модификатор = Модификатор;
    
КонецПроцедуры

Обратим внимание: БСП автоматически открывает именно основную форму обработки. Убедимся, что у создаваемой формы в свойствах обработки установлен признак основной.

Шаг 2. Получение ссылки на исходный документ в форме обработки

Когда подсистема БСП открывает форму обработки с типом команды "ОткрытиеФормы", она автоматически передает в параметры формы контекст вызова. Проанализируем структуру переданных параметров в модуле открываемой формы:


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

Кроме того, на клиенте свойство ВладелецФормы автоматически указывает на ту форму, из которой была вызвана команда (например, форма редактируемого документа или форма списка).

Шаг 3. Передача заполненных данных обратно в документ

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

  1. Прямое заполнение открытой формы документа (рекомендуется для интерактивной работы).

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

    Чтобы избежать этой коллизии, изменим данные напрямую в контексте формы документа через обращение к владельцу:

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

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

Шаг 4. Особенности вызова из формы списка и работа с блокировками

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

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

Шаг 5. Безопасный режим и права доступа

Обратим внимание на параметр регистрации "БезопасныйРежим". Если в алгоритме формы обработки планируется загрузка данных из локальных файлов на диске, взаимодействие с COM-объектами или внешними компонентами, безопасный режим платформы ограничит эти действия. В таких ситуациях в функции СведенияОВнешнейОбработке() следует передавать БезопасныйРежим = Ложь или настраивать явные разрешения безопасности в профиле безопасности информационной базы.

← На главную