BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
bemariec
Obsidian | Level 7

Hi! I did a code to list every folder in a certain path and I sorted them (befor this step) and the folder I'm interested in are in the table "Filenames1593_epuree", witch I called at the end of the macro bellow. It contains 25 folder names.

 

/*****List of all the folders to open****/

/*****determine the number of different name in the table*****/
%macro ouvrir(table);
    data _null_;
    set &table. end=eof;
    if eof then call symput('nomdossier',_n_);
run;

 

/*****for every non empty line, attribute a memname into the 'dossier' variable************/
%do i=1 %to &nomdossier;
    data _null_;
    set &table.(where=(numero=&i.));
    call symput('dossier',memname);
    run;
    %put &dossier;
%end;
%mend ouvrir;
%ouvrir(Filenames1593_epuree);

 

This macro up here works well. The problem is when I want to use these folder names to open them and get to every file inside of it. I did this bellow and it works well if I test it with a specific folder instead of &dossier. But, when I do it with a variable in de %let statement, I get nothing... (see log message after the code). What am I doing wrong? Thank you very much!!


%let rep=\\sdlc000-000010\soutien$\Projets\ORN - STL-0108\Acquisitions\1593\&dossier.;

filename profileA "&rep.";

data fichiers_profileA;
length name $55;
drop rc did i;
did=dopen("profileA");
if did > 0 then do;
do i=1 to dnum(did);
    name=dread(did,i);
    if findw(name, 'profileA.csv')>0 then output;
end;
rc=dclose(did);
end;
else put 'Could not open directory';
run;

 

log message

2764  %let rep=\\sdlc000-000010\soutien$\Projets\ORN - STL-0108\Acquisitions\1593\&dossier.;
WARNING: Apparent symbolic reference DOSSIER not resolved.
2765
2766  filename profileA "&rep.";
WARNING: Apparent symbolic reference DOSSIER not resolved.
2767
2768  data fichiers_profileA;
2769  length name $55;
2770  drop rc did i;
2771  did=dopen("profileA");
2772  if did > 0 then do;
2773  do i=1 to dnum(did);
2774      name=dread(did,i);
2775      if findw(name, 'profileA.csv')>0 then output;
2776  end;
2777  rc=dclose(did);
2778  end;
2779  else put 'Could not open directory';
2780  run;

Could not open directory
NOTE: The data set WORK.FICHIERS_PROFILEA has 0 observations and 1 variables.
NOTE: DATA statement used (Total process time):
      real time           0.01 seconds
      cpu time            0.01 seconds

 

1 ACCEPTED SOLUTION

Accepted Solutions
Reeza
Super User

@bemariec wrote:
I'm such a begginer in all this :|..




Sometimes not recreating the wheel is a good idea. 

There are a lot of macros on line that cover how to list all files, here's one example from the SAS documentation:

Example 2: List All Files within a Directory Including Subdirectories

http://support.sas.com/documentation/cdl/en/mcrolref/69726/HTML/default/viewer.htm#n0js70lrkxo6uvn1f...

View solution in original post

6 REPLIES 6
Tom
Super User Tom
Super User

Sounds like a macro variable scoping issue, but it is hard to tell from what you posted.

What happens if you make the macro variable global?

 

Where are you setting the macro variable DOSSIER?

The only reference I see in you posted code is inside of %DO loop inside of one of the macros you posted.  Is that the value you want? If so which version did you want to use?

 

bemariec
Obsidian | Level 7
I'm such a begginer in all this :|... I created the first macro so I can list every observation from the variable memname in the table "Filenames1593_epuree". You can consider that there is nothing before this macro... So it is the only place where I have defined the variable "dossier" (in the call symput). I try to use this variable "dossier" in the next macro so I can get a new file with all the names of the .csv files that contains "profile.csv" in the name. I tried what you suggested (define the variable dossier in a global statement), but it doesn't help... the log doesn't even give me the kind of error... (see below)
%macro ouvrir(table);
data _null_;
set &table. end=eof;
if eof then call symput('nomdossier',_n_);
run;

