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
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
*** This is part of the SPSS Macro tutorials found in page
	http://spsstools.net/macros/learning-macros#ReplacingChrInManyVars
***.


*****************.
*EXAMPLE 1.
*****************.

** Create a data file to work with.
INPUT PROGRAM.
LOOP id=1 TO 3.
VECTOR var(100A8).
LOOP cnt=1 TO 100.
COMPUTE var(cnt)="txt.abc".
END LOOP.
END CASE.
END LOOP.
END FILE.
END INPUT PROGRAM.
EXECUTE.

* The following approach using a loop does NOT work because SUBSTR needs an actual variable name. 
* It does not recognize the vector v(cnt) as a variable name.
VECTOR v=var1 TO var100. 
LOOP cnt=1 TO 100. 
+ LOOP IF INDEX(v(cnt),".")>0. 
+ COMPUTE SUBSTR(v(cnt),INDEX(v(cnt),"."),1)=",". 
+ END LOOP. 
END LOOP. 
EXECUTE. 

* Using DO REPEAT does work. 
DO REPEAT v=var1 TO var100. 
LOOP IF INDEX(v,".")>0. 
+ COMPUTE SUBSTR(v,INDEX(v,"."),1)=",". 
END LOOP. 
END REPEAT. 
EXECUTE. 

* The following macro solution also works. 
* Re-create data file.
INPUT PROGRAM.
LOOP id=1 TO 3.
VECTOR var(100A8).
LOOP cnt=1 TO 100.
COMPUTE var(cnt)="txt.a.bc".
END LOOP.
END CASE.
END LOOP.
END FILE.
END INPUT PROGRAM.
EXECUTE.

SET MPRINT=no. 
*/////////////////////. 
DEFINE !replace (vname=!TOKENS(1)
	/nbvars=!TOKENS(1)
	/oldchar=!TOKENS(1)
	/newchar=!TOKENS(1))
* To replace a character in many string variables.
!DO !cnt=1 !TO !nbvars 
LOOP IF INDEX(!CONCAT(!vname,!cnt),!oldchar)>0.
+ COMPUTE SUBSTR(!CONCAT(!vname,!cnt),INDEX(!CONCAT(!vname,!cnt),!oldchar),1)=!newchar. 
END LOOP. 
!DOEND 
EXECUTE. 
!ENDDEFINE. 
*/////////////////////. 

SET MPRINT=yes. 
* The macro is called as follows.
!replace vname=var nbvars=100 oldchar='.' newchar=','. 


*****************.
*EXAMPLE 2.
*****************.

*Assume variables have unrelated names but are consecutive in the data file 
	(for instance vara, name, address, ..., product are consecutive in the data file).

* The most convenient way to handle this situation is when one has simply to give to a macro 
	the name of the 	first and last variables which have to be processed.
* One of the macro Gems (see "Define list of variables between two variables.SPS" 
	in http://pages.infinit.net/rlevesqu/Macros.htm#MacroGems) can then be used.

* Create a data file.
INPUT PROGRAM.
LOOP id=1 TO 3.
STRING strone text34 str2 beta gamma alpha (A8).
DO REPEAT var=strone text34 str2 beta gamma alpha.
COMPUTE var="txt.ab.c".
END REPEAT PRINT.
END LOOP.
END CASE.
END FILE.
END INPUT PROGRAM.
EXECUTE.
SAVE OUTFILE='c:\temp\testdata.sav'.

* Supppose we want to process variables between text34 and gamma inclusively. This solution assumes we
	have hundreds of variables between these 2 variables. It is not convenient to list them manually. 
* Note however that the following soltuion can also be used when you know that all variables after a given 
	variables need to be processed but you do not know ahead of time the name of the last variable,
	in that case you simply create a new string variable and use that name as the "ending variable".

* Note: when you save the macro Gem in your macro folder, keep ONLY the macro definition, in
	other words, delete the data definition and the example of macro call,
INCLUDE FILE='c:\Program Files\SPSS\macros\DefineListOfVariablesBetweenTwoVariables.SPS'.

* Call the macro Gem to define a macro which gives the list of all variables between the 2 given variables.
!DefList var1=text34 var2=gamma fname='c:\temp\testdata.sav'.

* The macro is called as follows.
SET MPRINT=yes.
!rep_chr oldchar='.' newchar=',' vnames=!list1. 

* See Example 4 below for the definition of the macro !rep_chr.


*****************.
*EXAMPLE 3.
*****************.
*Assume variables have unrelated names; that they are NOT consecutive in the data file; 
	that variables which are between the first and last string variables and do not have to 
	be processed are all NUMERICS.

* The same solution as in EXAMPLE 2 can be used.


* Create a data file.
INPUT PROGRAM.
LOOP id=1 TO 3.
STRING strone text34 str2 beta gamma (A8).
DO REPEAT var=strone text34 str2 beta gamma.
COMPUTE var="txt.ab.c".
END REPEAT PRINT.
END LOOP.
END CASE.
END FILE.
END INPUT PROGRAM.
EXECUTE.
* create a numeric variable between the first and last string variables.
COMPUTE numvar=2.
STRING alpha(A8).
COMPUTE alpha="txt.a.b.c".
SAVE OUTFILE='c:\temp\testdata.sav'.

INCLUDE FILE='c:\Program Files\SPSS\macros\DefineListOfVariablesBetweenTwoVariables.SPS'.

* Call the macro Gem to define a macro which gives the list of all variables between the 2 given variables.
!DefList var1=text34 var2=alpha fname='c:\temp\testdata.sav'.

* The macro is called as follows.
SET MPRINT=yes.
!rep_chr oldchar='.' newchar=',' vnames=!list1. 

* Note that *errors* will occur when the macro attempts to modify the numeric variables (variable numvar), as
	a result of that error, the command will not be executed. We do not care since we did not intend to modify 
	numeric variables in any event.

* See Example 4 below for the definition of the macro !rep_chr.


*****************.
*EXAMPLE 4.
*****************.
* In this case, the names of each string variable which needs to be processed must be explicitely given to the macro.
INPUT PROGRAM.
LOOP id=1 TO 3.
STRING strone text34 str2 alpha (A8).
DO REPEAT var=strone text34 str2 alpha .
COMPUTE var="txt.ab.c".
END REPEAT PRINT.
END LOOP.
END CASE.
END FILE.
END INPUT PROGRAM.
EXECUTE.

* A macro can be used. 
SET MPRINT=no. 
*/////////////////////. 
DEFINE !rep_chr(oldchar=!TOKENS(1) 
	/newchar=!TOKENS(1)
	/vnames=!CMDEND) 
/* To replace a character in many string variables */ 
!DO !vname  !IN  (!vnames) 
LOOP IF INDEX(!vname,!oldchar)>0.
+ COMPUTE SUBSTR(!vname,INDEX(!vname,!oldchar),1)=!newchar. 
END LOOP. 
!DOEND 
EXECUTE. 
!ENDDEFINE. 
*/////////////////////. 


* Assume we want to replace all dots by commas in the last 3 variables.
* The macro is called as follows.
SET MPRINT=yes.
!rep_chr oldchar='.' newchar=',' vnames=text34 str2 alpha .