前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SAS-RTF的合并【完善篇】

SAS-RTF的合并【完善篇】

作者头像
Setup
发布2019-10-20 14:33:02
4K1
发布2019-10-20 14:33:02
举报
文章被收录于专栏:SAS程序分享号号号

这一篇推文是针对上一篇推文,进行SAS程序与功能上的完善!点击此处将可跳转至上一篇推文:SAS-如何简单快捷的实现RTF合并。在上一篇推文推送后,有不少人都对RTF的合并感兴趣,并找到了小编。于是小编决定将RTF的合并完善一下,写成宏程序,以便有需要的朋友可以直接使用。

功能介绍

上一篇小编着重放在原理的介绍以及程序的实现上,太多细节由于小编太懒了没有好好优化。而这篇将是小编在程序上进行优化、功能上进行完善。在介绍功能之前,先来看看小编设置的宏参数。

下图为宏参数及简单说明

功能1:合并顺序的控制

解决办法:通过宏参数order进行控制。如果order=1,则判断待合并的RTF文件所在的路径下是否存在file_order.xls文件,如果不存在,则将RTF文件名输出到此文件中,并跳出当前宏程序的执行。待编辑完此文件后(人工编辑此Excel中的order列的值),再次执行宏,将会根据Excel中的order列的值进行排序(升序),来控制合并的先后顺序。如果order列的值为空,这样的RTF文件将不会被合并。

下图为编辑后的file_order.xls文件

功能2:页码错误的修正

解决办法:将观测中RTF标记符\pgnrestart清除即可实现页码的修正。

宏程序

嗯,还是早早的把程序贴出来凑字数。代码有点长,建议先转发到朋友圈进行收藏

再回来接着看。

下面是程序部分

代码语言:javascript
复制
%macro   rtf_merge(inpath=,outfile=,order=,pageyn=1)

options ps=800 ls=256  nonotes  nosource nosource2   ;
skip 5;
*获取指定路径下文件夹下RTF文件名称;
filename xcl_fil pipe "dir &inpath.\*.rtf /b/s"; 
data add_rtflist;
   infile xcl_fil truncover;
   input fname $char1000.;
   order=.;
run;
*默认以文件名进行升序排别;
proc sort data=add_rtflist  out=add_rtflist1  sortseq=linguistic(numeric_collation=on);by fname ;quit;

*判断是否需要人工排序;
*当order为1时则需要进行排序,同时根据step判断是否需要将文件名导出到外部Excel进行人工手动添加顺序;

%if  &order. eq  1 %then %do;
*判断待合并RTF文件夹下有无file_order.xls文件(存放RTF文件合并先后的排序列表)
  *如无,则生成此文件并退出宏的执行;
  %if %sysfunc(fileexist(&inpath.\file_order.xls))=0   %then %do;
skip 2;
    %put *宏参数order=1,但发现&inpath.\file_order.xls文件未存在,系统将自动生成此文件并退出当前程序的执行!;
    %put *请在人工完成此文件的编辑后,再次执行此程序;
    proc export data= add_rtflist1
        outfile="&inpath.\file_order.xls"
      dbms=excel replace label;
      sheet="order";
        newfile= no;
    run;
    %return;
  %end;

  *如文件存在,则将此文件导入;
  %if %sysfunc(fileexist(&inpath.\file_order.xls))   %then %do;
  proc import out = order1
      datafile = "&inpath.\file_order.xls"
      dbms = excel replace;
      sheet = "order";
      dbdsopts = "firstobs=1";
  run;

  data _null_ ;
    set order1(where=(missing(order) ));
    put "RTF文件(将不会参与RTF的合并):" fname;
  run;
  skip 3;

   *如果数据集观测为0,1,则不进行合并,跳出循环;
  %let dsid=%sysfunc(open(order1));
  %let _checkobs=%sysfunc(attrn(&dsid,nobs));
  %let rc= %sysfunc(close(&dsid));
  %if &_checkobs. eq 0 or &_checkobs. eq 1 %then %return;
  proc sort data=order1(where=(^missing(order) ))  out=add_rtflist1  sortseq=linguistic(numeric_collation=on);by order fname;quit;
  %end;
