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

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

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

Выясним причину поведения системы

Прежде всего, проанализируем ситуацию с точки зрения механизмов БСП. В конфигурациях, использующих БСП версии 3.0 и выше, за логику отображения команд заполнения отвечает общий модуль ДополнительныеОтчетыИОбработки. Если мы заглянем внутрь процедуры ПриОпределенииКомандЗаполненияПодключенныхКОбъекту, то обнаружим жесткую логику определения режима записи:


Если СтрокаТаблицы.ВариантЗапуска = ЗаполнениеФормы Тогда
    Команда.Обработчик  = "ДополнительныеОтчетыИОбработки.ОбработчикКомандыЗаполнения";
    Команда.РежимЗаписи = "НеЗаписывать";
Иначе
    Команда.Обработчик  = "ДополнительныеОтчетыИОбработкиКлиент.ОбработчикКомандыЗаполнения";
    Команда.РежимЗаписи = "Записывать";
КонецЕсли;

Таким образом, мы видим, что если выбран вариант запуска, отличный от прямого серверного вызова ЗаполнениеФормы (например, ВызовКлиентскогоМетода или ОткрытиеФормы), БСП автоматически устанавливает свойство РежимЗаписи в значение "Записывать". Это сделано из соображений безопасности: разработчики БСП предполагают, что клиентской обработке может потребоваться ссылка на объект, которой у нового документа еще нет.

Способ 1. Использование типа команды "ЗаполнениеФормы"

Самый простой способ избежать вопроса о записи — использовать вариант запуска ЗаполнениеФормы. В этом случае БСП по умолчанию устанавливает режим НеЗаписывать. Рассмотрим пример формирования структуры команды в модуле объекта внешней обработки:


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

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

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

Способ 2. Изменение вида обработки на "Дополнительная обработка"

Если вам критично открыть форму обработки для уточнения параметров перед заполнением документа, но вы не хотите записывать документ, можно сменить вид обработки с ЗаполнениеОбъекта на ДополнительнаяОбработка. Посмотрим, как это изменит поведение системы.

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

Рассмотрим пример кода в форме внешней обработки:


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

Способ 3. Использование расширения конфигурации

Если бизнес-процесс требует, чтобы кнопка находилась именно в меню "Заполнение", и при этом документ не должен записываться, нам придется прибегнуть к расширению конфигурации. Это наиболее гибкий, но требующий внесения изменений в логику базы метод.

Проанализируем, где можно перехватить управление. Нам необходимо расширить процедуру ПриСозданииНаСервере формы документа или использовать механизм перехвата формирования команд. В БСП существует коллекция ПараметрыПодключаемыхКоманд. Мы можем программно изменить свойство ЗаписыватьДанные для конкретной команды после того, как БСП ее сформировала.

Пример кода в расширении для формы документа:


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

Более надежный вариант в расширении — это перехват в модуле менеджера объекта документа в процедуре ДобавитьКомандыЗаполнения, если конфигурация позволяет явно указывать параметры подключаемых команд через этот механизм.

Резюме и рекомендации

Проанализировав ситуацию, мы пришли к выводу, что стандартное поведение БСП направлено на обеспечение целостности ссылочных связей. Тем не менее, для обхода запроса о записи можно использовать следующие стратегии:

  1. Для простых серверных алгоритмов: переходите на ТипКомандыЗаполнениеФормы(). Это самый "чистый" способ с точки зрения архитектуры БСП.
  2. Для сложных интерактивных сценариев: используйте вид ДополнительнаяОбработка. Это избавит вас от необходимости борьбы с типовыми проверками БСП, хотя и немного изменит пользовательский интерфейс.
  3. Для сохранения интерфейса "меню Заполнить": используйте расширение, чтобы программно изменить свойство РежимЗаписи уже после того, как БСП инициализировала свои структуры данных.

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

← На главную