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
* Переупорядочить имена векторов в файле данных.

* Это очень удобно, если у нас есть "вектор" переменных вроде a1 TO a50, b1 TO b50, c1 TO c50.
* и мы хотим переупорядочить их как a1 b1 c1 a2 b2 c2 ... a50 b50 c50.
* Автор: Raynald Levesque, 28.04.2001.

* Такие преобразования могут потребоваться, например, если данные удобнее вводить с опросных листов как a1 - a50, а обрабатывать - логическими триадами a1 b1 c1, a2 b2 c2 и т.д. Макрос адски хитрый. В нём цикл !DO запускается как часть параметра команды MATCH FILES, т.е. автор грамотно использует ту особенность макросов, что они преобразуются в файл синтаксиса строчка за строчкой (разворачиваются с учётом переданных параметров, "expanding") и лишь затем исполняются. - А.Б.

DATA LIST LIST /dummy.
BEGIN DATA
1
END DATA.
LIST.

* Следующие вектора задаются "последовательно" (все "a", все "b", затем все "c").
NUMERIC id x y a1 TO a50 z1 b1 TO b50  z2 c1 TO c50 k.
* Допустим, мы хотим переупорядочить их в "триады" a b c, т.е. a1 b1 c1 a2 b2 c2 ... a50 b50 c50.
SET MPRINT=yes.

*//////////////////////.
DEFINE !reorder (id=!TOKENS(1) /beg !TOKENS(1) / end !TOKENS(1) /vnames !CMDEND)
MATCH FILES FILE=* /KEEP=!id !DO !i=!beg !TO !end !DO !var !IN (!vnames) !CONCAT(!var,!i," ") !DOEND !DOEND ALL.
!ENDDEFINE.
*//////////////////////.

* Пример вызова макроса.

!reorder id=id beg=1 end=50 vnames=a b c.
EXECUTE.

**********************.
*** Пояснения***.
**********************.

* Следующая запись помогает понять запись цикла !DO - !END выше, 
*!DO !i=!beg !TO !end 
*	!DO !var !IN (!vnames) 
*		!CONCAT(!var,!i," ") 
*	!DOEND 
*!DOEND
*ALL.

* ALL означает сохранение всех переменных, не упомянутых выше.
* В макросе цикл !DO записан в строку, чтобы уменьшить количество строк синтаксиса при "развёртывании" макроса.
* Обратите внимание, что макро команды не нуждаются в разделителе (точке) в конце. В частности, если точки будут вставлены после
!DO !i=!beg !TO !end
например, макрос более не будет работать! Происходит это от того, что точка принудительно завершает выполнение команды MATCH FILES.