Имя: Пароль:
1C
1С v8
Кто каким методом решил подобное?
,
0 happysan
 
21.06.22
13:30
Необходимо написать алгоритм для распределения суммы пропорционально количеству в таблице. Сумму для распределения пользователь вносит в реквизит формы, сумма может быть отрицательная или положительная. Проблема копеек должны быть решена.

Количество    Сумма
10    
13    
-5    
1.33    
100    
1    
20
1 Один С
 
21.06.22
13:33
Для Каждого Стр Из Таблицы
  Стр.Сумма = Стр.Количество / ОбщееКоличество * ОбщаяСумма;
КонецЦикл
2 Гипервизор
 
21.06.22
13:39
(0) Функции распределения типовых конфигураций не предлагать?
3 happysan
 
21.06.22
13:40
(2) Можно
4 RomanYS
 
21.06.22
13:45
(3) РаспределитьПропорционально ищи в типовых
5 Гипервизор
 
21.06.22
13:48
6 lodger
 
21.06.22
13:48
писал такой велосипед в нетиповой.
вроде всё банально? по правилам математики берешь и делишь сумму в пропорции.
7 VoditelKobyly
 
21.06.22
13:56
к (1) добавить накопленную сумму по строкам и если последняя строка, то:
Стр.Сумма = ОбщаяСумма-НакопленнаяСумма;
8 happysan
 
21.06.22
14:15
(7) Напишешь полностью то, что имеешь в виду в итоге?
9 nicxxx
 
21.06.22
14:17
(0) это что, тестовое задание на собеседовании? :)
10 mikecool
 
21.06.22
14:18
(7) а можно и выпендриться - в проходе выявлять строку с мин и макс суммой
дельту, если меньше нуля - добавить к мин сумме, больше нуля - отнять от максимальной
11 Garykom
 
гуру
21.06.22
14:26
(0) количество это количество или % ?
12 happysan
 
21.06.22
15:13
(11) Количество.
13 Lama12
 
21.06.22
16:18
(5) Плохой алгоритм. В ERP стандартный очень хороший.
14 Гипервизор
 
21.06.22
16:22
(13) Данная функция из БСП. В ERP другая?
15 Lama12
 
21.06.22
16:42
(14) Мда, раньше там другая была. Через вычитания. В ней не могло быть погрешности в конце распределения. И почему-то мне казалось что она дает более равномерное распределение погрешности в один проход.
16 happysan
 
21.06.22
17:19
В итоге есть (1), (5), (7) и (13). 1 и 5 отметаем? Что в них не так?
17 bolobol
 
21.06.22
17:51
В (5) не допускается отрицательное среди положительных, да и что оно означает? Забрать вместо распределить?
А в (1) - идеальный алгоритм, если б не минус пять в количестве
18 Гипервизор
 
21.06.22
18:03
(15)(16) Это типа как в (4) в "старых" типовых?

Функция РаспределитьПропорционально(Знач ИсхСумма, МассивКоэф, Знач Точность = 2, ПроверкаНулевыхЗначений=Истина) Экспорт

    Если МассивКоэф.Количество() = 0 Или (ПроверкаНулевыхЗначений И ИсхСумма = 0) Или ИсхСумма = Null Тогда
        Возврат Неопределено;
    КонецЕсли;

    СуммаКоэф  = 0;

    Для К = 0 По МассивКоэф.Количество() - 1 Цикл
        СуммаКоэф = СуммаКоэф + МассивКоэф[К];
    КонецЦикла;

    Если СуммаКоэф = 0 Тогда
        Возврат Неопределено;
    КонецЕсли;

    МассивСумм = Новый Массив(МассивКоэф.Количество());

    Для К = 0 По МассивКоэф.Количество() - 1 Цикл
        МассивСумм[К] = ?(СуммаКоэф <> 0, Окр(ИсхСумма * МассивКоэф[К] / СуммаКоэф, Точность, 1), 0);
        ИсхСумма = ИсхСумма - МассивСумм[К];
        СуммаКоэф = СуммаКоэф - МассивКоэф[К];
    КонецЦикла;

    Возврат МассивСумм;

КонецФункции
19 RetardedToBoot
 
21.06.22
18:05
(0) программисты уже не те...
20 RetardedToBoot
 
