BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
data_null__
Jade | Level 19

Below is the optsave/optload macro that I am currently using.  I'm not sure the code is mine or borrowed. 

 

It addresses the problem described in this discussion

Solved: Why does Proc OPTLOAD change the PAGESIZE to 55? - SAS Support Communities

by only reloading options that were changed.

 

I would like to figure a way that this macro can be called from a macro that has already called it and not overwrite the data sets from the level above.

unique data set names

 

macro1
   %u_optstore(SAVE)
      change options
      macro2  
         %u_optstore(SAVE)
         change options
         %u_optsave(LOAD)
         macro2 mend
    change more options maybe.
    %u_optstore(LOAD);
    macro1 mend
      

Maybe create a unique global macro variable to save a unique call index.  &SYSINDEX involved I think.

 

%macro u_isnull(macvar);
   %if %symexist(&macvar.) %then %sysevalf(%superq(%superq(macvar)) =, boolean);
   %else 1
   %mend u_isnull;

%macro u_optstore(arg);
   %put NOTE: &=SYSINDEX;
   %if %qupcase(&arg) eq SAVE or %u_isnull(arg) %then %do;
      proc optsave out=__optbase__;
         run;
      %end;
   %else %do;
      proc optsave out=__optcomp__;
         run;
      proc compare base=__optbase__ comp=__optcomp__ out=__optload__ outbase outnoequal noprint;
         run;
      proc optload data=__optload__;
         run;
      proc delete data=__optbase__ __optcomp__ __optload__;
         run;
      %end;
   %mend u_optstore;

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
yabwon
Onyx | Level 15

Sysindex may be problematic because of this: "You can use SYSINDEX in a program that uses macros when you need a unique number that changes after each macro invocation." (taken form documentation)

 

But maybe something like this:

%macro u_isnull(macvar);
   %if %symexist(&macvar.) %then %sysevalf(%superq(%superq(macvar)) =, boolean);
   %else 1
   %mend u_isnull;

%macro u_optstore(arg,caller);
   %put NOTE: &=SYSINDEX;
   %if %qupcase(&arg) eq SAVE or %u_isnull(arg) %then %do;
      proc optsave out=__optbase_&caller._;
         run;
      %end;
   %else %do;
      proc optsave out=__optcomp_&caller._;
         run;
      proc compare base=__optbase_&caller._ comp=__optcomp_&caller._ out=__optload_&caller._ outbase outnoequal noprint;
         run;
      proc optload data=__optload_&caller._;
         run;
      proc delete data=__optbase_&caller._ __optcomp_&caller._ __optload_&caller._;
         run;
      %end;
   %mend u_optstore;






options mprint;
%macro macro2();
  %put B;
  %local caller;
  %let caller=&sysmacroname.;
  %u_optstore(SAVE,&caller.)
  %put BB;
  %u_optstore(LOAD,&caller.)
  %put BBB;
%mend macro2;

%macro macro1();
  %put A;
  %local caller;
  %let caller=&sysmacroname.;
  %u_optstore(SAVE,&caller.)
  %put AA;
  %macro2()
  %put AAA;
  %u_optstore(LOAD,&caller.)
  %put AAAA;
%mend macro1;

%macro1()

The only restriction is that &CALLER. cannot be "to long". 

 

 

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



View solution in original post

4 REPLIES 4
yabwon
Onyx | Level 15

Sysindex may be problematic because of this: "You can use SYSINDEX in a program that uses macros when you need a unique number that changes after each macro invocation." (taken form documentation)

 

But maybe something like this:

%macro u_isnull(macvar);
   %if %symexist(&macvar.) %then %sysevalf(%superq(%superq(macvar)) =, boolean);
   %else 1
   %mend u_isnull;

