0. invertex 91 27.06.18 21:53 Сейчас в теме

Пропорциональное распределение в запросе

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

Перейти к публикации

Комментарии
Избранное Подписка Сортировка: Древо
1. Rustig 1206 29.06.18 08:16 Сейчас в теме
(0) у меня по этой задаче целая подсистема механизмов получилась: https://infostart.ru/public/829908/
2. val_bel 29.06.18 10:38 Сейчас в теме
Хотелось бы пояснений к логике запросов. Вот например какая логика в этом фрагменте, что есть ЗначениеНакопленное?

ВЫБРАТЬ
	Элементы1.Элемент КАК Элемент,
	Элементы1.Группа КАК Группа,
	ВЫРАЗИТЬ(Элементы1.Значение КАК ЧИСЛО(15, 2)) КАК Значение,
	ВЫРАЗИТЬ(ЕСТЬNULL(СУММА(Элементы2.Значение), 0) КАК ЧИСЛО(15, 2)) КАК ЗначениеНакопленное
ПОМЕСТИТЬ ЭлементыСНакоплением
ИЗ
	Элементы КАК Элементы1
		ЛЕВОЕ СОЕДИНЕНИЕ Элементы КАК Элементы2
		ПО Элементы1.Элемент > Элементы2.Элемент
			И Элементы1.Группа = Элементы2.Группа

СГРУППИРОВАТЬ ПО
	Элементы1.Элемент,
	Элементы1.Значение,
	Элементы1.Группа
;
Показать
5. romankoav 29.06.18 17:16 Сейчас в теме
(2) Валерий, обратите внимание на соединение Элементы1.Элемент > Элементы2.Элемент. Немного не обычно, но результат как будто делается соединение по номерам строк таблицы. Соответственно каждая строка будет иметь итог предыдущих строк.
3. romankoav 29.06.18 13:32 Сейчас в теме
Это так должно быть, что суммы распределения отличаются в приведенном запросе от того что на картинке к статье?
4. sommid 29.06.18 14:18 Сейчас в теме
https://www.forum.mista.ru/topic.php?id=616801 - распределение с "размазыванием" округления
пост 91 от Speshuric
6. romankoav 04.07.18 11:32 Сейчас в теме
(4) Да. фактически эта статья усложненный "на группы" вариант с Мисты
7. vpaoli 28 11.10.18 15:14 Сейчас в теме
К сожалению данный алгоритм не работает корректно при произвольных (взятых из практической задачи) значениях базы распределения.
Например, на такой таблице данных он не работает:

Временная таблица: ВТ_УправленческиеРасходы_Распределяемые (Записей в результате: 2)
УправленческиеРасходы_Распределяемые ОперационныйСегмент
27 504 652,9 Сегмент1
3 781 595,5 Прочие


Временная таблица: Данные (Записей в результате: 12)
Объект ОперационныйСегмент База
МК-00001853Экспорт Сегмент1 3 044 491,7155362
МК-00001854Внутренний рынок Сегмент1 3 149 669,367952
МК-00001854Экспорт Сегмент1 14 775 706,07857
МК-00001855Внутренний рынок Сегмент1 3 163 001,7726148
МК-00001855СНГ Сегмент1 968 615,0756743
МК-00001856Экспорт Сегмент1 1 189 318,7971243
МК-00001857Экспорт Сегмент1 1 160 673,1357024
МК-00001860Экспорт Прочие 779 552,4115997
МК-00001861Экспорт Прочие 2 041 707,0284046
МК-00001870Внутренний рынок Прочие 765 162,6133091
МК-00001871Внутренний рынок Сегмент1 53 176,9540751
МК-000013Внутренний рынок Прочие 195 173,4463082

Временная таблица: Итог (Записей в результате: 2)
СуммаБазы ОперационныйСегмент
27 504 652,8972491 Сегмент1
3 781 595,4996216 Прочие

Временная таблица: ДанныеСНакоплением (Записей в результате: 12)
Объект ОперационныйСегмент База БазаНакопленная
МК-000013Внутренний рынок Прочие 195 173,45
МК-00001853Экспорт Сегмент1 3 044 491,72
МК-00001854Внутренний рынок Сегмент1 3 149 669,37 3 044 491,72
МК-00001854Экспорт Сегмент1 14 775 706,08 6 194 161,08
МК-00001855Внутренний рынок Сегмент1 3 163 001,77 20 969 867,16
МК-00001855СНГ Сегмент1 968 615,08 24 132 868,93
МК-00001856Экспорт Сегмент1 1 189 318,8 25 101 484,01
МК-00001857Экспорт Сегмент1 1 160 673,14 26 290 802,81
МК-00001860Экспорт Прочие 779 552,41 195 173,45
МК-00001861Экспорт Прочие 2 041 707,03 974 725,86
МК-00001870Внутренний рынок Прочие 765 162,61 3 016 432,89
МК-00001871Внутренний рынок Сегмент1 53 176,95 27 451 475,94

