DATA Step, Macro, Functions and more

Countw within a macro

Accepted Solution Solved
Reply
Frequent Contributor
Posts: 128
Accepted Solution

Countw within a macro

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

 

 

 

 


Accepted Solutions
Solution
‎09-15-2016 11:55 AM
Frequent Contributor
Posts: 128

Re: Countw within a macro

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.  Smiley Happy

 

%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


All Replies
Solution
‎09-15-2016 11:55 AM
Frequent Contributor
Posts: 128

Re: Countw within a macro

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.  Smiley Happy

 

%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;

Super Contributor
Posts: 308

Re: Countw within a macro

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 ();

 

Frequent Contributor
Posts: 128

Re: Countw within a macro

I dont' know what you mean. When it wasn't working, varlist was called another macro:
(varList = &_mClist)
Super User
Posts: 11,343

Re: Countw within a macro

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.

 

 

Frequent Contributor
Posts: 128

Re: Countw within a macro

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.
Super User
Posts: 5,504

Re: Countw within a macro

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.

Frequent Contributor
Posts: 128

Re: Countw within a macro

Posted in reply to Astounding
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.
Super User
Posts: 5,504

Re: Countw within a macro

[ Edited ]

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

☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 8 replies
  • 805 views
  • 1 like
  • 4 in conversation