Самодельный обработчик ПослеЗаписи объекта

02.07.23

Разработка - Механизмы платформы 1С

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

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование SM По подписке [?]
Демо база
.dt 110,23Kb
34
34
0 SM
Скачать

Статья актуальна для 8.3.22. Описанный в статье способ совместим с платформой 8.1 (немного отличается запись движений).
Статья НЕ рекомендуется к применению начинающими разработчиками, т.к. требует глубокого понимания рассмотренных механизмов платформы.

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

Самым простым способом решения задачи является использование события ОбработкаПослеЗаписиВерсийИсторииДанных менеджера, которое выполняется в отдельном фоновом задании. Но он не дает доступа к не хранимому в БД состоянию объекта (свойства ОбменДанными и ДополнительныеСвойства) и требует включать историю данных для объекта. Поэтому рассмотрим более сложное решение.

Ранее в статье Безопасная работа с транзакциями во встроенном языке в разделе "Разрыв неявной транзакции" я описал как можно досрочно завершить транзакцию записи объекта, если она открыта неинтерактивно (не из формы объекта). Там я не рекомендовал применять этот прием в рабочем коде из-за ряда условий, которые нужно соблюдать для надежной работы такого кода. Теперь показываю как его применить для реализации обработчика ПослеЗаписи объекта. Наша цель - обеспечить выполнение кода

		ЗафиксироватьТранзакцию(); // Фиксируем неявную транзакцию
		// Делаем что то после транзакции записи
		НачатьТранзакцию(); // Открывает фиктивную транзакцию, чтобы платформенная фиксация транзакции не вызвала ошибку

последним среди всех возможных обработчиков записи:

  • обработчики событий записи
  • обработчики подписок на события
  • расширения обработчиков
  • регистрация на узлах планов обмена (платформа)
  • запись движений (платформа)

Тогда явное завершение транзакции не повлечет нарушения атомарности (неделимости) внесения изменений в БД.

Для достижений столь амбициозной цели нам понадобится механизм динамического подключения/отключения обработчиков объекта - операторы ДобавитьОбработчик и УдалитьОбработчик. Они легко находятся в синтакс-помощнике. Они по факту всегда добавляют обработчик в самый конец очереди обработчиков события конкретного объекта (проверено на 8.1, 8.2, 8.3.22), однако в документации это явно не обозначено. Вероятность изменения этого поведения в платформе представляется крайне низкой, т.к.

  • платформа создает очереди обработчиков для всех событий объекта сразу при его создании
  • если подключать обработчик не последним, то при подключении внутри обработки события будет риск что он не выполнится в текущем обходе очереди

У большинства типов метаданных последним в транзакции неинтерактивной записи выполняется событие ПриЗаписи. Поэтому нам нужно будет подключать обработчик на него. Но у документов это может быть и ОбработкаПроведения.

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

Создадим подписку на событие ПередЗаписью для документов и подписку на событие ПередЗаписью для остальных ссылочных типов объектов, у которых хотим создать обработчик ПослеЗаписи. Подключим внутри этих подписок динамический обработчик на последнее событие транзакции. А в самом динамическом обработчике последнего события выполним явно

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

Процедура ОбъектПередЗаписью(Источник, Отказ) Экспорт
	Сообщить("Подписка1 ПередЗаписью. Динамическое подключение обработчика");
	УдалитьОбработчик Источник.ПриЗаписи, ПриЗаписиПоследний;
	Добавитьобработчик Источник.ПриЗаписи, ПриЗаписиПоследний;
КонецПроцедуры

Процедура ДокументПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
	Сообщить("Подписка1 ПередЗаписью. Динамическое подключение обработчика");
	УдалитьОбработчик Источник.ПриЗаписи, ПриЗаписиПоследний;
	УдалитьОбработчик Источник.ОбработкаПроведения, ОбработкаПроведенияПоследний;
	Если РежимЗаписи = РежимЗаписиДокумента.Запись Или РежимЗаписи = РежимЗаписиДокумента.ОтменаПроведения Тогда
		Добавитьобработчик Источник.ПриЗаписи, ПриЗаписиПоследний;
	ИначеЕсли РежимЗаписи = РежимЗаписиДокумента.Проведение Тогда
		Добавитьобработчик Источник.ОбработкаПроведения, ОбработкаПроведенияПоследний;
	КонецЕсли;
КонецПроцедуры

//////////////////////////

Процедура ПриЗаписиПоследний(Источник, Отказ) Экспорт 
	ПослеЗаписи(Источник, Отказ);
КонецПроцедуры

Процедура ОбработкаПроведенияПоследний(Знач Источник, Знач Отказ, Знач РежимПроведения)
	Если Не Отказ Тогда
		#Если Сервер И Не Сервер Тогда
			Источник = Документы.Документ1.СоздатьДокумент();
		#КонецЕсли
		Для Каждого НаборДвижений Из Источник.Движения Цикл
			#Если Сервер И Не Сервер Тогда
				НаборДвижений = РегистрыНакопления.РегистрНакопления1.СоздатьНаборЗаписей();
			#КонецЕсли
			Если НаборДвижений.Записывать Тогда 
				НаборДвижений.Записать();
				НаборДвижений.Записывать = Ложь;
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	ПослеЗаписи(Источник, Отказ);
КонецПроцедуры 

Процедура ПослеЗаписи(Источник, Отказ) 
	Если Не Отказ Тогда
		ВыполнитьРегистрациюЕслиНадо(Источник);
		Попытка
			ЗафиксироватьТранзакцию();
			ЭтоИнтерактивнаяЗапись = Ложь;
		Исключение
			ОписаниеОшибки = ОписаниеОшибки();
			ЭтоИнтерактивнаяЗапись = Истина;
		КонецПопытки;
		Источник.ПослеЗаписи();
		Если Не ЭтоИнтерактивнаяЗапись Тогда
			НачатьТранзакцию();
		КонецЕсли;
	КонецЕсли;
