Подписка на регистр Накопления, ПОСЛЕЗаписи
Необходимо отслеживать складские движения на складах. Т.е. проведение по РегиструНакопления "ТоварыНаСкладах", запись в которые могут делать к примеру ПоступлениеТовара, ПеремещениеТовара, а завтра еще какойнибудь документ.
Самое логичное на мой взгляд было сделать подписку на событие по этому регистру. Выбор событий там очень скудный. Выбрал "ПриЗаписи".
Но он срабатывает ДО проведения. А как поймать изменения уже внесенные в РегистрНакопления?
Неужели на каждый документ вешать подписку "ОбработкаПроведения"?
Самое логичное на мой взгляд было сделать подписку на событие по этому регистру. Выбор событий там очень скудный. Выбрал "ПриЗаписи".
Но он срабатывает ДО проведения. А как поймать изменения уже внесенные в РегистрНакопления?
Неужели на каждый документ вешать подписку "ОбработкаПроведения"?
По теме из базы знаний
Ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
(1) Уточните, пожалуйста, а каким образом Вы определили, что событие "ПриЗаписи" регистра срабатывает до проведения документа? Запись движений документа в УТ11 осуществляется именно в обработчике "ОбработкаПроведения" этого документа:
ПроведениеСерверУТ.ЗаписатьНаборыЗаписей(ЭтотОбъект);
Можно сделать подписку на событие ОбработкаПроведения. Оно будет выполняться после записи в регистры. А можно регл. задание, например каждые 5 минут мониторить. А можно план обмена создать и оттуда изменения проверять, брать и удалять.
(5)
(5)
можно, но прийдется на каждый документ. Я думал можно только на регистр.
(5)
нельзя по условию задания.
(5)
я сделал план обмена, сделал подписку на события при записи в регистр. По этой подписки дергаю из плана обмена, Измененые данные из регистра. НО они еще не попали туда, т.к. Подписка на событие срабатывает ДО проведение документа.
(5)
Можно сделать подписку на событие ОбработкаПроведения
можно, но прийдется на каждый документ. Я думал можно только на регистр.
(5)
А можно регл. задание, например каждые 5 минут мониторить
нельзя по условию задания.
(5)
А можно план обмена создать и оттуда изменения проверять, брать и удалять.
я сделал план обмена, сделал подписку на события при записи в регистр. По этой подписки дергаю из плана обмена, Измененые данные из регистра. НО они еще не попали туда, т.к. Подписка на событие срабатывает ДО проведение документа.
(8)
Если создали план обмена, то подписка на контроль записи в регистр уже не нужна. План обмена сам отслеживает изменения в регистре и сохраняет их в таблице изменений. После успешного обмена таблица изменений очищается.
я сделал план обмена, сделал подписку на события при записи в регистр.
Если создали план обмена, то подписка на контроль записи в регистр уже не нужна. План обмена сам отслеживает изменения в регистре и сохраняет их в таблице изменений. После успешного обмена таблица изменений очищается.
(23) А как быть с тем, что документ был распроведен, и табличная часть очищена?
Что тогда выгрузится на сайт по вашей логике?
У меня так же есть план обмена, в котором ничего не регистрируется автоматом, регистрирую при событии изменения РН.ТоварыНаСкладах / РН.ВзаиморасчетыСКонтрагентами / РН.ЦеныНоменклатуры.
Т.е. отлавливаю изменение данных, которые нужно оперативно передать на сайт.
В обработчике ПердЗаписью запросом выбираю товары(контрагентов) из РН с отбором по регистратору
Или выгружаю данные из источника, в зависимости от того какое событие происходит (проведение / отмена проведения)
Все это дело фиксирую в плане обмена и каждые 5 минут передаю данные на сайт с очисткой изменений а ПО
Что тогда выгрузится на сайт по вашей логике?
У меня так же есть план обмена, в котором ничего не регистрируется автоматом, регистрирую при событии изменения РН.ТоварыНаСкладах / РН.ВзаиморасчетыСКонтрагентами / РН.ЦеныНоменклатуры.
Т.е. отлавливаю изменение данных, которые нужно оперативно передать на сайт.
В обработчике ПердЗаписью запросом выбираю товары(контрагентов) из РН с отбором по регистратору
Или выгружаю данные из источника, в зависимости от того какое событие происходит (проведение / отмена проведения)
Все это дело фиксирую в плане обмена и каждые 5 минут передаю данные на сайт с очисткой изменений а ПО
"ПриЗаписи" срабатывает после записи набора в базу данных, скорее всего вы не так смотрели
(В регистр может писаться 2 раза в зависимости от конфигурации, в начале проведения эти данные очищаются(1 запись, что бы старые движения не влияли на остатки), 2 запись идет в конце когда добавляются уже движения документа.
(В регистр может писаться 2 раза в зависимости от конфигурации, в начале проведения эти данные очищаются(1 запись, что бы старые движения не влияли на остатки), 2 запись идет в конце когда добавляются уже движения документа.
Я запутался окончательно.
Сделал две разные подписки на событие:
1) Подписка на РегистрНакопленияНаборЗаписей - ТоварыНаСклада - Событие - "ПриЗаписи"
2) Подписка на ДокументОбъект.ПоступлениеТоваров - Событие - "ОбработкаПроведения"
На складе товара 0.
Провожу документ Поступления, в подписках код:
этот запрос, что по первой подписке, что по второй - выдаст результат ДО записи документа в регистр.
На складе 0, в документе 1. Провожу - ловлю 0.
Провожу ЕЩЕ раз этот же документ. Уже ловлю 1.
отборы по Номенклатуре и Складам "статичные". т.е. там данные не меняются.
дата документа меньше на месяц "текущей даты"
Что я делаю не так?
Сделал две разные подписки на событие:
1) Подписка на РегистрНакопленияНаборЗаписей - ТоварыНаСклада - Событие - "ПриЗаписи"
2) Подписка на ДокументОбъект.ПоступлениеТоваров - Событие - "ОбработкаПроведения"
На складе товара 0.
Провожу документ Поступления, в подписках код:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура,
| ТоварыНаСкладахОстатки.ВНаличииОстаток КАК ВНаличииОстаток,
| ТоварыНаСкладахОстатки.Склад КАК Склад
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(
| &НаДату,
| Номенклатура В ИЕРАРХИИ (&массивНоменклатуры)
| И Склад В (&массивСкладов)) КАК ТоварыНаСкладахОстатки";
Запрос.УстановитьПараметр("массивНоменклатуры", МассивОбъектов[0]);
Запрос.УстановитьПараметр("массивСкладов", МассивОбъектов[1]);
Запрос.УстановитьПараметр("НаДату", ТекущаяДата());
Показатьэтот запрос, что по первой подписке, что по второй - выдаст результат ДО записи документа в регистр.
На складе 0, в документе 1. Провожу - ловлю 0.
Провожу ЕЩЕ раз этот же документ. Уже ловлю 1.
отборы по Номенклатуре и Складам "статичные". т.е. там данные не меняются.
дата документа меньше на месяц "текущей даты"
Что я делаю не так?
(17) вот тут: "Запрос.УстановитьПараметр("НаДату", ТекущаяДата());"
Из виртуальной таблицы Остатки выбираются данные не включая саму дату. Т.е. данные до указанной даты. Если дата записи в регистр и текущая дата в пределах 1 секунды, то эти данные не попадут в выборку. Используйте Граница.
Еще в обработчике проведения данные могут не записываться в пределах самого обработчика, а записываться по окончанию обработчика.
Но сам алгоритм вызывает сомнения.
Из виртуальной таблицы Остатки выбираются данные не включая саму дату. Т.е. данные до указанной даты. Если дата записи в регистр и текущая дата в пределах 1 секунды, то эти данные не попадут в выборку. Используйте Граница.
Еще в обработчике проведения данные могут не записываться в пределах самого обработчика, а записываться по окончанию обработчика.
Но сам алгоритм вызывает сомнения.
(19) Провел эксперимент в демо-базе УТ 11.4.7.150.
Создал 2 подписки на события: одну для обработки проведения документа, другую для записи регистра. В обработчиках обоих документов реализовал запись в журнал регистрации информации об остатках по регистру "ТоварыНаСкладах":
Создал новый документ "Приобретения товаров и услуг" с двумя позициями номенклатуры и с датой 13.06.19. Дважды подряд провел документ и сформировал журнал регистрации с отбором по сообщениям для отладки. Результат во вложении.
Как видите, остатки в регистре после повторного проведения не меняются. Значит вся необходимая информация в регистре уже имелась после первого проведения.
Отсюда вывод. Подписка на событие при записи регистра работает как и ожидалось. Вероятнее всего ошибка где-то у Вас в алгоритмах.
Создал 2 подписки на события: одну для обработки проведения документа, другую для записи регистра. В обработчиках обоих документов реализовал запись в журнал регистрации информации об остатках по регистру "ТоварыНаСкладах":
Процедура ДокументОбработкаПроведения(Источник, Отказ, РежимПроведения) Экспорт
ТекстСообщения = ТекстСообщенияОДвижениях(Источник.Ссылка);
ЗаписьЖурналаРегистрации("Отладка.Проведение",
УровеньЖурналаРегистрации.Информация,
Источник.Метаданные(),
Источник.Ссылка,
ТекстСообщения);
КонецПроцедуры
Процедура РегистрПриЗаписи(Источник, Отказ, Замещение) Экспорт
Регистратор = Источник.Отбор.Регистратор.Значение;
ТекстСообщения = ТекстСообщенияОДвижениях(Регистратор);
ЗаписьЖурналаРегистрации("Отладка.Запись",
УровеньЖурналаРегистрации.Информация,
Источник.Метаданные(),
Регистратор,
ТекстСообщения);
КонецПроцедуры
Функция ТекстСообщенияОДвижениях(Регистратор)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Товары.Номенклатура КАК Номенклатура,
| Товары.Склад КАК Склад
|ПОМЕСТИТЬ ВтТовары
|ИЗ
| Документ.ПриобретениеТоваровУслуг.Товары КАК Товары
|ГДЕ
| Товары.Ссылка = &Регистратор
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ПРЕДСТАВЛЕНИЕССЫЛКИ(ТоварыНаСкладахОстатки.Склад) КАК Склад,
| ПРЕДСТАВЛЕНИЕССЫЛКИ(ТоварыНаСкладахОстатки.Номенклатура) КАК Номенклатура,
| ТоварыНаСкладахОстатки.ВНаличииОстаток КАК Количество
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(
| ,
| (Склад, Номенклатура) В
| (ВЫБРАТЬ
| ВтТовары.Склад,
| ВтТовары.Номенклатура
| ИЗ
| ВтТовары)) КАК ТоварыНаСкладахОстатки";
Запрос.УстановитьПараметр("Регистратор", Регистратор);
Выборка = Запрос.Выполнить().Выбрать();
ТекстСообщения = "";
Пока Выборка.Следующий() Цикл
Если ТекстСообщения <> "" Тогда
ТекстСообщения = ТекстСообщения + Символы.ПС;
КонецЕсли;
ТекстСообщения = ТекстСообщения + СтрШаблон("Склад=%1; Номенклатура=%2; Количество=%3",
Выборка.Склад, Выборка.Номенклатура, Выборка.Количество);
КонецЦикла;
Возврат ТекстСообщения;
КонецФункции
ПоказатьКак видите, остатки в регистре после повторного проведения не меняются. Значит вся необходимая информация в регистре уже имелась после первого проведения.
Отсюда вывод. Подписка на событие при записи регистра работает как и ожидалось. Вероятнее всего ошибка где-то у Вас в алгоритмах.
Прикрепленные файлы:

(18) (17) Дополню немного касательно алгоритма. Полагаю, что он вполне корректен применительно к УТ11. Запись движений в обозначенный регистр осуществляется в обработчике проведения документа. Здесь же осуществляется типовой алгоритм контроля отрицательных остатков. Фактически подписка на событие "ПриЗаписи" набора записей регистра сработает сразу после записи этого набора, но до контроля остатков. В рамках одной транзакции конечно.
ТС, держи кусочек кода, надеюсь поможет, Это вставляешь в подписку на событие ПердЗаписью твоего/твоих регистров
На выходе у меня таблица с товарами, по которым изменены остатки и/или цены. Далее думаю разберешься
Если Источник.Количество()=0 Тогда
Если ТипИсточника=Тип("РегистрНакопленияНаборЗаписей.ТоварыНаСкладах") Тогда
Запрос=Новый Запрос;
Запрос.Текст=
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| Рег.Номенклатура КАК Номенклатура,
| Рег.Склад КАК Склад
|ИЗ
| РегистрНакопления.ТоварыНаСкладах КАК Рег
|ГДЕ
| Рег.Регистратор = &Регистратор";
КонецЕсли;
Если ТипИсточника=Тип("РегистрСведенийНаборЗаписей.ЦеныНоменклатуры") Тогда
Запрос=Новый Запрос;
Запрос.Текст=
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| Рег.Номенклатура КАК Номенклатура,
| ЗНАЧЕНИЕ(Справочник.Склады.ПустаяСсылка) КАК Склад
|ИЗ
| РегистрСведений.ЦеныНоменклатуры КАК Рег
|ГДЕ
| Рег.Регистратор = &Регистратор";
КонецЕсли;
Запрос.УстановитьПараметр("Регистратор",Источник.Отбор.Регистратор.Значение);
СписокТоваров=Запрос.Выполнить().Выгрузить();
Иначе
СписокТоваров=Источник.Выгрузить(,"Склад,Номенклатура");
Если СписокТоваров.колонки.Найти("Склад")=Неопределено Тогда
МассивТипов=Новый Массив;
МассивТипов.Добавить(Тип("СправочникСсылка.Склады"));
ОписаниеТипов=Новый ОписаниеТипов(МассивТипов);
СписокТоваров.Колонки.Добавить("Склад",ОписаниеТипов);
СписокТоваров.ЗаполнитьЗначения(Справочники.Склады.ПустаяСсылка(),"Склад");
КонецЕсли;
КонецЕсли;
На выходе у меня таблица с товарами, по которым изменены остатки и/или цены. Далее думаю разберешься
Если Источник.Количество()=0 Тогда
Если ТипИсточника=Тип("РегистрНакопленияНаборЗаписей.ТоварыНаСкладах") Тогда
Запрос=Новый Запрос;
Запрос.Текст=
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| Рег.Номенклатура КАК Номенклатура,
| Рег.Склад КАК Склад
|ИЗ
| РегистрНакопления.ТоварыНаСкладах КАК Рег
|ГДЕ
| Рег.Регистратор = &Регистратор";
КонецЕсли;
Если ТипИсточника=Тип("РегистрСведенийНаборЗаписей.ЦеныНоменклатуры") Тогда
Запрос=Новый Запрос;
Запрос.Текст=
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| Рег.Номенклатура КАК Номенклатура,
| ЗНАЧЕНИЕ(Справочник.Склады.ПустаяСсылка) КАК Склад
|ИЗ
| РегистрСведений.ЦеныНоменклатуры КАК Рег
|ГДЕ
| Рег.Регистратор = &Регистратор";
КонецЕсли;
Запрос.УстановитьПараметр("Регистратор",Источник.Отбор.Регистратор.Значение);
СписокТоваров=Запрос.Выполнить().Выгрузить();
Иначе
СписокТоваров=Источник.Выгрузить(,"Склад,Номенклатура");
Если СписокТоваров.колонки.Найти("Склад")=Неопределено Тогда
МассивТипов=Новый Массив;
МассивТипов.Добавить(Тип("СправочникСсылка.Склады"));
ОписаниеТипов=Новый ОписаниеТипов(МассивТипов);
СписокТоваров.Колонки.Добавить("Склад",ОписаниеТипов);
СписокТоваров.ЗаполнитьЗначения(Справочники.Склады.ПустаяСсылка(),"Склад");
КонецЕсли;
КонецЕсли;
Делал через подписку на событие "ОбработкаПроведения"
Источник: "ДокументОбъект" т.е. отработает при проведении любого дока как и хотел ТС.
В начале процедуры-обработчика определяем двигался ли документ по нужному регистру:
Если Источник.Движения.ТоварыНаСкладах.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Источник: "ДокументОбъект" т.е. отработает при проведении любого дока как и хотел ТС.
В начале процедуры-обработчика определяем двигался ли документ по нужному регистру:
Если Источник.Движения.ТоварыНаСкладах.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Прикрепленные файлы:

Обманул в предыдущем посте. В таком варианте написания будет ошибка выпадать в тех документах, которые не являются регистраторами по нужному регистру. Можно например так:
Есть ещё варианты. Например, проверять отдельно может ли документ в принципе двигаться по данному регистру и если да, то сделал ли движения по нему в данный момент.
Основная суть в том, что подписку можно не на конкретный тип документа сделать, а на все сразу. Потом проверить наличие движений по нужным регистрам.
НетДвиженийПоОстаткам = Ложь;
Попытка НетДвиженийПоОстаткам = (Источник.Движения.ТоварыНаСкладах.Количество() = 0) Исключение КонецПопытки;
Если НетДвиженийПоОстаткам Тогда
Возврат;
КонецЕсли;
Есть ещё варианты. Например, проверять отдельно может ли документ в принципе двигаться по данному регистру и если да, то сделал ли движения по нему в данный момент.
Основная суть в том, что подписку можно не на конкретный тип документа сделать, а на все сразу. Потом проверить наличие движений по нужным регистрам.
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот