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.

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

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