In the following example, which doesn't work, I am breaking a dataset into separate files within separate directories. The directories get created like I want them to and, if I remove the ods related lines, all of the text files get created.
What would I have to change/add to get the ods part to work?
data have;
input branch team customer;
cards;
1 1 1
1 1 2
1 2 3
2 1 1
2 1 2
2 2 1
;
proc sort data=have;
by branch team;
run;
%let root=c:\art;
data _null_;
set have;
retain filename htmlname;
by branch team;
if first.branch then do;
rc = DCREATE(catx('_','Branch',branch),"&root.");
end;
if first.team then do;
rc = DCREATE(catx('_','Team',team),catt("&root.\Branch_",branch));
filename = catt("&root.\Branch_",branch,'\Team_',team,'\Team_',team,'.txt');
htmlname=catt("&root.\Branch_",branch,'\Team_',team,'\Team_',team,'.html');
filename hdummy htmlname;
ODS HTML BODY=hdummy;
end;
file dummy filevar=filename;
put branch team customer;
if last.team then do;
ods html close;
end;
run;
Under the Arthur.T 's helpful idea, I got the final code like this:
data have; input branch team customer; cards; 1 1 1 1 1 2 1 2 3 2 1 1 2 1 2 2 2 1 ; proc sort data=have(keep=branch team) out=temp nodupkey; by branch team; run; %let root=c:\art; data _null_; set temp; rc = DCREATE(catx('_','Branch',branch),"&root."); rc = DCREATE(catx('_','Team',team),catt("&root.\Branch_",branch)); call execute(catt("proc export data=have (where=(branch=",branch, "and team=",team,")) outfile='&root.\Branch_",branch,"\Team_",team, "\Team_",team,".txt' dbms=TAB replace;run ;")); call execute(catt("ods listing close;ods html file='&root.\Branch_", branch,"\Team_",team,"\Team_",team,".html' style=sasweb; proc print noobs data=have(where=(branch=",branch," and team=",team,")); run;ods listing ;ods html close;")); run;
Xia Keshan
Are attempting to create a single HTML document that has references/links to the text files or displays the content of the text files?
I'm trying to create 4 html files that are basically the same as the 4 txt files that are produced by the code, and in the same four directories. Thus, in answer to your question, the content.
I was thinking File Print ODS with Put _ods_ might help but it looks like the fileref has to be set outside of the data step writing the output. The 9.2 documention says explicitly not to use the filevar option which I though might be a way to get there.
The following creates blank html files. Anyone know how to correct the code so that the html files include the same data as the txt files?
data have;
input branch team customer;
cards;
1 1 1
1 1 2
1 2 3
2 1 1
2 1 2
2 2 1
;
proc sort data=have;
by branch team;
run;
%let root=c:\art;
proc sql noprint;
select distinct
catt("&root.\Branch_",branch,'\Team_',team,'\Team_',team,'.html')
into :fnames separated by ","
from have
order by branch,team
;
quit;
%let counter=&sqlobs.;
filename code2run temp;
data _null_;
file code2run;
length fname $80;
put 'Select (counter);';
do i=1 to &counter;
put 'when (' @;
put i @;
put ') do;';
put 'ODS HTML BODY="' @;
fname=scan("&fnames.",i,',');
put fname @;
put '";';
put 'end;';
end;
put 'otherwise;end;';
run;
data _null_;
set have;
if _n_ eq 1 then counter=1;
retain filename;
by branch team;
if first.branch then do;
rc = DCREATE(catx('_','Branch',branch),"&root.");
end;
if first.team then do;
rc = DCREATE(catx('_','Team',team),catt("&root.\Branch_",branch));
filename = catt("&root.\Branch_",branch,'\Team_',team,'\Team_',team,'.txt');
%include code2run;
counter+1;
end;
file print ods={variables=(branch
team
customer)};
put _ods_ ;
file dummy filevar=filename;
put branch team customer;
if last.team then do;
ods html close;
end;
run;
What do your txt files contain ? Have they already existed in those directories ? or these txt files are generated from other where ?
Arthur.T,
You already have these txt files in different directories? and want generate html files for those txt files and populate them into the same directories separately ?
data have; input branch team customer; cards; 1 1 1 1 1 2 1 2 3 2 1 1 2 1 2 2 2 1 ; run; proc sort data=have; by branch team; run; %let root=c:\art ; data _null_; set have; by branch team; if _n_ eq 1 then call execute('options noxwait;'); if first.team then do; call execute(cats("x 'mkdir &root\",branch,"\",team,"\';")); call execute(catt("proc export data=have(where=(branch=",branch," and team=",team,")) outfile='&root\",branch,"\",team,"\",team,".txt' dbms=TAB replace;run ;")); call execute(catt("ods listing close;ods html file='&root\",branch,"\",team,"\",team,".html' style=sasweb; proc print noobs data=have(where=(branch=",branch," and team=",team,"));run;ods listing ;ods html close;")); end; run;
Xia Keshan
Message was edited by: xia keshan Find a little problem.
: Nice way to solve the problem. Very much appreciated.
I had to change a couple of minor things to keep the file and path names in the desired naming format, and I kept the dcreate function as the code will be run on both EG and different operating systems:
data have;
input branch team customer;
cards;
1 1 1
1 1 2
1 2 3
2 1 1
2 1 2
2 2 1
;
proc sort data=have;
by branch team;
run;
%let root=c:\art;
data _null_;
set have;
if _n_ eq 1 then call execute('options noxwait;');
by branch team;
if first.branch then do;
rc = DCREATE(catx('_','Branch',branch),"&root.");
end;
if first.team then do;
rc = DCREATE(catx('_','Team',team),catt("&root.\Branch_",branch));
call execute(catt("proc export data=have (where=(branch=",branch,
"and team=",team,")) outfile='&root.\Branch_",branch,"\Team_",team,
"\Team_",team,".txt' dbms=TAB replace;run ;"));
call execute(catt("ods listing close;ods html file='&root.\Branch_",
branch,"\Team_",team,"\Team_",team,".html' style=sasweb;
proc print noobs data=have(where=(branch=",branch," and team=",team,"));
run;ods listing ;ods html close;"));
end;
run;
No. You will need to create 4 blocks of code to produce 4 distinct ODS outputs.
ODS LISTING FILE='BRANCH_1\TEAM_1.txt' ;
ODS HTML file='BRANCH_1\TEAM_1.html' ;
proc print ;
where branch=1 and team=1 ;
run;
ODS LISTING CLOSE;
ODS HTML CLOSE;
Tom,
Yes, but KSharp's use of call execute got around the need to hard code the individual blocks. Since there are a large number of branch/team combinations his approach will definitely be a lot easier to maintain.
Art
Under the Arthur.T 's helpful idea, I got the final code like this:
data have; input branch team customer; cards; 1 1 1 1 1 2 1 2 3 2 1 1 2 1 2 2 2 1 ; proc sort data=have(keep=branch team) out=temp nodupkey; by branch team; run; %let root=c:\art; data _null_; set temp; rc = DCREATE(catx('_','Branch',branch),"&root."); rc = DCREATE(catx('_','Team',team),catt("&root.\Branch_",branch)); call execute(catt("proc export data=have (where=(branch=",branch, "and team=",team,")) outfile='&root.\Branch_",branch,"\Team_",team, "\Team_",team,".txt' dbms=TAB replace;run ;")); call execute(catt("ods listing close;ods html file='&root.\Branch_", branch,"\Team_",team,"\Team_",team,".html' style=sasweb; proc print noobs data=have(where=(branch=",branch," and team=",team,")); run;ods listing ;ods html close;")); run;
Xia Keshan
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.