Подписка на регистр Накопления, ПОСЛЕЗаписи

1. sys1c 12.06.19 15:49 Сейчас в теме
Необходимо отслеживать складские движения на складах. Т.е. проведение по РегиструНакопления "ТоварыНаСкладах", запись в которые могут делать к примеру ПоступлениеТовара, ПеремещениеТовара, а завтра еще какойнибудь документ.

Самое логичное на мой взгляд было сделать подписку на событие по этому регистру. Выбор событий там очень скудный. Выбрал "ПриЗаписи".
Но он срабатывает ДО проведения. А как поймать изменения уже внесенные в РегистрНакопления?
Неужели на каждый документ вешать подписку "ОбработкаПроведения"?
По теме из базы знаний
Ответы
Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
6. dhurricane 12.06.19 17:30 Сейчас в теме
(1) Уточните, пожалуйста, а каким образом Вы определили, что событие "ПриЗаписи" регистра срабатывает до проведения документа? Запись движений документа в УТ11 осуществляется именно в обработчике "ОбработкаПроведения" этого документа:
ПроведениеСерверУТ.ЗаписатьНаборыЗаписей(ЭтотОбъект);
7. sys1c 12.06.19 17:52 Сейчас в теме
(6) Событие подписки, а не документа.
9. dhurricane 12.06.19 17:54 Сейчас в теме
(7) Не понял, какое событие обрабатывает подписка и от какого источника?
10. sys1c 12.06.19 17:57 Сейчас в теме
(9)
Подписка на событие.
Источник: РегистрНакопленияНаборЗаписей.ТоварыНаСкладах
Событие: ПриЗаписи
Обработчик: МоиФункции.МойОбработчик
14. dhurricane 12.06.19 19:01 Сейчас в теме
(10) Так почему же Вы решили, что обработчик срабатывает ДО проведения документа?
15. danjer74 3 12.06.19 19:04 Сейчас в теме
(1)Как вариант - использовать журнал регистрации
2. alex-l19041 8 12.06.19 16:09 Сейчас в теме
обычно отчеты используют для просмотра данных регистров... что конкретно надо ?
3. sys1c 12.06.19 16:41 Сейчас в теме
Конкретно при изменении складских остатков выгружать данные на Web сервер
22. mifka186 8 13.06.19 10:13 Сейчас в теме
(3) Зачем так извращаться? Настройте отдельный план обмена по этому регистру, и на вэб сервис уже отправляйте данные по таблице изменений.
pm74; acanta; +2 Ответить
4. sys1c 12.06.19 17:17 Сейчас в теме
Как поймать событие ПОСЛЕ записи в Регистр Накопления?
13. acanta 12.06.19 18:57 Сейчас в теме
(4) событие после записи в регистр накопления срабатывает по каждой записи регистра или по набору записей?
5. JohnGalt 57 12.06.19 17:25 Сейчас в теме
Можно сделать подписку на событие ОбработкаПроведения. Оно будет выполняться после записи в регистры. А можно регл. задание, например каждые 5 минут мониторить. А можно план обмена создать и оттуда изменения проверять, брать и удалять.
8. sys1c 12.06.19 17:54 Сейчас в теме
(5)
(5)
Можно сделать подписку на событие ОбработкаПроведения

можно, но прийдется на каждый документ. Я думал можно только на регистр.


(5)
А можно регл. задание, например каждые 5 минут мониторить

нельзя по условию задания.


(5)
А можно план обмена создать и оттуда изменения проверять, брать и удалять.

я сделал план обмена, сделал подписку на события при записи в регистр. По этой подписки дергаю из плана обмена, Измененые данные из регистра. НО они еще не попали туда, т.к. Подписка на событие срабатывает ДО проведение документа.
11. JohnGalt 57 12.06.19 17:59 Сейчас в теме
(8) Так можно один обработчик для списка документов сделать.
12. sys1c 12.06.19 18:00 Сейчас в теме
(11)
прийдет другой программист и создаст свой документ и я об этом не узнаю.
сама методика 1с то и состоит чтобы писать и читать из регистра, а не из документов.