КонецПроцедуры

// https://its.1c.ru/db/intgr83#content:121:hdoc
Процедура ВыполнитьРегистрациюЕслиНадо(Источник) 
	#Если Сервер И Не Сервер Тогда
		Источник = Справочники.Справочник1.СоздатьЭлемент();
	#КонецЕсли
	Получатели = Источник.ОбменДанными.Получатели;
	Если Получатели.Количество() > 0 Тогда
		ПланыОбмена.ЗарегистрироватьИзменения(Получатели, Источник);
		Сообщить(СтрШаблон("Регистрация на %1 узлах планов обмена", Получатели.Количество()));
		Получатели.Очистить();
		Источник.ДополнительныеСвойства.Вставить("ПолучателиОчищены");
	ИначеЕсли Источник.ДополнительныеСвойства.Свойство("ПолучателиОчищены") Тогда 
		ВызватьИсключение "Необходимо заново заполнить получателей объекта или удалить доп. свойство ""ПолучателиОчищены""";
	КонецЕсли;
КонецПроцедуры

// Демо подписка
Процедура ДемоПриЗаписи(Источник, Отказ) Экспорт
	Сообщить("Подписка Демо ПриЗаписи");
КонецПроцедуры

Теперь вставим в модули объектов обработчик ПослеЗаписи

Процедура ПослеЗаписи() Экспорт 
	Сообщить("ПослеЗаписи. Транзакция = " + ТранзакцияАктивна());
КонецПроцедуры

Проверка

К статье приложена демонстрационная база с подсистемой СобытиеПослеЗаписи (общий модуль и 2 подписки). Запустив эту базу в обычном клиентском приложении, вы увидите форму с кнопкой "Тест" и формы модифицированных рассмотренным в статье образом справочника и документа. Кнопка "Тест" для выполнит следующий код

	ф = Справочники.Справочник1.я.ПолучитьОбъект();
	Сообщить(">>> Новая запись справочника");
	ф.Записать();
	Сообщить(">>> Повторная запись справочника");
	ф.Записать();
	ф = Справочники.Справочник1.я.ПолучитьОбъект().ПолучитьФорму();
	Если ТипЗнч(Ф) = Тип("Форма") Тогда
		Сообщить(">>> Новая запись справочника в форме");
		ф.ЗаписатьВФорме();
		Сообщить(">>> Повторная запись справочника в форме");
		ф.ЗаписатьВФорме();
	Иначе
		Сообщить(">>> Новая запись справочника в форме");
		ф.Записать();
		Сообщить(">>> Повторная запись справочника в форме");
		ф.Записать();
	КонецЕсли;

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

Получим результат:

>>> Новая запись справочника
Подписка1 ПередЗаписью. Динамическое подключение обработчика
ПриЗаписи модуля объекта
ПриЗаписи расширения
ПриЗаписи модуля объекта динамический
Подписка Демо ПриЗаписи
Регистрация на 1 узлах планов обмена
ПослеЗаписи. Транзакция = Нет

>>> Повторная запись справочника
Подписка1 ПередЗаписью. Динамическое подключение обработчика
ПриЗаписи модуля объекта
ПриЗаписи расширения
ПриЗаписи модуля объекта динамический
Подписка Демо ПриЗаписи
Регистрация на 1 узлах планов обмена
ПослеЗаписи. Транзакция = Нет

>>> Новая запись справочника в форме
Подписка1 ПередЗаписью. Динамическое подключение обработчика
ПриЗаписи модуля объекта
ПриЗаписи расширения
ПриЗаписи модуля объекта динамический
Подписка Демо ПриЗаписи
Регистрация на 1 узлах планов обмена
ПослеЗаписи. Транзакция = Да
При записи в форме

>>> Повторная запись справочника в форме
Подписка1 ПередЗаписью. Динамическое подключение обработчика
ПриЗаписи модуля объекта
ПриЗаписи расширения
ПриЗаписи модуля объекта динамический
Подписка Демо ПриЗаписи
Регистрация на 1 узлах планов обмена
ПослеЗаписи. Транзакция = Да
При записи в форме

>>> Новая запись документа
Подписка1 ПередЗаписью. Динамическое подключение обработчика
ПриЗаписи модуля объекта
ПриЗаписи расширения
Подписка Демо ПриЗаписи
Регистрация на 1 узлах планов обмена
ПослеЗаписи. Транзакция = Нет

>>> Повторная запись документа с проведением
Подписка1 ПередЗаписью. Динамическое подключение обработчика
ПриЗаписи модуля объекта
ПриЗаписи расширения
Подписка Демо ПриЗаписи
ОбработкаПроведения модуля объекта
ОбработкаПроведения расширения
Записан регистрРегистрНакопления1
Регистрация на 1 узлах планов обмена
ПослеЗаписи. Транзакция = Нет

>>> Повторная запись документа с отменой проведения
Подписка1 ПередЗаписью. Динамическое подключение обработчика
ОбработкаУдаленияПроведения модуля объекта
Записан регистрРегистрНакопления2
Записан регистрРегистрНакопления1
ПриЗаписи модуля объекта
ПриЗаписи расширения
Подписка Демо ПриЗаписи
Регистрация на 1 узлах планов обмена
ПослеЗаписи. Транзакция = Нет

>>> Новая запись документа в форме
Подписка1 ПередЗаписью. Динамическое подключение обработчика
ПриЗаписи модуля объекта
ПриЗаписи расширения
Подписка Демо ПриЗаписи
Регистрация на 1 узлах планов обмена
ПослеЗаписи. Транзакция = Да
При записи в форме

