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

08.06.22

Разработка - БСП (Библиотека стандартных подсистем)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

БСП ВыполнитьВФоне Расширения Временное хранилище контекст

См. также

БСП (Библиотека стандартных подсистем) Программист Платные (руб)

Синтакс-помощник БСП - cправочник по библиотеке стандартных подсистем. В состав справочника входит описание экспортных процедур и функций, размещенных в областях кода ПрограммныйИнтерфейс БСП.

1800 руб.

21.11.2024    158    1    0    

2

БСП (Библиотека стандартных подсистем) Программист Платформа 1С v8.3 Бесплатно (free)

В статье описан алгоритм для включения документа или справочника в систему БСП. Будет полезно программистам 1С, начинающим работать с БСП.

24.10.2024    1129    PROSTO-1C    0    

13

БСП (Библиотека стандартных подсистем) Работа с интерфейсом Программист Платформа 1С v8.3 Бесплатно (free)

В материале описан универсальный механизм работы с добавленными элементами на общую форму «ФормаОтчета». Думаю, облегчит работу многим разработчикам.

08.10.2024    1007    PROSTO-1C    4    

12

БСП (Библиотека стандартных подсистем) Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

В статье рассмотрим пошаговую инструкцию создания дополнительного отчета с фоновым формированием результата.

04.10.2024    1856    MadRave    11    

24

БСП (Библиотека стандартных подсистем) Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пример отслеживания прогресса фонового выполнения дополнительной обработки с использованием программного интерфейса длительных операций БСП.

10.09.2024    1849    MadRave    1    

17

БСП (Библиотека стандартных подсистем) Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

А что, если долгожданная реализация Паузы в 1С смутно напоминает старую, проверенную? А?!

06.09.2024    1267    n_mezentsev    10    

8

БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Добавим дополнительные свойства в новый документ средствами БСП

02.09.2024    4125    John_d    10    

52

БСП (Библиотека стандартных подсистем) Программист Платформа 1С v8.3 Бесплатно (free)

Всё больше организаций выбирает для серверов под 1С операционные системы Linux. Одним из отличий систем Windows и Linux является отсутствие COM объектов, которые зачастую использовались для формирования печатных форм офисных документов (Word). Конечно, можно выполнять печать и на клиенте, но есть риск импортозамещения. В работе у меня случались проблемы с зависанием процесса Word, поэтому я не люблю его использовать.

29.07.2024    5379    PROSTO-1C    12    

52
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. quazare 3802 08.06.22 08:54 Сейчас в теме
почему не использовали "Вместо" ?
sergathome; +1 Ответить
2. dsdred 3631 08.06.22 09:00 Сейчас в теме
(1)тогда уж "ИзменениеИКонтроль"
sergathome; mrChOP93; quazare; +3 Ответить
3. RustIG 1747 08.06.22 09:13 Сейчас в теме
(2) у меня ИзменениеИКонтроль на 8.3.18 не работает - видимо что-то надо еще изменить в типовой КА 2.4
ПС. Статью еще не читал, написал к слову
sergathome; quazare; +2 Ответить
7. sergathome 4 08.06.22 10:38 Сейчас в теме
(2) Разумеется, можно и так. Просто эта деталь к теме имеет слабое отношение.
6. sergathome 4 08.06.22 09:59 Сейчас в теме
(1) Хотелось как проще и прямее, а оно вона как всё неочевидно оказалось. Самая засада, конечно, это режим отладки. С одной стороны он позволяет упростить отладку, с другой вносит вот такие ньюансы
4. quazare 3802 08.06.22 09:26 Сейчас в теме
(2) согласен, но пример привел для "упрощения понимания".
5. dsdred 3631 08.06.22 09:48 Сейчас в теме
8. RustIG 1747 08.06.22 10:48 Сейчас в теме
(5) сам режим предполагает использование директив #Вставить #Удалить
так вот 1с-ка (платофрма) ругается на эти директивы - поэтому режим ИзмененияИКонтроль "не работает"
если вы используете этот режим без дополнительных директив, то и использовать его смысла нет
11. dsdred 3631 08.06.22 12:03 Сейчас в теме
(8)режим совместимости какой выставлен?
13. RustIG 1747 08.06.22 12:05 Сейчас в теме
(11) типовая 1С:Предприятие 8.3.18.1334, 1С:Комплексная автоматизация 2.4.14.164
в типовой конфигурации разве можно изменить режим совместимости?
если нет - тогда зачем знать какой там режим?
9. RustIG 1747 08.06.22 11:00 Сейчас в теме
онтекст расширения, и контекст основной процедуры имеют доступ к общему контексту формы, из которой они вызываются, и, соответственно, именно там и создаётся хранилище, оказываясь доступным в обоих контекстах.

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


