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;
Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.
Register today!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.
Select SAS Training centers are offering in-person courses. View upcoming courses for: