Каталог решений - Нюансы использования расширений применительно к процедурам, исполняющимся методом ВыполнитьВФоне (БСП)

Нюансы использования расширений применительно к процедурам, исполняющимся методом ВыполнитьВФоне (БСП)

Нюансы использования расширений применительно к процедурам, исполняющимся методом ВыполнитьВФоне (БСП)

В наличии

Несколько нюансов при использовании расширений применительно к процедурам, исполняющимся методом ВыполнитьВФоне (БСП)

Категория:

Описание

Потребовалось недавно модифицировать в БП 3 процедуру акта сверки ПодготовитьДанныеДляЗаполнения(СтруктураПараметров, АдресХранилища) — бухи попросили сделать свёртку однотипных ручных операций по договору и дате. Типа не несколько операций, а одна любая из них с суммой всех, чтобы акт не пух.

Родная процедура выглядит так:

	Процедура ПодготовитьДанныеДляЗаполнения(СтруктураПараметров, АдресХранилища) Экспорт
...
// Заполним возвращаемую структуру
	СтруктураДанныхЗаполнения.Вставить("ПоДаннымОрганизации", ТаблицаПоДаннымОрганизации);
	Если СтруктураПараметров.ЗаполнятьДанныеКонтрагента Тогда
		СтруктураДанныхЗаполнения.Вставить("ПоДаннымКонтрагента", ТаблицаПоДаннымКонтрагента(ТаблицаПоДаннымОрганизации));
	КонецЕсли;
	СтруктураДанныхЗаполнения.Успешно = Истина;
	ПоместитьВоВременноеХранилище(СтруктураДанныхЗаполнения, АдресХранилища);

Вроде всё просто, делаем в расширении процедуру с аннотацией &После, извлекаем из хранилища результат, модифицируем его и помещаем обратно, как-то так:

&После("ПодготовитьДанныеДляЗаполнения")
Процедура Расш1_ПодготовитьДанныеДляЗаполнения(СтруктураПараметров, АдресХранилища) Экспорт

    СтруктураДанныхЗаполнения = ПолучитьИзВременногоХранилища(АдресХранилища);
    ТаблицаПоДаннымОрганизации = СтруктураДанныхЗаполнения.ПоДаннымОрганизации;

    лСтСтр = Неопределено;
	лИнд = ТаблицаПоДаннымОрганизации.Количество() - 1;
	Пока лИнд >= 0 Цикл
		лСтр = ТаблицаПоДаннымОрганизации[лИнд];
		Если ТипЗнч(лСтр.Документ) = Тип("ДокументСсылка.ОперацияБух") Тогда
			Если лСтСтр <> Неопределено Тогда
				Если лСтСтр.Договор = лСтр.Договор И лСтСтр.Дата = лСтр.Дата Тогда
					лСтр.Дебет = лСтр.Дебет + лСтСтр.Дебет; 
					лСтр.Кредит = лСтр.Кредит + лСтСтр.Кредит; 
					ТаблицаПоДаннымОрганизации.Удалить(лСтСтр);
				КонецЕсли;
			КонецЕсли;            
			лСтСтр = лСтр;
		Иначе
			лСтСтр = Неопределено;
		КонецЕсли;
		лИнд = лИнд - 1;
	КонецЦикла;

	// Заполним возвращаемую структуру
	СтруктураДанныхЗаполнения.Вставить("ПоДаннымОрганизации", ТаблицаПоДаннымОрганизации);
	Если СтруктураПараметров.ЗаполнятьДанныеКонтрагента Тогда
		СтруктураДанныхЗаполнения.Вставить("ПоДаннымКонтрагента", ТаблицаПоДаннымКонтрагента(ТаблицаПоДаннымОрганизации));
	КонецЕсли;
	СтруктураДанныхЗаполнения.Успешно = Истина;
	ПоместитьВоВременноеХранилище(СтруктураДанныхЗаполнения, АдресХранилища);
	
КонецПроцедуры

Запускаем из конфигуратора в режиме отладки (ключ РежимОтладки) — всё прекрасно работает, подбор выполняется как надо, со свёрткой, ошибок нет. Выключаем режим отладки, запускаем — подбор выполняется, но так, как будто расширения просто нет. Ставим точку останова на первой строке процедуры в расширении, включаем подключение к фоновым заданиям и видим, что исполнение до неё доходит. Так в чем же дело ?

А дело в том, что подбор выполняется с помощью функции БСП ДлительныеОперации.ВыполнитьВФоне:

	Результат = ДлительныеОперации.ВыполнитьВФоне(
		"Документы.АктСверкиВзаиморасчетов.ПодготовитьДанныеДляЗаполнения",
		СтруктураПараметров,
		ПараметрыВыполнения);

И если посмотреть Результат после исполнения, то там будет видно, что при исполнении произошла ошибка вида СтруктураДанныхЗаполнения.ПоДаннымОрганизации не является значением объектного типа.

Итак, нюанс первый — ошибка эта не обрабатывается, результат при этом приходит из выполнившейся процедуры основной конфигурации, что и создаёт впечатление успешного  выполнения без расширения !

Проверяем адрес хранилища — он заполнен… В чём же дело ? Нюанс второй — как известно, процедура основной конфигурации и процедура расширения исполняются каждая в своём контексте, адрес хранилища передаётся в расширение как параметр процедуры, но само хранилище — нет, оно остаётся в контексте процедуры основной конфигурации и недоступно для расширения.

И нюанс третий — при использовании параметра запуска РежимОтладки БСП исполняет фоновые задачи синхронно, в контексте вызова, и, таким образом и контекст расширения, и контекст основной процедуры имеют доступ к общему контексту формы, из которой они вызываются, и, соответственно, именно там и создаётся хранилище, оказываясь доступным в обоих контекстах.

Вот так нам не дают соскучиться… Пришлось использовать полное замещение &Вместо.

has been added to your cart:
Оформление заказа