Временная таблица: ВТ_РаспределеноПоБазе (Записей в результате: 12)
Объект База ОперационныйСегмент РаспределеноПоБазе
МК-000013Внутренний рынок 195 173,45 Прочие 195 173,45
МК-00001853Экспорт 3 044 491,72 Сегмент1 3 044 491,72
МК-00001854Внутренний рынок 3 149 669,37 Сегмент1 3 149 669,37
МК-00001854Экспорт 14 775 706,08 Сегмент1 14 775 706,08
МК-00001855Внутренний рынок 3 163 001,77 Сегмент1 3 163 001,77
МК-00001855СНГ 968 615,08 Сегмент1 968 615,08
МК-00001856Экспорт 1 189 318,8 Сегмент1 1 189 318,8
МК-00001857Экспорт 1 160 673,14 Сегмент1 1 160 673,14
МК-00001860Экспорт 779 552,41 Прочие 779 552,41
МК-00001861Экспорт 2 041 707,03 Прочие 2 041 707,03
МК-00001870Внутренний рынок 765 162,61 Прочие 765 162,61
МК-00001871Внутренний рынок 53 176,95 Сегмент1 53 176,95

Использовался полностью аналогичный код:

ВЫБРАТЬ
    СУММА(Данные.База) КАК СуммаБазы ,
    Данные.ОперационныйСегмент
ПОМЕСТИТЬ Итог
ИЗ
    Данные КАК Данные
СГРУППИРОВАТЬ ПО Данные.ОперационныйСегмент

;
///////////////////////////////////////////////////

ВЫБРАТЬ
    Данные1.Объект КАК Объект,
    Данные1.ОперационныйСегмент  КАК ОперационныйСегмент,
    ВЫРАЗИТЬ(Данные1.База КАК ЧИСЛО(15, 2)) КАК База,
    ВЫРАЗИТЬ(ЕСТЬNULL(СУММА(Данные2.База), 0) КАК ЧИСЛО(15, 2)) КАК БазаНакопленная
ПОМЕСТИТЬ ДанныеСНакоплением
ИЗ
    Данные КАК Данные1
        ЛЕВОЕ СОЕДИНЕНИЕ Данные КАК Данные2
        ПО Данные1.Объект > Данные2.Объект
        	И Данные1.ОперационныйСегмент = Данные2.ОперационныйСегмент

СГРУППИРОВАТЬ ПО
    Данные1.Объект,
    Данные1.База  ,
    Данные1.ОперационныйСегмент
;
////////////////////////////////////////////////////////////­////////////////////


ВЫБРАТЬ
   Данные.Объект, 
    Данные.База,
    Данные.ОперационныйСегмент,
    (ВЫРАЗИТЬ(ВТ_УправленческиеРасходы_Распределяемые.УправленческиеРасходы_Распределяемые * (Данные.БазаНакопленная + Данные.База) / Итог.СуммаБазы КАК ЧИСЛО(15, 2))) 
    - (ВЫРАЗИТЬ(ВТ_УправленческиеРасходы_Распределяемые.УправленческиеРасходы_Распределяемые * Данные.БазаНакопленная / Итог.СуммаБазы КАК ЧИСЛО(15, 2))) КАК РаспределеноПоБазе
ПОМЕСТИТЬ ВТ_РаспределеноПоБазе
ИЗ
    ДанныеСНакоплением КАК Данные 
    ЛЕВОЕ СОЕДИНЕНИЕ Итог КАК Итог
    ПО Итог.ОперационныйСегмент = Данные.ОперационныйСегмент
    ЛЕВОЕ СОЕДИНЕНИЕ ВТ_УправленческиеРасходы_Распределяемые КАК ВТ_УправленческиеРасходы_Распределяемые
    ПО ВТ_УправленческиеРасходы_Распределяемые.ОперационныйСегмент =  Итог.ОперационныйСегмент
 
Показать

Но если сначала округлить значения таблицы Данные до 15,2 , то алгоритм начинает работать.
Оставьте свое сообщение
Новые вопросы с вознаграждением
Автор темы объявил вознаграждение за найденный ответ, его получит тот, кто первый поможет автору.

Вакансии

Ведущий программист 1С
Омск
зарплата от 70 000 руб. до 110 000 руб.
Полный день

Программист 1С
Екатеринбург
зарплата до 120 000 руб.
Полный день

Консультант-аналитик 1С
Рязань
зарплата до 80 000 руб.
Полный день

Программист 1С
Рязань
зарплата от 90 000 руб.
Полный день

Бизнес-архитектор 1С, ведущий консультант
Санкт-Петербург
Полный день