Программный контроль границы последовательности партионного учета при проведении документов задним числом

04.11.15

Задачи пользователя - Адаптация типовых решений

Редактирование и проведение документов задним числом несмотря на обилие корректировочных документов - суровая необходимость, особенно на больших предприятиях. Естественно, что если документ двигает границу последовательности партионного учета, граница устанавливается на этот документ, и для получения актуальных данных требуется восстанавливать последовательность, как правило в монопольном режиме. Вернем границу последовательности программно на её законное место, если движения по партиям документа, проведенного задним числом не изменились.

Приступим...

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

Последовательность ПартионныйУчет

2. Создадим в общем модуле процедуру для подписки. Для хранения таблицы движений документа используем встроенный реквизит документа ДополнительныеСвойства. Информация, помещаемая в эту структуру, хранится всё время "путешествия" объекта по подпискам. Запомним движения по партиям до проведения, а также границу последовательности, которая была на момент проведения документа.

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

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

Таблицу движений по партиям получили и запомнили. Теперь надо сравнить с тем, что получилось после проведения. Создаем еще одну подписку на событие ОбработкаПроведения, также включаем туда документы из последовательности партионного учета. Таблицу движения по партиям после проведения также поместим в ДополнительныеСвойства.

Процедура ОбработкаПроведенияДляКонтроляГП(Источник, Отказ, РежимПроведения) Экспорт
    ВыполнитьКонтрольГП(Источник);
КонецПроцедуры

Процедура ВыполнитьКонтрольГП(Источник) Экспорт
    Если Источник.Метаданные().Реквизиты.Найти("ОтражатьВУправленческомУчете") <> Неопределено Тогда
        Если НЕ Источник.ОтражатьВУправленческомУчете Тогда
            Возврат;
        КонецЕсли;
    КонецЕсли;
    Если НЕ Источник.ЭтоНовый() Тогда
        Если Источник.Движения.Найти("ПартииТоваровНаСкладах") <> Неопределено Тогда
            ПартииПослеПроведения = Источник.Движения.ПартииТоваровНаСкладах.Выгрузить();
            Если ПартииПослеПроведения.Количество() = 0 Тогда
                // для части документов партии появляются после записи объекта в базу
                ПартииПослеПроведения = ВернутьТаблицуДвиженийПоПартиям(Источник.Ссылка);
            КонецЕсли;
            Источник.ДополнительныеСвойства.Вставить("ПартииПослеПроведения", ПартииПослеПроведения);
            ОпределитьНеобходимостьВозвращенияГП(Источник);
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Ну и, наконец, анализ необходимости возвращения последовательности.

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

Извлекли из ДополнительныеСвойства таблицы движений до и после, сравнили, определили необходимость возвращения последовательности и вернули при необходимости на место.

Механизм также полезен для ситуаций, когда пользователь открывает документ, проведенный задним числом, и вместо закрытия нажимает ОК. Граница улетает на "закрытый" таким образом документ.

Если еще углубляться в детали, в стандартной конфигурации граница последовательности сбрасывается программно кодом:

	Если мУдалятьДвижения Тогда
		ОбщегоНазначения.УдалитьДвиженияРегистратора(ЭтотОбъект, Отказ);
	КонецЕсли;

То есть при перепроведении независимо ни от чего движения документа очищаются и записываются заново. В более современных продвинутых конфигурациях вроде это уже не так, но на родной переписанной до почти неузнаваемости УТ 10.3 вопрос восстановления границы последовательности потребовал программного решения.

контроль границы последовательности партионного учета партионный учет восстановление последовательности

См. также

Логистика, склад и ТМЦ Адаптация типовых решений Пользователь Платформа 1С v8.3 1С:Управление нашей фирмой 1.6 1С:Управление нашей фирмой 3.0 Россия Управленческий учет Платные (руб)

Чтобы не допустить путаницы с обещаниями клиентам и для четкого контроля исполнения заказов мы используем резервирование товаров. Мы доработали УНФ, чтобы она автоматически отменяла старые резервы и не мешала эффективно продавать.

7200 руб.

02.08.2023    4172    15    1    

33

Адаптация типовых решений Платформа 1С v8.3 1С:Документооборот Россия Платные (руб)

Расширение конфигурации для «1С:Документооборот КОРП», редакция 3.0. позволяет: 1.использовать произвольные табличные части в качестве дополнительных реквизитов к документу; 2 использовать произвольные табличные части в шаблонах в формате docx для автоматического заполнения таблиц.

29400 руб.

29.06.2023    6001    14    5    

24

Печатные формы Адаптация типовых решений Бухгалтер Пользователь Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Платные (руб)

Расширение позволяет вывести в табличном документе факсимиле печати и подписей и/или вывести произвольную картинку из прикреплённых файлов организации для 1С УТ 11.5, КА 2.5, ERP 2.5, УНФ 3, Розница 3. Вывод факсимиле возможен в табличные документы УПД, УКД, Счёт-фактура, ТОРГ-12 и другие. Возможно настроить вывод для любых типовых макетов (Акт сверки, М-15, ТТН), для этого потребуется отредактировать макет и разместить на нём картинки с установленными именами. Редактирование осуществляется через типовой механизм в пользовательском интерфейсе.

3000 руб.

07.02.2023    6712    73    10    

30

Адаптация типовых решений Программист Пользователь Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Абонемент ($m)

Каждый из нас сталкивается с ситуацией, когда какой-нибудь менеджер показывает свой Excel и рассказывает, как он что-то из 1С копирует в него, снабжает пояснениями, выделяет цветом и т.д. и т.п. Заканчивается все просьбой сделать вот чтобы также было в 1С. И оказывается такой человек (почти с гарантией) либо лучшим продажником, либо каким-то важным, за все отвечающим, - на ком все держится.

2 стартмани

22.04.2024    5270    dimanich70    15    

22

БСП (Библиотека стандартных подсистем) Адаптация типовых решений Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 Бесплатно (free)

Понадобилось в подменю "Создать на основании" добавить свою команду, которая открывает обработку. В процессе доработок появилась проблема двух подменю "Создать на основании". В статье о том, как решились проблемы.

01.03.2024    6869    dimanich70    9    

18
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. karpik666 3851 05.11.15 05:08 Сейчас в теме
Код функции СравнитьТаблицыЗначений
// Функция сравнивает две таблицы значений на идентичность структуры и данных
//
// Параметры
//  ТаблицаЗначений1 - ТаблицаЗначений для сравнения
//  ТаблицаЗначений2 - ТаблицаЗначений для сравнения
//
// Возвращаемое значение:
//   Булево, идентичны или нет две таблицы
//
Функция СравнитьТаблицыЗначений(ТаблицаЗначений1, ТаблицаЗначений2)

	Если ТипЗнч(ТаблицаЗначений1) <> Тип("ТаблицаЗначений") ИЛИ ТипЗнч(ТаблицаЗначений2) <> Тип("ТаблицаЗначений") Тогда
		Возврат Ложь;
	КонецЕсли; 
	
	Если ТаблицаЗначений1.Количество() <> ТаблицаЗначений2.Количество() Тогда
		Возврат Ложь;
	КонецЕсли; 

	Если ТаблицаЗначений1.Колонки.Количество() <> ТаблицаЗначений2.Колонки.Количество() Тогда
		Возврат Ложь;
	КонецЕсли; 

	Для каждого Колонка Из ТаблицаЗначений1.Колонки Цикл
		
		Если ТаблицаЗначений2.Колонки.Найти(Колонка.Имя) = Неопределено Тогда
			Возврат Ложь;
		КонецЕсли;
		
		Для каждого СтрокаТаблицы Из ТаблицаЗначений1 Цикл
		
			Попытка
			
				Если СтрокаТаблицы[Колонка.Имя] <> ТаблицаЗначений2[ТаблицаЗначений1.Индекс(СтрокаТаблицы)][Колонка.Имя] Тогда
				
					Возврат Ложь;
				
				КонецЕсли;
			
			Исключение
				
				Возврат Ложь;
				
			КонецПопытки;
		
		КонецЦикла; 
	
	КонецЦикла; 
	
	Возврат Истина;
	
