我们有一组在SAS中开发的预定义宏,用于使用SAS数据集生成表、列表和图形。我的需求是专门为表自动生成SAS代码。有一些固定数量的模板可用于生成表格。此外,SAS程序可用于生成每个表的输出。每当需要从这些模板生成表时,都需要修改相关的SAS程序以生成所需的输出。
为了避免每次单独编写SAS程序以生成固定类型的输出的冗余,我想创建一个将生成SAS代码的工具。这段代码将作为生成表的源。
我已经准备了一个excel工作簿,其中包含构建程序所需的所有细节(如各种参数及其值,例如标题、脚注、源数据集、按行/列分组)。在Excel中创建的简单用户表单用于显示和配置这些参数。
现在的问题是-如何使用Excel VBA生成SAS语句?以及如何使用Excel VBA连接SAS来执行SAS程序?
如果你以前做过这样的事情,或者如果你对这种类型的问题陈述有任何想法,请在这里分享它们。任何帮助都是非常有用的。
谢谢。
发布于 2019-12-10 02:36:50
我不会牵涉到VBA。我会写一个SAS程序来读取需求,生成表格,并将它们推回到一个新的Excel程序中。如果您想要完全从Excel程序中驱动它,我建议您使用用于Excel的SAS插件,而不是VBA代码,尽管您可以通过VBA触发它。克里斯·海米丁格是这类问题的专家,他确实在communities.sas.com上发帖,因为另一位用户建议你应该在那里发帖(在评论中)。
创建空表是一个微不足道的过程,但报表通常具有非常特定的布局,因此您可以进一步推广此过程。例如,我有一个宏,它为一个数据集创建了我的标准表1(特征表),其中我只需要按类型(连续、分类、二进制)指定输入变量,输出就会生成,并可以通过ODS EXCEL推送到excel中。我还使用PROC REPORT来格式化它,因为我将交替地对不同变量的行进行着色,这样更容易阅读/显示。
/*
This macro creates a table of charateristics for the variables listed.
It handles categorical, binary and continuous variables and produces and output dataset that can be further customized. No statistical information is
included in this analysis
*/
/*Parameters to be set:
dsetin - name of dataset to be analyzed
cont = macro variable list of variable names, ie cont=age weight height
cat=list of categorical variables ie cat=sex grade
bin=binary variables, such as smoking now, smoking ever
dsetout=name of output dataset
Run example at the end for a sample output dataset call sample_table_char in the work directory
*/
*options mprint symbolgen;
%macro table_char(dsetin, cont, cat, bin, dsetout);
*delete old dataset;
proc datasets nodetails nolist;
delete &dsetout;
quit;
/****************************************************************
Handle Categorical Variables
****************************************************************/
*loop through variable list;
%let i=1;
%do %while (%scan(&cat, &i, " ") ^=%str());
%let var=%scan(&cat, &i, " ");
*Get format for variable;
data _null_;
set &dsetin;
call symput("var_fmt", vformat(&var));
run;
proc freq data=&dsetin noprint;
table &var/missing out=tab_var;
run;
data temp1;
length categorical $200.; format categorical $200.;
length value $200.; format value $200.;
set tab_var;
percent=percent/100;
categorical=put(&var., &var_fmt.);
if _n_=1 then do;
value=put(count, 8.)||"("||compress(put(percent, percent8.1))||")";
order=2;
output;
order=1;
value='';
categorical=propcase(vlabel(&var.));
output;
end;
else do;
order=2;
value=put(count, 8.)||"("||compress(put(percent, percent8.1))||")";
output;
end;
keep categorical value order;
run;
proc sort data=temp1 out=temp2 (drop=order); by order categorical; run;
proc append base=&dsetout data=temp2;
run;
*clean up;
proc datasets nodetails nolist;
delete tab_var temp1 temp2;
run; quit;
*Increment counter;
%let i=%eval(&i+1);
%end; *Categorical;
/****************************************************************
Handle Continuous Variables
****************************************************************/
%let i=1;
%do %while (%scan(&cont, &i, " ") ^=%str());
%let var=%scan(&cont, &i, " ");
proc means data=&dsetin (rename=&var=vn) noprint;
var vn;
output out=table_var n= nmiss= mean= min= max= std= median= p25= p75= p90=/autoname;
run;
*get label of variable for clean reporting;
data _null_;
set &dsetin;
call symput("var_label", vlabel(&var));
run;
data temp1;
length categorical $200.; format categorical $200.;
format value $200.; length value $200.;
set table_var;
categorical="&var_label.";
value=.;
output;
categorical='Count(Missing)';
value=put(vn_n, 5.)||"("||compress(put(vn_nmiss, 5.))||")";
output;
categorical='Mean (SD)';
value=put(vn_mean, 8.1)||"("||compress(put(vn_stddev, 8.1))||")";
output;
categorical='Median (IQR)';
value=put(vn_median, 8.1)||"("||compress(put(vn_p25, 8.1))||" - "||compress(put(vn_p75, 8.1))||")";
output;
categorical='Range';
value=put(vn_min, 8.1)||" - "||compress(put(vn_max, 8.1));
output;
categorical='90th Percentile';
value=put(vn_p90, 8.1);
output;
keep categorical value;
run;
proc append base=&dsetout data=temp1;
run;
*clean up;
proc datasets nodetails nolist;
delete table_var temp1;
run; quit;
*Increment counter;
%let i=%eval(&i+1);
%end; *Continuous;
/*****************************************************************
Handle Binary Variables (only report 1s)
*****************************************************************/
%let i=1;
%do %while (%scan(&bin, &i, " ") ^=%str());
%let var=%scan(&bin, &i, " ");
proc freq data=&dsetin noprint;
table &var/missing out=tab_var;
run;
data tab_var;
set tab_var;
where &var=1;
run;
data temp1;
length categorical $200.; format categorical $200.;
length value $200.; format value $200.;
set tab_var;
percent=percent/100;
if _n_=1 then do;
value=put(count, 8.)||"("||compress(put(percent, percent8.1))||")";
order=1;
categorical=propcase(vlabel(&var.));
output;
end;
keep categorical value;
run;
proc append base=&dsetout data=temp1;
run;
*clean up;
proc datasets nodetails nolist;
delete tab_var temp1;
run; quit;
*Increment counter;
%let i=%eval(&i+1);
%end;*Binary;
%mend table_char;
/* *Example of macro usage; */
/* data sample; */
/* set sashelp.class; */
/* female=ifn( sex='F',1,0); */
/* run; */
/* */
/* */
/* %table_char(sample, height weight age, sex, female, sample_table_char); */
https://stackoverflow.com/questions/59243893
复制相似问题