DATA Step, Macro, Functions and more

Macro Loop issue

Reply
Super Contributor
Posts: 275

Macro Loop issue

Hello,
I am using this sample note by SAS to loop through a set of character values. The original macro loop works fine but not sure why mine does not.

DATA METRICS;
LENGTH MT $25;
INPUT MT ;
CARDS;
TOT_COMP_PGM
REG_MEM
BIO_SCREEN
FAX_MAIL_BIO_SCREEN
HEALTH_ASSESS
;
RUN;
PROC SQL NOPRINT;
SELECT MT
INTO :MACVAR_METRICS SEPARATED BY ','
FROM METRICS
;
QUIT;
%PUT &MACVAR_METRICS;
%MACRO _LOOP_TO_TRANSPOSE_DATASETS(values);
%let count=1;
%let value=%qscan(&values,&count,%str(,));
/* Loop through the total number of values */
%do %while(&value ne);
%put &value;
%let count=%eval(&count+1);
%let value=%qscan(&values,&count,%str(,));
%end;

%MEND _LOOP_TO_TRANSPOSE_DATASETS;

/* %STR is used to mask the commas from the macro compiler when */
/* the macro %LOOP is called. */
%_LOOP_TO_TRANSPOSE_DATASETS(&MACVAR_METRICS)

I am getting this error -
SYMBOLGEN: Macro variable MACVAR_METRICS resolves to TOT_COMP_PGM,REG_MEM,BIO_SCREEN,FAX_MAIL_BIO_SCREEN,HEALTH_ASSESS
ERROR: More positional parameters found than defined.

I tried using different ways to invoke the macro but I still keep getting an error -
%_LOOP_TO_TRANSPOSE_DATASETS(value=&MACVAR_METRICS)


46 TOT_COMP_PGM,REG_MEM,BIO_SCREEN,FAX_MAIL_BIO_SCREEN,HEALTH_ASSESS
__________
180
ERROR: All positional parameters must precede keyword parameters.
ERROR 180-322: Statement is not valid or it is used out of proper order.

I would appreciate any help.

Thanks,
saspert.
Super Contributor
Super Contributor
Posts: 365

Re: Macro Loop issue

Hello SASpert,

I've replaced your macro call with this one and did not get any errors:

%_LOOP_TO_TRANSPOSE_DATASETS(%Bquote(&MACVAR_METRICS))

Sincerely,
SPR
Super Contributor
Posts: 275

Re: Macro Loop issue

Hello SPR,
Thank you for your suggestion. The macro runs fine but I get back this in the log -

SYMBOLGEN: Macro variable COUNT resolves to 1
SYMBOLGEN: Macro variable VALUE resolves to %bqoute(TOT_COMP_PGM
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
SYMBOLGEN: Macro variable VALUE resolves to %bqoute(TOT_COMP_PGM
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
%bqoute(TOT_COMP_PGM

I think the string '%Bquote' too is being passed to the macro while invocation. I want only the TOT_COMP_PGM to return for the first value.

Thanks,
saspert
Super User
Posts: 10,035

Re: Macro Loop issue

Another better choice is :


[pre]
%Macro_Loop /parmbuff;
........&syspbuff............
%mend;
[/pre]




Ksharp
Super Contributor
Posts: 275

Re: Macro Loop issue

Hi Ksharp,
Thank you for your suggestion. This option is new to me. I just looked up the documentation for 9.1.3 and it might be worth a try.

But do you know if it will work for 2 macro variables which will have several values like this

%macro somemacro (value1=,value2=);
%mend;
%somemacro (a1,b1,c1, b2,c2,d2)

The SAS example has only 1 macro variable.

Regards,
saspert.
Super User
Posts: 10,035

Re: Macro Loop issue

Yes. This way only supports 1 macro variable.



Ksharp
Super Contributor
Super Contributor
Posts: 365

Re: Macro Loop issue

Hello SASpert,

I did not see %bqoute(TOT_COMP_PGM in my LOG I see TOT_COMP_PGM. I use EG 4.3 may be this is the reason? What version of SAS or EG do you use?

Sincerely,
SPR
Super Contributor
Posts: 275

Re: Macro Loop issue

Hi SPR,
I have SAS Enterprise Guide 4.1 (4.1.0.1016). Do you know if different versions of EG can cause such issues? I was thinking the macro quoting functions are pretty much standard, arent they?

Thanks,
saspert.
Super Contributor
Super Contributor
Posts: 365

Re: Macro Loop issue

Hello SASpert,

I do not know the answers on your questions because do not have EG 4.1. I suggest using " " instead of "," as a separator:
[pre]
PROC SQL NOPRINT;
SELECT MT
INTO :MACVAR_METRICS SEPARATED BY ' '
FROM METRICS
;
QUIT;
%PUT &MACVAR_METRICS;
%MACRO _LOOP_TO_TRANSPOSE_DATASETS(values);
%let count=1;
%let value=%qscan(&values,&count,%str(" "));
/* Loop through the total number of values */
%do %while(&value ne);
%put &value;
%let count=%eval(&count+1);
%let value=%qscan(&values,&count,%str(" "));
%end;
%MEND _LOOP_TO_TRANSPOSE_DATASETS;

/* %STR is used to mask the commas from the macro compiler when */
/* the macro %LOOP is called. */
%_LOOP_TO_TRANSPOSE_DATASETS(&MACVAR_METRICS)
[/pre]
SPR
Super User
Posts: 11,343

Re: Macro Loop issue

Part of the issue may be use of %QSCAN which quotes special characters, ie %bquote.

%scan may yield more expected results BUT you want to pass a list with commas either with %STR() , another approach that makes the commas invisible (or not used) or the PARMBUFF automatic macro variable
Ask a Question
Discussion stats
  • 9 replies
  • 595 views
  • 0 likes
  • 4 in conversation