There certainly is Cynthia. I wrote this macro into my toolkit in 2000, so I haven't looked at any changes of behaviour in the move from V6 to SAS8 and later.
%Macro XGetDNob( MDSName = , /* NObs in this data set */
MMacVar = ) /* Place NObs in this macro */
/ /*Store*/ Des = 'Get data set observation count to macro';
%Local DSid;
%Global &MMacVar;
%Let &MMacVar = -1; /* If data set does not exist,
force -1 return value */
%Let DSid = %SysFunc( Open( &MDSName) );
%If &DSid %Then %Do;
%Let &MMacVar = %SysFunc( Attrn( &DSid, NLObs) );
%Let SysRc = %SysFunc( Close( &DSid) );
%If &SysRc %Then
%Put Macro Call Error: Data Set &MDSName was not closed properly;
%End;
%Else %Put Macro Call error: - %SysFunc( SysMsg( ) );
%Mend XGetDNob;
There was an extended version I also wrote that could retrieve any data set attribute. With the extended V9 data set attributes, this has proven very useful as well.
I know you recognise the meaning of the attribute NLObs, but it is worth documenting that it is the number of Logical Observations, and will not include obs marked for deletion, which are otherwise included in the NObs count. It is a reminder that when you look under the bonnet in SAS, you need to know what you are looking for.
Kind regards
David