Hi All,
Are there any ways to convert the executed code from the log to a SAS file (with or with out a indentation)?
For example: The below is the macro executed code printed in the log. Can it be possible to send this to a SAS file which can be executable?
Thanks in Advance,
Venkat.
Hello,
I do not think there's an easy way.
Do you want to do this because you do not have the source code of a compiled macro?
Be cautious as one execution of the macro might only reveal 10% of its code.
Anyway, you could send the log to an external file, like here :
filename myfile '/users/myid/mydir/mylog';
proc printto log=myfile;
run;
Then import that log-file into a SAS-dataset (every line of the log becomes one record, and the full line is in one variable).
You can use the $VARYINGw. informat to do that, or just columns-input 1 - 150 (for example).
Then filter out the records (i.e. observations) starting with the string 'MPRINT(TEMP):' and remove that part with substr function.
Then put (file statement and put statements) the records of your new dataset to an external file again.
That external file should be a valid program that you can %INCLUDE.
Thanks,
Koen
You can easily get 90% there. Keep the lines that start with MPRINT(. Remove the MPRINT(...): from the start of the lines.
data _null_;
infile 'myfile.log';
file 'myfile.sas';
input ;
if _infile_ ne ' ' and _infile_=:'MPRINT(';
_infile_=substrn(_infile_,length(scan(_infile_,1,' '))+1);
put _infile_;
run;
But watch out for extremely long statements, like PROC SQL SELECT statements.
If you can re-run the program instead then it is even easier. Just use the MFILE option.
https://documentation.sas.com/doc/en/vdmmlcdc/8.1/mcrolref/p1dhqw0i5yj2m8n15opapnwteqra.htm
options mfile mprint; filename mprint 'debugmac';
Try this example at home:
filename ds2post url 'https://raw.githubusercontent.com/sasutils/macros/master/ds2post.sas';
%include ds2post;
filename mprint temp;
options mfile mprint;
%ds2post(sashelp.class);
Here is what was written to the fileref MPRINT.
310 options nomfile;
311 data _null_;
312 infile mprint;
313 input;
314 put _infile_;
315 run;
NOTE: The infile MPRINT is:
Filename=/saswork/SAS_work9085000092C9_odaws03-usw2.oda.sas.com/#LN00038,
Owner Name=tom.xxx,Group Name=oda,
Access Permission=-rw-r--r--,
Last Modified=04Aug2022:15:26:47,
File Size (bytes)=3377
*----------------------------------------------------------------------------;
* Get member label in format of dataset option. ;
* Get dataset contents information in a format to facilitate code generation.;
* Column names reflect data statement that uses the value. ;
*----------------------------------------------------------------------------;
proc sql noprint;
select cats('(label=',quote(trim(memlabel),"'"),')') into :memlabel trimmed from dictionary.tables where libname="SASHELP" and memna
me="CLASS" and not missing(memlabel) ;
create table _ds2post_ as select varnum , nliteral(name) as name length=66 , substrn(informat,1,findc(informat,' .',-49,'kd')) as in
f length=32 , case when type='char' then cats(':$',length,'.') when not (lowcase(calculated inf) in ('best','f',' ') and scan(inform
at,2,'.') = ' ') then ':F.' else ' ' end as input length=8 , case when type='num' and length < 8 then cats(max(3,length)) else ' ' e
nd as length length=1 , lowcase(format) as format length=49 , lowcase(informat) as informat length=49 , case when missing(label) the
n ' ' else quote(trim(label),"'") end as label length=300 from dictionary.columns where libname="SASHELP" and memname="CLASS" order
by varnum ;
quit;
*----------------------------------------------------------------------------;
* Generate data step code ;
* - For each statement use value of variable named the same as the statement.;
* - Only variables that are required in that statement are generated. ;
* - For LABEL statement use = between name and value instead of space. ;
* - Wrap statements when lines get too long. ;
* - Eliminate statements when no variables required that statement. ;
*----------------------------------------------------------------------------;
filename _code_ temp;
data _null_;
file _code_ column=cc ;
set _ds2post_ (obs=1) ;
put "data work.class (label='Student Data');" ;
put @3 "infile datalines dsd dlm='|' truncover;" ;
length statement $10 string $370 ;
do statement='input','length','format','informat','label';
call missing(any,anysplit);
put @3 statement @ ;
do p=1 to nobs ;
set _ds2post_ point=p nobs=nobs ;
string=vvaluex(statement);
if statement='input' or not missing(string) then do;
any=1;
string=catx(ifc(statement='label','=',' '),name,string);
if 72<(cc+length(string)) then do;
anysplit=1;
put / @5 @ ;
end;
put string @ ;
end;
end;
if anysplit then put / @3 @ ;
if not any then put @1 10*' ' @1 @ ;
else put ';' ;
end;
put 'datalines4;' ;
run;
*----------------------------------------------------------------------------;
* Generate data lines ;
*----------------------------------------------------------------------------;
data _null_;
file _code_ mod dsd dlm='|';
if _n_ > 20 then stop;
set sashelp.class ;
format _numeric_ best32. _character_ ;
put (_all_) (+0) ;
run;
data _null_;
file _code_ mod ;
put ';;;;';
run;
*----------------------------------------------------------------------------;
* Copy generated code to target file name and remove temporary file. ;
*----------------------------------------------------------------------------;
data _null_ ;
infile _code_;
file log ;
input;
put _infile_;
run;
filename _code_ ;
*----------------------------------------------------------------------------;
* Remove generated metadata. ;
*----------------------------------------------------------------------------;
proc delete data=_ds2post_;
run;
NOTE: 75 records were read from the infile MPRINT.
The minimum record length was 4.
The maximum record length was 671.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
Notice the long SQL statement makes a line that is 671 bytes long.
April 27 – 30 | Gaylord Texan | Grapevine, Texas
Walk in ready to learn. Walk out ready to deliver. This is the data and AI conference you can't afford to miss.
Register now and lock in 2025 pricing—just $495!
Still thinking about your presentation idea? The submission deadline has been extended to Friday, Nov. 14, at 11:59 p.m. ET.
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.