%end;

*定义filename定义路径便于合并;
data _null_;
  set add_rtflist1  end=last;
     rtffn=strip("filename rtffn")||strip(_N_)||right(' "')||strip(fname)||strip('" lrecl=5000 ;');
     call execute(rtffn);
  call symput('ard_rtf'||compress(put(_n_,best.)),strip(fname));
  if last then call symput('maxn',vvalue(_n_));
run;
  skip 3;

%do i=1 %to &maxn.;
/*将文件导入SAS中,变成SAS数据集*/
%put  即将完成对文件:&&ard_rtf&i. 的合并!;

  data have&i. ;
    infile rtffn&i.  truncover;
    informat line $5000.;format line $5000.;length line $5000.;input line $1-5000;
    line=strip(line);
  run;
/*实现三个处理过程:
    1.除首个RTF外,其他RTF第一行的“{”要删除。
    2.除最后一个RTF外,其他RTF最后一行的“}”要删除。
    3.在每个俩个RTF编码间插入一行。这样一行放下面一串代码。
    \sect\sectd\linex0\endnhere\pgwsxn15840\pghsxn12240\lndscpsxn\headery1440\footery1440\marglsxn1440\margrsxn1440\margtsxn1440\margbsxn1440
*/
  %if  &i. eq 1 %then %do;
    data want;
      set have&i. end=last;
      if last then line=substr(strip(line),1,length(strip(line))-1);
    run;
  %end;
  %if  &i. ne 1 %then %do;
    proc sql;
    insert into want(line) values ('\sect\sectd\linex0\endnhere\pgwsxn15840\pghsxn12240\lndscpsxn\headery1440\footery1440\marglsxn1440\margrsxn1440\margtsxn1440\margbsxn1440');
    quit;
    data have&i.;
      set have&i. end=last;
      if last then line=substr(strip(line),1,length(strip(line))-1);
      if _n_=1 then line=substr(line,2);
    run;
    data want;
      set want  have&i. ;
    run;
    %if  &i. eq &maxn. %then %do;
    data want;
      set want end=last;
      if last then line=strip(line)||strip("}");
      %if &pageyn. eq 1 %then %do; /*删除 pgnrestart   即可解决页码错乱问题*/
      if index(line,'\pgnrestart\') then line=compress(tranwrd(line,'\pgnrestart',' '));
      %end;
    run;
    %end;
  %end;
  proc delete data= have&i.;quit;
%end;

%put  已完成所有文件的合并!;
/*文件输出成合并完成后的RTF*/
  data _null_;
     set want;
     file "&outfile." lrecl=5000 ;
     put line ;
  run;
proc delete data=want;quit;
%mend;

注意事项

在写完代码后,一向自信的小编也难免不自信,为了测试宏的通用性,于是小编找了一位其他公司的朋友帮忙,跑了一下程序果真发现bug一大堆!!!辛亏小编有先见之明,没有直接发推送,不然就被啪啪啪的打脸。

为了不被打脸

上面的程序是在测试后,反复修改后诞生了,即便⁶₆⁶ 如小编,也有难以解决的bug~于是就有了这里的注意事项:.

目前已发现待解决的Bug就是,如果RTF内容为中文,并后期对RTF内容做了编辑(加颜色等等任何操作),合并的时候页眉页脚等处会发生乱码!如果内容是英文,那就可以尽情的放肆,随意修改编辑RTF的内容。程序也就简单的测试了一下,没有进行大规模的验证。欢迎留言指正,以及提出新的功能和需求。(如果小编感兴趣的话,会去完善的。)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-11-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 SAS程序分享号号号 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档