编写VBA代码在SAS

问题描述 投票:2回答:3

我想实现我的VBA代码到我的SAS代码,这样我就可以一次运行做的全过程。我的SAS代码读取大的SAS表,做一些转换,最后exportes到Excel文件(代码如下所示)。我也写了Excel文件中的一些VBA代码(例如自动筛选了一些变量,你可以看到下面的代码)。

该表如下所示:

A B C Var1 Var2 Var3
--------------------
1 1 1 10 15 20
1 1 2 15 20 30
1 2 1 20 30 40
1 2 2 30 40 50
2 1 1 40 50 60
2 1 2 50 60 70
2 2 1 60 70 80
..............
..............

不过,我想实现我的VBA代码到我的SAS代码,这样我就可以一次运行做的全过程。我知道如何打开并运行SAS(代码如下)Excel文件,但我不知道如何在我的SAS实现VBA代码。

如果你想知道为什么我想实现我的SAS我的宏代码,我将在未来类似的SAS-表很多次工作,所以它会更practicle以保持整个代码在一个地方。

我才意识到,我不能在启用宏的Excel格式在SAS导出表,XLSM。我想这也是一个challange。此外,它也不是那么practicle从Excel文件保存宏的代码,因为它必须保存在又添式菜单。因此,这将是更好的处理,整个过程在一个地方,像SAS编辑器中。

在SAS代码其中出口决赛桌到Excel文件:

PROC EXPORT DATA=File1
        OUTFILE= "&server\&env\test1.xlsx" 
        DBMS=EXCEL REPLACE; 
   SHEET="sheet1"; 
RUN;

在Excel中的VBA代码示例文件创建自动筛选在Excel文件变量:

Sub Macro1()
    Dim N As Long, r As Range
With Sheets("sheet1")
    N = .Cells(Rows.Count, "B").End(xlUp).Row
    ReDim ary(1 To N)
    For i = 1 To N
        ary(i) = .Cells(i, 1)
    Next i
End With

Range("A1:F20").AutoFilter
ActiveSheet.Range("$A$1:$F$20").AutoFilter Field:=1, Criteria1:=ary, Operator:=xlFilterValues
End Sub

在SAS的代码来启动和运行SAS Excel文件:

OPTIONS NOXWAIT NOXSYNC;
   DATA _NULL_;
   RC=SYSTEM('START EXCEL');
   RC=SLEEP(0.5);
RUN;
FILENAME CMDS DDE 'EXCEL|SYSTEM';
DATA _NULL_;
   FILE CMDS;
   PUT "[OPEN(""&server\&env\test1.XLS"")]";
   PUT '[RUN("Macro1")]';
   PUT '[SAVE.AS("&server\&env\FORMATTED_FILE.XLSM")';
   PUT "[QUIT()]";
RUN;
QUIT;
excel vba excel-vba sas sas-macro
3个回答
2
投票

要做到这一点的常用方法是使用一个模板文件。你有你的模板保存,其中有保存在它的Excel宏(或许也有一些做它的格式;使用DDE您不必启动一个空白工作表,毕竟)。

您可以使用DDE来填充模板的工作簿/工作表,然后“另存为”其他文件,或者您可以使用DDE来创建一个新的工作簿和工作表,打开模板的工作簿,运行宏,关闭该模板。你做的可能取决于是否要对你的成绩一起分发宏。

这可以让你无需以任何方式与它交互运行一切 - 你不必到一个新的宏添加到它或任何东西,因为模板的宏已经存在。一切都可以在一个运行这种方式来完成。

这示出例如在纸Step-by-Step in Using SAS® DDE to Create an Excel Graph Based on N Observations from a SAS Data Set,以及关于所述对象的其它几篇论文。


1
投票

我总是发现DDE是有点笨重,如果你摸的Excel工作簿,而它的运行它得到不高兴。本实施例中写一个VBScript来SAS工作区然后执行IUT。基本上,你可以得到看跌语句编写代码为任何你想要的程序做的,它可以通过最新的SAS数据集驱动。这个例子将头部和foter到现有的Excel电子表格...

