База знаний Одина — Одинэсника › Форумы › ODIN — Форум по 1С Предприятию › Как использовать метод Итог() для оптимизации функции распределения? › Ответ в теме: Как использовать метод Итог() для оптимизации функции распределения?
24 апреля 2026 в 19:18
#36819
Вот переделанный вариант функции с использованием метода Итог() для подсчёта общей суммы по колонкам. Это позволяет убрать вложенные циклы для подсчёта общей суммы и упростить код:
1С (Код)
|
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 112 113 114 115 116 |
Функция РаспределитьПропорционально(СуммаКРаспределению, ТаблицаБаза, ИмяКолонкиБаза = "Сумма", КоличествоКолонок = 20) Если ТаблицаБаза = Неопределено Или ТаблицаБаза.Количество() = 0 Тогда Возврат Новый ТаблицаЗначений; КонецЕсли; // Считаем общую сумму по всем колонкам с помощью Итог() ОбщаяСумма = 0; Для НомерКолонки = 1 По КоличествоКолонок Цикл ИмяКолонки = ИмяКолонкиБаза + Формат(НомерКолонки, "ЧГ="); Если ТаблицаБаза.Колонки.Найти(ИмяКолонки) <> Неопределено Тогда ОбщаяСумма = ОбщаяСумма + ТаблицаБаза.Итог(ИмяКолонки); КонецЕсли; КонецЦикла; Если ОбщаяСумма = 0 Тогда // Если сумма базы 0, то возвращаем копию с нулями по всем колонкам Результат = ТаблицаБаза.Скопировать(); Для Каждого Строка Из Результат Цикл Для НомерКолонки = 1 По КоличествоКолонок Цикл ИмяКолонки = ИмяКолонкиБаза + Формат(НомерКолонки, "ЧГ="); Если Результат.Колонки.Найти(ИмяКолонки) <> Неопределено Тогда Строка[ИмяКолонки] = 0; КонецЕсли; КонецЦикла; КонецЦикла; Возврат Результат; КонецЕсли; // Создаем новую таблицу для результата с нужными колонками Результат = Новый ТаблицаЗначений; Результат.Колонки.Добавить("Показатель"); Результат.Колонки.Добавить("КодIC"); Для НомерКолонки = 1 По КоличествоКолонок Цикл Результат.Колонки.Добавить(ИмяКолонкиБаза + Формат(НомерКолонки, "ЧГ="), Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2))); КонецЦикла; // Найдем индекс строки с максимальной общей суммой по колонкам (для компенсации погрешности) МаксимальноеЗначение = -1; ИндексМаксимума = 0; Для НомерСтроки = 0 По ТаблицаБаза.Количество() - 1 Цикл Строка = ТаблицаБаза[НомерСтроки]; СуммаСтроки = 0; Для НомерКолонки = 1 По КоличествоКолонок Цикл ИмяКолонки = ИмяКолонкиБаза + Формат(НомерКолонки, "ЧГ="); Если ТаблицаБаза.Колонки.Найти(ИмяКолонки) <> Неопределено Тогда Если ЗначениеЗаполнено(Строка[ИмяКолонки]) Тогда СуммаСтроки = СуммаСтроки + Строка[ИмяКолонки]; КонецЕсли; КонецЕсли; КонецЦикла; Если СуммаСтроки > МаксимальноеЗначение Тогда МаксимальноеЗначение = СуммаСтроки; ИндексМаксимума = НомерСтроки; КонецЕсли; КонецЦикла; // Распределяем сумму пропорционально сумме по колонкам в каждой строке Для НомерСтроки = 0 По ТаблицаБаза.Количество() - 1 Цикл Строка = ТаблицаБаза[НомерСтроки]; НоваяСтрока = Результат.Добавить(); НоваяСтрока.Показатель = Строка.Показатель; НоваяСтрока.КодIC = Строка.КодIC; // Считаем сумму по колонкам для текущей строки СуммаСтроки = 0; Для НомерКолонки = 1 По КоличествоКолонок Цикл ИмяКолонки = ИмяКолонкиБаза + Формат(НомерКолонки, "ЧГ="); Если ТаблицаБаза.Колонки.Найти(ИмяКолонки) <> Неопределено Тогда Если ЗначениеЗаполнено(Строка[ИмяКолонки]) Тогда СуммаСтроки = СуммаСтроки + Строка[ИмяКолонки]; КонецЕсли; КонецЕсли; КонецЦикла; // Распределяем пропорционально сумме строки Для НомерКолонки = 1 По КоличествоКолонок Цикл ИмяКолонки = ИмяКолонкиБаза + Формат(НомерКолонки, "ЧГ="); Если ТаблицаБаза.Колонки.Найти(ИмяКолонки) <> Неопределено Тогда Если ЗначениеЗаполнено(Строка[ИмяКолонки]) Тогда ИсходноеЗначение = Строка[ИмяКолонки]; Иначе ИсходноеЗначение = 0; КонецЕсли; Если ОбщаяСумма = 0 Тогда РаспределенноеЗначение = 0; Иначе РаспределенноеЗначение = Окр(СуммаКРаспределению * ИсходноеЗначение / ОбщаяСумма, 2, Истина); КонецЕсли; НоваяСтрока[ИмяКолонки] = РаспределенноеЗначение; КонецЕсли; КонецЦикла; КонецЦикла; // Корректируем погрешность округления по каждой колонке, добавляя разницу в строку с максимальной суммой Для НомерКолонки = 1 По КоличествоКолонок Цикл ИмяКолонки = ИмяКолонкиБаза + Формат(НомерКолонки, "ЧГ="); СуммаКолонки = 0; Для НомерСтроки = 0 По Результат.Количество() - 1 Цикл Если ЗначениеЗаполнено(Результат[НомерСтроки][ИмяКолонки]) Тогда СуммаКолонки = СуммаКолонки + Результат[НомерСтроки][ИмяКолонки]; КонецЕсли; КонецЦикла; Разница = СуммаКРаспределению - СуммаКолонки; Если Разница <> 0 Тогда Если ЗначениеЗаполнено(Результат[ИндексМаксимума][ИмяКолонки]) Тогда Результат[ИндексМаксимума][ИмяКолонки] = Результат[ИндексМаксимума][ИмяКолонки] + Разница; Иначе Результат[ИндексМаксимума][ИмяКолонки] = Разница; КонецЕсли; КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции |
Теперь метод Итог() используется для подсчёта общей суммы по каждой колонке, что упрощает и ускоряет подсчёт.