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
Amethyst | Level 16

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
Amethyst | Level 16

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;

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

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
  • 7 replies
  • 6356 views
  • 4 likes
  • 5 in conversation