База знаний Одина — Одинэсника › Форумы › ODIN — Форум по 1С Предприятию › Как переработать функцию для распределения сумм по 20 колонкам? › Ответ в теме: Как переработать функцию для распределения сумм по 20 колонкам?
Вот переработанный вариант функции, который распределяет одну общую сумму пропорционально сумме по 20 колонкам «Сумма1», «Сумма2», …, «Сумма20» в каждой строке таблицы. Итог по каждой из этих колонок в результате будет равен исходной сумме к распределению.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
Функция РаспределитьПропорционально20(СуммаКРаспределению, ТаблицаБаза) Если ТаблицаБаза = Неопределено Или ТаблицаБаза.Количество() = 0 Тогда Возврат Новый ТаблицаЗначений; КонецЕсли; // Считаем общую сумму по всем 20 колонкам и всем строкам ОбщаяСумма = 0; Для Каждого Строка Из ТаблицаБаза Цикл Для НомерКолонки = 1 По 20 Цикл ИмяКолонки = "Сумма" + Формат(НомерКолонки, "ЧГ="); Если ТаблицаБаза.Колонки.Найти(ИмяКолонки) <> Неопределено Тогда ОбщаяСумма = ОбщаяСумма + ?(Строка[ИмяКолонки], 0); КонецЕсли; КонецЦикла; КонецЦикла; Если ОбщаяСумма = 0 Тогда // Если сумма базы 0, то возвращаем копию с нулями по всем колонкам Результат = ТаблицаБаза.Скопировать(); Для Каждого Строка Из Результат Цикл Для НомерКолонки = 1 По 20 Цикл ИмяКолонки = "Сумма" + Формат(НомерКолонки, "ЧГ="); Если Результат.Колонки.Найти(ИмяКолонки) <> Неопределено Тогда Строка[ИмяКолонки] = 0; КонецЕсли; КонецЦикла; КонецЦикла; Возврат Результат; КонецЕсли; // Создаем новую таблицу для результата с нужными колонками Результат = Новый ТаблицаЗначений; Результат.Колонки.Добавить("Показатель"); Результат.Колонки.Добавить("КодIC"); Для НомерКолонки = 1 По 20 Цикл Результат.Колонки.Добавить("Сумма" + Формат(НомерКолонки, "ЧГ="), Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2))); КонецЦикла; // Найдем индекс строки с максимальной общей суммой по 20 колонкам (для компенсации погрешности) МаксимальноеЗначение = -1; ИндексМаксимума = 0; Для НомерСтроки = 0 По ТаблицаБаза.Количество() - 1 Цикл Строка = ТаблицаБаза[НомерСтроки]; СуммаСтроки = 0; Для НомерКолонки = 1 По 20 Цикл ИмяКолонки = "Сумма" + Формат(НомерКолонки, "ЧГ="); Если ТаблицаБаза.Колонки.Найти(ИмяКолонки) <> Неопределено Тогда СуммаСтроки = СуммаСтроки + ?(Строка[ИмяКолонки], 0); КонецЕсли; КонецЦикла; Если СуммаСтроки > МаксимальноеЗначение Тогда МаксимальноеЗначение = СуммаСтроки; ИндексМаксимума = НомерСтроки; КонецЕсли; КонецЦикла; // Распределяем сумму пропорционально сумме по 20 колонкам в каждой строке СуммаРаспределена = 0; Для НомерСтроки = 0 По ТаблицаБаза.Количество() - 1 Цикл Строка = ТаблицаБаза[НомерСтроки]; НоваяСтрока = Результат.Добавить(); НоваяСтрока.Показатель = Строка.Показатель; НоваяСтрока.КодIC = Строка.КодIC; // Считаем сумму по 20 колонкам для текущей строки СуммаСтроки = 0; Для НомерКолонки = 1 По 20 Цикл ИмяКолонки = "Сумма" + Формат(НомерКолонки, "ЧГ="); Если ТаблицаБаза.Колонки.Найти(ИмяКолонки) <> Неопределено Тогда СуммаСтроки = СуммаСтроки + ?(Строка[ИмяКолонки], 0); КонецЕсли; КонецЦикла; // Распределяем пропорционально сумме строки Для НомерКолонки = 1 По 20 Цикл ИмяКолонки = "Сумма" + Формат(НомерКолонки, "ЧГ="); Если ТаблицаБаза.Колонки.Найти(ИмяКолонки) <> Неопределено Тогда ИсходноеЗначение = ?(Строка[ИмяКолонки], 0); Если ОбщаяСумма = 0 Тогда РаспределенноеЗначение = 0; Иначе // Пропорция по всей базе, умножаем на исходное значение колонки РаспределенноеЗначение = Окр(СуммаКРаспределению * ИсходноеЗначение / ОбщаяСумма, 2, Истина); КонецЕсли; НоваяСтрока[ИмяКолонки] = РаспределенноеЗначение; КонецЕсли; КонецЦикла; КонецЦикла; // Корректируем погрешность округления по каждой колонке, добавляя разницу в строку с максимальной суммой Для НомерКолонки = 1 По 20 Цикл ИмяКолонки = "Сумма" + Формат(НомерКолонки, "ЧГ="); СуммаКолонки = 0; Для НомерСтроки = 0 По Результат.Количество() - 1 Цикл СуммаКолонки = СуммаКолонки + ?(Результат[НомерСтроки][ИмяКолонки], 0); КонецЦикла; Разница = 0; Если СуммаКолонки <> 0 Тогда Разница = СуммаКРаспределению - СуммаКолонки; Иначе Разница = 0; КонецЕсли; Если Разница <> 0 Тогда Результат[ИндексМаксимума][ИмяКолонки] = Результат[ИндексМаксимума][ИмяКолонки] + Разница; КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции |
Кратко:
— Считаем сумму по всем 20 колонкам и всем строкам.
— Распределяем пропорционально каждой ячейке в колонках «Сумма1″… «Сумма20» от общей суммы.
— Округляем до 2 знаков.
— Корректируем погрешность округления по каждой колонке, добавляя разницу в строку с максимальной суммой по всем колонкам.
Если нужно, могу помочь с примером вызова.