КонецФункции // СравнитьТаблицыЗначений()
Показать
2. cargobird 308 05.11.15 07:04 Сейчас в теме
(1) karpik666, спасибо, добавлю в статью.
10. vis_tmp 32 08.02.17 08:51 Сейчас в теме
(1)А не быстрее будет вместо поячеечного сравнения таблиц значений сравнить "ЗначениеВСтрокуВнутр()" их обоих?
3. insurgut 208 05.11.15 07:41 Сейчас в теме
Увеличивая нагрузку на проведение документа уменьшаем (возможно даже кратно) нагрузку на перепроведение по партиям. Неплохой вариант! На какой версии конфигурации отлажен механизм? Работает ли он с корректировками записей регистров?
4. cargobird 308 05.11.15 08:07 Сейчас в теме
(3) insurgut, Управление Торговлей, ред. 10.3. Версия конфигурации более чем двухгодовалой давности, даже затрудняюсь определиться с номером. При этом добавлялись необходимые новые документы, вроде корректировок поступления и реализации.
Корректировка записей регистров при перезаписи без изменений движений в партионном учете границу не роняет (и вроде это штатное поведение, не помню чтобы что-то там трогал), поэтому по нему дорабатывать не понадобилось.
5. svilsa 12 13.11.15 20:14 Сейчас в теме
Супер! Спасибо, это то что нужно. Особенно, когда настроен обмен УТ-БП, и все документы. которые "провелись по партиям" зря хотят выгрузиться в бухгалтерию. Очень-очень пригодилась статья! С помощью метода статьи надеюсь снизить в разы количество документов обмена из-за того, что в "Отчетах о розничных продажах" месячной давности бухгалтер меняет вид кредита банка.
cargobird; +1 Ответить
6. cargobird 308 14.11.15 08:12 Сейчас в теме
(5) svilsa, могу предложить еще одну оптимизацию работы, раз дорабатываете конфигурацию: если ввести дополнительный параметр сеанса типа Булево (назвать его, например, "ВосстановлениеПоследовательности"), перед восстановлением последовательности взвести его в Истина, и по Истина отключать работу этого механизма - последовательность будет восстанавливаться немного быстрее...
7. svilsa 12 14.11.15 13:10 Сейчас в теме
8. lx@ 20.11.15 10:16 Сейчас в теме
Мне показалось, что не хватает блокировок. Может получиться, что движения у документа остались, однако граница была сдвинута другим документом и посему возращать ее не надо.
9. cargobird 308 20.11.15 12:13 Сейчас в теме
(8) lx@, в УТ 10.3 механизм блокировок еще жесткий - при проведении блокируется вся таблица регистра целиком, поэтому пока проводится один документ, второй не проведется. Или дождется, или выпадет в транзакцию. То есть двигать границу может только один документ, который проводит и тот и двигает. Вроде так.
11. WWWolfy 133 12.03.20 00:36 Сейчас в теме
Можно не загонять в память сервера большие таблицы и не мучаться с их сравнением.
Как вариант - делать хеш MD5 и сравнивать их.
Пример:

	ХешированиеДанных  = Новый ХешированиеДанных(ХешФункция.MD5) ;
 	ХешированиеДанных.Добавить(  ЗначениеВСтрокуВнутр( ТЗДвижений ) );
	Хэш = НРег(СтрЗаменить(ХешированиеДанных.ХешСумма, " ", ""));


А чтобы не отрабатывать при перепроведениях и т.п. можно анализировать, что работаем из открытой Формы, для этого выставить флаг "ОткрытаФорма" в какой-нибудь общей процедуре, например:
Процедура УстановитьДоступностьПоляВводаНомера(МетаданныеОбъекта, ФормаОбъекта, ПодменюДействия, ПолеВводаНомера) Экспорт
	
	//Для всех документов вставим флаг, что работаем с ним из Формы. Нужно для проведения.
ФормаОбъекта.ДокументОбъект.ДополнительныеСвойства.Вставить("ЗаписанИзФормы", Истина );
12. vis_tmp 32 21.12.22 12:29 Сейчас в теме
Кажется, это очень дельное предложение по оптимизации проведения по партиям.
Особенно с учётом дополнений в комментариях.
Оставьте свое сообщение