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
* Удаление наблюдений со сторнированными суммами.

* Дано: записи, содержащие код клиента (clientid), дату записи (date)
  и некоторые суммы (sum). Некоторые записи содержат отрицательные
  (сторнированные) суммы.

* Требуется: удалить из данных пары записей "исходная сумма / сторно" в 
  случае, если сторнирование было сделано для того же клиента, тем же числом
  и в той же сумме, что и исходная сумма.

* Примечание: в данных могут встречаться пропуски; записи с пропущенными значениями
  не должны быть удалены. Для одного и того же клиента на одну и ту же дату может
  быть несколько пар "исходная сумма / сторно". Например, для клиента №3 в примере ниже
  имеется 6 записей на сумму 543 от 08.10.2007, причём 4 из них должны быть удалены,  
  так как являются парами "исходная сумма / сторно", а 2 записи на сумму 543 (непарные)
  не удаляются.

* Пример данных: .

DATA LIST LIST /clientid (F8.0) date (EDATE9) sum (F8.2).
BEGIN DATA
3 08.10.2007 543
2 08.10.2007 5664
35 14.10.2007 4555
3 08.10.2007 -543
3 08.10.2007 543
3 08.10.2007 -543
3 08.10.2007 744
2 08.10.2007 4566
35 09.10.2007 120
35 14.10.2007 -4555
3 08.10.2007 543
3 08.10.2007 .
3 08.10.2007 543
3 08.10.2007 -5
. 14.09.2007 .
. 17.10.2007 553
. 17.10.2007 553
. 17.10.2007 -553
. 17.10.2007 -553
2 08.10.2007 -543
39 14.10.2007 -4555
END DATA.


* Пронумеруем одинаковые суммы в пределах одной и той же даты отдельно по каждому клиенту.
* (записи с пропусками всегда имеют order = 1, так как неизвестен результат сравнения в выражении IF).
SORT CASES BY clientid date sum.
COMPUTE order=1.
IF clientid=Lag(clientid) And date=Lag(date) And sum=Lag(sum) order=Lag(order)+1.

* Пометим "парные" записи "исходная сумма / сторно".
COMPUTE abssum=Abs(sum).
SORT CASES BY clientid date abssum order.
COMPUTE casenum=$casenum.
* (записи с пропусками не помечаются, так как неизвестен результат сравнения в выражении IF).
IF clientid=Lag(clientid) And date=Lag(date) And abssum=Lag(abssum) And order=Lag(order) mark=1.
SORT CASES BY casenum (D).
COMPUTE dmark=Lag(mark).
EXECUTE.
COMPUTE mark=Sum(0, mark, dmark).
EXECUTE.

* Отберём только неотмеченные записи.
SELECT IF mark = 0 .

* Уберём лишние переменные.
ADD FILES FILE=* /DROP order mark dmark abssum casenum.