Jinhua Wang
Jinhua Wang

Reputation: 1759

ERROR: No logical assign for filename FNAME

I was running the following code:

%LET TIME_INTERVAL='MINUTE15';
/*
 * Get the file names of a specific location
 */
%MACRO get_filenames(location,filenames);
filename _dir_ "%bquote(&location.)";
data &filenames(keep=fname);
  handle=dopen( '_dir_' );
  if handle > 0 then do;
    count=dnum(handle);
    do i=1 to count;
      fname=dread(handle,i);
      output &filenames;
    end;
  end;
  rc=dclose(handle);
run;
filename _dir_ clear;
%MEND;

%MACRO NBBO (fname);
DATA TICKERS_NBBO;
    INFILE &fname;
    INPUT SYMBOL $;
RUN;
%mend;

%MACRO CALCU(DATE_VAR);
%get_filenames('./groups',filenames);
data _null_;
    set filenames;
    by fname;
    if fname =: "&TIME_INTERVAL";
    %NBBO(fname);
run;
%mend;

However, I got the error: ERROR: No logical assign for filename FNAME.

I was wondering what is the reason that caused this?

There are lots of csv files in the folder groups. I was trying to run the NBBO macro on each of the files and load each of the files into a dataset with infile statement.

Upvotes: 0

Views: 2186

Answers (1)

Joe
Joe

Reputation: 63424

You're mixing up data step code and macro code in a manner that's not permitted. You can't extract the contents of the variable fname and use it to populate a macro variable in this way. Instead you're passing the text fname to that macro variable, which then doesn't work.

You also can't run another data step inside a data step in this manner. You need to use one of the various methods for executing it after the data step terminates or during execution.

Finally, it's entirely unclear to me what you're really doing here: because you're going to end up with just one of those files in the dataset.

I think you may want something like this, which is much easier. I use the FILEVAR option in infile, which uses the value of a variable; I have to make some changes to how you calculate fname (I think you have to do this anyway, it has no directory name in it).

%MACRO get_filenames(location,filenames);
filename _dir_ "%bquote(&location.)";
data &filenames(keep=fname);
  length fname $512;
  handle=dopen( '_dir_' );
  if handle > 0 then do;
    count=dnum(handle);
    do i=1 to count;
      fname=catx('\',"%bquote(&location.)",dread(handle,i));
      output &filenames;
    end;
  end;
  rc=dclose(handle);
run;
filename _dir_ clear;
%MEND;

%get_filenames(location=c:\temp\cars, filenames=fnam);

data tickers_nbbo;
  set fnam;
  infile a filevar=fname  dlm=',';
  input symbol $;
run;

If you really do need to call a data step separately, you either need to use CALL EXECUTE, DOSUBL, or construct macro calls in another way (PROC SQL SELECT INTO, %INCLUDE, etc.).

Upvotes: 1

Related Questions