BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
havmaage
Obsidian | Level 7

Hi, 

i am trying to substr myu macro variable, 

%macro runit;
		data _null_;
			call symputx('control_tb','sqldlz.mytable');
		run;
		
	data _null_;
		put substr(&control_tb,6,length(&control_tb));
	run;
%mend;
%runit;


20 ! data _null_;
21 put substr(&control_tb,6,length(&control_tb));
_
22
76
ERROR: Invalid variable specification, sqldlz.mytable.
Variable names of the form X.X must be either FIRST.X or LAST.X.
ERROR 22-322: Syntax error, expecting one of the following: [, {.

ERROR 76-322: Syntax error, statement will be ignored.

it errors out with 

 

what is wrong 

 

1 ACCEPTED SOLUTION

Accepted Solutions
PaigeMiller
Diamond | Level 26

A couple of things. First, when you post a portion of the log, you absolutely MUST use the </> icon here at SAS communites, and post the log into the window that appears. This maintains the formatting of the log, and makes it much more readable. Please DO NOT SKIP THIS STEP in the future.

 

When you write macros, the macros (when resolved) MUST produce legal working valid SAS code. And the best way to do that is to get the SAS code to work properly without macros and without macro variables — and only then turn it into a macro. If it doesn't work without macros and without macro variables, then it will not work with macros and with macro variables.

 

So, what is the reason your code produces an error? Your macro does not produce legal valid working SAS code when resolved. Specifically:

 

You can't use SUBSTR() immediately following a PUT command. The SUBSTR() function requires an actual variable name or text string as the first argument. And the LENGTH() function requires a variable name or text string. But when you call SUBSTR(), you do not have a variable name, and you do not have a text string as the first argument. The same is true for the LENGTH() function, the argument is not a variable name, and the argument is not a text string.

 

So, please go back and get this code to work without macro variables and outside of a macro. Then it should be easy to turn this into a macro.

--
Paige Miller

View solution in original post

4 REPLIES 4
PaigeMiller
Diamond | Level 26

A couple of things. First, when you post a portion of the log, you absolutely MUST use the </> icon here at SAS communites, and post the log into the window that appears. This maintains the formatting of the log, and makes it much more readable. Please DO NOT SKIP THIS STEP in the future.

 

When you write macros, the macros (when resolved) MUST produce legal working valid SAS code. And the best way to do that is to get the SAS code to work properly without macros and without macro variables — and only then turn it into a macro. If it doesn't work without macros and without macro variables, then it will not work with macros and with macro variables.

 

So, what is the reason your code produces an error? Your macro does not produce legal valid working SAS code when resolved. Specifically:

 

You can't use SUBSTR() immediately following a PUT command. The SUBSTR() function requires an actual variable name or text string as the first argument. And the LENGTH() function requires a variable name or text string. But when you call SUBSTR(), you do not have a variable name, and you do not have a text string as the first argument. The same is true for the LENGTH() function, the argument is not a variable name, and the argument is not a text string.

 

So, please go back and get this code to work without macro variables and outside of a macro. Then it should be easy to turn this into a macro.

--
Paige Miller
DavePrinsloo
Pyrite | Level 9
The macro runit compiles 1st, and then tries to resolve the macro variable, which is only known after the data step is run.
You need to use the symget function in the 2nd data step.
Or have 2 macros
Kurt_Bremser
Super User

Your macro variable contains this:

sqldlz.mytable

so the statement in the second data step resolves to this:

put substr(sqldlz.mytable,6,length(sqldlz.mytable));

which is not valid SAS data step code. If you want to treat the contents of a macro variable as a string in Base SAS code, you need to enclose it in double quotes. But that won't make your code work either, as you cannot use functions in a put statement. You need to create a variable, which you use in the PUT:

%macro runit;
		data _null_;
			call symputx('control_tb','sqldlz.mytable');
		run;
		
	data _null_;
		x = substr("&control_tb",6,length("&control_tb"));
		put x;
	run;
%mend;
%runit;

But this will still throw an ERROR, as your third argument to SUBSTR() is too large:

 73         %macro runit;
 74         data _null_;
 75         call symputx('control_tb','sqldlz.mytable');
 76         run;
 77         
 78         data _null_;
 79         x = substr("&control_tb",6,length("&control_tb"));
 80         put x;
 81         run;
 82         %mend;
 83         %runit;
 
 NOTE:  Verwendet wurde: DATA statement - (Gesamtverarbeitungszeit):
       real time           0.00 seconds
       cpu time            0.00 seconds
       
 
 
 NOTE: Invalid third argument to function SUBSTR at Zeile 83 Spalte 93.
 z.mytable
 x=z.mytable _ERROR_=1 _N_=1

So, as was already said, you should discard all the macro code for now and create working data step code without any use of the macro preprocessor. Without having in-depth knowledge about the code you want to create (keep in mind that the macro preprocessor is just a text generator, nothing more), any dabbling in macro programming is just a waste of time.

 

 

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
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
  • 698 views
  • 3 likes
  • 4 in conversation