In reply to Jens Pfeil.

Hi Jens,
Thank you for sharing your implementation. Your main point is to call this macro once and get everything it can provide at once. It makes sense in some scenarios, but there are some caveats:

1. With this implementation this code stops being a macro function as it does not return a value. It is a macro, but not a macro function. I addressed that in my previous blog post How to create and use SAS macro functions, and my goal for this post was to show how to create multi-purpose macro functions.

2. I strongly advise not to define hard-coded global macro variable names within a SAS macro as this is prone to wreaking havoc in your SAS program invoking such a macro in case that program uses the same macro variable names for other purposes. Such a practice contradicts the principle of foolproof software development (see Are you developing foolproof solutions?) For your implementation, instead of hard-coding your global macro variable names inside the macro, I would make them parameters to allow macro users to assign their own names. Also, by making them named parameters (instead of positional) you would effectively make them optional parameters, so you can only request calculating those that you need. Below is how I would write this code:

%macro GetDSinfo(dset=, nobs=, nvars=, varlist=, varlistc=);
/* dset - data set name */
/* nobs, nvars, varlist, varlistc - optional macro variable names */
%local dsid result i;
%let dsid = %sysfunc(open(&dset));
%global &nobs &nvars &varlist &varlistc;

%if &dsid %then
%do;
%if &nobs ne %then %let &nobs = %sysfunc(attrn(&dsid,nlobs));
%if &nvars ne %then %let &nvars = %sysfunc(attrn(&dsid,nvars));
%if &varlist ne %then
%do i=1 %to %sysfunc(attrn(&dsid,nvars));
%let result = &result %sysfunc(varname(&dsid,&i));
%let &varlist = &result;
%end;
%if &varlistc ne %then
%do i=1 %to %sysfunc(attrn(&dsid,nvars));
%if &i eq 1 %then %let result = %sysfunc(varname(&dsid,&i));
%else %let result = &result,%sysfunc(varname(&dsid,&i));
%let &varlistc = &result;
%end;
%let dsid = %sysfunc(close(&dsid));
%end;
%else %put %sysfunc(sysmsg());

%mend GetDSinfo;

%GetDSinfo(dset=SASHELP.CARS, nobs=_NOBS1, varlist=_VARLIST1);
%put &=_NOBS1;
%put &=_VARLIST1;

%GetDSinfo(dset=SASHELP.CARS, nobs=_NOBS2, nvars=_NVARS2, varlist=_VARLIST2, varlistc=_VARLISTC2);
%put &=_NOBS2;
%put &=_NVARS2;
%put &=_VARLIST2;
%put &=_VARLISTC2;