Каталог решений - Новая упрощенная процедура перерасчета записей регистров расчета (пример)

Новая упрощенная процедура перерасчета записей регистров расчета (пример)

Новая упрощенная процедура перерасчета записей регистров расчета (пример)

В наличии

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

Категория:

Описание

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

Возникла мысль, а почему нельзя полностью сделать отбор в самой процедуре перерасчета и передавать для расчета только "нужный" набор. Но здесь можно столкнуться с трудностями: Набор записей — это единая сущность (объект системы), которая должна читаться и записываться только полностью. Это ограничение можно обойти, используя некоторый "искусственный" прием.

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

Привожу пример процедуры перерасчета для регистра расчета "ДополнительныеНачисления" (релиз платформы 8.3.18.1128):

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

 

has been added to your cart:
Оформление заказа