Search code examples
macrosspsssubstr

SPSS: using char.substr in macro / Split String into multiple variables (macro)


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.


Solution

  • 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.