DATA Step, Macro, Functions and more

Return values, sort of

Reply
Contributor
Posts: 24

Return values, sort of

Hi all,

I'm trying to have a macro that counts number of obs in a dataset that is passed. But why the if statement does not work as shown below. Thanks in advance.


%MACRO COUNTOBS(DSNM,retval);
DATA existingMacroVars;
SET sashelp.vmacro
( WHERE= ( UPCASE( name ) = UPCASE( "&retval" ) AND SCOPE = 'GLOBAL' )) ;
RUN;
%LET dsid=%SYSFUNC(OPEN(existingMacroVars ));
%LET cnt=%SYSFUNC(ATTRN( &dsid, nobs ));
%LET dsid=%SYSFUNC(CLOSE( &dsid ));
%IF &cnt GT 0 %THEN %DO;
%LET dsid = %SYSFUNC( OPEN(&DSNM) );
%LET nobs = %SYSFUNC( ATTRN(&dsid,nobs) );
%LET rc = %SYSFUNC( CLOSE(&dsid) );
%LET &retval = &nobs;
%END;
%MEND COUNTOBS;

data mydata;
input name $ dept $;
datalines;
John Sales
Mary Acctng
Bill Admin
;
run;

%GLOBAL gRetVal;
%LET gRetVal=;
%COUNTOBS(mydata,gRetVal);

%if &gRetVal > 0 %then %do;
proc sql;
select * from mydata;
quit;
%end;

RUN;
Super Contributor
Super Contributor
Posts: 3,174

Re: Return values, sort of

Running your SAS code piece gives this error:

ERROR: The %IF statement is not valid in open code.


So, you need to put any SAS macro language code within a SAS macro.

Scott Barry
SBBWorks, Inc.
Contributor
Posts: 24

Re: Return values, sort of

thanks for the advise. But can you please give out the fix that makes the code running because I'm tired of the piece of code. thanks a lot.
Super Contributor
Super Contributor
Posts: 3,174

Re: Return values, sort of

Honestly, this is the most basic SAS MACRO language coding skill. How can you expect to be able to support, enhance, etc. the code if you are unable to get it to function in the first place?

Scott Barry
SBBWorks, Inc.

Suggested Google advanced search argument, this topic / post:

macro language programming introduction site:sas.com
Contributor
Posts: 24

Re: Return values, sort of

Ok, thanks for the encouragement, sort of. But I'm very new to SAS and I developed that piece of macro. I think there must be a way to use the variable so code can be conditionally executed.

Anybody else has an idea to make it work? Thanks in advance!
Regular Contributor
Posts: 165

Re: Return values, sort of

You were already told how to get it to work. You need to put your %IF ... %THEN %DO ... %END inside of a macro and then call the macro. This is just 3 lines of code to add so why do you need someone else to write it for you?
Contributor
Posts: 24

Re: Return values, sort of

I guess this is way smart SAS dudes help others. I came from .NET and I've never seen this kind of attitude.

The only stupid questions are the ones that are not asked. Thanks anyway.
Contributor
Posts: 60

Re: Return values, sort of

Did you try to run the code with the changes that I posted?
Contributor
Posts: 24

Re: Return values, sort of

Posted in reply to sasuser1000
Yes, I did. It works. You're my hero. I now have a much better understanding of how macro works. Thanks a lot.
Contributor
Posts: 60

Re: Return values, sort of

Great Smiley Happy
Regular Contributor
Posts: 165

Re: Return values, sort of

Asking why your macro doesn't work is not the issue. You need to show others that you are, at the very least, listening to them and putting forth some effort. sbb told you what you needed to do to get the code working and your reply was, "thanks for the advise. But can you please give out the fix that makes the code running because I'm tired of the piece of code." Asking what he meant by put the code within a macro would have been ok. Asking someone to do it for you because you are "too tired" is insulting. It implies that you think their time is worth less than your's.
Contributor
Posts: 24

Re: Return values, sort of

Your thinking is naively deep and in a wrong direction. No one's time is more valuable professionally than other's in this forum. We come here to seek solutions or "shortcuts" and enjoy the programming in SAS. Please don't think any other ways, otherwise please just have a laugh and don't reply.
Contributor
Posts: 60

Re: Return values, sort of

Run this

options mprint mlogic symbolgen;
%MACRO COUNTOBS(DSNM,retval);
DATA existingMacroVars;
SET sashelp.vmacro
( WHERE= ( UPCASE( name ) = UPCASE( "&retval" ) AND SCOPE = 'GLOBAL' )) ;
RUN;
%LET dsid=%SYSFUNC(OPEN(existingMacroVars ));
%LET cnt=%SYSFUNC(ATTRN( &dsid, nobs ));
%LET dsid=%SYSFUNC(CLOSE( &dsid ));
%IF &cnt GT 0 %THEN %DO;
%LET dsid = %SYSFUNC( OPEN(&DSNM) );
%LET nobs = %SYSFUNC( ATTRN(&dsid,nobs) );
%LET rc = %SYSFUNC( CLOSE(&dsid) );
%LET &retval = &nobs;
%END;
%MEND COUNTOBS;

data mydata;
input name $ dept $;
datalines;
John Sales
Mary Acctng
Bill Admin
;
run;

%GLOBAL gRetVal;
%LET gRetVal=;
%COUNTOBS(mydata,gRetVal);

%MACRO test;
%if &gRetVal > 0 %then %do;
proc sql;
select * from mydata;
quit;
%end;
%mend test;
%test;
Regular Contributor
Posts: 241

Re: Return values, sort of

It is not trivial to write a general macro that returns the number of observations in a SAS data set. Read Jack Hamilton's famous SUGI26 paper to see the reasons why this is so. You can see his macro source code in the appendix of the paper.
Respected Advisor
Posts: 3,799

Re: Return values, sort of

It is rare that you really need to know how many obs. Usually just knowing SOME or NONE is usually adequate. This is evidenced by your code
[pre]%if &gRetVal > 0 %then %do;[/pre]
I would suggest a more conservative approach that uses a simple data step.

[pre]
data class;
set sashelp.class;
stop; *remove(or comment) to get obs;
run;
data noobs;
msg = 'No observations present in the dataset.';
attrib msg label='~';
if eof then do;
output;
call execute('proc print split="~" noobs data=noobs; run;');
end;
else call execute('proc print data=class; run;');
stop;
set class(drop=_all_) end=eof;
run;
[/pre]
Ask a Question
Discussion stats
  • 16 replies
  • 259 views
  • 0 likes
  • 7 in conversation