还有这个解决方案可能更适合您的需求。
首先创建一个将用作模板的HTML文件。不管你想要把一个值,使用宏变量作为一个占位符,像这样:
<html>
<h1> My title is &title </h1><br>
Name: &name <br>
Value of Blah: &blah
</html>
让它作为吸引目光,只要你喜欢。
接下来创建一个宏,将导入HTML模板,用实际值替换占位符,并将结果保存到一个新的文件:
/*****************************************************************************
** PROGRAM: MACRO.RESOLVE_FILE.SAS
**
** READS IN A FILE AND REPLACES ANY MACRO REFERENCES IN THE FILE WITH THE
** ACTUAL MACRO VALUES. EG. IF THE FILE WAS AN HTML FILE AND IT CONTAINED
** THE FOLLOWING HTML:
**
** <TITLE>&HTML_TITLE</TITLE>
**
** THEN THE PROGRAM WOULD READ THE FILE IN AND RESOLVE IT SO THAT THE OUTPUT
** LOOKED LIKE THIS:
**
** <TITLE>ROB</TITLE>
**
** ... WHEN THE MACRO VARIABLE "HTML_TITLE" EXISTED AND CONTAINED A VALUE OF
** "ROB". THIS IS USEFUL WHEN YOU NEED TO CREATE "DYNAMIC" HTML FILES FROM
** SAS BUT DONT WANT TO DO IT FROM A DATASTEP USING PUT STATEMENTS. DOING
** IT THIS WAY IS MUCH CLEANER.
**
** PARAMETERS: NONE
**
******************************************************************************
** HISTORY:
** 1.0 MODIFIED: 22-JUL-2010 BY:RP
** - CREATED.
** 1.1 MODIFIED: 18-FEB-2011 BY:RP
** - ADDED LRECL OF 32K TO STOP TRUNCATION
*****************************************************************************/
%macro resolve_file(iFileIn=, iFileOut=);
data _null_;
length line $32767;
infile "&iFileIn" truncover lrecl=32767;
file "&iFileOut" lrecl=32767;
input;
line = resolve(_infile_);
len = length(line);
put line $varying. len;
run;
%mend;
创建一些测试数据。还可以创建一些命令来调用上面的宏和数据集的值传递:
data mydata;
attrib name length=$10 format=$10. label='FirstName'
blah length=6 format=comma6. label='SomeValue'
cmd1 length=$1000
cmd2 length=$1000
;
title = 1;
name = "Rob" ;
blah = 1000;
cmd1 = cats('%let title=',title,';',
'%let name=',name,';',
'%let blah=',blah,';');
cmd2 = cats('%resolve_file(iFileIn=c:\template.html, iFileOut=c:\result',title,'.html);');
output;
title = 2;
name = "Pete";
blah = 100 ;
cmd1 = cats('%let title=',title,';',
'%let name=',name,';',
'%let blah=',blah,';');
cmd2 = cats('%resolve_file(iFileIn=c:\template.html, iFileOut=c:\result',title,'.html);');
output;
run;
使用call execute
运行,我们在之前的数据集创建的CMD1和CMD2。我们必须一次只在一行上执行调用执行,以便使用正确的宏变量,因此可以使用循环。
proc sql noprint;
select count(*) into :nobs from mydata;
quit;
然后通过DataSet迭代同时执行的命令之一,并建立每行到一个新文件:使用您的首选技术首先计算数据集中的行数
%macro publish;
%local tmp;
%do tmp = 1 %to &nobs;
data _null_;
set mydata(firstobs=&tmp obs=&tmp);
call execute (cmd1);
call execute (cmd2);
run;
%end;
%mend;
%publish;
那应该做的伎俩。
这真的很酷。我不知何故错过了这个答案(并通过导出数据解决了我的问题,然后使用一个Excel工作簿来生成表格),但我不得不再次做类似的事情,并且肯定会尝试这种方法。 – orh 2012-08-20 22:00:06
谢谢 - 以防万一你最终使用它,我已经更新了'%resolve_file'宏,并修复了一些错误并增强了输出HTML的可读性(它现在保留了输出文件中的前导空格)。 – 2012-08-21 01:19:13