Имя: Пароль:
1C
1C 7.7
v7: Вопрос по методологии - в производстве из-за округлений записает 0,001
0 Vladal
 
02.12.11
18:56
После распределения затрат и проведения окончательной калькуляции, на остатке материалов зависает количество 0,001.

Я уже в отладчике смотрел - количество распределяется на суммы затрат и при больших оборотах (стоимости) из-за округлений выпадает 0,001.

Оборот количества - несколько тысяч единиц. Суммы распределяются замечательно, построчно (3 проводки по сырью) арифметика тоже правильно считает.

Как бы это откорректировать?
Ручная операция не подходит - количество не убрать, например, на 00 счет, но и оставить переходящим тоже нельзя.

Может, при проведении рассчитывать остаток и сравнивать с количеством в проводке?

Решение "в лоб":

Разница = ОстатокНаСчете - КвоПроводки;
Если Разница <= 0.001 Тогда
   КвоПроводки = КвоПроводки + Разница;
КонецЕсли;
1 Vladal
 
02.12.11
18:58
Решение "в лоб" мне кажется неправильным.
2 Темный Эльф
 
02.12.11
18:58
А придумать алгоритм, который распределяет сумму пропорционально без потерь очень сложно?
3 aleks-id
 
02.12.11
18:59
не дело. я писал алгоритм, который при списании последнюю сумму и количество закрывал полностью под 0
4 Vladal
 
02.12.11
19:03
Выпустили асфальта 1500 тонн на несколько сот тысяч. Количество измеряется в тоннах. Построчно в отладчике я смотрел - при распределении затрат получается сумма, у которой в 4 знаке после запятой меньше 3. Например, 1234,56701

Вот формула:
КвоПроводки = ОКР(тз.Кво*СуммаБаза/Итог("СуммаБаза")
5 Темный Эльф
 
02.12.11
19:08
(4)Полагаю, это не единственные параметры? Есть некое количество или сумма, которые надо распределить, есть веса распределения. На каждой итерации промежуточный результат округляется. И на каждой итерации необходимо сделать поправку.
6 Vladal
 
02.12.11
19:09
Вот количенство из трех проводок:

КвоПроводки = 1546.34044
КвоПроводки = 1716.40728
КвоПроводки = 700.90528

Если их в таком виде сложить - то получается красиво - 3963,653.
Но в проводках точность количества до 3 знаков, и получается итого списано 3963,652.

Вот как раз эта разница и зависает - 0,001
7 Vladal
 
02.12.11
19:16
(5) Это те параметры, которые влияют на распределение количества.

Вычисление происходит непосредственно перед проводкой по приведенной формуле.
Потом записывается проводка и количество округляется в соответствии с точностью, заданной в конфигураторе
8 Темный Эльф
 
02.12.11
19:19
(6)Я обычно использую такой алгоритм. Есть число, которое надо распределить, Сумма, есть массив числе, пропорционально которым ее надо распределить ТЗ.НормаРаспределения. Пишу
К1=0;К2=0;
ТЗ.Выбратьстроки();
Пока ТЗ.получитьстроку()=1 цикл
если ТЗ.итог("НормаРаспределения")-К2=0 тогда
 продолжить;
конецесли;
ТЗ.Результат=окр((Сумма-К1)*ТЗ.НормаРаспределения/(ТЗ.итог("НормаРаспределения")-К2),2);
К1=К1+ТЗ.Результат;
К2=К2+ТЗ.НормаРаспределения;
конеццикла;
Всегда все распределяет до копейки :)
9 Vladal
 
02.12.11
19:28
Что-то начинаю въезжать...
Твоя НормаРаспределения - это у меня СуммаБаза?
10 Vladal
 
02.12.11
19:28
Твоя Сумма - это СуммаБаза из строчки?
11 Темный Эльф
 
02.12.11
19:28
(9)Похоже на то.
12 Темный Эльф
 
