BookmarkSubscribeRSS Feed
bearda
Obsidian | Level 7

 

EDIT:

 

My question was badly formed and the actual problem still exist.

 

It's easiest to show the issue by example:

 

/* No open code allowed in macro */
%macro wrapper;
   
    %let options = %sysfunc(getoption(option_name));
    %let rc          = %sysfunc(SETOPTION(option_name));
    
    %* ...code... ;

    %let return_value = 123;
    
    %let rc = %sysfunc(SETOPTION(&options));

    &return_value
%mend wrapper;

%wrapper;

So what I'm looking is the replacement for nonexistent SETOPTION function to set options with pure macro language. And still macro should be used like %let value = %wrapper; or %put %wrapper;. (which means there's only macro language in macro definition)

 

Options set inside DOSUBL does not affect options outside DOSUBL code.

 

 


 

 

Hi,

 

I've been struggling with this issue for a long time and finally decided to post a question about it if someone has found an answer or have circumvent the problem somehow.

 

We often want to produce macros which can be used like this:

%let variables = %getvarlist(dataset = sashelp.cars);

i.e there is no open code inside the macro.

 

There are situations when SAS Programmer wants to change the system options in macro described above. Here is an example where we don't want message: "NOTE: The quoted string currently being processed has become more than 262 char....": to appear in SAS log. I'm not looking for an answer to guides macro users to set certain system options before using the macro.

 

 

%macro sysopts_withing_macro;

    %local l_rc;

    %let l_rc = %sysfunc(dosubl('
        options noquotelenmax;

        data _null_;
            length long_string $6000.;
            string = "This is a long string that will be repeated. ";
            do i = 1 to 100;
                long_string = strip(long_string) || string;
            end;
            put long_string;
        run;
    '));

%mend sysopts_withing_macro;

%sysopts_withing_macro;

 

 

7 REPLIES 7
Tom
Super User Tom
Super User

I don't understand what the question is. 

Are you saying your attempt to change the option inside the DOSUBL call didn't work?

Please show the results.

 

Are you asking why does the DOSUBL call not work when I add extra single quotes before and after the code I want to run?

 

Are you saying the note about string too long is being triggered by the macro generating a long quoted string?

Why IS the macro generating a long quoted string?

 

 

 

bearda
Obsidian | Level 7

Hi Tom,

 

You can play with the code I passed.

 

"Are you saying your attempt to change the option inside the DOSUBL call didn't work?"

- I'm asking whether one can change SAS system options within a macro on run time without using open code

 

"Are you saying the note about string too long is being triggered by the macro generating a long quoted string?"

- Yes

 

"Why IS the macro generating a long quoted string?"

- Not relevant ... EDIT: THIS WAS THE MOST RELEVANT THING HERE. 

Tom
Super User Tom
Super User

Replace the single quotes with %NRSTR() instead.

bearda
Obsidian | Level 7

Oh my, this actually worked. The issue wasn't about the string inside a data step, of course... It was exactly what the NOTE says..

 

Thanks a lot Tom for your help!

Tom
Super User Tom
Super User

I don't think there is a general solution to a way to change an option.  Your method seems sound in general.

But for this particular option SAS is constantly scanning the input to check for the dreaded unbalanced quotes.  When you compile the macro.  When it passes the string through the %SYSFUNC() function call to the DOSUBL() function.

 

So even though if you macro protect the quotes the macro quoting gets removed by the process.

 

Best solution is to re-work your code not to have long quoted strings.  For example put them into macro variables and use SYMGET() function get the value into your character variable.

options quotelenmax;

%macro sysopts_withing_macro;
%local l_rc string;
%let string= 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
;
%let l_rc = %sysfunc(dosubl(%nrstr(
  data _null_;
    length long_string $6000.;
    long_string = symget('string');
    put long_string=;
  run;
)));

%mend sysopts_withing_macro;
%put macro is defined;

%put before macro is called;
%sysopts_withing_macro;
%put after macro is called;

PS Why the heck does calling DOSUBL in this way write a bunch of blank lines to the LOG?

185   %put before macro is called;
before macro is called























































long_string=12345678901234567890123456789012345678901234567890123456789012345678901234567890123456
78901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890123
45678901234567890 12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890
NOTE: DATA statement used (Total process time):
      real time           0.03 seconds
      cpu time            0.03 seconds


186   %sysopts_withing_macro;
187   %put after macro is called;
after macro is called

 

Reeza
Super User

1. Use PROC OPTIONS to get the current status/settings of the options you want to change.

2. Change/set your options in your macro

3. Reset at the end to the original values to avoid messing up someone else's system. 

 


@bearda wrote:

Hi,

 

I've been struggling with this issue for a long time and finally decided to post a question about it if someone has found an answer or have circumvent the problem somehow.

 

We often want to produce macros which can be used like this:

%let variables = %getvarlist(dataset = sashelp.cars);

i.e there is no open code inside the macro.

 

There are situations when SAS Programmer wants to change the system options in macro described above. Here is an example where we don't want message: "NOTE: The quoted string currently being processed has become more than 262 char....": to appear in SAS log. I'm not looking for an answer to guides macro users to set certain system options before using the macro.

 

 

%macro sysopts_withing_macro;

    %local l_rc;

    %let l_rc = %sysfunc(dosubl('
        options noquotelenmax;

        data _null_;
            length long_string $6000.;
            string = "This is a long string that will be repeated. ";
            do i = 1 to 100;
                long_string = strip(long_string) || string;
            end;
            put long_string;
        run;
    '));

%mend sysopts_withing_macro;

%sysopts_withing_macro;

 

 


 

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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.

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
  • 7 replies
  • 1430 views
  • 1 like
  • 3 in conversation