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
Amethyst | Level 16

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
Amethyst | Level 16

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
Amethyst | Level 16

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

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