Since there are no CALL statements, is there a way to output to a Macro variable from within a DS2 block?
Something like this?
data have;
word = "Hello";
run;
proc ds2;
data _null_;
method run();
set have;
end;
method term();
put word;
call symput('word',word);
end;
enddata;
run;
quit;
%put &word;
No, there is no way.
DS2 opens up a lot of coding avenues and shuts down some others.
Functional Trickery can be attempted but will eventually fail.
One extreme is write a custom function in FCMP that acts as an adapter for the FCMP function RUN_MACRO that is invoked via a DS2 FCMP package. However, at DS2 program runtime the FCMP package execution domain will be sandboxed as well and the custom function will fail.
Example of failed trickery (Cannot find a library containing subroutine RUN_MACRO)
options nosource; %global hackysack; %macro mvassign; %let hackysack = &value; %mend; * interface function to run_macro (which has its own foibles); proc fcmp outlib=work.hacks.interface; function mvassign (value $); return (run_macro('mvassign',value)); endsub; run; data have; word = "Hello"; run; * test user defined function 'mvassign' in DATA Step execution domain; * hint: this works %let hackysack=; data _null_; set have; rc = mvassign(word); run; %put &=hackysack; * test user defined function 'mvassign' in Proc DS2 step DATA program; %let hackysack=; proc ds2; package hackspkg / overwrite=yes language='fcmp' table='work.hacks'; run; data _null_; declare package hackspkg hackro(); method run(); set have; end; method term(); declare double rc; put 'NOTE:' word= ' <------------- in ds2 data program term section'; rc = hackro.mvassign(word); end; enddata; run; quit; %put &=hackysack; ----- LOG ----- NOTE: There were 1 observations read from the data set WORK.HAVE. NOTE: DATA statement used (Total process time): real time 0.48 seconds cpu time 0.17 seconds HACKYSACK='Hello' (FOIBLED result from run_macro interface function) NOTE: Created package hackspkg in data set work.hackspkg. NOTE: Execution succeeded. No rows affected. NOTE: word=Hello <------------- in ds2 data program term section ERROR: Cannot find a library containing subroutine RUN_MACRO. ERROR: Function RUN_MACRO not found. ERROR: Line 3392: FCMP function failed with internal error. ERROR: General error NOTE: The SAS System stopped processing this step because of errors. NOTE: PROCEDURE DS2 used (Total process time): real time 0.10 seconds cpu time 0.09 seconds HACKYSACK=
There may be some eventual hackery that does work, but it would be far outside the norm.
No, there is no way.
DS2 opens up a lot of coding avenues and shuts down some others.
Functional Trickery can be attempted but will eventually fail.
One extreme is write a custom function in FCMP that acts as an adapter for the FCMP function RUN_MACRO that is invoked via a DS2 FCMP package. However, at DS2 program runtime the FCMP package execution domain will be sandboxed as well and the custom function will fail.
Example of failed trickery (Cannot find a library containing subroutine RUN_MACRO)
options nosource; %global hackysack; %macro mvassign; %let hackysack = &value; %mend; * interface function to run_macro (which has its own foibles); proc fcmp outlib=work.hacks.interface; function mvassign (value $); return (run_macro('mvassign',value)); endsub; run; data have; word = "Hello"; run; * test user defined function 'mvassign' in DATA Step execution domain; * hint: this works %let hackysack=; data _null_; set have; rc = mvassign(word); run; %put &=hackysack; * test user defined function 'mvassign' in Proc DS2 step DATA program; %let hackysack=; proc ds2; package hackspkg / overwrite=yes language='fcmp' table='work.hacks'; run; data _null_; declare package hackspkg hackro(); method run(); set have; end; method term(); declare double rc; put 'NOTE:' word= ' <------------- in ds2 data program term section'; rc = hackro.mvassign(word); end; enddata; run; quit; %put &=hackysack; ----- LOG ----- NOTE: There were 1 observations read from the data set WORK.HAVE. NOTE: DATA statement used (Total process time): real time 0.48 seconds cpu time 0.17 seconds HACKYSACK='Hello' (FOIBLED result from run_macro interface function) NOTE: Created package hackspkg in data set work.hackspkg. NOTE: Execution succeeded. No rows affected. NOTE: word=Hello <------------- in ds2 data program term section ERROR: Cannot find a library containing subroutine RUN_MACRO. ERROR: Function RUN_MACRO not found. ERROR: Line 3392: FCMP function failed with internal error. ERROR: General error NOTE: The SAS System stopped processing this step because of errors. NOTE: PROCEDURE DS2 used (Total process time): real time 0.10 seconds cpu time 0.09 seconds HACKYSACK=
There may be some eventual hackery that does work, but it would be far outside the norm.
I was afraid of that. I am finding DS2 can't be used to write processes that do not know the variable names in advance. I might post another question that get more directly at that issue.
Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.