>>> Повторная запись документа с проведением в форме
Подписка1 ПередЗаписью. Динамическое подключение обработчика
ПриЗаписи модуля объекта
ПриЗаписи расширения
Подписка Демо ПриЗаписи
ОбработкаПроведения модуля объекта
ОбработкаПроведения расширения
Записан регистрРегистрНакопления1
Регистрация на 1 узлах планов обмена
ПослеЗаписи. Транзакция = Да
При записи в форме

>>> Повторная запись документа с отменой проведения в форме
Подписка1 ПередЗаписью. Динамическое подключение обработчика
ОбработкаУдаленияПроведения модуля объекта
Записан регистрРегистрНакопления2
Записан регистрРегистрНакопления1
ПриЗаписи модуля объекта
ПриЗаписи расширения
Подписка Демо ПриЗаписи
Регистрация на 1 узлах планов обмена
ПослеЗаписи. Транзакция = Да
При записи в форме

См. также

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

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

23.06.2024    4064    bayselonarrend    18    

142

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

Пример использования «Сервисов интеграции» без подключения к Шине и без обменов.

13.03.2024    4083    dsdred    16    

77

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

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

24.01.2024    9644    YA_418728146    25    

70

Перенос данных 1C Механизмы платформы 1С Системный администратор Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    8884    dsdred    44    

123

Механизмы платформы 1С Программист Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    21098    SeiOkami    46    

129

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

Начиная с версии платформы 8.3.22 1С снимает стандартные блокировки БД на уровне страниц. Делаем рабочий скрипт, как раньше.

14.09.2023    15248    human_new    27    

79

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    11573    YA_418728146    7    

154
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. JohnyDeath 301 04.04.23 08:23 Сейчас в теме
А как же подписки на события и расширения? Ведь их "ПриЗаписи" выполняются уже после события "ПриЗаписи" модуля объекта. Т.е. если мы возможно будем иметь неактуальные данные объекта, если будем работать с "ПриЗаписи" в модуле объекта.
Да и дописывать такое в типовые модули не очень хотелось бы.

Есть другой вопрос-предложение. Ты не смотрел в сторону "МенеджерИсторииДанных" и события "ОбработкаПослеЗаписиВерсийИсторииДанных"? Там есть настоящее событие "ПослеЗаписи", которое еще и отрабатывает вне основной транзакции, а это огромный плюс для такого события.
DrAku1a; tormozit; cleaner_it; +3 Ответить
2. tormozit 7193 04.04.23 08:29 Сейчас в теме
(1)
Там есть настоящее событие "ПослеЗаписи"

Где там? Укажи ссылку на документацию и лучше же сразу с цитатой из нее, где указано как создать обработчик такого "события".
3. JohnyDeath 301 04.04.23 08:36 Сейчас в теме
(2) "там" - это в механизме истории данных.
Документация здесь https://its.1c.ru/db/v8322doc#bookmark:dev:TI000001940
Там смысл в том, что надо добавить "ОбработкаПослеЗаписиВерсийИсторииДанных" в модуль менеджера объекта, которое срабатывает при вызове "ИсторияДанных.ОбновитьИсторию()" или "ИсторияДанных.ВыполнитьОбработкуПослеЗаписиВерсий()". Обновление истории обычно вешают в отдельное рег задание.
5. tormozit 7193 04.04.23 08:57 Сейчас в теме
(3)
ОбработкаПослеЗаписиВерсийИсторииДанных

1. Этот обработчик доступен только в режиме совместимости 8.3.15
2. Он вызывается только если у объекта метаданных включено ведение истории данных, т.е. уже не универсально.
3. Выполнил запись в файловой базе при включенных флажках "Обновлять историю..." и "Выполнять обработку после записи..". Обработчик не вызывался, т.е. вызывается он только при явном запуске обновления версий, что опять же не универсально.
3. И у него кажется много других ограничений, например
Обработчик выполняется с установленным безопасным режимом разделения для всех независимых разделителей конфигурации - переключение в другую область данных будет запрещено.
Исключение в обработчике приводит к прерыванию выполнения обработки остальных версий в очереди, поэтому рекомендуется не допускать возникновения исключений.
Прикрепленные файлы:
triviumfan; +1 Ответить
4. tormozit 7193 04.04.23 08:42 Сейчас в теме
(1)
А как же подписки на события и расширения?

Подписки всегда выполняются ДО обработчика в модуле. Расширения обработчика ПриЗаписи также будут вызваны до выполнения динамически подключенного обработчика. Так что схема полностью надежна. Обновил демо базу - добавил расширения для всех обработчиков модуля объекта с выводом сообщений для наглядности отслеживания порядка выполнения обработчиков.
>>> ПриЗаписи Я
ПриЗаписи расширения
ПослеЗаписи
>>> ПриЗаписи Документ1 000000016 от 04.04.2023 8:42:08
ПриЗаписи расширения
ПослеЗаписи
>>> ПриЗаписи Документ1 000000016 от 04.04.2023 8:42:08
ПриЗаписи расширения
ОбработкаПроведения
ОбработкаПроведения расширения
ПослеЗаписи
Показать
21. tormozit 7193 06.04.23 10:14 Сейчас в теме
(4)
Подписки всегда выполняются ДО обработчика в модуле

Извиняюсь. Тут я ошибся. Переделаю статью вечером на подписки. Будет даже красивее.
23. JohnyDeath 301 06.04.23 10:18 Сейчас в теме
(21)
Переделаю статью вечером на подписки. Будет даже красивее.