%do i=1 %to &nomdossier;
data _null_;
set &table.(where=(numero=&i.));
%global dossier;
call symput('dossier',memname);
run;
%put &dossier;
%end;
%mend ouvrir;
%ouvrir(Filenames1593_epuree);

LOG :
3003 %let rep=\\sdlc000-000010\soutien$\Projets\ORN - STL-0108\Acquisitions\1593\&dossier.;
3004
3005 filename profileA "&rep.";
3006
3007 data fichiers_profileA;
3008 length name $55;
3009 drop rc did i;
3010 did=dopen("profileA");
3011 if did > 0 then do;
3012 do i=1 to dnum(did);
3013 name=dread(did,i);
3014 if findw(name, 'profileA.csv')>0 then output;
3015 end;
3016 rc=dclose(did);
3017 end;
3018 else put 'Could not open directory';
3019 run;

NOTE: The data set WORK.FICHIERS_PROFILEA has 0 observations and 1 variables.
NOTE: DATA statement used (Total process time):
real time 0.03 seconds
cpu time 0.00 seconds

you posted: "The only reference I see in you posted code is inside of %DO loop inside of one of the macros you posted. Is that the value you want? If so which version did you want to use?"

I don't understand what is a version of a variable... and yess, the 'dossier' in the %do loop is the variable I want... it is a character variable...



Thanks for your patience!!


Tom
Super User Tom
Super User

My quesiton is which of the many values of the dataset variable MEMNAME that you are pushing into the macro variable named DOSSIER with the CALL SYMPUT() function call do you want to access after the macro has finished?

 

So let's make a simplied version of what it looks like you macro is doing (at least in regard to the setting macro variables). Lets use TEST instead of DOSSIER because it easier for me to spell.

%macro test(N);
%local i;
%global test ;
%do i=1 %to &n ;
  %let test=&i;
  %put &=i &=test ;
%end ;
%mend test;

So now let's see what happens to TEST when I call this macro and what value of TEST it leaves after it finishs.

%let test=BEFORE MACRO CALL;
%put &=test;
%test(5);
%put &=test;

So the macro assigned 5 different values to TEST when it was running, but only the last one is available after the macro stops.

1096  %let test=BEFORE MACRO CALL;
1097  %put &=test;
TEST=BEFORE MACRO CALL
1098  %test(5);
I=1 TEST=1
I=2 TEST=2
I=3 TEST=3
I=4 TEST=4
I=5 TEST=5
1099  %put &=test;
TEST=5

What is your actual goal with this program?

Reeza
Super User

@bemariec wrote:
I'm such a begginer in all this :|..




Sometimes not recreating the wheel is a good idea. 

There are a lot of macros on line that cover how to list all files, here's one example from the SAS documentation:

Example 2: List All Files within a Directory Including Subdirectories

http://support.sas.com/documentation/cdl/en/mcrolref/69726/HTML/default/viewer.htm#n0js70lrkxo6uvn1f...

ballardw
Super User

This sounds like you have a data set that is supposed to have  a list of file names and then you are searching a directory to see if the specific filename exists in the directory. Is that what you are actually attempting to do?

 

If so what will you do when you have the list of found files?

 

The path you show for your &rep macro variable indicates to me that the name referenced by memname may well be case sensitive.

 

And your current code will only have a value of dossier for the last record in the table after the end of that loop.

You would have to have the entire

%let rep=\\sdlc000-000010\soutien$\Projets\ORN - STL-0108\Acquisitions\1593\&dossier.;

filename profileA "&rep.";

data fichiers_profileA;
length name $55;
drop rc did i;
did=dopen("profileA");
if did > 0 then do;
do i=1 to dnum(did);
    name=dread(did,i);
    if findw(name, 'profileA.csv')>0 then output;
end;
rc=dclose(did);
end;
else put 'Could not open directory';
run;

Inside the %do loop in your Ouvir macro to have a chance of opening more than one folder. Your output data set would have to change for each value, otherwise you overwrite the set or you would have to append the values to different dataset at each pass through the loop.

 

chithra
Quartz | Level 8

Use %global dossier inside the macro.

Hope this will solve your pbm.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 6 replies
  • 745 views
  • 4 likes
  • 5 in conversation