вообщем понял, никак... только через документы (
23. mifka186 8 13.06.19 10:15 Сейчас в теме
(8)
я сделал план обмена, сделал подписку на события при записи в регистр.

Если создали план обмена, то подписка на контроль записи в регистр уже не нужна. План обмена сам отслеживает изменения в регистре и сохраняет их в таблице изменений. После успешного обмена таблица изменений очищается.
24. НовенькийЯ 14.06.19 17:26 Сейчас в теме
(23) А как быть с тем, что документ был распроведен, и табличная часть очищена?
Что тогда выгрузится на сайт по вашей логике?

У меня так же есть план обмена, в котором ничего не регистрируется автоматом, регистрирую при событии изменения РН.ТоварыНаСкладах / РН.ВзаиморасчетыСКонтрагентами / РН.ЦеныНоменклатуры.
Т.е. отлавливаю изменение данных, которые нужно оперативно передать на сайт.

В обработчике ПердЗаписью запросом выбираю товары(контрагентов) из РН с отбором по регистратору
Или выгружаю данные из источника, в зависимости от того какое событие происходит (проведение / отмена проведения)

Все это дело фиксирую в плане обмена и каждые 5 минут передаю данные на сайт с очисткой изменений а ПО
16. coollerinc 186 12.06.19 19:55 Сейчас в теме
"ПриЗаписи" срабатывает после записи набора в базу данных, скорее всего вы не так смотрели
(В регистр может писаться 2 раза в зависимости от конфигурации, в начале проведения эти данные очищаются(1 запись, что бы старые движения не влияли на остатки), 2 запись идет в конце когда добавляются уже движения документа.
17. sys1c 13.06.19 07:20 Сейчас в теме
Я запутался окончательно.

Сделал две разные подписки на событие:
1) Подписка на РегистрНакопленияНаборЗаписей - ТоварыНаСклада - Событие - "ПриЗаписи"
2) Подписка на ДокументОбъект.ПоступлениеТоваров - Событие - "ОбработкаПроведения"

На складе товара 0.
Провожу документ Поступления, в подписках код:

	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура,
		|	ТоварыНаСкладахОстатки.ВНаличииОстаток КАК ВНаличииОстаток,
		|	ТоварыНаСкладахОстатки.Склад КАК Склад
		|ИЗ
		|	РегистрНакопления.ТоварыНаСкладах.Остатки(
		|			&НаДату,
		|			Номенклатура В ИЕРАРХИИ (&массивНоменклатуры)
		|				И Склад В (&массивСкладов)) КАК ТоварыНаСкладахОстатки";
	
	Запрос.УстановитьПараметр("массивНоменклатуры", МассивОбъектов[0]);
	Запрос.УстановитьПараметр("массивСкладов", МассивОбъектов[1]);
	Запрос.УстановитьПараметр("НаДату", ТекущаяДата());
Показать


этот запрос, что по первой подписке, что по второй - выдаст результат ДО записи документа в регистр.
На складе 0, в документе 1. Провожу - ловлю 0.
Провожу ЕЩЕ раз этот же документ. Уже ловлю 1.

отборы по Номенклатуре и Складам "статичные". т.е. там данные не меняются.
дата документа меньше на месяц "текущей даты"

Что я делаю не так?
18. spacecraft 13.06.19 07:45 Сейчас в теме
(17) вот тут: "Запрос.УстановитьПараметр("НаДату", ТекущаяДата());"
Из виртуальной таблицы Остатки выбираются данные не включая саму дату. Т.е. данные до указанной даты. Если дата записи в регистр и текущая дата в пределах 1 секунды, то эти данные не попадут в выборку. Используйте Граница.
Еще в обработчике проведения данные могут не записываться в пределах самого обработчика, а записываться по окончанию обработчика.
Но сам алгоритм вызывает сомнения.
19. sys1c 13.06.19 08:00 Сейчас в теме
(18) "Если дата записи в регистр и текущая дата в пределах 1 секунды, то эти данные не попадут в выборку"

дата документа меньше на месяц "текущей даты"
целый месяц разницы.
21. dhurricane 13.06.19 08:34 Сейчас в теме
(19) Провел эксперимент в демо-базе УТ 11.4.7.150.

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

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

Функция ТекстСообщенияОДвижениях(Регистратор)
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
	"ВЫБРАТЬ
	|	Товары.Номенклатура КАК Номенклатура,
	|	Товары.Склад КАК Склад
	|ПОМЕСТИТЬ ВтТовары
	|ИЗ
	|	Документ.ПриобретениеТоваровУслуг.Товары КАК Товары
	|ГДЕ
	|	Товары.Ссылка = &Регистратор
	|;
	|
	|////////////////////////////////////////////////////////////­////////////////////
	|ВЫБРАТЬ
	|	ПРЕДСТАВЛЕНИЕССЫЛКИ(ТоварыНаСкладахОстатки.Склад) КАК Склад,
	|	ПРЕДСТАВЛЕНИЕССЫЛКИ(ТоварыНаСкладахОстатки.Номенклатура) КАК Номенклатура,
	|	ТоварыНаСкладахОстатки.ВНаличииОстаток КАК Количество
	|ИЗ
	|	РегистрНакопления.ТоварыНаСкладах.Остатки(
	|			,
	|			(Склад, Номенклатура) В
	|				(ВЫБРАТЬ
	|					ВтТовары.Склад,
	|					ВтТовары.Номенклатура
	|				ИЗ
	|					ВтТовары)) КАК ТоварыНаСкладахОстатки";
	
	Запрос.УстановитьПараметр("Регистратор", Регистратор);
	
	Выборка = Запрос.Выполнить().Выбрать();
	
	ТекстСообщения = "";
	Пока Выборка.Следующий() Цикл
		Если ТекстСообщения <> "" Тогда
			ТекстСообщения = ТекстСообщения + Символы.ПС;
		КонецЕсли; 
		ТекстСообщения = ТекстСообщения + СтрШаблон("Склад=%1; Номенклатура=%2; Количество=%3",
			Выборка.Склад, Выборка.Номенклатура, Выборка.Количество);
	КонецЦикла; 
	
	Возврат ТекстСообщения;
	