21.06.22
18:06
Даже название темы оформить не могут.
21 Lama12
 
21.06.22
18:15
(18) Да, мне этот вариант больше нравится.
22 RomanYS
 
21.06.22
19:17
Чтобы сделать задачу интереснее нужно добавить требование минимального отклонения округленных значений от неокругленных.
Мера отклонения - сумма квадратов отклонений.
Вроде ни одно из приведенных решений это не гарантирует, хотя в большинстве случаев (18) будет удовлетворять, но контрпример придумать не сильно сложно (кстати это отдельная интересная задачка)
23 timurhv
 
21.06.22
19:30
(21) Нет контроля остатка от округлений.
24 Said_We
 
21.06.22
19:42
Вот заняться не чем.
Распределите сумма 42 по таблице чисел:

10
20
-15
-5
0
-10

Общая сумма = 0, но это не означает что 42 нельзя размазать по этим коэффициентам. При этом количество вариантов это не одно решение.
Уже на этом форуме по моему данная задача была не раз
25 rudnitskij
 
21.06.22
20:21
(0) Делал похожее людям, для решения по копейкам суммировал распределенные суммы, а в последней строке не умножал на количество, а в "сумму" писал разность общей суммы и распределенной по строкам выше
ЗЫ. Если количество может быть отрицательным - надо еще предусмотреть ошибку деления на ноль. Код писать не буду, его и школьник напишет
26 RomanYS
 
21.06.22
20:23
(23) автоматически происходит, ты же каждый раз остаток распределяет
(24) математически нельзя распределить пропорционально по нулевой базе. А значит и с округлением задача смысла не имеет - у тебя просто не будет критериев оценки решения
27 rudnitskij
 
21.06.22
20:23
(24) наверное, вот данном случае не получится размазать 42 пропорционально. Будет либо не пропорционально, либо не 42
28 ДедМорроз
 
21.06.22
20:35
(27) всегда можно решить задачу
Сумма(Ai)=СуммаРаспределения
При условии
Сумма((Ai*Kj-Aj*Ki)^2) минимальна.
29 ДедМорроз
 
21.06.22
20:36
И очевидно,что вся сумма уходит в значение с нулевым коэффициентом.
30 RomanYS
 
21.06.22
20:37
(28) странная формула.
31 RomanYS
 
21.06.22
20:37
(29) ?
32 Злопчинский
 
21.06.22
21:41
Все уже спиз.. решено до нас...
https://infostart.ru/public/16630/
33 RomanYS
 
21.06.22
22:10
(32) вся суть ИС: типа статья типа по математике, но кода нет, только обработки по подписке.
И да вариант 4. как раз про (22)
34 Злопчинский
 
21.06.22
22:42
(33) "только обработки по подписке."
- а кто сказал что будет легко?
понятно, что 70 рублей от души оторвать жаба не дает...
35 Злопчинский
 
21.06.22
22:42
;-)
36 RomanYS
 
21.06.22
22:53
(34) заплатить за то, чтобы поковыряться в чужом г.? Это же заведомо не готовое решение, а академический материал для обсуждения (иначе нафига там 4 варианта). Моя жаба такое точно не пропустит)
И что-то подсказывает, что там нет тарифов по 70 руб))
37 Злопчинский
 
21.06.22
23:42
(36) ну дык возми типовую конфигу с заведомо готовым решением, никто ж не ограничивает.. ;-)
38 Злопчинский
 
21.06.22
23:42
(36) стоимость обработки = 1см.
39 RomanYS
 
21.06.22
23:58
(37) представленные здесь типовые решения, не удовлетворяют (22). А иногда это реально может быть реально важно, хот наверное ооочень редко))
Ну и интерес чисто академический, в формулировке (22) имеет минимальную сложность, остальное вообще не интересно.
40 Один С
 
22.06.22
09:17
Оптимизировал. Теперь учитывается нулевая база и минуса.

Для Каждого Стр Из Таблицы
  Стр.Сумма = Стр.Количество / ?(ОбщееКоличество=0, 1, ОбщееКоличество) * ОбщаяСумма;
КонецЦикл
41 RomanYS
 
