Основная проблема с которой сталкивается разработчик это остатки от распределения. Остатки возникают из-за округлений и представляют собой разницу между распределяемой и распределенной суммами.
Существуют разные методы решения проблемы. Один из методов - перенос разницы на элемент с самым большим значением. Недостатком такого метода является существенное изменение корректируемого элемента, при некоторых условиях. Например большое количество элементов распределения и маленькая точность округления. Иногда такой способ может привести к аномалиям, вплоть до перехода изначально положительных элементов базы распределения в отрицательные значения.
Другим методом решения проблемы является выравнивание результата не по общему итогу, а в процессе распределения по промежуточным итогам. При этом методе погрешность округлений переносится на элементы малыми частями. Следует заметить, что такой метод в сравнении с первым:
- более затратен по вычислительным ресурсам
- в результате распределения может случиться, что на элементы с одинаковыми значениями были распределены разные суммы
Вторая проблема разработчика, это определение распределяемой суммы/сумм в процессе выполнения запроса, отсутствие возможности передать распределяемую сумму/суммы в запрос параметром.
Ниже пример пропорционального распределения в запросе 1С методом выравнивания с определением распределяемых сумм в запросе.
ВЫБРАТЬ
"Элемент1" КАК Элемент,
"Группа1" КАК Группа,
2 КАК Значение
ПОМЕСТИТЬ Элементы
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
"Элемент2",
"Группа2",
2
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
"Элемент3",
"Группа2",
3
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
"Элемент4",
"Группа3",
3
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
"Элемент5",
"Группа3",
3
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
"Элемент6",
"Группа3",
5
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
"Элемент7",
"Группа3",
5
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
"Группа1" КАК Группа,
3 КАК РаспределяемаяСумма
ПОМЕСТИТЬ РаспределяемыеГруппы
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
"Группа2",
9
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
"Группа3",
7
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Элементы.Группа КАК Группа,
СУММА(Элементы.Значение) КАК Итог
ПОМЕСТИТЬ ИтогиПоГруппам
ИЗ
Элементы КАК Элементы
СГРУППИРОВАТЬ ПО
Элементы.Группа
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Элементы1.Элемент КАК Элемент,
Элементы1.Группа КАК Группа,
ВЫРАЗИТЬ(Элементы1.Значение КАК ЧИСЛО(15, 2)) КАК Значение,
ВЫРАЗИТЬ(ЕСТЬNULL(СУММА(Элементы2.Значение), 0) КАК ЧИСЛО(15, 2)) КАК ЗначениеНакопленное
ПОМЕСТИТЬ ЭлементыСНакоплением
ИЗ
Элементы КАК Элементы1
ЛЕВОЕ СОЕДИНЕНИЕ Элементы КАК Элементы2
ПО Элементы1.Элемент > Элементы2.Элемент
И Элементы1.Группа = Элементы2.Группа
СГРУППИРОВАТЬ ПО
Элементы1.Элемент,
Элементы1.Значение,
Элементы1.Группа
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Элементы.Элемент КАК Элемент,
Элементы.Группа КАК Группа,
Элементы.Значение КАК Значение,
РаспределяемыеГруппы.РаспределяемаяСумма КАК РаспределяемаяСумма,
ВЫБОР
КОГДА ИтогиПоГруппам.Итог = 0
ТОГДА 0
ИНАЧЕ (ВЫРАЗИТЬ(РаспределяемыеГруппы.РаспределяемаяСумма * (Элементы.ЗначениеНакопленное + Элементы.Значение) / ИтогиПоГруппам.Итог КАК ЧИСЛО(15, 2))) - (ВЫРАЗИТЬ(РаспределяемыеГруппы.РаспределяемаяСумма * Элементы.ЗначениеНакопленное / ИтогиПоГруппам.Итог КАК ЧИСЛО(15, 2)))
КОНЕЦ КАК РаспределеноНаЭлемент
ИЗ
ЭлементыСНакоплением КАК Элементы
ЛЕВОЕ СОЕДИНЕНИЕ ИтогиПоГруппам КАК ИтогиПоГруппам
ПО (Элементы.Группа = ИтогиПоГруппам.Группа)
ЛЕВОЕ СОЕДИНЕНИЕ РаспределяемыеГруппы КАК РаспределяемыеГруппы
ПО (Элементы.Группа = РаспределяемыеГруппы.Группа)
В приложенном файле отчет с приведенным примером распределения. Проверено на релизе 8.3.10.2753.