%macro u_optstore(arg,caller);
   %put NOTE: &=SYSINDEX;
   %if %qupcase(&arg) eq SAVE or %u_isnull(arg) %then %do;
      proc optsave out=__optbase_&caller._;
         run;
      %end;
   %else %do;
      proc optsave out=__optcomp_&caller._;
         run;
      proc compare base=__optbase_&caller._ comp=__optcomp_&caller._ out=__optload_&caller._ outbase outnoequal noprint;
         run;
      proc optload data=__optload_&caller._;
         run;
      proc delete data=__optbase_&caller._ __optcomp_&caller._ __optload_&caller._;
         run;
      %end;
   %mend u_optstore;






options mprint;
%macro macro2();
  %put B;
  %local caller;
  %let caller=&sysmacroname.;
  %u_optstore(SAVE,&caller.)
  %put BB;
  %u_optstore(LOAD,&caller.)
  %put BBB;
%mend macro2;

%macro macro1();
  %put A;
  %local caller;
  %let caller=&sysmacroname.;
  %u_optstore(SAVE,&caller.)
  %put AA;
  %macro2()
  %put AAA;
  %u_optstore(LOAD,&caller.)
  %put AAAA;
%mend macro1;

%macro1()

The only restriction is that &CALLER. cannot be "to long". 

 

 

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



data_null__
Jade | Level 19

Hi @yabwon 

 

Yes, this is good idea.   You could use SAS Help Center: %SYSMEXECNAME Macro Function to retrieve the name of the calling macro.   But I think all we need to know is the depth of the call SAS Help Center: %SYSMEXECDEPTH Macro Function and not have to worry about the length of the caller's name. 

%macro u_isnull(macvar);
   %if %symexist(&macvar.) %then %sysevalf(%superq(%superq(macvar)) =, boolean);
   %else 1
   %mend u_isnull;

%macro u_optstore(arg);
   %put NOTE: %nrstr(%%)sysmexecdepth=%sysmexecdepth;
   %put NOTE: &=depth;
   %local /readonly depth=%sysmexecdepth;
   %if %qupcase(&arg) eq SAVE or %u_isnull(arg) %then %do;
      proc optsave out=__optbase_&depth.__;
         run;
      %end;
   %else %do;
      proc optsave out=__optcomp_&depth.__;
         run;
      proc compare base=__optbase_&depth.__ comp=__optcomp_&depth.__ out=__optload_&depth.__ outbase outnoequal noprint;
         run;
      proc print;
         run;
      proc optload data=__optload_&depth.__;
         run;
      proc delete data=__optbase_&depth.__ __optcomp_&depth.__ __optload_&depth.__;
         run;
      %end;
   %mend u_optstore;

%put %nrstr(%%)sysmexecdepth=%sysmexecdepth;

%u_optstore(save)

%macro macro2();
  %put %nrstr(%%)sysmexecdepth=%sysmexecdepth;
  %put B;
  %u_optstore(SAVE)
  %put BB;
  %u_optstore(LOAD)
  %put BBB;
%mend macro2;

%macro macro1();
  %put %nrstr(%%)sysmexecdepth=%sysmexecdepth;
  %put A;
  %u_optstore(SAVE)
  %put AA;
  %macro2()
  %put AAA;
  %u_optstore(LOAD)
  %put AAAA;
%mend macro1;

%macro1()

%u_optstore(LOAD);

 

yabwon
Onyx | Level 15

Yes, that's better idea!

 

With just a small modification:

   %put NOTE: %nrstr(%%)sysmexecdepth=%sysmexecdepth;
   %local / readonly depth=%sysmexecdepth;
   %put NOTE: &=depth;

to avoid:

"WARNING: Apparent symbolic reference DEPTH not resolved."

 

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



data_null__
Jade | Level 19
I hadn't tested that change. 🙂

hackathon24-white-horiz.png

The 2025 SAS Hackathon Kicks Off on June 11!

Watch the live Hackathon Kickoff to get all the essential information about the SAS Hackathon—including how to join, how to participate, and expert tips for success.

YouTube LinkedIn

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
  • 4 replies
  • 734 views
  • 5 likes
  • 2 in conversation