BookmarkSubscribeRSS Feed
buckeye
Obsidian | Level 7
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;
16 REPLIES 16
sbb
Lapis Lazuli | Level 10 sbb
Lapis Lazuli | Level 10
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.
buckeye
Obsidian | Level 7
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.
sbb
Lapis Lazuli | Level 10 sbb
Lapis Lazuli | Level 10
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
buckeye
Obsidian | Level 7
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!
RickM
Fluorite | Level 6
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?
buckeye
Obsidian | Level 7
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.
sasuser1000
Calcite | Level 5
Did you try to run the code with the changes that I posted?
buckeye
Obsidian | Level 7
Yes, I did. It works. You're my hero. I now have a much better understanding of how macro works. Thanks a lot.
sasuser1000
Calcite | Level 5
Great 🙂
RickM
Fluorite | Level 6
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.
buckeye
Obsidian | Level 7
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.
sasuser1000
Calcite | Level 5
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;
chang_y_chung_hotmail_com
Obsidian | Level 7
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.
data_null__
Jade | Level 19
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]

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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
  • 16 replies
  • 1441 views
  • 0 likes
  • 7 in conversation