База знаний Одина — Одинэсника › Форумы › ODIN — Форум по 1С Предприятию › Как оптимизировать функцию с параметрами ИмяКолонки и КоличествоКолонок? › Ответ в теме: Как оптимизировать функцию с параметрами ИмяКолонки и КоличествоКолонок?
24 апреля 2026 в 19:14
#36817
Вот оптимизированный вариант функции с параметрами:
— ИмяКолонкиБаза — базовое имя колонки, например, «Сумма»
— КоличествоКолонок — количество колонок, например, 20
Функция автоматически формирует имена колонок: «Сумма1», «Сумма2», …, «СуммаN».
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 117 118 119 120 |
Функция РаспределитьПропорционально(СуммаКРаспределению, ТаблицаБаза, ИмяКолонкиБаза = "Сумма", КоличествоКолонок = 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 Тогда Если ЗначениеЗаполнено(Результат[ИндексМаксимума][ИмяКолонки]) Тогда Результат[ИндексМаксимума][ИмяКолонки] = Результат[ИндексМаксимума][ИмяКолонки] + Разница; Иначе Результат[ИндексМаксимума][ИмяКолонки] = Разница; КонецЕсли; КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции |
Теперь можно вызвать, например:
1С (Код)
|
1 |
РаспределитьПропорционально(10000, МояТаблица, "Сумма", 20); |
Или, если колонки называются «СуммаОтгрузки1», «СуммаОтгрузки2» и т.п.:
1С (Код)
|
1 |
РаспределитьПропорционально(5000, МояТаблица, "СуммаОтгрузки", 10); |
Функция универсальна и легко настраивается под любое количество и базовое имя колонок.