на то они и расширения, что проблемы с контекстами всегда будут при отладке... элементарно запрос написать не получится через конструктор запросов...

ПС. прочитал статью... что ж ладно, все понятно с контекстами...
по самой задаче и ее решению - есть вопросы и сомнения что так правильно ...
Я бы все таки в документ Акт заполнил все ручные Операции, затем добавил вторую печатную форму для Акта - в которой бы сгруппировал Операции, как надо бухгалтерам, первая печатная форма осталась бы как базовая, с которой сумму можно сравнить
sergathome; +1 Ответить
10. sergathome 4 08.06.22 11:35 Сейчас в теме
(9) Тема с печатной формой, конечно, теоретически более правильная, поскольку изменения вносятся на максимально высоком уровне, выше только ручное редактирование), но в моём случае не прокатывает, исходный документ уже должен содержать готовые данные, его обрабатывает робот дальше для рассылки по ЭДО. Корёжить робота зашквар, остаётся впилиться в подготовку данных. Они для всех будут одинаковые, по крайней мере.
12. RustIG 1747 08.06.22 12:04 Сейчас в теме
14. RustIG 1747 08.06.22 12:12 Сейчас в теме
(10) Акт сверки кто создает: робот или бухгалтер?
Если бухгалтер - я бы оставил типовое заполнение и добавил кнопку для бухгалтера "Сгруппировать Операции".
15. sergathome 4 08.06.22 12:13 Сейчас в теме
(14) Робот. Внешняя обработка вызывает заполнение. Массовая рассылка.
16. RustIG 1747 08.06.22 12:14 Сейчас в теме
17. RustIG 1747 08.06.22 12:14 Сейчас в теме
20. sergathome 4 08.06.22 14:32 Сейчас в теме
(17) Если внимательно посмотреть код, который приведён в статье, то неожиданно выясница, что этот ньюанс не имеет отношения к делу. Схлопываются только ручные операции. В тексте про это тоже есть, кстати.
21. RustIG 1747 08.06.22 14:38 Сейчас в теме
18. dsdred 3631 08.06.22 13:14 Сейчас в теме
(13)у меня на работе тоже КА с версией 2.4.14.140, Предприятие версии 8.3.20, режим совместимости 8.3.16

Когда я пришёл стояла ка помладше и предприятие 8.3.18 с совместимость 8.3.15

ИзменениеИКонтроль работало и так и так.

Но если режим совместимости у вас 8.3.14 тогда работать не будет.

И да когда чел обновил КА не поменял в расширении режим и пару дней КА в основной конфигурации отличалась режимом совместимости с расширением
19. RustIG 1747 08.06.22 13:21 Сейчас в теме
(18) мысль уловил - на след. неделе проверю. спасибо)
22. Irwin 562 09.06.22 05:28 Сейчас в теме
Нюанс №2 - причина не в этом.

Хранилище живет в рамках сеанса. Фоновое и клиент - это два разных сеанса. Из фонового можно передать данные сеанс в клиента (который инициировал сеанс фонового), получив адрес в сеансе клиента, передать этот адрес в фоновое и потом поместить в хранилище используя этот адрес. После этого в сеансе клиента можно пользоваться данными, полученными из фонового задания (если оно выполнилось. До этого момента данные недоступны).

И здесь есть особенность. Даже в сеансе фонового задания нельзя получить данные из хранилища по адресу, который получен в сеансе клиента. Поместить можно, получить нельзя. Если адрес получен в рамках сеанса фонового задания - можно и помещать и получать в этом фоновом задании. Попробуйте без расширения выполнить код, на котором у Вас возникает ошибка - получите точно такой же результат.
Cyberhawk; user811769; +2 Ответить
23. Irwin 562 09.06.22 05:30 Сейчас в теме
(22) По Нюансу №3 вывод, соответственно, тоже неверный. Нет фонового задания - нет проблемы с хранилищем, и расширения здесь ни при чем.
Cyberhawk; user811769; +2 Ответить
24. sergathome 4 09.06.22 11:47 Сейчас в теме
(23) Травой поделишься ? ))
25. Irwin 562 09.06.22 12:16 Сейчас в теме
(24) С удовольствием бы попробовал Вашу.

