I want to implement my VBA code into my SAS-code, so I can do the whole process with one run. My SAS code reads a big SAS table, does some transformations, and finally exportes to an Excel file (the code is below). I also wrote some VBA code in the Excel file (for example AutoFiltering for some variables, you can see the code below).
The table looks like this:
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
..............
..............
However, I want to implement my VBA code into my SAS-code, so I can do the whole process with one run. I know how to open and run an Excel file in SAS (the code is below), but I don't know how to implement a VBA code in my SAS.
If you wonder why I want to implement my Macro-code in my SAS, I will work with similar SAS-tables many times in the future, so it would be more practicle to keep the whole-code in one place.
I just realized that I can't export an table in SAS in macro-enabled Excel format, XLSM. I guess it is also a challange. Also, it is not so practicle to save a Macro-code from an Excel file, because it must be saved in Adds-in menu. So it would be much better to handle the whole process in one place, like inside the SAS editor.
THE code in SAS which exports the final table to an Excel file:
PROC EXPORT DATA=File1
OUTFILE= "&server\&env\test1.xlsx"
DBMS=EXCEL REPLACE;
SHEET="sheet1";
RUN;
The VBA code example in the Excel file to create AutoFilter for variables in the Excel file:
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
The code in SAS to start and run an Excel file in SAS:
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;
The common way to do this is to use a template file. You have your template saved, which has the excel macro saved in it (and perhaps also has some of the formatting done to it; using DDE you don't have to start with a blank worksheet, after all).
You can either use DDE to populate the template workbook/worksheet, and then "Save As" another file, or you can use DDE to create a new workbook and worksheet, open the template workbook, run the macro, close the template. Which you do may depend on whether you want to distribute the macro along with your results.
This allows you to run everything without interacting with it in any way - you don't have to add a new macro to it or anything, since the template macro already exists. Everything can be done in one run this way.
This is shown for example in the paper Step-by-Step in Using SAS® DDE to Create an Excel Graph Based on N Observations from a SAS Data Set, as well as several other papers on the subject.