тут другая подстава ожидает.
Подписки выполняются в очередности как они отображаются в дереве метаданных. И то - это не гарантированно.
Т.е. если ты сейчас сделаешь подписку, а потом с обновлением прилетит новая подписка, то твоя уже не будет видеть изменений, которые сделала новая подписка.
Ну или кто-нибудь банально отсортирует подписки по алфавиту. У меня такое уже было (
24. tormozit 7193 06.04.23 10:42 Сейчас в теме
(23) Думаю я справлюсь с этим)
6. JohnyDeath 301 04.04.23 09:06 Сейчас в теме
(5) Скачал твою базу и сделал в ней. Для упрощения включил всё сразу в конфигураторе, в том числе и обработку "сразу", чтоб не городить отельное РЗ. Но всё это можно делать и программно. Да, ограничение по платформе в 8.3.15 есть, но мне кажется, что это совсем не тот факт, на который нужно обращать внимание.
Прикрепленные файлы:
7. JohnyDeath 301 04.04.23 09:08 Сейчас в теме
Не знаю как прикреплять несколько картинок/файлов к сообщению, поэтому вот скринн из ЖР по этой конфе на такой код в модуле менеджера:
Код
Процедура ОбработкаПослеЗаписиВерсийИсторииДанных(инфоОЗаписиВерсии) Экспорт
   Для Каждого записьИстории Из инфоОЗаписиВерсии Цикл
      ЗаписьЖурналаРегистрации(
         "СобытиеПослеЗаписи",
         УровеньЖурналаРегистрации.Предупреждение,
         ,
         ,
         "ХХХ ПослеЗаписи: " + записьИстории.Данные
      );
      ИсторияДанных.УдалитьИзОбработкиПослеЗаписиВерсий(записьИстории.Данные, записьИстории.НомерВерсии);
   КонецЦикла;   
КонецПроцедуры
Показать полностью
Прикрепленные файлы:
tormozit; +1 Ответить
9. tormozit 7193 04.04.23 09:13 Сейчас в теме
(7) Есть и еще беда у твоего способа - передача несериализуемого состояния объекта, например ДополнительныеСвойства в это событие не попадут, как и ОбменДанными.
Также он более затратный, т.к. требует считывания как минимум самого объекта из базы заново, а может еще и связанных данных, которые уже были в ДополнительныеСвойства в моей реализации.
10. JohnyDeath 301 04.04.23 09:17 Сейчас в теме
(9) я ниже скинул твою же дт-шку. Разворачивал как файловую ес-но.
Может ты не установил свойство "Обновлять историю данных сразу после записи"?

Про ДопСвойства и ОбменДанными вообще не понял. Зачем они в "ПослеЗаписи"?
Обычно "ПослеЗаписи" нужно как раз для того, чтобы сделать постобработку ВНЕ основной транзакции, которая, как правило, и так слишком длинная. Например, для того, чтобы отправить измененные объекты в какой-то свой супер-обмен.

Т.е. я в свое время наоборот искал то, что бы отрабатывало после записи и никак не влияло на основную логику: ни временем, ни тем более своими ошибками
12. tormozit 7193 04.04.23 09:25 Сейчас в теме
(10) Если тебе не нужны ДополнительныеСвойства, то это не значит что они всем не нужны. В современных конфигурациях это свойство очень активно используется для хранения несериализуемого состояния объекта, которое в том числе может использоваться в обработчике ПослеЗаписи например для принятия решения, какие фоновые задания запустить для ускорения прохождения объектом бизнес процессов.
13. JohnyDeath 301 04.04.23 09:32 Сейчас в теме
(12) в "ПриЗаписи" - согласен, эти свойства нужны. Но в "После" - обычно нет.
Но, опять же, нужно отталкиваться от задачи.
Чаще всего ПослеЗаписи нужно для того, чтобы отправить измененные объекты в обмен. Для этого по классической схеме делают РС, в который пихают ссылки на измененные объекты в ПриЗаписи и потом делают его постобработку. Или примерно тоже самое через ПланыОбмена.
Здесь же не нужно вообще никак встраиваться в ПриЗаписи, что гарантирует нам, что основная логика не нарушится и время на транзакцию никак не увеличится. Плюс не надо городить и поддерживать доп. объекты метаданных.
Ну и не менее важное - весь типовой код (если конфа на поддержке), останется девственным. Ведь обработчик "ПослеЗаписи" можно добавить через свою подписку:
Прикрепленные файлы:
14. tormozit 7193 04.04.23 09:42 Сейчас в теме
Если конфа на поддержке, то в моем подходе можно сделать расширение и в нем сделать все тоже самое (но подключение обработчиков делать в расширении метода ПередЗаписью) и будет работать также.
8. JohnyDeath 301 04.04.23 09:12 Сейчас в теме
И сама база из публикации, но с использованием истории данных
Прикрепленные файлы:
PUBID_1838612-Platform-After.dt
geoscan_1c; cleaner_it; tormozit; +3 Ответить
11. tormozit 7193 04.04.23 09:23 Сейчас в теме
С вызовом события ОбработкаПослеЗаписиВерсийИсторииДанных разобрался. У меня не было включено подключение фоновых заданий в отладчике. Так что его автоматический вызов в файловой базе тоже выполняется.
15. VZhulanov 5 04.04.23 18:35 Сейчас в теме
Я себе по другому реализовал механизм. Сделал справочник подписок на события, к котором можно указать какое событие (запись/проведение/отмена проведения) и для какого объекта (конкретный справочник или документ) надо отработать. Так-же указывается какой скрипт надо выполнить для обработки события, в качестве скрипта использую алгоритмы из ИР, так как в них не только скрипт можно прописать, но и параметры дополнительные.
В подписках на события проверяется нужна ли доп.обработка и нужное событие фиксируется в очереди на обработку.
Далее регламентным заданием эта очередь обрабатывается и выполняются нужные действия.

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

Конфигурация своя собственная, т.е. никаких проблем с внедрением подобного механизма нет.
А вот клиенты, которые используют мою конфу, имеют своих сисадминов и программистов и им нет необходимости конфу/расширения править, они просто нужные алгоритмы добавляют в справочник.

Вообще приходится много где использовать обычные скрипты или алгоритмы из ИР, чтобы расширить возможности настройки программы.
16. PerlAmutor 130 04.04.23 21:35 Сейчас в теме
Взял труды Сергея и сделал свою реализацию полностью на расширении через Обработку.

Работает следующим образом:
// Заимствуем документ или справочник в расширении и пишем одну единственную строчку в модуле объекта:
Обработки._СобытияОбъектов.СобытиеПослеЗаписи(ЭтотОбъект, "ОбщийМодуль1.Документ1_ПослеЗаписи", "Тест");


Из неё понятно какая процедура и откуда будет вызвана и с каким параметром После Записи. В общем модуле или любом другом месте пишем свою реализацию алгоритма. Можно сделать единственную точку входа для всех объектов подписанных таким образом, а потом проверять тип.
Прикрепленные файлы:
РасширениеПослеЗаписи.cfe
17. Cyberhawk 135 05.04.23 21:38 Сейчас в теме
досрочное завершение неявной транзакции в его конце почти дает гарантию, что мы не повлияем на логику работы других обработчиков, которые рассчитаны на выполнение в единой транзакции записи
логика работы обработчика ПриЗаписи2 будет нарушена, если мы применим описанный прием в первом обработчике ПриЗаписи
А можешь привести какой-нибудь "живой" пример такого нарушения? На ум приходит только что-то связанное с управляемыми или объектными блокировками (которые завершатся при разрыве транзакции и туда могут успеть вклиниться транзакции из других сеансов), но может есть что-то более простое для понимания?
26. tormozit 7193 06.04.23 11:41 Сейчас в теме
(17) Нарушится принцип атомарности (неделимости) обработчиков записи, т.е. единая транзакция подразумевает что результат выполнения обработчиков в БД сохранится либо всех либо никого из них (при откате транзакции).
27. Cyberhawk 135 06.04.23 11:50 Сейчас в теме
(26) Я имел в виду пример последствий от такого нарушения
18. Unknown31 06.04.23 09:25 Сейчас в теме
Обработчик ПриЗаписи модуля объекта справочника почти всегда выполняется самым последним в транзакции записи, т.е. после выполнения всех подписок.

Подписки выполняются после основного кода
При наступлении указанного события выполняется следующая последовательность действий:
...Сначала отрабатывается событие в самом объекте и вызывается обработчик события, определенный в модуле объекта или набора записей..
... Затем в произвольном порядке вызываются внешние обработчики, назначенные для данного события.
L0z4; tormozit; RustIG; +3 Ответить
20. RustIG 1720 06.04.23 09:36 Сейчас в теме
(18)я тожже так читал до сегодняшнего утра.... теперь вот сомневаюсь
22. tormozit 7193 06.04.23 10:16 Сейчас в теме
19. RustIG 1720 06.04.23 09:35 Сейчас в теме
Есть же процедура ОбработкаПроведения() - ее можно использовать вместо ПослеЗаписи().

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

В одном проекте - специально посмотрел сейчас - использую процедуру ОбработкаПроведения() в качестве отсутствующей процедуры ПослеЗаписи() - изменяю статус заказа покупателя (храню статус в регистре сведений) + формирую csv, выгружаю на фтп для сайта. Лет 10 назад сделал - работает. Были прерывания транзакции - когда я днем всех отрубал от 1с для обновления - статус заказа "отгружен" и файл ушел на сайт - при прерывании транзакции статус откатывается, а файл уже не вернуть, или статус = отгружен, а файл не прилетел на фтп... Но это все редкие случаи, решаются все равно через менеджера - менеджер готовит заказы - заказ перепроводится.... Не стал усложнять алгоритмы - поток пока такой, что ошибок не возникает.

Второй проект - тоже открыл специально - в процедуре ПередЗаписью() записываю свой реквизит объекта "Зарегистрирован", хотя регистрация в плане обмена происходит в следующей процедуре ПриЗаписи(). Здесь есть допущение, что транзакция не прервется между процедурами ПередЗаписью() и ПриЗаписи().
За несколько лет не было случаев прерывания транзакций:
Если Не Отказ И Зарегистрирован Тогда
//регистрирую в процедуре ПриЗаписи()....

Здесь переменная "Зарегистрирован" это аналог ДополнительныхСвойств для разделения логики алгоритма, но у меня была возможность создать реквизит в документе и не использовать ДопСвойства.

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

(0) Я так понимаю, вы решаете задачи связанные с адресным хранением - там конечно замудрено - видел я разные технологии и все почти недоделанные - в адресном хранении все процессы движутся только вперед - откатить назад или задним числом нереально проводить, поскольку документы связаны с другими документами. Наглядный пример Есть Реализация, но отгрузка товаров через РасходныйОрдер, а он в свою очередь зависит от нескольких статусов Отобран и Отгружен. На каждый момент времени (на каждую секунду) проверяется наличие товара в ячейке.
Может быть не убедительно написал, но при возникновении ошибок - в середине дня вылетает сервер - потом весь день ковыряешься, и легче удалить все документы и заново на компе (но не на ТСД) вручную провести все отгрузки в режиме План=Факт...
Сложно описал....Но как бы не прописывались отмены транзакций в адресном хранении - они корректно не откатывают....Вот я такое видел...Как говорится, не все конфы видел, с Акселот не работал...
25. tormozit 7193 06.04.23 10:58 Сейчас в теме
(19)
изначальную постановку задачи не знаю

В самом верху жирным написано при записи объекта хочется обработчик ПослеЗаписи, который бы выполнялся всегда после успешного завершения транзакции записи объекта
28. RustIG 1720 06.04.23 11:59 Сейчас в теме
(25) я наверное один из тех кто внимательно читает, особенно перед тем как оставить коммент....
...я видел вашу "постановку"... у нас же не олимпиада по 1с-программированию...
я имел в виду, что хотел бы услышать предметную из реальной жизни задачу.. и понять для начала почему ее нельзя решить имеющимися платформенными механизмами...
30. PerlAmutor 130 06.04.23 20:34 Сейчас в теме
(28) Этот прием можно использовать, чтобы не растягивать время открытой транзакции и уменьшить время ожидания на блокировках других пользователей, когда требуется до кучи автоматически создать еще подчиненные документы с проведением по тем же регистрам, такие как Корректировка Назначения в ERP. "Разрыв" транзакции можно сделать как до проведения документа, например, чтобы автоматически создать документ образующий остаток, так и после проведения, чтобы не схватить взаимоблокировку при проведении следующего документа в цепочке. Из практики - просили автоматически создавать Установку цен номенклатуры при проведении Перемещения Товаров, чтобы в регистр сведений цена "легла" уже с другим Видом цены, который настроен на складе-получателе. В момент перехода на учет товаров по сериям алгоритм формирования установки цен сильно деградировал из-за объема данных, аиз-за того, что выполнялся в транзакции Перемещения - проведение длилось около минуты и остальные пользователи начинали веерно висеть на блокировках друг друга, т.к. чтение остатка было заблокировано долгим формированием установки цен. И вот вы говорите почему бы не пользоваться обычными средствами - фоновое/регламентное задание. Объясняю. Пользователь после проведения начинает формировать печатную форму, где должны уже быть прописаны цены, чтобы распечатать и отнести. Когда в печатной форме нет цен - пользователь звонит по телефону и сообщает: "приехала машина, водитель ждет документы, не можем сделать отгрузку". Я должен ему сказать что-то типа "Дождитесь выполнения регламентного задания, которое срабатывает раз в 30 минут и если там небольшая очередь накопилась, то попробуйте сформировать еще раз. Если ничего не помогает, то ждите расчета себестоимости в конце месяца, когда в ЗУПе посчитается зарплата, мы её распределим на себестоимость и выполним закрытие месяца." ?
33. RustIG 1720 06.04.23 22:15 Сейчас в теме
(30)
просили автоматически создавать Установку цен номенклатуры при проведении Перемещения Товаров

у меня два или три проекта были - просили то же самое, только на основании Заказа покупателя, ПоступленияТоваров, ПеремещенияТоваров... Я пробовал как вы - в обработке проведения создавать документ - но на чем-то застопорился (не помню). Теперь подобные задачи делаю просто - расширяю документы-регистраторы регистра ЦеныНоменклатуры - добавляю нужный документ (Заказ, Поступление, Перемещение) и делаю движения напрямую в регистр сведений ЦеныНоменклатуры.
Использовать регл. или фоновые задания - я не предлагал - тем более по вашей задаче - их использовать не получится.
Если нужно, могу глубже окунуться в вашу задачу и реализовать простым способом в ходе обсуждения.
41. JohnyDeath 301 07.04.23 12:50 Сейчас в теме
(30)
Пользователь после проведения начинает формировать печатную форму, где должны уже быть прописаны цены, чтобы распечатать и отнести.

В этом случае делают немедленный запуск процедуры формирования нужных вам записей в регистре в момент печати. Из очереди ес-но его тоже надо будет удалить.
Либо при печати просто принудительно стартовать нужное рег задание.
44. PerlAmutor 130 08.04.23 07:02 Сейчас в теме
(41) Представьте ситуацию, 31 марта пользователь создал документ. Наступило 1 апреля - всем закрывается период. Теперь пользователь решил сформировать печатную форму, а создать документ Установки Цен из печатной формы в марте уже не может. Да перемещения на склад бывают заранее создают, а оформляют документы позже.
45. JohnyDeath 301 08.04.23 07:16 Сейчас в теме
(44) так у вас же есть рег задание, которое раз в N минут делает всё нужное.
Или между созданием документа и стартом рег задания успели закрыть месяц? ))
59. check2 370 11.04.23 21:35 Сейчас в теме
(30)
Из практики - просили автоматически создавать Установку цен номенклатуры при проведении Перемещения Товаров

Чистов на экзамене по платформе поставил за такое решение 2 балла (не мне). Хотя сами разработчики такими решениями блещут часто, например, при определенных настройках (вполне себе так сказать валидных) в УХе при проведении ПТУ создаётся(если нет) и проводится документ ОФД, а за ними ещё изменяется и перепроводится документ ВСКД... Привет бухгалтеру проводящему закрытие месяца с восстановлением последовательности.
JohnyDeath; +1 Ответить
60. JohnyDeath 301 11.04.23 22:14 Сейчас в теме
(59) аналогично и в бухгалтерии каждое поступление/реализация дёргает связанный с ней счет-фактуру.
Но надо такого избегать конечно же.
61. check2 370 11.04.23 22:26 Сейчас в теме
(60) А, ну да, про СФ я забыл, УХ же на БП КОРПе положена :) Целых 3 документа в нагрузку, при проведении ПТУ.
Причём писал УХашникам не раз про эту проблему. В каждом релизе вплоть до 3.1.16.5 вставляли доп. свойство при проведение из закрытия месяца, чтобы все вышеописанные документы не дёргались, а проводилась только ПТУ. Но тщетно...

(60)
Но надо такого избегать конечно же.

Просто как избежать если поставщик такое вытворяет? Не переписывать же целых 4 блока. Этаж анриал снимать с поддержки такой пласт механизмов. (БУ-НУ-ОУ-БЮДЖЕТ). Вот и ставим костыли в каждый релиз...

Ещё в ЕРПУХе не смотрел, но что то мне подсказывает что там всё то же самое.
62. JohnyDeath 301 11.04.23 22:29 Сейчас в теме
(61)
Просто как избежать если поставщик такое вытворяет?

я имел ввиду, что надо избегать тем, кто делает что-то своё. Типовое, конечно же, лучше не трогать. Очень дорого выйдет
29. tormozit 7193 06.04.23 20:23 Сейчас в теме
Обновил статью
- полностью переделал механизм
- учел порядок вызова и наличие множественных подписок
- учел авторегистрацию в планах обмена
- обновил демобазу и в частности расширил тест для проверки всех возможных ситуаций
- указал в начале пример применения события
PlatonStepan; +1 Ответить
34. RustIG 1720 06.04.23 22:19 Сейчас в теме
(29)
Он может быть полезен для выполнения необязательных действий, например оперативного запуска фонового задания обработки очереди, в которую записанный объект помещен и которая обрабатывается регламентным заданием.

а как устроена "очередь"?
38. RustIG 1720 07.04.23 08:22 Сейчас в теме
(29)
Он может быть полезен для выполнения необязательных действий, например оперативного запуска фонового задания обработки очереди, в которую записанный объект помещен и которая обрабатывается регламентным заданием.


вот у меня пример: очередь устроена в виде регистра сведений - есть колонка (поле) приоритет. Если я запускаю групповую обработку, то документы попадают в очередь с приоритетом 2, если менеджер формирует документ, то он попадает в очередь с приоритетом 0, есть случаи когда документы садятся в очередь с приоритетом 1.

при этом регл. задание каждые N минут обрабатывает очередь - берет первые M документов в порядке возрастания приоритета (0 - самый первый, 2 - самый последний) и обрабатывает документы.

то есть за "оперативный запуск" отвечает "приоритет" в очереди.
39. tormozit 7193 07.04.23 08:40 Сейчас в теме
(38)
каждые N минут

У тебя гарантированная оперативность выполнения фонового задания обработки очереди не менее N минут. А с обработчиком ПослеЗаписи она может быть 0 секунд. Например я записал какой то особо важный документ и хочу опционально сразу его обработать в той очереди. Для этого мне без события ПослеЗаписи надо из транзакции записи вызывать запуск фонового задания. А с событием ПослеЗаписи - я его запущу вне транзакции.
40. RustIG 1720 07.04.23 12:30 Сейчас в теме
(39) все понятно.
можно два регл. задания создать - первое мониторит очередь с приоритетом 0 - каждые 15-30 сек (в зав. от скорости выполнения обработки одного документа), второе рег. задание - мониторит очередь с приоритетом 1 и 2 каждые N минут.
но если надо прям сразу - то я бы дальше призадумался - "может и в очередь не надо помещать?" - сразу вызвать процедуру обработки после строки кода , где происходит запись документа (объекта). То есть локализовать вызов записи док-а (объекта) и сразу прописать после него вызов обработки без помещения в очередь....
31. Dach 378 06.04.23 21:41 Сейчас в теме
(0) круто! Приём с обманом платформой фиксации транзакции - особенно необычно, "свежо" что называется.

Вопрос. Не за компом, так бы сам проверил.
Что будет, если наш объект, внутри которого мы создаём платформенный обработчик "ПослеЗаписи" не завершит транзакцию? То есть, пресловутый "красный крест" в рантайме? Отмена транзакции из-за ожидания на блокировке или нехватке прав. Наш обработчик выполнится или все-таки нет? Ты просто пишешь про некую "очередь", а добавление в неё синхронное или нет? И если асинхронное, то может ты нашёл способ обойти "красный крест", сам того не подозревая???

Хотя раз мы там фиксируем неявную транзакцию, значит это тот же самый синхронный поток - значит не выполнится наш добавленный обработчик при выбросе исключения...?
32. Dach 378 06.04.23 21:55 Сейчас в теме
(31) ещё отсюда вопрос. Если исключение будет восстановимое, то есть, например, кто-то взвел Отказ в Истину - мы выходит так, что можем это проигнорировать и все равно зафиксировать такую транзакцию?

Или нам достаточно просто Отказ вернуть в Ложь. Иначе говоря: значение Отказ проверяется в момент окончания транзакции в НАШЕМ новом обработчике или оно уже проверено к моменту попадания к НАМ и транзакция по факту уже откачена?
35. tormozit 7193 06.04.23 22:45 Сейчас в теме
(32)
Отказ в Истину ... можем это проигнорировать и все равно зафиксировать такую транзакцию?

Технически это возможно, но с большой вероятностью нарушит корректную бизнес-логики.
значение Отказ проверяется в момент окончания транзакции в НАШЕМ новом обработчике или оно уже проверено к моменту попадания к НАМ и транзакция по факту уже откачена?

