I'm trying to loop through a table and call a macro. Before I call the macro I'd like to set the value of a variable.
%global curProgram;
proc sql;
create table AllProgramList (
SMRPRLE_PROGRAM varchar(100)
);
insert into AllProgramList(SMRPRLE_PROGRAM) values ("One");
;
data _null_; set AllProgramList;
file code;
put '%let curProgram = bquote('SMRPRLE_PROGRAM +(-1)')';
/*put '%setProgramClause()';
put '%callStudentBody(No)'; */
run;
%put curProgram &curProgram;
%include code / source2;
Why does
put '%let curProgram = bquote('SMRPRLE_PROGRAM +(-1)')';
Make this error message then not set the value of curProgram?
49
NOTE 49-169: The meaning of an identifier after a quoted string might change in a future SAS release. Inserting white space
between a quoted string and the succeeding identifier is recommended.
Hi,
look at the comments in the code:
%global curProgram;
proc sql;
create table AllProgramList (
SMRPRLE_PROGRAM varchar(100)
);
insert into AllProgramList(SMRPRLE_PROGRAM) values ("One");
;
filename code TEMP; /* <- create temporary file */
data _null_; set AllProgramList;
file code;
put '%let curProgram = %bquote(' SMRPRLE_PROGRAM +(-1) ');'; /* <- here:
0) add spaces around `SMRPRLE_PROGRAM +(-1)`
1) semicolon after macrovariable declaration is missing
2) it should be '%bquote', not 'bquote'
*/
/*put '%setProgramClause()';
put '%callStudentBody(No)'; */
run;
%put curProgram &curProgram;
%include code / source2;
%put curProgram &curProgram;
log:
19 %global curProgram;
20 proc sql;
21 create table AllProgramList (
22 SMRPRLE_PROGRAM varchar(100)
23 );
NOTE: One or more variables were converted because the data type is not supported by the V9
engine. For more details, run with options MSGLEVEL=I.
NOTE: Table WORK.ALLPROGRAMLIST created, with 0 rows and 1 columns.
24 insert into AllProgramList(SMRPRLE_PROGRAM) values ("One");
NOTE: 1 row was inserted into WORK.ALLPROGRAMLIST.
25 ;
26
27 filename code TEMP;
NOTE: PROCEDURE SQL used (Total process time):
real time 0.04 seconds
cpu time 0.01 seconds
28 data _null_; set AllProgramList;
29 file code;
30 put '%let curProgram = %bquote(' SMRPRLE_PROGRAM +(-1) ');';
31 /*put '%setProgramClause()';
32 put '%callStudentBody(No)'; */
33 run;
NOTE: The file CODE is:
Filename=C:\SAS_Temporary_Files\computer_name\#LN00241,
RECFM=V,LRECL=32767,File Size (bytes)=0,
Last Modified=30Jan2020:15:28:14,
Create Time=30Jan2020:15:28:14
NOTE: 1 record was written to the file CODE.
The minimum record length was 31.
The maximum record length was 31.
NOTE: There were 1 observations read from the data set WORK.ALLPROGRAMLIST.
NOTE: DATA statement used (Total process time):
real time 0.02 seconds
cpu time 0.03 seconds
34 %put curProgram &curProgram;
curProgram
35 %include code / source2;
NOTE: %INCLUDE (level 1) file CODE is file
C:\SAS_Temporary_Files\computer_name\#LN00241.
36 +%let curProgram = %bquote(One);
NOTE: %INCLUDE (level 1) ending.
37
38 %put curProgram &curProgram;
curProgram One
All the best
Bart
@DavidPhillips2 wrote:
I'm trying to loop through a table and call a macro. Before I call the macro I'd like to set the value of a variable.
%global curProgram;
proc sql;
create table AllProgramList (
SMRPRLE_PROGRAM varchar(100)
);
insert into AllProgramList(SMRPRLE_PROGRAM) values ("One");
;
data _null_; set AllProgramList;
file code;
put '%let curProgram = bquote('SMRPRLE_PROGRAM +(-1)')';
/*put '%setProgramClause()';
put '%callStudentBody(No)'; */
run;
%put curProgram &curProgram;
%include code / source2;Why does
put '%let curProgram = bquote('SMRPRLE_PROGRAM +(-1)')';
Make this error message then not set the value of curProgram?
49
NOTE 49-169: The meaning of an identifier after a quoted string might change in a future SAS release. Inserting white space
between a quoted string and the succeeding identifier is recommended.
It doesn't set any values because you have told the data step to display some text in the log. Not to set a value.
That is not an error. What SAS is telling you that a PUT (or some other statements) with text after a closing quote may in the future be interpreted differently.
Date literals '01JAN2020'D reserve the D immediately after the quote to treat the quoted value as a date. Similar with Time and T, Datetime and DT and Name literals such as "This is not a typical var"N when the Validvarname=Any is in effect.
Because you have multiple quotes the text after the second ' the text SMRPRLE is considered "an identifier after a quoted string".
If you change
put '%let curProgram = bquote('SMRPRLE_PROGRAM +(-1)')';
to
put '%let curProgram = bquote(' SMRPRLE_PROGRAM +(-1) ')';
the warning will go away but you still aren't creating or setting a macro variable.
You would use the CALL SYMPUT or CALL SYMPUTX statement to assign the value of a macro variable in a datastep.
Possibly you want
Call symputx('curprogram', "some value") ;
I suspect that you don't want bquote as part of the macro variable though. MAYBE %bquote but I doubt it.
But you would have to show us the exact value you expect the macro variable curprogam to have.
The note has the hint embedded :
NOTE 49-169: The meaning of an identifier after a quoted string might change in a future SAS release. Inserting white space between a quoted string and the succeeding identifier is recommended.
Inserting a white space after the quote has worked for me.
36 data _null_;
37 set AllProgramList;
38 file code;
39 put '%let curProgram = %bquote(' SMRPRLE_PROGRAM +(-1)')';
40
41 /*put '%setProgramClause()';
42 put '%callStudentBody(No)'; */
43 run;
NOTE: 1 record was written to the file CODE.
The minimum record length was 30.
The maximum record length was 30.
NOTE: There were 1 observations read from the data set WORK.ALLPROGRAMLIST.
I'm trying to read the value One from the dataset dynamically into curProgram.
Your put statement puts three elements (a string, a variable value, another string), so it is a good idea to separate those elements visually in the first place. You should also add the necessary semicolon to end the macro statement created by your code:
put '%let curProgram = bquote(' SMRPRLE_PROGRAM +(-1) ');';
Your program will then create this code in the file referenced by fileref "code":
%let curProgram = bquote(One);
Is this what you want?
I think I'm missing something simple in the thread. When I run the below the last line does not print out the value of the macro.
%global curProgram;
proc sql;
create table AllProgramList (
SMRPRLE_PROGRAM varchar(100)
);
insert into AllProgramList(SMRPRLE_PROGRAM) values ("One");
;
data _null_;
set AllProgramList;
file code;
put '%let curProgram = bquote(' SMRPRLE_PROGRAM +(-1) ');';
run;
%put curProgram &curProgram;
Hi,
look at the comments in the code:
%global curProgram;
proc sql;
create table AllProgramList (
SMRPRLE_PROGRAM varchar(100)
);
insert into AllProgramList(SMRPRLE_PROGRAM) values ("One");
;
filename code TEMP; /* <- create temporary file */
data _null_; set AllProgramList;
file code;
put '%let curProgram = %bquote(' SMRPRLE_PROGRAM +(-1) ');'; /* <- here:
0) add spaces around `SMRPRLE_PROGRAM +(-1)`
1) semicolon after macrovariable declaration is missing
2) it should be '%bquote', not 'bquote'
*/
/*put '%setProgramClause()';
put '%callStudentBody(No)'; */
run;
%put curProgram &curProgram;
%include code / source2;
%put curProgram &curProgram;
log:
19 %global curProgram;
20 proc sql;
21 create table AllProgramList (
22 SMRPRLE_PROGRAM varchar(100)
23 );
NOTE: One or more variables were converted because the data type is not supported by the V9
engine. For more details, run with options MSGLEVEL=I.
NOTE: Table WORK.ALLPROGRAMLIST created, with 0 rows and 1 columns.
24 insert into AllProgramList(SMRPRLE_PROGRAM) values ("One");
NOTE: 1 row was inserted into WORK.ALLPROGRAMLIST.
25 ;
26
27 filename code TEMP;
NOTE: PROCEDURE SQL used (Total process time):
real time 0.04 seconds
cpu time 0.01 seconds
28 data _null_; set AllProgramList;
29 file code;
30 put '%let curProgram = %bquote(' SMRPRLE_PROGRAM +(-1) ');';
31 /*put '%setProgramClause()';
32 put '%callStudentBody(No)'; */
33 run;
NOTE: The file CODE is:
Filename=C:\SAS_Temporary_Files\computer_name\#LN00241,
RECFM=V,LRECL=32767,File Size (bytes)=0,
Last Modified=30Jan2020:15:28:14,
Create Time=30Jan2020:15:28:14
NOTE: 1 record was written to the file CODE.
The minimum record length was 31.
The maximum record length was 31.
NOTE: There were 1 observations read from the data set WORK.ALLPROGRAMLIST.
NOTE: DATA statement used (Total process time):
real time 0.02 seconds
cpu time 0.03 seconds
34 %put curProgram &curProgram;
curProgram
35 %include code / source2;
NOTE: %INCLUDE (level 1) file CODE is file
C:\SAS_Temporary_Files\computer_name\#LN00241.
36 +%let curProgram = %bquote(One);
NOTE: %INCLUDE (level 1) ending.
37
38 %put curProgram &curProgram;
curProgram One
All the best
Bart
Slightly shorter code. I didn't realize I could just call the column name directly in this case. the -1 reference in the code was not needed.
%global curProgram;
proc sql;
create table AllProgramList (
SMRPRLE_PROGRAM varchar(100)
);
insert into AllProgramList(SMRPRLE_PROGRAM) values ("One");
insert into AllProgramList(SMRPRLE_PROGRAM) values ("Two");
;
data _null_; set AllProgramList;
file code;
Call symputx('curprogram', SMRPRLE_PROGRAM);
run;
%put curProgram &curProgram;
April 27 – 30 | Gaylord Texan | Grapevine, Texas
Walk in ready to learn. Walk out ready to deliver. This is the data and AI conference you can't afford to miss.
Register now and lock in 2025 pricing—just $495!
Still thinking about your presentation idea? The submission deadline has been extended to Friday, Nov. 14, at 11:59 p.m. ET.
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.
Ready to level-up your skills? Choose your own adventure.