Search code examples
sassas-macro

Can I nest %sysfunc-functions or achieve similar results?


I have the following strings that are used (in different variations) as variable names:

Data variables;
input variable;
datalines;
Exkl_UtgUtl_Flyg 
Exkl_UtgUtl_Tag 
Exkl_UtgUtl_Farja 
Exkl_UtgUtl_Hyrbil 
Exkl_UtgUtl_Bo 
Exkl_UtgUtl_Aktiv 
Exkl_UtgUtl_Annat
;
run; 

In order to reference related variables I need to turn variables of the type "Exkl_UtgUtl_Flyg" to variables of the type "UtgUtl_FlygSSEK_Pers" and "UtgUtl_FlygSSEK_PPmedel".I try to do this in the following macro, along with other manipulations:

%macro imputera_saknad_utgift(variabel);

DATA IBIS3_5;
SET IBIS3_5;
if &variabel=1 and %sysfunc(cats(%qsysfunc(TRANWRD(&variabel,'Exkl_','')),SSEK_Pers))=. then 
        %sysfunc(cats(%qsysfunc(TRANWRD(&variabel,'Exkl_','')),SSEK_Pers))=%sysfunc(cats(%qsysfunc(TRANWRD(&variabel,'Exkl_','')),SSEK_PPmedel));

RUN; %mend imputera_saknad_utgift;

The documentation stated that %sysfunc can't be nested, but mentioned something about alternating %sysfunc- and %qsysfunc-functions so I tried that. I then try to execute the code:

data _null_;
    set variabler2;
    call execute(cats('%imputera_saknad_utgift(',utgifter_inte_missing,')'));
run;

This does not seem to work however. The cats-function seems to have worked, but not the nested TRANWRD-function:

NOTE: DATA statement used (Total process time):
      real time           0.11 seconds
      cpu time            0.12 seconds
      

5         + DATA IBIS3_5; SET IBIS3_5; if Exkl_UtgUtl_Bo=1 and Exkl_UtgUtl_BoSSEK_Pers=. then    
Exkl_UtgUtl_BoSSEK_Pers=Exkl_UtgUtl_BoSSEK_PPmedel;

How do I make this work? The output should look something like:

DATA IBIS3_5; SET IBIS3_5; if Exkl_UtgUtl_Bo=1 and UtgUtl_BoSSEK_Pers=. then    
UtgUtl_BoSSEK_Pers=UtgUtl_BoSSEK_PPmedel;

Solution

  • I don't think your macro variable values have quote characters in them, so this code is not going to work:

    %qsysfunc(TRANWRD(&variabel,'Exkl_',''))
    

    Since it is looking to replace the 7 character string 'Exkl_' with just the two character string '', two quotes next to each other.

    You probably meant to search for Exkl_ instead. You probably also do not want to use %QSYSFUNC() here since that will preserve the space that TRANWRD() will insert. You could use %SYSFUNC() to avoid having that leading space as part of the value. Or perhaps use the TRANSTRN() function instead since that function, unlike TRANWRD(), can translate to an empty string instead of a single space.

    Example:

    439  %let variable=Exkl_UtgUtl_Flyg ;
    440  %put %qsysfunc(TRANWRD(&variable,'Exkl_','')) ;
    Exkl_UtgUtl_Flyg
    441  %put %qsysfunc(TRANWRD(&variable,Exkl_,)) ;
     UtgUtl_Flyg
    442  %put %sysfunc(TRANWRD(&variable,Exkl_,)) ;
    UtgUtl_Flyg
    443  %put %qsysfunc(TRANSTRN(&variable,Exkl_,)) ;
    UtgUtl_Flyg