BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
ydang
Calcite | Level 5

Hi, 

I would like to use a macrovariable in filename in a macro, but it gives error NOTE: Argument 1 to function DNUM(0) at line 41 column 69 is invalid.
ERROR: Invalid DO loop control information, either the INITIAL or TO expression is missing or the BY expression is missing, zero,
or invalid. File doesn't seem to open.  pathname is created earlier as C:\Users\ydang\OneDrive - Prinses Maxima Centrum\CDM_share\Briga share\

 

%macro basefile2 (pathname, haveseq );
%let path=cats(strip("&studypath"),strip("&pathname"));
data have1;
rc=filename('xx','&path');
did=dopen('xx');
do i=1 to dnum(did);
fname=dread(did,i);
output;
end;
rc=dclose(did);
run;
%put path;
%mend basefile2;

%basefile2 (01 Source\20230609,1);

 

It works fine if I use:

rc=filename('xx',C:\Users\ydang\OneDrive - Prinses Maxima Centrum\CDM_share\Briga share\01 Source\20230609

1 ACCEPTED SOLUTION

Accepted Solutions
quickbluefish
Barite | Level 11
You need to use double quotes around all macro variables, not single. SAS will not resolve them otherwise.

View solution in original post

7 REPLIES 7
quickbluefish
Barite | Level 11
You need to use double quotes around all macro variables, not single. SAS will not resolve them otherwise.
ydang
Calcite | Level 5

Add double quotation marks, but still getting same error.

 

ydang_0-1737105851190.png

 

%macro basefile6 ( haveseq, pathname );
data have_&haveseq;
rc=filename("xx",symget("pathname"));
did=dopen("xx");
do i=1 to dnum(did);
fname=dread(did,i);
output;
end;
rc=dclose(did);
rc=filename (did);
run;
%mend basefile6;

ydang
Calcite | Level 5

Double quotes without using symget worked. 

 

%macro basefile ( haveseq, pathname );
data have_&haveseq;
rc=filename('xx',"&pathname");
did=dopen('xx');
do i=1 to dnum(did);
fname=dread(did,i);
output;
end;
rc=dclose(did);
rc=filename (did);
run;
%mend basefile;

yabwon
Onyx | Level 15

There are several things to fix/understand in your code.

 

1) Whatever value macrovariable PATH will have in this part:

rc=filename('xx','&path');

macrovariable's value will NOT be resolved because single quoted text strings are not resolved by macroprocesor.

Run this and see what will you get:

%let ABC = 123456789;

data _null_;
x = "&ABC.";
y = '&ABC.';

put x= ;
put y= ;
run;

2) when you are creating macrovariable PATH value you have the following:

%let path=cats(strip("&studypath"),strip("&pathname"));

all that is considered by the macroprocesor as a text, so CATS and STRIP are not considered as functions but just ordinary text strings, so for example if STUDYPATH and PATHNAME would be:

%let studyname=C:\directory1;
%let pathname=\directory2\directory3\;

your final value of macrovariable PATH would be:

cats(strip("C:\directory1"),strip("\directory2\directory3\"))

not as I guess you would like to have:

C:\directory1\directory2\directory3\

BTW. use of STRIP is redundand since CATS already strips blank spaces (that's the "S" at the name)

 

3) if you really would like to grab macrovariable's value in data step, instead:

rc=filename('xx',"&path");

use SYMGET:

rc=filename('xx',symget('path'));

it's much more robust solution.

 

And 4) just for clarity, what is your purpose? What do you want the cod to do? If you could describe it maybe the community could share better solution. Trust me SAS is old enough language (50+ years) to have majority of questions already answered (sometimes multiple times).

 

 

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



ydang
Calcite | Level 5

I'm now using symget. I would like to run the macro with a call execute, so I will get a list of all the files in the folder. In the end some of these files would need to be deleted. 

I've now created the full path in variable pathname in the dataset deletefolders, this also contains the pathname.  The deletefolder dataset has multiple folders listed with haveseq as sequence number. 

 

I'm still getting the same error when using symget. 

 

%macro basefile3 ( haveseq, pathname );
data have_&haveseq;
rc=filename('xx',symget('pathname'));
did=dopen('xx');
do i=1 to dnum(did);
fname=dread(did,i);
output;
end;
rc=dclose(did);
run;
%mend basefile3;

 

data _null_;
set Deletefolders;
call execute(cats('%basefile3(',haveseq||','||pathname,')'));
run;

yabwon
Onyx | Level 15

Use BasePlus package for that task, in particular macro called %DirsAndFiles()

 

Installation:

filename packages "/a/path/to/store/package";

filename SPFinit url "https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/SPF/SPFinit.sas";
%include SPFinit;
filename SPFinit clear;

%installPackage(SPFinit BASEPLUS) 

Package use:

/* LOAD PACKAGE: */
filename packages "/a/path/to/store/package"; /* setup directory for packages */
%include packages(SPFinit.sas);                     /* enable the framework */

%loadPackage(BasePlus)


 /* USE PACKAGE: */

%dirsandfiles(C:\your\path\to\search\for,ods=work.result)

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



Tom
Super User Tom
Super User

@ydang wrote:

I'm now using symget. I would like to run the macro with a call execute, so I will get a list of all the files in the folder. In the end some of these files would need to be deleted. 

I've now created the full path in variable pathname in the dataset deletefolders, this also contains the pathname.  The deletefolder dataset has multiple folders listed with haveseq as sequence number. 

 

I'm still getting the same error when using symget. 

 

%macro basefile3 ( haveseq, pathname );
data have_&haveseq;
rc=filename('xx',symget('pathname'));
did=dopen('xx');
do i=1 to dnum(did);
fname=dread(did,i);
output;
end;
rc=dclose(did);
run;
%mend basefile3;

 

data _null_;
set Deletefolders;
call execute(cats('%basefile3(',haveseq||','||pathname,')'));
run;


First point is fix the CALL EXECUTE call so that the macro execute AFTER the data step.  Wrap the macro triggers in %NRSTR() so that the call to the macro is pushed to run instead of the code the macro generates being pushed to run.  Also remove the || since you are already using CATS() to do the concatenation.

call execute(cats('%nrstr(%basefile3)(',haveseq,',',pathname,')'));

But why make separate datasets for each folder?  Ditch the macro and just put the DOPEN(),DREAD() logic into a data step and make ONE dataset with all of the file names.

data DeleteFiles;
  set Deletefolders;
  rc = filename('xx',pathname);
  did=dopen('xx');
  if did then do;
    do filenum=1 to dnum(did);
      length fname $256 ;
      fname=dread(did,filenum);
      output;
    end;
    rc=dclose(did);
  end;
  else put 'WARNING: Unable to open ' pathname 'as a directory.';
  drop rc did;
run;

If you want to use a macro then perhaps use one like https://github.com/sasutils/macros/blob/master/dirtree.sas

data _null_;
  set deletefolders end=eof;
  if _n_=1 then call execute('%nrstr(%dirtree)(out=deletefiles,directory=');
  else call execute('|');
  call execute(pathname);
  if eof then call execute(')');
run;
  

Add MAXDEPTH=1 to the macro call if you don't want it to recurse into subdirectories. 

hackathon24-white-horiz.png

The 2025 SAS Hackathon Kicks Off on June 11!

Watch the live Hackathon Kickoff to get all the essential information about the SAS Hackathon—including how to join, how to participate, and expert tips for success.

YouTube LinkedIn

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 7 replies
  • 1167 views
  • 1 like
  • 4 in conversation