При разработке внешних обработок заполнения объекта (тип ЗаполнениеОбъекта) программисты часто сталкиваются с тем, что система Библиотеки Стандартных Подсистем (БСП) принудительно выводит диалоговое окно: "Для выполнения операции данные будут записаны. Продолжить?". Это происходит даже в тех случаях, когда алгоритм заполнения не требует наличия ссылки в базе данных (например, когда мы просто хотим заполнить табличную часть нового, еще не сохраненного документа данными из внешнего файла или формы параметров). Рассмотрим подробнее, почему так происходит, и разберем способы решения этой задачи.
Прежде всего, проанализируем ситуацию с точки зрения механизмов БСП. В конфигурациях, использующих БСП версии 3.0 и выше, за логику отображения команд заполнения отвечает общий модуль ДополнительныеОтчетыИОбработки. Если мы заглянем внутрь процедуры ПриОпределенииКомандЗаполненияПодключенныхКОбъекту, то обнаружим жесткую логику определения режима записи:
Если СтрокаТаблицы.ВариантЗапуска = ЗаполнениеФормы Тогда
Команда.Обработчик = "ДополнительныеОтчетыИОбработки.ОбработчикКомандыЗаполнения";
Команда.РежимЗаписи = "НеЗаписывать";
Иначе
Команда.Обработчик = "ДополнительныеОтчетыИОбработкиКлиент.ОбработчикКомандыЗаполнения";
Команда.РежимЗаписи = "Записывать";
КонецЕсли;
Таким образом, мы видим, что если выбран вариант запуска, отличный от прямого серверного вызова ЗаполнениеФормы (например, ВызовКлиентскогоМетода или ОткрытиеФормы), БСП автоматически устанавливает свойство РежимЗаписи в значение "Записывать". Это сделано из соображений безопасности: разработчики БСП предполагают, что клиентской обработке может потребоваться ссылка на объект, которой у нового документа еще нет.
Самый простой способ избежать вопроса о записи — использовать вариант запуска ЗаполнениеФормы. В этом случае БСП по умолчанию устанавливает режим НеЗаписывать. Рассмотрим пример формирования структуры команды в модуле объекта внешней обработки:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиЗаполнениеОбъекта();
ПараметрыРегистрации.Наименование = "Заполнение ТЧ без записи";
ПараметрыРегистрации.Назначение.Добавить("Документ.ЗаказКлиента");
Команда = ПараметрыРегистрации.Команды.Добавить();
Команда.Представление = "Заполнить из файла (сервер)";
Команда.Идентификатор = "ЗаполнитьБезЗаписиСервер";
Команда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыЗаполнениеФормы();
Команда.РежимЗаписи = "НеЗаписывать";
Возврат ПараметрыРегистрации;
КонецФункции
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначенияМассив, ПараметрыВыполнения) Экспорт
// Здесь мы работаем напрямую с формой через ПараметрыВыполнения.ЭтаФорма
ОбъектДокумента = ПараметрыВыполнения.ЭтаФорма.Объект;
// Алгоритм заполнения ТЧ
НоваяСтрока = ОбъектДокумента.Товары.Добавить();
НоваяСтрока.Количество = 10;
// ...
КонецПроцедуры
Важное ограничение: этот метод работает только тогда, когда вам не нужно открывать форму самой внешней обработки для ввода дополнительных параметров пользователем. Процедура ВыполнитьКоманду в модуле объекта выполняется на сервере, и интерактивные действия там недоступны.
Если вам критично открыть форму обработки для уточнения параметров перед заполнением документа, но вы не хотите записывать документ, можно сменить вид обработки с ЗаполнениеОбъекта на ДополнительнаяОбработка. Посмотрим, как это изменит поведение системы.
В этом случае кнопка вызова обработки переместится из меню "Заполнить" в меню "Отчеты и обработки" (или "Сервис"). БСП не накладывает таких жестких ограничений на дополнительные обработки, так как они считаются контекстно-независимыми. В форме такой обработки вы сможете получить доступ к форме документа через свойство ВладелецФормы.
Рассмотрим пример кода в форме внешней обработки:
&НаКлиенте
Процедура ВыполнитьЗаполнение(Команда)
// Получаем форму документа, из которой была вызвана обработка
ФормаДокумента = ВладелецФормы;
Если ФормаДокумента = Неопределено Тогда
Возврат;
КонецЕсли;
// Прямое обращение к данным формы документа
НоваяСтрока = ФормаДокумента.Объект.Товары.Добавить();
НоваяСтрока.Номенклатура = ВыбраннаяНоменклатура;
НоваяСтрока.Количество = ВведенноеКоличество;
// Оповещаем форму о том, что данные изменены
ФормаДокумента.Модифицированность = Истина;
ЭтаФорма.Закрыть();
КонецПроцедуры
Если бизнес-процесс требует, чтобы кнопка находилась именно в меню "Заполнение", и при этом документ не должен записываться, нам придется прибегнуть к расширению конфигурации. Это наиболее гибкий, но требующий внесения изменений в логику базы метод.
Проанализируем, где можно перехватить управление. Нам необходимо расширить процедуру ПриСозданииНаСервере формы документа или использовать механизм перехвата формирования команд. В БСП существует коллекция ПараметрыПодключаемыхКоманд. Мы можем программно изменить свойство ЗаписыватьДанные для конкретной команды после того, как БСП ее сформировала.
Пример кода в расширении для формы документа:
&НаСервере
Процедура Расш_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
// Перебираем сформированные команды заполнения
Для Каждого Элемент Из ЭтаФорма.Команды Цикл
Если Найти(Элемент.Имя, "ДополнительнаяКомандаЗаполнения") > 0 Тогда
// Здесь можно найти настройки команды и принудительно сбросить флаг записи
// Однако в БСП 3.1 настройки часто хранятся в ПараметрыПодключаемыхКоманд
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Более надежный вариант в расширении — это перехват в модуле менеджера объекта документа в процедуре ДобавитьКомандыЗаполнения, если конфигурация позволяет явно указывать параметры подключаемых команд через этот механизм.
Проанализировав ситуацию, мы пришли к выводу, что стандартное поведение БСП направлено на обеспечение целостности ссылочных связей. Тем не менее, для обхода запроса о записи можно использовать следующие стратегии:
ТипКомандыЗаполнениеФормы(). Это самый "чистый" способ с точки зрения архитектуры БСП.ДополнительнаяОбработка. Это избавит вас от необходимости борьбы с типовыми проверками БСП, хотя и немного изменит пользовательский интерфейс.РежимЗаписи уже после того, как БСП инициализировала свои структуры данных.Обратите внимание: даже если вы успешно обойдете предварительный запрос о записи, после заполнения табличной части документ станет модифицированным (Модифицированность = Истина). Это означает, что при закрытии формы пользователь все равно увидит стандартный вопрос: "Данные были изменены. Сохранить изменения?". Это поведение является правильным и гарантирует, что пользователь не потеряет результаты работы вашей обработки.