BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
CurtisMackWSIPP
Lapis Lazuli | Level 10

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;
1 ACCEPTED SOLUTION

Accepted Solutions
RichardDeVen
Barite | Level 11

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.

 

View solution in original post

2 REPLIES 2
RichardDeVen
Barite | Level 11

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.

 

CurtisMackWSIPP
Lapis Lazuli | Level 10

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.

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

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!

Register Now

How to Concatenate Values

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 2 replies
  • 1396 views
  • 0 likes
  • 2 in conversation