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

Hi,

 

I saw a couple of other posts on countw within a macro, but none addressed what i'm seeing.

 

I've inherited code, and i understand what it's doing (added commas between the list of words), but i keep getting errors when i try to run it.  Don't ask why one macro variable is another macro variable that holds the list.  I havent' gotten that far in cleaning it up yet...

%let _mClist     = PROVHCFA seq_keyc HCFASAF DISCSTAT PDGNS_CD;             *define variables of interest;

%macro test (varList = &_mClist);
    %put _mClist     = &varList;                 *define variables of interest;
    %let _mSelectedVar =;
    %do i = 1 %to %sysfunc(countw(&varList.));
            %if &i < %sysfunc(countw(&varList.)) %then
                  %let _mSelectedVar = &_mSelectedVar %scan(&varList,%eval(&i)),;    /*if  < 5 then _mSelectedVar = _mSelectedVar + a comma*/
            %else %let _mSelectedVar = &_mSelectedVar %scan(&varList,%eval(&i));    /*if last variable (ie, 5 < 5 will be false), then just _mSelectedVar, no comma*/
    %end;
%mend;
%test (varlist=);

When i run that, the log says:

ERROR: The function COUNTW referenced by the %SYSFUNC or %QSYSFUNC macro function has too few
       arguments.
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric
       operand is required. The condition was: %sysfunc(countw(&varList.))
ERROR: The %TO value of the %DO I loop is invalid.
ERROR: The macro TEST will stop executing.

 

But i've seen countw with just a single macro input before, so i dont' know what it thinks is missing.

 

So then i replaced the macro variable with the actual variable list, and i get this in the log after each cycle:

ERROR: The function COUNTW referenced by the %SYSFUNC or %QSYSFUNC macro function has too few
       arguments.

 

Any ideas?

 

Thanks,
Megan

 

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
MeganE
Pyrite | Level 9

So, messing around with it still, i removed the input macro reference on the %macro line, and set it up as a %let instead for testing, and it ran without error.  I changed nothing else. 

 

So the code works now, but if someone knows WHY!?!?!?!?!?!?, that would be incredibly helpful.  🙂

 

%let varlist     = PROVHCFA seq_keyc HCFASAF DISCSTAT PDGNS_CD;             *define variables of interest;

%macro test;
    %put _mClist     = &varList;                 *define variables of interest;
    %let _mSelectedVar =;
    %let end=%sysfunc(countw(&varList.));
    %do i = 1 %to &end.;
            %if &i < %sysfunc(countw(&varList.)) %then
                  %let _mSelectedVar = &_mSelectedVar %scan(&varList,%eval(&i)),;    /*if 1 < 5 then _mSelectedVar = _mSelectedVar + a comma*/
            %else %let _mSelectedVar = &_mSelectedVar %scan(&varList,%eval(&i));    /*if last variable (ie, 5 < 5 will be false), then just _mSelectedVar, no comma*/
    %end;
%mend;
%test;

View solution in original post

8 REPLIES 8
MeganE
Pyrite | Level 9

So, messing around with it still, i removed the input macro reference on the %macro line, and set it up as a %let instead for testing, and it ran without error.  I changed nothing else. 

 

So the code works now, but if someone knows WHY!?!?!?!?!?!?, that would be incredibly helpful.  🙂

 

%let varlist     = PROVHCFA seq_keyc HCFASAF DISCSTAT PDGNS_CD;             *define variables of interest;

%macro test;
    %put _mClist     = &varList;                 *define variables of interest;
    %let _mSelectedVar =;
    %let end=%sysfunc(countw(&varList.));
    %do i = 1 %to &end.;
            %if &i < %sysfunc(countw(&varList.)) %then
                  %let _mSelectedVar = &_mSelectedVar %scan(&varList,%eval(&i)),;    /*if 1 < 5 then _mSelectedVar = _mSelectedVar + a comma*/
            %else %let _mSelectedVar = &_mSelectedVar %scan(&varList,%eval(&i));    /*if last variable (ie, 5 < 5 will be false), then just _mSelectedVar, no comma*/
    %end;
%mend;
%test;

Loko
Barite | Level 11

hello,

 

when you call the macro like you do - %test (varlist=); you set the value of the macro variable varlist to blank.

if you want it to have the value of _mClist, call the macro: %test ();

 

MeganE
Pyrite | Level 9
I dont' know what you mean. When it wasn't working, varlist was called another macro:
(varList = &_mClist)
ballardw
Super User

HOW are you actually attempting to use this macro? I do not see how anything sees the result of this this variable unless you are dangerously expecting a global macro variable _mSelectedVar to exist before calling the macro.

And what was the value of &_mClist when the error occurs.

 

You might want to set Option Mprint Symbolgen; then re-run the code and show us the log.

 

 

MeganE
Pyrite | Level 9
I didn't write the code, i'm just trying to recreate it. It builds a list of variables that don't have commas, with commas, so they can be used in a proc sql step a bit further on. I got it to run though, thanks.
Astounding
PROC Star

Megan,

 

Loko actually gave you the correct answer.  Look at the difference between the macro call that didn't work, vs. the one that did work.

 

%test (varlist=);   /* did not work */

%test;  /* did work */

 

The first macro call uses the macro but overrides the default value for &VARLIST, giving it a null value.  The second macro call uses the default value for &VARLIST from when the macro was defined.

 

COUNTW will have trouble when it encounters a null value for &VARLIST. 

 

Finally, note that you may not need this macro at all.  The IN operator in a WHERE clause does not require commas to separate values.  Spaces are usually fine.

MeganE
Pyrite | Level 9
As far as i know, you can't separate variables in the select statement of proc sql without commas. That's where this string is being used.
Astounding
PROC Star

You're right about that.  I was picturing values of a variable.  The variable names require the commas.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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.

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
  • 8 replies
  • 5332 views
  • 1 like
  • 4 in conversation