Когда указан режим отладки, то фоновые задания подсистемы длительных операций не выполняются. Функция "ВыполнитьВФоне()" в этом случае просто пытается выполнить процедуру.
Не понимаю Вашу реакцию, ведь все, что я написал легко проверить.
26. sergathome 4 09.06.22 15:16 Сейчас в теме
(25) Вы не читали статью. Я не собираюсь спорить сам с собой. Точнее так - вы её не дочитали. Скорее всего в одном Вы правы - 1С опять отжок и рид не читает того что райт записал. Нельзя читать хранилище не только в расширении, но и вообще на сервере, в том числе если хранилище создано на сервере вне контекста формы. И даже в одном сеансе. Наверное вот так. Давно где-то про это слышал.
27. Irwin 562 09.06.22 16:24 Сейчас в теме
(26) Да нет, статью я прочитал внимательно, т.к. как раз удивили выводы, которые были сделаны. Даже специально провел тесты с Вашим примером, чтобы убедиться, что все работает так, как должно работать, а не так как описано в статье.

А вот мои сообщения Вы прочитали, к сожалению, невнимательно. Потому что хранилище оперирует как раз понятием "сеанс", а не "контекст". Фоновое задание запускается под своим сеансом. Пользователь работает под своим сеансом. Когда мы переходим с клиента на сервер или же возвращаемся с сервера на клиент, то сеанс остается тот же самый. Неважно, в рамках контекста формы или это же это вызов серверного модуля. И хранилище доступно только в рамках этого сеанса. Хранилище как раз для этого и предназначено - для обмена данными между клиентом и сервером. Например, передать файл с клиента, чтобы обработать его на сервере.
В рамках одного сеанса неважно на чьей стороне было помещение в хранилище - на стороне сервера или клиента. Мы можем поместить в хранилище на клиенте, передать адрес на сервер и на сервере мы можем как прочитать, так и записать в хралищие по этому адресу.

Цитата с ИТС: "В 1С:Предприятии существует механизм работы с временным хранилищем, обеспечивающий хранение некоторых данных, привязанных к сеансу."

Аналогично с фоновыми заданиями. В рамках сеанса фонового задания мы можем также создавать хранилище, помещать в него, читать и все это без проблем.

Как уже писал выше, временное хранилище доступно только в рамках того сеанса, в котором оно было создано. Но! В 1С нам все-таки дали возможность передавать данные из одного сеанса в другой. Это возможно, если получить адрес хранилища в одном сеансе, затем этот адрес передать в сеанс фонового задания. При этом сеанс фонового задания должен быть создан из первого сеанса. И в этом фоновом задании можно записать данные в хранилище по этому адресу. Но прочитать нельзя. На самом деле здесь есть небольшое противоречие, что писать можно, а читать почему-то нельзя. Но, т.к. это сделано для возможности хоть как-то вернуть данные из фонового задания, а не просто результат "выполнено" / "не выполнено", то можно на это закрыть глаза. Иначе пришлось бы каждый раз писать результат фонового задания в базу, а затем читать в родительском сеансе из базы.

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

Еще раз повторюсь. Неважно на стороне сервера или на стороне клиента было создано хранилище и неважно в каком контексте. Если читаем и пишем во временное хранилище в рамках одного сеанса - проблем не будет.

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

И чтобы разговор вошел в более конструктивное русло, можно просто создать тестовую базу, в которой в рамках сеанса пользователя попробовать поместить данные во временное хранилище на сервере, прочитать на клиенте. Потом поместить на клиенте и прочитать/записать на сервер. Все вопросы сразу отпадут и придет понимание как работает временное хранилище. Следующим шагом создавать фоновое задание, где проделать аналогичные операции с хранилищем. Затем уже передать адрес хранилища одного сеанса в другое и читать/писать из него/в него. Я такую базу создавал. А Вы?

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

P.S. Ссылка на статью на ИТС про механизм временного хранилища: https://its.1c.ru/db/v8320doc/bookmark/dev/TI000000803
user1603434; 77dream77; au260; JohnyDeath; Cyberhawk; Redokov; TMV; +7 Ответить
Оставьте свое сообщение