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;
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.