Hi, I would like to read inline paragraphs into a dataset at the beginning of my SAS programs. How can I automate this operation with a macro.? So far, I get an error when the macro processor expands the datalines4 statement in :
%macro docu;
data docu;
length id $32 text $2000;
retain id text;
infile datalines eof=eof;
input;
if first(_infile_) = "@" then do;
if not missing(id) then output;
id = substr(_infile_, 2);
call missing(text);
end;
else text = catx(" ", text, _infile_);
return;
eof: if not missing(id) then output;
datalines4;
%mend docu;
%docu;
@c1
Comment Comment Comment Comment Comment Comment
Comment Comment Comment Comment Comment
Comment Comment Comment
Comment Comment
Comment
@c2
Comment
;;;;
What else can I do?
Agree with @Ksharp's suggetion to move the data to a file.
I misread your post, and thought that you were okay with having the data itself outside of the macro definition (immediately after the macro call). If that were the case, you could remove the DATALINES statement from the macro definition as well, and add it after the call, e.g.:
%docu;
datalines4;
@c1
Comment Comment Comment Comment Comment Comment
Comment Comment Comment Comment Comment
Comment Comment Comment
Comment Comment
Comment
@c2
Comment
;;;;
Which looks a bit odd, but works.
PG, If I was right, you can't use CARDS or DATALINES in a Macro. Try to make a file instead.
This is an explicit SAS restriction:
http://support.sas.com/kb/43/902.html
@Ksharp's suggestion of an external file is an alternative approach.
Agree with @Ksharp's suggetion to move the data to a file.
I misread your post, and thought that you were okay with having the data itself outside of the macro definition (immediately after the macro call). If that were the case, you could remove the DATALINES statement from the macro definition as well, and add it after the call, e.g.:
%docu;
datalines4;
@c1
Comment Comment Comment Comment Comment Comment
Comment Comment Comment Comment Comment
Comment Comment Comment
Comment Comment
Comment
@c2
Comment
;;;;
Which looks a bit odd, but works.
Thank you @Ksharp, @SASKiwi, @Quentin. My first idea was to move the comments to a separate file, as you suggested. But I want the comments to be strongly bound to the program (analysis). If the program could somehow find the comments by itself, e.g. program toto.sas reads comments toto.txt in the same directory, that would be good enough for me. I tried to implement that, but got stuck when trying to get the path and filename of the program currently running. I'd be really pleased if anybody knew a way to get that info.
I think I'll go with Quentin's suggestion to move the datalines4 outside the macro.
Hi PG,
I take it that those "inline paragraphs" are individual text that you would type, say, into the Enhanced Editor and you would like to read this text into the DOCU dataset using your macro. (I don't know how WORK.DOCU would be "bound to the program (analysis)," though, but I assume you have prepared something to establish this connection.)
So, how about this:
F12 submit "%inc 'C:\Temp\docu.sas';"
Now, the procedure would be:
If you type the text into a Program Editor (not Enhanced Editor) window, you can omit step 3 by adding the STORE command before the SUBMIT command in the key definition. (If someone knows how to get this to work with the Enhanced Editor, please post it here. To me it seems that the Enhanced Editor macros on the one hand can't submit code and the DM commands STORE and WCOPY on the other hand do not work for the Enhanced Editor.)
Hi PG,
Glad it helped. re finding the path and name of the currently executing program, how are your running it (PC SAS interactive/batch, EG, SAS Studio, etc?) Usually there is a way. In PC SAS interactive, I use %qsysfunc(sysget(SAS_EXECFILEPATH)). In PC SAS batch, I use %qsysfunc(getOption(SYSIN)). In EG I can get the path to the project file, not sure about the program. In DI Studio it takes some processing of the metadata, but it's in there...
I'm not quite seeing the big picture of what you are doing. But I wrote a paper about parsing program headers to pull data from them. http://www.lexjansen.com/nesug/nesug04/po/po04.pdf . I haven't done it before, but it looks like a .sas program can read itself (i.e. the .sas file) as data. In interactive PC SAS, if I save the following code as a .sas file and submit it, it reads itself and writes the comment to the log.
/***
COMMENT: Hi Mom
***/
data _null_;
infile "%qsysfunc(sysget(SAS_EXECFILEPATH))";
input;
if _infile_ =: "COMMENT:" then put _infile_;
run;
So something like that could be another approach, if you want to parse text from the current .sas program.
--Q.
PARMCARDS is a global statement.
Put this in and auto call library.
options parmcards=FT77F001;
filename FT77F001 temp;
parmcards4;
This is the comment
This is the comment
This is the comment
This is the comment
;;;;
options parmcards=FT15F001;
%macro pgstats(arg);
data _null_;
infile FT77F001;
input;
put _infile_;
run;
%put NOTE: Did it work;
proc print data=sashelp.class;
run;
%mend pgstats;
And this is what you get
46 %pgstats();
MPRINT(PGSTATS): data _null_;
MPRINT(PGSTATS): infile FT15F001;
MPRINT(PGSTATS): input;
MPRINT(PGSTATS): put _infile_;
MPRINT(PGSTATS): run;
NOTE: The infile FT15F001 is:
(system-specific pathname),
(system-specific file attributes)
This is the comment
This is the comment
This is the comment
This is the comment
NOTE: 4 records were read from the infile (system-specific pathname).
The minimum record length was 19.
The maximum record length was 19.
NOTE: DATA statement used (Total process time):
real time 0.15 seconds
cpu time 0.03 seconds
NOTE: Did it work
MPRINT(PGSTATS): proc print data=sashelp.class;
MPRINT(PGSTATS): run;
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.07 seconds
cpu time 0.06 seconds
It doesn't have to be in a macro but a self documenting autocall macro seems more interesting.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.