КонецФункции
Показать
Создал новый документ "Приобретения товаров и услуг" с двумя позициями номенклатуры и с датой 13.06.19. Дважды подряд провел документ и сформировал журнал регистрации с отбором по сообщениям для отладки. Результат во вложении.

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

Отсюда вывод. Подписка на событие при записи регистра работает как и ожидалось. Вероятнее всего ошибка где-то у Вас в алгоритмах.
Прикрепленные файлы:
20. dhurricane 13.06.19 08:01 Сейчас в теме
(18) (17) Дополню немного касательно алгоритма. Полагаю, что он вполне корректен применительно к УТ11. Запись движений в обозначенный регистр осуществляется в обработчике проведения документа. Здесь же осуществляется типовой алгоритм контроля отрицательных остатков. Фактически подписка на событие "ПриЗаписи" набора записей регистра сработает сразу после записи этого набора, но до контроля остатков. В рамках одной транзакции конечно.
25. НовенькийЯ 14.06.19 17:30 Сейчас в теме
ТС, держи кусочек кода, надеюсь поможет, Это вставляешь в подписку на событие ПердЗаписью твоего/твоих регистров
На выходе у меня таблица с товарами, по которым изменены остатки и/или цены. Далее думаю разберешься


Если Источник.Количество()=0 Тогда

Если ТипИсточника=Тип("РегистрНакопленияНаборЗаписей.ТоварыНаСкладах") Тогда
Запрос=Новый Запрос;
Запрос.Текст=
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| Рег.Номенклатура КАК Номенклатура,
| Рег.Склад КАК Склад
|ИЗ
| РегистрНакопления.ТоварыНаСкладах КАК Рег
|ГДЕ
| Рег.Регистратор = &Регистратор";
КонецЕсли;
Если ТипИсточника=Тип("РегистрСведенийНаборЗаписей.ЦеныНоменклатуры") Тогда
Запрос=Новый Запрос;
Запрос.Текст=
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| Рег.Номенклатура КАК Номенклатура,
| ЗНАЧЕНИЕ(Справочник.Склады.ПустаяСсылка) КАК Склад
|ИЗ
| РегистрСведений.ЦеныНоменклатуры КАК Рег
|ГДЕ
| Рег.Регистратор = &Регистратор";
КонецЕсли;

Запрос.УстановитьПараметр("Регистратор",Источник.Отбор.Регистратор.Значение);
СписокТоваров=Запрос.Выполнить().Выгрузить();
Иначе
СписокТоваров=Источник.Выгрузить(,"Склад,Номенклатура");
Если СписокТоваров.колонки.Найти("Склад")=Неопределено Тогда
МассивТипов=Новый Массив;
МассивТипов.Добавить(Тип("СправочникСсылка.Склады"));
ОписаниеТипов=Новый ОписаниеТипов(МассивТипов);
СписокТоваров.Колонки.Добавить("Склад",ОписаниеТипов);
СписокТоваров.ЗаполнитьЗначения(Справочники.Склады.ПустаяСсылка(),"Склад");
КонецЕсли;
КонецЕсли;
цукар; +1 Ответить
26. Redoubtable 02.06.20 13:41 Сейчас в теме
Делал через подписку на событие "ОбработкаПроведения"
Источник: "ДокументОбъект" т.е. отработает при проведении любого дока как и хотел ТС.

В начале процедуры-обработчика определяем двигался ли документ по нужному регистру:

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

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


Есть ещё варианты. Например, проверять отдельно может ли документ в принципе двигаться по данному регистру и если да, то сделал ли движения по нему в данный момент.
Основная суть в том, что подписку можно не на конкретный тип документа сделать, а на все сразу. Потом проверить наличие движений по нужным регистрам.
28. softmaker 39 17.03.21 07:32 Сейчас в теме
(27)

Если Источник.Движения.Найти("ТоварыНаСкладах") <> Неопределено Тогда

КонецЕсли;
Pryanishnikov_Vladimir; +1 Ответить
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот