In general it is probably not good to force the dataset name to match exactly the string used to build the physical filename. SAS names have many more restrictions than physical filenames have. In addition to the pain of having to use name literals when the names are non conforming there is a maximum of 32 characters for a name in SAS code.
Better to make your macro/process a little smarter.
For example your macro could use two input parameters. One to be used in finding the physical file and one to be used in naming the SAS dataset. You could even make the macro smart enough to try to use the physical file name in creating the dataset name.
%macro import(file,dataset);
%if 0=%length(&dataset) %then
%let dataset=%sysfunc(nliteral(%qsysfunc(substrn(&file,1,32))))
;
data &dataset;
infile "/top_leve_directory/&file..txt" ....
...
%mend import;
Then you can use it with a name for the dataset
%import(1_apple,apple1)
Or without
%import(1_apple)
Thanks a lot! That's a good point.
But I rewrite a code and fix the dataset name but still has the same error.
%macro import(filename);
data apple1;
infile "/myaddress/&filename..txt" dsd dlm = ',';
input Number :$17.
Country :$18.;
run;
data in.apple1;
set apple1;
run;
%mend import;
%import(1_Apple);
I don't see any error. In fact I don't see any lines from your SAS log at all.
NOTE: Line generated by the macro variable "FILENAME".
26 1_Apple
___
22
200
ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, ;, CUROBS, END, INDSNAME, KEY, KEYRESET, KEYS,
NOBS, OPEN, POINT, _DATA_, _LAST_, _NULL_.
ERROR 200-322: The symbol is not recognized and will be ignored.
Not enough of the log to tell what the error is talking about.
Make sure to turn on the MPRINT option before running the macro so the log will show the code that the macro generated.
Try this, if it doesn't work, please post the log from the code.
*debugging options for macro; options mprint symbolgen; %macro import(filename); *fix name for data set; data _null_; p1 = scan("&filename", 1,"_"); p2 = scan("&filename", 2, "_"); new_name = catx("_", p2, p1); call symputx('dsetname', new_name); run; *read in file and save to library; data in.&dsetname; infile "/myaddress/&filename..txt" dsd dlm = ','; input Number :$17. Country :$18.; run; %mend import; %import(1_Apple);
Use this macro to build your directory list as a SAS dataset:
https://github.com/scottbass/SAS/blob/master/Macro/dirlist.sas
You may have to post-process that dataset to create a valid SAS dataset name. For example, dataset = scan(basename,2,'_');
Use this macro to loop over that list, calling the child macro %code to create your datasets:
https://github.com/scottbass/SAS/blob/master/Macro/loop.sas
You create the %code macro to suit your needs, in this case a simple data step. Although PROC IMPORT ... CSV might also work?
Read the macro headers for use cases.
You may need to download additional utility macros, such as
https://github.com/scottbass/SAS/blob/master/Macro/parmv.sas
Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!
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.
Ready to level-up your skills? Choose your own adventure.