22.06.22
09:39
(40) офигеть оптимизация. В случае с 0 распределить у тебя не получилось). Ну и вся суть задачи во фразе "проблема копеек должны быть решена", которую ты проигнорировал.
42 Один С
 
22.06.22
10:01
(41)
В случае 0 всё прекрасно распределяется, можешь проверить.
А по поводу копеек, ВодительКобылы в (7) уже написал, что надо делать с копейками.

НакопленнаяСумма = 0;
Для Каждого Стр Из Таблица
  Если Стр.НомерСтроки = Таблица.Количество() Тогда
     Стр.Сумма = ОбщаяСумма-НакопленнаяСумма;  
  Иначе
     Стр.Сумма = ОКР(Стр.Количество / ?(ОбщееКоличество=0, 1, ОбщееКоличество) * ОбщаяСумма, 2);
  КонецЕсли;
  НакопленнаяСумма = НакопленнаяСумма + Стр.Сумма;
КонецЦикл
43 Мультук
 
гуру
22.06.22
10:06
Народ с умным видом разбирает задачу на 5-6 строк.
Спорит и ищет решение.

После этого обижается на слова "1С-ники  не программисты" (тема отдельная недавно была)
44 RomanYS
 
22.06.22
10:12
(42)
1. Проверил. Пример: распредели 1 по базе (1, -1)
2. По поводу копеек: интересно получить решение удовлетворяющее (22) (более подробно описано как вариант 4 в (32)). Засунуть ошибки в последнюю строку иногда не вариант.
45 Мимохожий Однако
 
22.06.22
10:15
(43) Так и есть. Одинэсники не программисты, а разработчики )
46 Один С
 
22.06.22
10:20
(44) Да всё норм.
Это как с зарплатой.
В твоем примере всю сумму заберет Первый.
Первому начислят 1,
А когда у Второго вычтут 1, тогда в сумме работодатель выйдет в ноль (но это будет потом).
47 RomanYS
 
22.06.22
10:36
(46) >>  работодатель выйдет в ноль
Так надо было распределить 1, а не выйти в 0
48 Мимохожий Однако
 
22.06.22
10:40
Ветка напомнила следующее рассуждение бухгалтера: "Интересно, кто нибудь сможет получить цену одного яблока, если купили за рубль три штуки? А в накладной указать цену так, чтобы в результате умножения цены на 3 получить тот же рубль."
Дальше ступор ))
49 timurhv
 
22.06.22
10:47
(26) >автоматически происходит, ты же каждый раз остаток распределяет
Увидел, такое округление не надо. Получается в питании и прочих производствах с малым количеством какого-то коэффициента получится в конце неадекватная сумма.
Условно 1 кг дорогой вырезки мяса + куча дорогих продуктов и 1г специй. Есть вероятность получить сумму в конце на специи как за целый килограмм.

В БСП как-раз ошибки округления распределяются на самые большие коэффициенты.
50 RomanYS
 
22.06.22
10:50
(49) ты неправильно понимаешь. Этот алгоритм гарантирует, что по каждой строчке ошибка будет меньше копейки. А вот БСП повесит всю ошибку на одну строку.
51 timurhv
 
22.06.22
10:58
(50) Получается: 10р за 1кг соли, 1г = 0.01р. После распределения = 0.02р?
52 Bigbro
 
22.06.22
10:59
делал аналогично 3му методу из (32)
до 4го не дошел, всех устроило)
53 Said_We
 
22.06.22
11:08
Раскидать сумму по месяцам.

Я же говорил что уже было когда-то....
И это не единственный раз. Периодичность данного вопроса на мисте - регулярно :-)
54 RomanYS
 
22.06.22
11:20
(51) не очень понял. Где база в твоем примере?
Вот например нужно распределить 2 копейки по базе (1,1,1,1,1).
алгоритм с остатком даст (0,1,0,1,0) (в данном случае это "идеально")
БСП даст (0,0,0,0,2)
55 Said_We
 
22.06.22
11:22
56 Said_We
 
22.06.22
11:23
В (53) ссылка не открывается...
В (55) открывается.
57 Said_We
 
22.06.22
11:29
58 Said_We
 
22.06.22
11:30
Это вообще ветка от 2012 года
2 + 2 = 3.9999999999999999999999999999999...