I am trying to write a macro that extracts a defined part of strings stored in a variable. As I intend to use the macro on different variables, I pass the variable from which I get the string as an argument to my macro.
My Problem is that char.substr()
does not work in macros and !SUBSTR
won't work as expected, because it does not take a substring of the variable values. Instead it takes a substring of the variable name.
If I pass VAR1 as an argument to my macro it throws an error, because it subsets VAR1 to "VA" and then tries to assign the values of a (non-existing) variable "VA" to OUT2. At least I guess that's the problem.
If anybody could help me, I would really appreciate it :)
(What I am actually trying to achieve is to wirte a macro function that splits a user defined variable that contains a string into different variables based on a delimiter. Within this macro I need the !SUBSTR
function. That's why I chose my example the way I did. But if you know a solution to my real problem without providing a solution to the substring problem, you're welcome too :D)
* DEFINE DATA.
DATA LIST /ID 1-3 VAR1 (A10).
BEGIN DATA
001 abc
002 defgh
003 ijkl
END DATA.
* NON-MACRO CODE (works).
STRING OUT1 (A10).
COMPUTE OUT1 = char.substr(VAR1, 1, 2).
EXECUTE.
* MACRO CODE (does not work).
DEFINE crt_substr (var = !TOKENS(1)).
STRING OUT2 (A10).
COMPUTE OUT2 = !SUBSTR(VAR1,1,2).
!ENDDEFINE.
crt_substr var=VAR1.
EXECUTE.
On the one hand, there is no reason not to use char.substr
within a macro, when you actually want to read substrings from your data (!substr
only changes the syntax created by the macro).
So in your example - this works fine (note a few corrections to your macro syntax):
DEFINE crt_substr (vr = !TOKENS(1)).
STRING OUT2 (A10).
COMPUTE OUT2 = char.SUBSTR(!vr,1,2).
!ENDDEFINE.
crt_substr vr=var1.
EXECUTE.
All this being said, you don't necessarily need a macro to split a string with a delimiter - you can use loop
in regular syntax, take a look here for a nice tutorial.
This is another example of doing it with a macro.