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

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?

PG
1 ACCEPTED SOLUTION

Accepted Solutions
Quentin
Super User

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.

BASUG is hosting free webinars Next up: Jane Eslinger presenting PROC REPORT and the ODS EXCEL destination on Mar 27 at noon ET. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.

View solution in original post

7 REPLIES 7
Ksharp
Super User
PG,
If I was right, you can't use CARDS or DATALINES in a Macro.
Try to make a file instead.

SASKiwi
PROC Star

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.

Quentin
Super User

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.

BASUG is hosting free webinars Next up: Jane Eslinger presenting PROC REPORT and the ODS EXCEL destination on Mar 27 at noon ET. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
PGStats
Opal | Level 21

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. 

PG
FreelanceReinh
Jade | Level 19

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:

  1. Slightly modify your code to let SAS read the text from the clipboard: filename clippy clipbrd; ... infile clippy eof=eof; ... run;
  2. Save the program code (not necessarily as a macro) or the macro call somewhere, e.g., as C:\Temp\docu.sas.
  3. Enter an appropriate SUBMIT command into the KEYS window, e.g. 
F12    submit "%inc 'C:\Temp\docu.sas';"

 

Now, the procedure would be:

  1. Type the comment text,
  2. select it,
  3. copy it to the clipboard (Ctrl-C),
  4. hit F12 (in SAS). 

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.)

 

Quentin
Super User

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.

BASUG is hosting free webinars Next up: Jane Eslinger presenting PROC REPORT and the ODS EXCEL destination on Mar 27 at noon ET. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
data_null__
Jade | Level 19

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. 

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
  • 7 replies
  • 1801 views
  • 4 likes
  • 6 in conversation