Предлагаемая в этой статье методика не меняет логику работы параметра Отказ. Если он включен, то предлагаемый код просто не выполнится как, т.к. экранирован условием "Если НЕ Отказ Тогда".
36. tormozit 7193 06.04.23 22:49 Сейчас в теме
(31) Если будет необработанное исключение, то до нашего кода выполнение не дойдет. Если же исключение будет обработано, но сломает транзакцию, то при вызове ЗакфиксироватьТранзакцию() в нашем коде произойдет привычная ошибка "В данной транзакции уже происходили ошибки" и естественно транзакция откатится.
37. tormozit 7193 07.04.23 06:58 Сейчас в теме
Исправил процедуру ВыполнитьАвторегистрациюЕслиНадо. Учел возможность заполнения коллекции "Получатели" прикладным кодом.
42. Fedos 07.04.23 15:32 Сейчас в теме
Мы эту задачу решили по-другому.
Добавили РС Блокировки с измерением УИД.
В самом конце последнего ПослеЗаписи ставим блокировку на этот РС по рандомному УИДу.
Затем запускаем фоновое задание, которое начинает транзакцию и пытается поставить свою блокировку по тому же УИДу.
Как только блокировка успешно установится - родительская транзакция завершилась и можно выполнять действия после записи.
Этот метод более затратен по ресурсам, зато не "ломает" нормальную логику ПослеЗаписи.
PlatonStepan; check2; +2 Ответить
43. PerlAmutor 130 08.04.23 06:42 Сейчас в теме
Можно поподробнее для чего вызывается ВыполнитьРегистрациюЕслиНадо(). В описанном подходе к разрыву транзакции нарушается логика платформы и регистрации не происходит или для чего это?
46. tormozit 7193 08.04.23 08:52 Сейчас в теме
(43) В статье я писал
в самом динамическом обработчике последнего события выполним явно регистрацию на узлах планов обмена, т.к. платформа выполняет ее в самом конце неявной транзакции записи

Поэтому явное досрочное завершение транзакции не даст в ней выполнится коду платформы, который выполняет регистрацию на узлах планов обмена. Значит нужно сделать это опять же явно. При этом еще и надо сделать так, чтобы при второй (фиктивной) транзакции эта регистрация не повторилась платформой, чтобы не было двойной работы.
47. PerlAmutor 130 08.04.23 15:16 Сейчас в теме
(46) Что-то не до конца понимаю почему мы выполняем свою регистрацию на узлах, да еще и обходим вторую регистрацию на фиктивную транзакцию. Может оставить лишь одну последнюю, ту что фиктивная?
48. tormozit 7193 08.04.23 16:41 Сейчас в теме
(47) Ну вот например тогда запуск обмена данными в ПослеЗаписи не увидит регистрацию изменений.
49. PerlAmutor 130 08.04.23 20:05 Сейчас в теме
(48) Но увидит потом, когда документ запишется и вернет управление? Т.е. это сделано для того, чтобы в обработчике ПослеЗаписи были уже выполнены все действия выполняемые платформой в обычной ситуации, как если бы мы запустили Фоновое Задание сразу же после фиксации транзакции.
50. DrZombi 298 10.04.23 04:37 Сейчас в теме
Непонятное творение, не вижу проблем, вызвать на форме после записи, что на клинте, что на сервере....
51. tormozit 7193 10.04.23 09:24 Сейчас в теме
(50) думаю, если прочитать статью и комментарии, должно стать понятно. Про обработчик в форме написано в самом начале статьи. Это должно наводить на мысль, что задача выходит за рамки работы с формой.
52. tormozit 7193 10.04.23 19:47 Сейчас в теме
Нашел недостаток - обработчик ПриЗаписиНаСервере управляемой формы выполняется В транзакции после всех обработчиков объекта. Таким образом описанный в статье обработчик ПослеЗаписи будет не последним в транзакции и нарушит неделимость последовательности обработчиков записи в отношении ПриЗаписиНаСервере в управляемой форме.
53. tormozit 7193 10.04.23 19:53 Сейчас в теме
Еще не учел платформенную автозапись движений документа при проведении, которая выполняется после события ОбработкаПроведения. В текущем виде эта автозапись выполняется во второй транзакции. Доделаю позже.
54. triviumfan 95 11.04.23 09:17 Сейчас в теме
Спасибо, хоть за что-то новенькое, но я бы не стал это использовать, а, особенно, после прочтения замечаний.
55. JohnyDeath 301 11.04.23 09:18 Сейчас в теме
(54) да, это по-моему чисто академически-спортивный интерес.
Как я писал выше, у платформы уже есть собственный "ПослеЗаписи". Его и нужно использовать в таких случаях. ИМХО, конечно.
56. tormozit 7193 11.04.23 09:26 Сейчас в теме
(55) Как я тоже писал выше нет у платформы собственного обработчика ПослеЗаписи для объекта в памяти. Оно "есть" только для указателя на данные объекта в БД, т.е. без сохранения его доп. свойств.
57. JohnyDeath 301 11.04.23 09:29 Сейчас в теме
(56) но ты так и не рассказал зачем тебе нужны доп. свойства.
Насколько я понял, ты просто регистрируешь объекты к обмену в плане обмена. Для этого вполне достаточно указанной ссылки на объект в БД.
Ну и для меня (как и для любой нагруженной системы) самая важная борьба - это борьба за сокращение времени транзакции записи-проведения.
58. tormozit 7193 11.04.23 09:31 Сейчас в теме
(57) Я НЕ решал конкретную прикладную задачу. Я пытался решить задачу в общем с максимальным приближением к обработке обычного события. Кажется это довольно очевидно из статьи.
63. tormozit 7193 15.04.23 10:31 Сейчас в теме
Доработал статью
1. Учел интерактивные транзакции, т.е. запись из формы объекта. В них красивого решения не нашел, поэтому оставил выполнение обработчика в транзакции.
2. Добавил запись движений документа при явном завершении транзакции проведения документа.
3. Добавил абзац по событие ОбработкаПослеЗаписиВерсийИсторииДанных
PlatonStepan; +1 Ответить
Оставьте свое сообщение