02.12.11
19:29
(10)Распределяешь ты, насколько понимаю тз.Кво
13 Vladal
 
02.12.11
19:30
да. Мне тз.Кво надо распределить
14 Темный Эльф
 
02.12.11
19:33
(13)Значит моя Сумма - это твое тз.КВо
15 Vladal
 
02.12.11
19:36
Не въеду в тз.Результат - с чем моим соединить? // туплю
16 Джинн
 
02.12.11
19:50
(8) Идея хороша, код кривой.
17 Темный Эльф
 
02.12.11
19:52
(16)Тебе никто не мешает предложить лучший.
18 Темный Эльф
 
02.12.11
19:53
(15)КвоПроводки, судя по коду.
19 Vladal
 
02.12.11
19:53
(16) Подскажи, что надо исправить?
Потому что я его к себье приспособил и у меня в результате получается то же. что и в проводке:

КвоПроводки = 1546.340
КвоПроводки = 1716.407
КвоПроводки =  700.905
20 Vladal
 
02.12.11
19:53
(18) Да, я так поставил, не помогло. Блин...
21 Джинн
 
02.12.11
19:54
Кошернее всего накапливать ошибку округления и скидывать ее на последнюю проводку. И чтобы не так заметно было - отсортировать ТЗ, чтобы в конце самая "жирная" сумма была. Количество строк в ТЗ известно, номер текущей строки тоже.

(17) Предлагаю ТЗ.итог("НормаРаспределения") за пределы цикла вынести.
22 Темный Эльф
 
02.12.11
19:56
(21.2)Каюсь. Часто грешен неоптимальным кодом.
23 Джинн
 
02.12.11
19:57
(22) Кто не грешен, то пусть кинет в меня камень :)
24 Anton_2011
 
02.12.11
19:57
"Часто грешен неоптимальным кодом" - да это фраза для Лурка для статьи Индусский код!!!
25 Джинн
 
02.12.11
19:59
(24) Коллега, на что способен Темный Эльф мы хорошо знаем. А вот на что способен Anton_2011 пока нет. Это я об индусском коде.
26 Vladal
 
02.12.11
20:00
(21) Идея!

ОшибкаОкругления = 0;

Цикл
...
ОшибкаОкругления = КвоПроводки - Окр(КвоПроводки)
// Итерация1: 1546.34044 - 1546,340 = 0,00044 ОшибкаОкругления = 0,00044
// Итерация2: 1716.40728 - 1716.407 = 0,00028 ОшибкаОкругления = 0,00044+0,00028
// Итерация3: 700.90528 - = 700.905 = 0,00028 ОшибкаОкругления = 0,00044+0,00028+0,00028
// Итерация3 - последняяСтрока, КвоПроводки = КвоПроводки+ОшибкаОкругления
...
КонецЦикла
27 Anton_2011
 
02.12.11
20:01
Вы не охринели в пятницу округлениями заниматься?
Давайте сразу дифференциал под интегралом возьмем в квадрате числа Пи равному 4-м!
28 Vladal
 
02.12.11
20:02
(27) Нет, не охренели. Нать закрыт mgthbjl
29 Vladal
 
02.12.11
20:02
*период
30 Vladal
 
02.12.11
20:02
(27) И того, солнце зашло, уже священный субботний покой начался.
31 Vladal
 
02.12.11
20:21
Метод из (26) навеянный (21) сработал.

В итоге получилось (трассировка проведения):
Строка 1 ОшибкаОкругления = 0.00044 Накопленная ошибка округления = 0.00044
Строка 2 ОшибкаОкругления = 0.00028 Накопленная ошибка округления = 0.00072
Строка 3 ОшибкаОкругления = 0.00028 Накопленная ошибка округления = 0.001
32 Vladal
 
02.12.11
20:22
Всем спасибо!
Вопрос закрыт.

----------------
Но можем еще поговорить на эту тему ;)