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

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.

1 ACCEPTED SOLUTION

Accepted Solutions
yabwon
Onyx | Level 15

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

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



View solution in original post

7 REPLIES 7
ballardw
Super User

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

r_behata
Barite | Level 11

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.
DavidPhillips2
Rhodochrosite | Level 12

I'm trying to read the value One from the dataset dynamically into curProgram.

Kurt_Bremser
Super User

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?

DavidPhillips2
Rhodochrosite | Level 12

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;
yabwon
Onyx | Level 15

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

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



DavidPhillips2
Rhodochrosite | Level 12

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;

Ready to join fellow brilliant minds for the SAS Hackathon?

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

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 7 replies
  • 4930 views
  • 4 likes
  • 5 in conversation