BookmarkSubscribeRSS Feed
Tom
Super User Tom
Super User

An interesting puzzle was raised by this question. https://communities.sas.com/t5/SAS-Programming/Changing-SAS-System-options-within-a-macro-which-does...

 

If I try to run a line of code with single quotes around it then SAS will rightly throw an error message because you cannot have a free floating string literal in the middle of a block of SAS code.

 

Why does SAS remove the quotes around values passed to the DOSUBL() function when called via the %SYSFUNC() macro call?

 

So if I make a program file with this value:

>more qstring.sas
'data _null_;  string=symget("sysjobid");  put string;run;'

and run it with SAS I get this LOG.

NOTE: SAS initialization used:
      real time           0.27 seconds
      cpu time            0.03 seconds
      
1          'data _null_;  string=symget("sysjobid");  put string;run;'
           ___________________________________________________________
           180

ERROR 180-322: Statement is not valid or it is used out of proper order.

ERROR: Errors printed on page 1.

NOTE: SAS Institute Inc., SAS Campus Drive, Cary, NC USA 27513-2414
NOTE: The SAS System used:
      real time           0.28 seconds
      cpu time            0.03 seconds

But if I make a macro variable with that value.

%let string='data _null_;  string=symget("sysjobid");  put string;run;';

And run it through %SYSFUNC(DOSUBL()) it runs.

174   %put BEFORE;
BEFORE























































17548
NOTE: DATA statement used (Total process time):
      real time           0.01 seconds
      cpu time            0.01 seconds


175   %let rc=%sysfunc(dosubl(&string));
176   %put &=rc;
RC=0
177   %put AFTER;
AFTER

 

 

8 REPLIES 8
ChrisNZ
Tourmaline | Level 20

The way I see it:

Function DOSUBL does a lot behind the scenes and is not at all a regular function.
It starts a new SAS thread and passes code to that thread.
It looks that, as part of the code-passing, surrounding single quotes are removed.
This could be considered a feature or a bug.
Note that surrounding double quotes are not removed.

ChrisNZ
Tourmaline | Level 20

It's not only when called via a macro that the surrounding single quotes are removed.

This runs fine:

data _null_;
  RC=dosubl("  'data _null_;  string=symget(""sysjobid"");  put string;run;'  ");
run;

[Edit: This code does NOT run as expected.]

ErikLund_Jensen
Rhodochrosite | Level 12

Hi @ChrisNZ 

 

Interesting. When I run your code, id doesn't run

 

NOTE: SAS initialization used:
      real time           4.01 seconds
      cpu time            1.17 seconds

1    data _null_;
2      RC=dosubl("  'data _null_;  string=symget(""sysjobid"");  put string;run;'  ");
3    run;

ERROR 180-322: Statement is not valid or it is used out of proper order.
NOTE: DATA statement used (Total process time):
      real time           0.67 seconds
      cpu time            0.18 seconds
ChrisNZ
Tourmaline | Level 20

Mmmm. You are right. I did a few tests and got confused on the way. This code does generate an error.

Apologies for wasting your time.

ErikLund_Jensen
Rhodochrosite | Level 12

Hi @ChrisNZ 

 

Far from wasting my time, I had a very interesting evening experimenting with dosubl. I was aware of it from "What's new in SAS x.x.x", but have never used it. So it is like when I got a Dremel as a birthday present many years back. I had never missed it before, but now I'm on my third.

 

I got confused on the way too, I have some examples here. It makes sense that both 1.2 and 1.3 works, but why does 2.2 not work, when 2.3 does? - Any ideas?

 

******* without surrounding quotes *******;
%let cmd = %str(data _null_;  string=symget("sysjobid");  put string; run;);

* 1.1 - works;
%let rc = %sysfunc(dosubl(&cmd));

* 1.2 - works;
data _null_;
	cmd = symget('cmd');
	put cmd;
	RC = dosubl(cmd);
run;

* 1.3 - works;
data _null_;
	cmd = 'data _null_;  string=symget("sysjobid");  put string; run;';
	put cmd;
	RC = dosubl(cmd);
run;

******* with surrounding quotes ********;
%let cmd = %str('data _null_;  string=symget("sysjobid");  put string; run;');

* 2.1 - works;
%let rc = %sysfunc(dosubl(&cmd));

* 2.2 - DOES NOT WORK;
data _null_;
	cmd = symget('cmd');
	put cmd;
	RC = dosubl(cmd);
run;

* 2.3  - works;
data _null_;
	cmd = "'" || 'data _null_;  string=symget("sysjobid");  put string; run;' || "'";
	put cmd;
	RC = dosubl(cmd);
run;

 

 

 

FreelanceReinh
Jade | Level 19

@ErikLund_Jensen wrote:

It makes sense that both 1.2 and 1.3 works, but why does 2.2 not work, when 2.3 does? - Any ideas?

Good question. It seems that DOSUBL doesn't like the trailing blanks after the closing single quote in CMD (character variable of length 200) in 2.2, which are not present in 2.3 where CMD is a variable of length 60. As it turns out, it doesn't like leading blanks before the opening single quote either:

* 2.4 - DOES NOT WORK;
%let cmd1 = %str( 'data _null_;  string=symget("sysjobid");  put string; run;');
%let cmd2 = %str('data _null_;  string=symget("sysjobid");  put string; run;' );
%let rc = %sysfunc(dosubl(&cmd1));
%let rc = %sysfunc(dosubl(&cmd2));
ChrisNZ
Tourmaline | Level 20

> It seems that DOSUBL doesn't like the trailing blanks [...] it doesn't like leading blanks before the opening single quote either

 

Ah! That explains it! I added the spaces in my code after pasting it here, to making it more legible. This runs:

data _null_;
  RC=dosubl("'data _null_;  string=symget(""sysjobid"");  put string;run;'");
run;

 

ChrisNZ
Tourmaline | Level 20

In light of the comments by @FreelanceReinh, this

* 2.2 - DOES NOT WORK;
data _null_;
	cmd = symget('cmd');
	put cmd;
	RC = dosubl(cmd);
run;

can run like this:

* 2.2 - DOES WORK;
data _null_;
	cmd = symget('cmd');
	put cmd;
	RC = dosubl(trim(cmd));
run;

 

hackathon24-white-horiz.png

The 2025 SAS Hackathon has begun!

It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.

Latest Updates

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
  • 8 replies
  • 1588 views
  • 4 likes
  • 4 in conversation