%macro xlHeadFoot(WorkBookPath=,Header=FileName,Footer=SheetName,onlySheet=);

  %local _shortpath WorkBook;

  data _null_;
    length header footer $200;
    header=ifc(lowcase("&header.")='filename' or lowcase("&header.")='sheetname',tranwrd(tranwrd(lowcase("&header."),'filename','&F'),'sheetname','&A'),"&header.");
    footer=ifc(lowcase("&footer.")='filename' or lowcase("&footer.")='sheetname',tranwrd(tranwrd(lowcase("&footer."),'filename','&F'),'sheetname','&A'),"&footer.");
    call symput("header",trim(header));
    call symput("footer",trim(footer));
  run;

  %let WorkBook=%scan(&WorkBookPath.,%sysfunc(countw(&WorkBookPath.,\)),\);

    %* ***********************************************;
    %* get the short DOS name for the workspace folder;

    data _null_;
      rc=filename("inpipe",catx('"','for %I in (',"%sysfunc(pathname(work))",') do echo %~sI'),"pipe");
    run;

    data _null_;
      infile inpipe truncover end=last;
      input @1 data $256. ;
      rc=filename("inpipe","");
      if last then call symput('_shortpath',trim(data));
    run;

    %* *******************************;
    %* tidy up any previous executions;

    data _null_;
      if fileexist("&_shortpath\testx.vbs") then do;
        rc=filename("dump","&_shortpath\testx.vbs");
        rc=fdelete('dump');
        msg=sysmsg();
        if msg ne '' then put msg=;
      end;
      if fileexist("&_shortpath\xmlFile.xml") then do;
        rc=filename("dump","");
        rc=filename("dump","&_shortpath\xmlFile.xml");
        rc=fdelete('dump');
        msg=sysmsg();
        if msg ne '' then put msg=;
        rc=filename("dump","");
      end;
    run;


  %if %sysfunc(fileexist("&WorkBookPath."))=1 %then %do;


    data null;
      file "%sysfunc(pathname(work))\testx.vbs";
      put @1 'Set objExcel = CreateObject("Excel.Application")';
      put @1 'objExcel.Application.Visible = True';
      put @1 'objExcel.Workbooks.open  "' "&WorkBookPath." '"' ;
      %if %str(&onlySheet.) ne %str() %then %do;
        put @1 'onlySheetExisits=False';
        put @1 'for each sheet in objExcel.Workbooks("' "&WorkBook." '").sheets';  
        put @1 'if strcomp(sheet.name,"' "&onlySheet." '",1)=0 then onlySheetExisits=True';
        put @1 'if strcomp(sheet.name,"' "&onlySheet." '",1)=0 then sheet.PageSetup.CenterHeader = "' "%str(&Header.)" '"';
        put @1 'if strcomp(sheet.name,"' "&onlySheet." '",1)=0 then sheet.PageSetup.CenterFooter = "' "%str(&Footer.)" '"';
        put @1 'Next';
      %end;
      %else %do;
        put @1 'for each sheet in objExcel.Workbooks("' "&WorkBook." '").sheets';  
        put @1 'sheet.PageSetup.CenterHeader = "' "%str(&Header.)" '"';
        put @1 'sheet.PageSetup.CenterFooter = "' "%str(&Footer.)" '"';
        put @1 'Next'; 
      %end;

      put @1 'objExcel.Workbooks("' "&WorkBook." '").save';
      put @1 'objExcel.Workbooks("' "&WorkBook." '").Close';
      put @1 'objExcel.Application.Quit';
      %if %str(&onlySheet.) ne %str() %then %do;
        put @1 'if onlySheetExisits=False then msgbox "Error! Could not find Worksheet: '"&onlySheet."' in Workbook: "' ' & vbcr & ' '" '"&WorkBookPath." '",16,"SAS: '"&SYSMACRONAME"'"';
      %end;

    run;


    x %sysfunc(quote("&_shortpath.\testx.vbs")); 

  %end;
  %else %put %str(ERR)OR: [&SYSMACRONAME.] Unable to open: &WorkBookPath.  - check it exists!;


%mend;

0
投票

借助DDE你可以设置在SAS过滤器:

data _null_;
    FILE CMDS;
    /* select your worksheet */
    put '[workbook.select("your_sheet")]';
    /* select the column range you want to set the filter */
    put '[select("r1c2:r1c5")]';
    /* set filter */
    put '[filter]';
run;
© www.soinside.com 2019 - 2024. All rights reserved.