33
%macro a(libname=,domain=);
%let folder=C:\Users\SAS;
filename DIR1 "&folder";
data DT1 ;
length VAR $400 ;
*** Open directory ;
did = dopen("DIR1") ;
*** Store filename and label into dataset;
do i = 1 to dnum( did ) ;
VAR = scan(dread( did , i ),1,'.') ;
call symputx(compress('fname'||trim(i)),var);
output;
end;
/* I would like to get dnum(did) here instead of the actual number of 33 */
%do i=1 %to 33;
proc transpose data=&libname..&&fname&i (obs=0) out=&&fname&i;
var _ALL_;
run;
data a1 ;
length domainkeys $ 400;
set &&fname&i end=eof;
retain domainkeys '';
domainkeys = trim(domainkeys) ||' '||trim(put(_name_,20.));
if eof then call symputx(compress("&&fname&i"||"KEEPSTRINGfd"),domainkeys, 'G' );
run;
%end;
%mend;
A couple of items to consider.
First, to solve the problem entirely, you need to add a RUN statement to your DATA step. Without it, SAS tries to evaluate the %DO loop boundaries before actually running the DATA step, and &NUMFILES does not yet exist (because the DATA step has not yet executed).
Second, this might be a little simpler and would get rid of the annoying conversion note:
numfiles=dnum(did);
call symputx('numfiles', numfiles);
Switching to CALL SYMPUTX performs the numeric to character conversion without a note, and automatically strips out any blanks caused by the conversion.
Read the output of the DNUM function into a variable as explained in the documentation:
I mean
%do i=1 %to dnum(did);
does not work.
You need to do this:
numfiles=dnum(did);
call symput('numfiles', strip(put(numfiles, 8.)));
....
....
%do i = 1 %to &numfiles;
Thank you for your suggestion, but it seems it does not work.
NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
2:25
NOTE: The SAS System stopped processing this step because of errors.
WARNING: The data set WORK.DT1 may be incomplete. When this step was stopped there were 0 observations and 4 variables.
WARNING: Data set WORK.DT1 was not replaced because this step was stopped.
NOTE: DATA statement used (Total process time):
real time 24.37 seconds
cpu time 1.74 seconds
WARNING: Apparent symbolic reference NUMFILES not resolved.
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The
condition was: &numfiles
ERROR: The %TO value of the %DO I loop is invalid.
ERROR: The macro A will stop executing.
Depending on where you put the call symput(), it might happen that it is never executed (ie if no files are present there).
A better method of creating repeating code is to not use a %do loop, but to use call execute in a date _null_ step running off the dataset with dataset names.
Please post the complete log including the source statements otherwise we have no way of working out what went wrong.
A couple of items to consider.
First, to solve the problem entirely, you need to add a RUN statement to your DATA step. Without it, SAS tries to evaluate the %DO loop boundaries before actually running the DATA step, and &NUMFILES does not yet exist (because the DATA step has not yet executed).
Second, this might be a little simpler and would get rid of the annoying conversion note:
numfiles=dnum(did);
call symputx('numfiles', numfiles);
Switching to CALL SYMPUTX performs the numeric to character conversion without a note, and automatically strips out any blanks caused by the conversion.
Not using a run; is one of the little sins that people commit frequently, and that sometimes comes back and bites them in the behind.
Like the dot for macro variables, a run; (in the right place) is never wrong, and sometimes direly needed.
I have an inkling this will become Maxim 50.
Thank you very much for your help.
I should have added "run".
Please give the solution to @Astounding, because he caught the mistake. I just made a clever formulation out of it.
@Kurt_Bremser@LAYMAN_YO@Astounding I have marked the correct solution. Thanks, all!
Why are you using the list of files found in one directory to then find the variable names in datasets from a SAS libref?
If the libref is pointing to the same directory why not just query that metadata directly?
proc contents data=&libname.._all_ noprint out=contents; run;
proc sort data=contents;
by memname varnum;
run;
April 27 – 30 | Gaylord Texan | Grapevine, Texas
Walk in ready to learn. Walk out ready to deliver. This is the data and AI conference you can't afford to miss.
Register now and lock in 2025 pricing—just $495!
SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.
Find more tutorials on the SAS Users YouTube channel.