Имя: Пароль:
1C
 
Помогите придумать алгоритм по "свертке" ТЗ
,
0 vip03
 
17.02.16
07:35
Есть ТЗ, для простоты с тремя колонками:
Док, СуммаДолга, СуммаОплаты.

Док1   10   0
Док2   10   0
Док3   0   10
Док4   0   15
Док5   10   0

Из этой ТЗ нужно оставить только те строки, по которым останется долг или оплата по ФИФО.
Док3 полностью гасит Док1. Док4 полностью гасит Док2 и частично Док5. В результате в ТЗ должно остаться:

Док5   5   0

Натолкните на мысль. Уже мозги закипают...
1 НЕА123
 
17.02.16
07:43
сворачивай ТЗ.
документ - всегда последний.
кол1= макс(0,сумма(кол1)-сумма(кол2));
кол2= макс(0,сумма(кол2)-сумма(кол1));
2 patria0muerte
 
17.02.16
07:46
Добавь в ТЗ колонки "Док. погашения" и "Порядок" (либо без порядка, по дате ориентируйся). Заполни: Должно получиться что то типа:

Док1   10   0  Док3 1
Док2   10   0  Док4 1
Док3   0   10  
Док4   0   15  
Док5   10   0  Док4 2

ИМХО: А лучше вообще разнеси по разным таблицам - так наглядней будет. Отдельно долги, отдельно оплаты. И закрывай долги по ФИФО циклом по двум таблицам.
3 mehfk
 
17.02.16
07:51
(0) Получить итоги по двум колонкам, вычесть один итог из другого и потом циклом с конца подобрать доки.
4 vip03
 
17.02.16
07:53
(1) что значит "документ - всегда последний."?
если будет еще 1 строка:
Док6   10   0

то в итоге должно остаться:
Док5    5   0
Док6   10   0
5 YurAnt
 
17.02.16
07:54
(2) + к идее о разных таблицах.
как вариант - сверни таблицу
скажем итог:
СуммаДолгаВсего = 150, СуммаОплаты = 120

т.е. превышение на 30.
ищем доки которые вызвали превышение (нам ведь нужны последние документы, ибо "не последние" закрывали соответствующие суммы с противоположным знаком)

т.е. если долг превышает на 30, в обратном порядке доки по долгу где сумма >= 30

ну это метод в лоб...
возможно, если подумать можно и более изящно сделать
6 YurAnt
 
17.02.16
07:56
(5) "т.е. если долг превышает на 30, в обратном порядке доки по долгу где сумма >= 30 "

поправка: пока накопительный итог не станет >= 30
7 Смотрящий
 
17.02.16
08:00
(0) Все ж украдено до нас.
Тебе нужна таблица вида
Док1   10
Док2   10
Док5   10
И общий итог по СуммаОплаты

Ну и циклом выбирать и удалять из таблицы доки, уменшением итога по СуммаОплаты до 0
8 НЕА123
 
17.02.16
08:01
(4)
да.
тогда нах "документ - всегда последний." из (1).

ну и типа:
ищем доки с конца для погашения.
сумму последнего корректируем.
9 НЕА123
 
17.02.16
08:03
(8) это собственно (5),(6).
10 patria0muerte
 
17.02.16
08:06
Блин, чет подумал, что у тебя доки оплаты к конкретным документам задолженности привязаны. Так - да, смотри прочих ораторов, они дело говорят.
11 vip03
 
17.02.16
08:20
(10) они ДОЛЖНЫ быть привязаны. но по какой-то причине НЕ привязаны. нужно исправить этот косяк...

Пока делаю как в (2) ИМХО: А лучше вообще разнеси по разным таблицам - так наглядней будет. Отдельно долги, отдельно оплаты. И закрывай долги по ФИФО циклом по двум таблицам.

т.к. может остаться не только документ долга, но и документ предоплаты...
12 kosts
 
17.02.16
08:46
(11) Для упрощения алгоритма, 2 таблицы.

Таблица 1
Док, Долг, РазнесеннаяОплата
В РазнесеннаяОплата предварительно заполнено нулем.

Таблица 2
Док, Оплата, НеРазнесеннаяОплата
В НеРазнесеннаяОплата предварительно равна оплате.

Схема алгоритма - разнести суммы из НеРазнесеннаяОплата в РазнесеннаяОплата, не изменяя Долг и Оплата.

Обходя таблицу 1, ищем в таблице 2 документы, где в колонке НеРазнесеннаяОплата не ноль.
Найдя такой документ: вычисляем размер суммы, которую можно разнести.
Затем РазнесеннаяОплата увеличиваем на эту сумму.
Затем НеРазнесеннаяОплата уменьшаем на эту сумму.
Если Долг < РазнесеннаяОплата продолжаем поиск по Таблице 2.
Если Долг = РазнесеннаяОплата переходим на следующий документ по Таблице 1.
13 Лефмихалыч
 
17.02.16
09:07
Задача сводится к двум запросам:
1. Получить последний документ из выборки
2. Получить (СУММА(СуммаДолга) - СУММА(СуммаОплаты))

пункт 2 выводить в сумму долга, если она больше нуля, и в сумму оплаты, если - меньше (но с минусом)
14 Лефмихалыч
 
17.02.16
09:07
можно одним запросом, но тогда в нем будет ВЫБОРКОГДАТОГДА в полях сумм
Выдавать глобальные идеи — это удовольствие; искать сволочные маленькие ошибки — вот настоящая работа. Фредерик Брукс-младший