%let DorsHHFPath =/dorsshare/HHFit;
%put &DorsHHFPath;
%macro drive(dir,ext);
%local cnt filrf rc did memcnt name;
%let cnt=0;
%let filrf=mydir;
%let rc=%sysfunc(filename(filrf,&dir));
%let did=%sysfunc(dopen(&filrf));
%if &did ne 0 %then %do;
%let memcnt=%sysfunc(dnum(&did));
%do i=1 %to &memcnt;
%let name=%qscan(%qsysfunc(dread(&did,&i)),-1,.);
%if %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) %then %do;
%if %superq(ext) = %superq(name) %then %do;
%let cnt=%eval(&cnt+1);
%put %qsysfunc(dread(&did,&i));
proc import datafile="&dir\%qsysfunc(dread(&did,&i))" out=dsn&cnt
dbms=csv replace;
run;
%end;
%end;
%end;
%end;
%else %put &dir cannot be open.;
%let rc=%sysfunc(dclose(&did));
%mend drive;
%drive(&DorsHHFPath,csv)
The above script is supposed to import all contents of the &DorsHHFPath share drive into a sas dataset. It is a series of folders with some having .csv files inside. Instead I get this error
26 %macro drive(dir,ext);
ERROR: Invalid macro name (. It should be a valid SAS identifier no longer than 32 characters.
ERROR: A dummy macro will be compiled.
I researched the error on google however it does not seem to answer why this is happening in my case.
Must be something before the macro definition. The macro compiles and executes without any error.
Run the macro with Option mprint and post the full log please.
I did restart the pc and sas sessions and the code does in fact run without issues. Here is the log. The code does not state how to actually produce the datasets with a proc sql or datastep. This is where I got the code
1 The SAS System 13:46 Tuesday, January 30, 2018
1 ;*';*";*/;quit;run;
2 OPTIONS PAGENO=MIN;
3 %LET _CLIENTTASKLABEL='HHF_Test_Program4';
4 %LET _CLIENTPROJECTPATH='';
5 %LET _CLIENTPROJECTNAME='';
6 %LET _SASPROGRAMFILE=;
7
8 ODS _ALL_ CLOSE;
9 OPTIONS DEV=ACTIVEX;
10 GOPTIONS XPIXELS=0 YPIXELS=0;
11 FILENAME EGSR TEMP;
12 ODS tagsets.sasreport13(ID=EGSR) FILE=EGSR
13 STYLE=HtmlBlue
14 STYLESHEET=(URL="file:///C:/Program%20Files/SASHome2/SASEnterpriseGuide/7.1/Styles/HtmlBlue.css")
15 NOGTITLE
16 NOGFOOTNOTE
17 GPATH=&sasworklocation
SYMBOLGEN: Macro variable SASWORKLOCATION resolves to "/egwork/SAS_work998500002E5A_ga016ada6.suntrust.com/SAS_workE3FB00002E5A_ga016ada6.suntrust.com/"
18 ENCODING=UTF8
19 options(rolap="on")
20 ;
NOTE: Writing TAGSETS.SASREPORT13(EGSR) Body file: EGSR
21
22 %let DorsHHFPath =/dorsshare/HHFit;
23 %put &DorsHHFPath;
SYMBOLGEN: Macro variable DORSHHFPATH resolves to /dorsshare/HHFit
/dorsshare/HHFit
24
25 %macro drive(dir,ext);
26 %local cnt filrf rc did memcnt name;
27 %let cnt=0;
28
29 %let filrf=mydir;
30 %let rc=%sysfunc(filename(filrf,&dir));
31 %let did=%sysfunc(dopen(&filrf));
32 %if &did ne 0 %then %do;
33 %let memcnt=%sysfunc(dnum(&did));
34
35 %do i=1 %to &memcnt;
36
37 %let name=%qscan(%qsysfunc(dread(&did,&i)),-1,.);
38
39 %if %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) %then %do;
40 %if %superq(ext) = %superq(name) %then %do;
41 %let cnt=%eval(&cnt+1);
42 %put %qsysfunc(dread(&did,&i));
43 proc import datafile="&dir\%qsysfunc(dread(&did,&i))" out=dsn&cnt
44 dbms=csv replace;
45 run;
46 %end;
47 %end;
48
49 %end;
50 %end;
51 %else %put &dir cannot be open.;
52 %let rc=%sysfunc(dclose(&did));
53
54 %mend drive;
2 The SAS System 13:46 Tuesday, January 30, 2018
55 %drive(&DorsHHFPath,csv)
MLOGIC(DRIVE): Beginning execution.
SYMBOLGEN: Macro variable DORSHHFPATH resolves to /dorsshare/HHFit
MLOGIC(DRIVE): Parameter DIR has value /dorsshare/HHFit
MLOGIC(DRIVE): Parameter EXT has value csv
MLOGIC(DRIVE): %LOCAL CNT FILRF RC DID MEMCNT NAME
MLOGIC(DRIVE): %LET (variable name is CNT)
MLOGIC(DRIVE): %LET (variable name is FILRF)
MLOGIC(DRIVE): %LET (variable name is RC)
SYMBOLGEN: Macro variable DIR resolves to /dorsshare/HHFit
MLOGIC(DRIVE): %LET (variable name is DID)
SYMBOLGEN: Macro variable FILRF resolves to mydir
SYMBOLGEN: Macro variable DID resolves to 1
MLOGIC(DRIVE): %IF condition &did ne 0 is TRUE
MLOGIC(DRIVE): %LET (variable name is MEMCNT)
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable MEMCNT resolves to 23
MLOGIC(DRIVE): %DO loop beginning; index variable I; start value is 1; stop value is 23; by value is 1.
MLOGIC(DRIVE): %LET (variable name is NAME)
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 1
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 1
SYMBOLGEN: Macro variable NAME resolves to sc
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is FALSE
MLOGIC(DRIVE): %DO loop index variable I is now 2; loop will iterate again.
MLOGIC(DRIVE): %LET (variable name is NAME)
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 2
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 2
SYMBOLGEN: Macro variable NAME resolves to FL
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is FALSE
MLOGIC(DRIVE): %DO loop index variable I is now 3; loop will iterate again.
MLOGIC(DRIVE): %LET (variable name is NAME)
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 3
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 3
SYMBOLGEN: Macro variable NAME resolves to al
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is FALSE
MLOGIC(DRIVE): %DO loop index variable I is now 4; loop will iterate again.
MLOGIC(DRIVE): %LET (variable name is NAME)
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 4
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 4
SYMBOLGEN: Macro variable NAME resolves to az
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is FALSE
MLOGIC(DRIVE): %DO loop index variable I is now 5; loop will iterate again.
MLOGIC(DRIVE): %LET (variable name is NAME)
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 5
SYMBOLGEN: Macro variable DID resolves to 1
3 The SAS System 13:46 Tuesday, January 30, 2018
SYMBOLGEN: Macro variable I resolves to 5
SYMBOLGEN: Macro variable NAME resolves to ca
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is FALSE
MLOGIC(DRIVE): %DO loop index variable I is now 6; loop will iterate again.
MLOGIC(DRIVE): %LET (variable name is NAME)
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 6
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 6
SYMBOLGEN: Macro variable NAME resolves to dc
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is FALSE
MLOGIC(DRIVE): %DO loop index variable I is now 7; loop will iterate again.
MLOGIC(DRIVE): %LET (variable name is NAME)
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 7
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 7
SYMBOLGEN: Macro variable NAME resolves to ehlp
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is FALSE
MLOGIC(DRIVE): %DO loop index variable I is now 8; loop will iterate again.
MLOGIC(DRIVE): %LET (variable name is NAME)
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 8
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 8
SYMBOLGEN: Macro variable NAME resolves to ga
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is FALSE
MLOGIC(DRIVE): %DO loop index variable I is now 9; loop will iterate again.
MLOGIC(DRIVE): %LET (variable name is NAME)
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 9
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 9
SYMBOLGEN: Macro variable NAME resolves to il
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is FALSE
MLOGIC(DRIVE): %DO loop index variable I is now 10; loop will iterate again.
MLOGIC(DRIVE): %LET (variable name is NAME)
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 10
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 10
SYMBOLGEN: Macro variable NAME resolves to in
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is FALSE
MLOGIC(DRIVE): %DO loop index variable I is now 11; loop will iterate again.
MLOGIC(DRIVE): %LET (variable name is NAME)
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 11
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 11
SYMBOLGEN: Macro variable NAME resolves to ky
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is FALSE
4 The SAS System 13:46 Tuesday, January 30, 2018
MLOGIC(DRIVE): %DO loop index variable I is now 12; loop will iterate again.
MLOGIC(DRIVE): %LET (variable name is NAME)
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 12
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 12
SYMBOLGEN: Macro variable NAME resolves to md
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is FALSE
MLOGIC(DRIVE): %DO loop index variable I is now 13; loop will iterate again.
MLOGIC(DRIVE): %LET (variable name is NAME)
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 13
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 13
SYMBOLGEN: Macro variable NAME resolves to mi
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is FALSE
MLOGIC(DRIVE): %DO loop index variable I is now 14; loop will iterate again.
MLOGIC(DRIVE): %LET (variable name is NAME)
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 14
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 14
SYMBOLGEN: Macro variable NAME resolves to ms
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is FALSE
MLOGIC(DRIVE): %DO loop index variable I is now 15; loop will iterate again.
MLOGIC(DRIVE): %LET (variable name is NAME)
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 15
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 15
SYMBOLGEN: Macro variable NAME resolves to nc
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is FALSE
MLOGIC(DRIVE): %DO loop index variable I is now 16; loop will iterate again.
MLOGIC(DRIVE): %LET (variable name is NAME)
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 16
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 16
SYMBOLGEN: Macro variable NAME resolves to nj
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is FALSE
MLOGIC(DRIVE): %DO loop index variable I is now 17; loop will iterate again.
MLOGIC(DRIVE): %LET (variable name is NAME)
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 17
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 17
SYMBOLGEN: Macro variable NAME resolves to nv
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is FALSE
MLOGIC(DRIVE): %DO loop index variable I is now 18; loop will iterate again.
MLOGIC(DRIVE): %LET (variable name is NAME)
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 18
5 The SAS System 13:46 Tuesday, January 30, 2018
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 18
SYMBOLGEN: Macro variable NAME resolves to lnk
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is TRUE
MLOGIC(DRIVE): %IF condition %superq(ext) = %superq(name) is FALSE
MLOGIC(DRIVE): %DO loop index variable I is now 19; loop will iterate again.
MLOGIC(DRIVE): %LET (variable name is NAME)
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 19
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 19
SYMBOLGEN: Macro variable NAME resolves to or
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is FALSE
MLOGIC(DRIVE): %DO loop index variable I is now 20; loop will iterate again.
MLOGIC(DRIVE): %LET (variable name is NAME)
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 20
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 20
SYMBOLGEN: Macro variable NAME resolves to ri
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is FALSE
MLOGIC(DRIVE): %DO loop index variable I is now 21; loop will iterate again.
MLOGIC(DRIVE): %LET (variable name is NAME)
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 21
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 21
SYMBOLGEN: Macro variable NAME resolves to tn
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is FALSE
MLOGIC(DRIVE): %DO loop index variable I is now 22; loop will iterate again.
MLOGIC(DRIVE): %LET (variable name is NAME)
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 22
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 22
SYMBOLGEN: Macro variable NAME resolves to oh
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is FALSE
MLOGIC(DRIVE): %DO loop index variable I is now 23; loop will iterate again.
MLOGIC(DRIVE): %LET (variable name is NAME)
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 23
SYMBOLGEN: Macro variable DID resolves to 1
SYMBOLGEN: Macro variable I resolves to 23
SYMBOLGEN: Macro variable NAME resolves to db
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is TRUE
MLOGIC(DRIVE): %IF condition %superq(ext) = %superq(name) is FALSE
MLOGIC(DRIVE): %DO loop index variable I is now 24; loop will not iterate again.
MLOGIC(DRIVE): %LET (variable name is RC)
SYMBOLGEN: Macro variable DID resolves to 1
MLOGIC(DRIVE): Ending execution.
56
57 %LET _CLIENTTASKLABEL=;
6 The SAS System 13:46 Tuesday, January 30, 2018
58 %LET _CLIENTPROJECTPATH=;
59 %LET _CLIENTPROJECTNAME=;
60 %LET _SASPROGRAMFILE=;
61
62 ;*';*";*/;quit;run;
63 ODS _ALL_ CLOSE;
64
65
66 QUIT; RUN;
The code does not state how to actually produce the datasets with a proc sql or datastep
If you want the code generated, run the PROC IMPORT a single time, without the macro portion. Then the code will be in the log that you can embed in your macro or adapt however you want to use. But the macro does what you wanted, which is import files so it seems to meet your requirements.
Except for one time the line resolving similar to this:
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is FALSE
is False so the proc import is not executed.
the times it is true such as
MLOGIC(DRIVE): %IF condition %qupcase(%qsysfunc(dread(&did,&i))) ne %qupcase(&name) is TRUE MLOGIC(DRIVE): %IF condition %superq(ext) = %superq(name) is FALSE
the second comparison is false so the proc import is not executed. So it seems like none of the files in that folder actually have an extension exactly equal to csv. The values for NAME shown below were suspiciously like state abbreviations sc FL al az ca dc. It looks like you might have been in the comparisons with %superq comparing the stem of the file name sc instead of the extension
Proc import would create the data sets in this example. Since this one didn't seem to find a CSV to import there is not data step code to find.
I ran your code with my own file path and there were no issues, it ran fine and imported the CSV file.
When you get an error sometimes it come from a missing ; or unclosed quote or parentheses prior to the actual statement.
If that is the case here then when %macro is encountered it is not seeing the code as a macro definition but an invocation.
Save the program. Restart SAS as some of these errors are hard to correct for once a macro has been called or attempted.
Start with an empty log and re-run the program. Check the log carefully.
Also a long shot: if you copied this code from elsewhere there is a small chance that you have non-visible characters embedded in the code and those are making the compiler think that that your macro name is something besides "drive".
Note that the error:
ERROR: Invalid macro name (.
shows that SAS thinks you are invoking or compiling a macro named "( "
It might help to show the log with the code and error message. And paste it into a code box opened with the forum {I} icon to preserve error message formatting as the main windows here will reformat text and code. (Or do you really not indent any code???)
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.