C#中编程创建、调用Excel 宏
Wonsoft
在面向Office应用开发中,有时需要在C#中执行 VBA 宏,甚至有时还需要在执行了 VBA 宏之后,获取返回值再进行相应的处理。文章收集了一些在 Excel 中处理宏的操作为实例,供参考。
一、添加支持系统:
首先,系统需要安装Microsoft Office 2003/2007 包含主 Interop 程序集 (PIA)。
其次,在Microsoft Visual Studio .NET中的添加引用:1)在项目菜单上,单击添加引用。2)在 COM 选项卡上,找到 Microsoft Excel 对象库,然后单击选择。3)然后找到 Microsoft Visual Basic for Applications 扩展库并单击选择。
二、创建Excel文件、Excel宏
1、添加引用
- using Office = Microsoft.Office.Core;
- using VBIDE = Microsoft.Vbe.Interop;
- using Excel = Microsoft.Office.Interop.Excel;
2、源代码
- Excel.Application oExcel;
- Excel.Workbook oBook;
- VBIDE.VBComponent oModule;
- Office.CommandBar oCommandBar;
- Office.CommandBarButton oCommandBarButton;
- String sCode;
- Object oMissing = System.Reflection.Missing.Value;
- oExcel = new Excel.Application();
- oBook = oExcel.Workbooks.Add(oMissing);
- oModule = oBook.VBProject.VBComponents.Add(VBIDE.vbext_ComponentType.vbext_ct_StdModule);
-
- sCode =
- "sub VBAMacro()/r/n" +
- " msgbox /"VBA Macro called/"/r/n" +
- "end sub";
- oModule.CodeModule.AddFromString(sCode);
- try
- {
-
- oCommandBar = oExcel.CommandBars.Add("VBAMacroCommandBar",oMissing, oMissing,/);
- oCommandBar.Visible = true;
-
- oCommandBarButton = (Office.CommandBarButton) oCommandBar.Controls.Add(
- Office.MsoControlType.msoControlButton,
- oMissing, oMissing, oMissing, oMissing);
-
- oCommandBarButton.OnAction = "VBAMacro";
-
- oCommandBarButton.Caption = "Call VBAMacro";
-
- oCommandBarButton.FaceId = 2151;
- }
- catch(Exception eCBError) {
- MessageBox.Show("VBAMacroCommandBar already exists.","Error");
- }
- oExcel.Visible = true;
- oExcel.UserControl = true;
- oCommandBarButton = null;
- oCommandBar = null;
- oModule = null;
- oBook = null;
- oExcel = null;
- GC.Collect();
三、调用Excel宏
帮助类仅提供了一个方法:RunExcelMacro
参数说明:
string excelFilePath Excel文件路径
string macroName 宏名称
object[] parameters 宏参数组
out object rtnValue 宏返回值
bool isShowExcel 执行时是否显示Excel
补充说明:VBA宏需如下图写在模块中,才能被此方法识别。写在ThisWorkBook中不能被识别。
执行Excel VBA宏帮助类,注释比较详细,不再累赘代码过程。最核心部分其实就是通过反射方式调用Excel VBA宏,oBook.Save()这句话也很重要,否则即使执行了VBA宏调用,也不会保存Excel更改后的内容:
1
using
System;
2
using
System.Collections.Generic;
3
using
System.Text;
4
using
Excel
=
Microsoft.Office.Interop.Excel;
5
using
Microsoft.Office.Core;
6
using
System.IO;
7
8
namespace
DoVBAMacro
9
{
10
///
<summary>
11
///
执行Excel VBA宏帮助类
12
///
</summary>
13
public
class
ExcelMacroHelper
14
{
15
///
<summary>
16
///
执行Excel中的宏
17
///
</summary>
18
///
<param name="excelFilePath">
Excel文件路径
</param>
19
///
<param name="macroName">
宏名称
</param>
20
///
<param name="parameters">
宏参数组
</param>
21
///
<param name="rtnValue">
宏返回值
</param>
22
///
<param name="isShowExcel">
执行时是否显示Excel
</param>
23
public
void
RunExcelMacro(
24
string
excelFilePath,
25
string
macroName,
26
object
[] parameters,
27
out
object
rtnValue,
28
bool
isShowExcel
29
)
30
{
31
try
32
{
33
#region
检查入参
34
35
//
检查文件是否存在
36
if
(
!
File.Exists(excelFilePath))
37
{
38
throw
new
System.Exception(excelFilePath
+
"
文件不存在
"
);
39
}
40
41
//
检查是否输入宏名称
42
if
(
string
.IsNullOrEmpty(macroName))
43
{
44
throw
new
System.Exception(
"
请输入宏的名称
"
);
45
}
46
47
#endregion
48
49
#region
调用宏处理
50
51
//
准备打开Excel文件时的缺省参数对象
52
object
oMissing
=
System.Reflection.Missing.Value;
53
54
//
根据参数组是否为空,准备参数组对象
55
object
[] paraObjects;
56
57
if
(parameters
==
null
)
58
{
59
paraObjects
=
new
object
[] { macroName };
60
}
61
else
62
{
63
//
宏参数组长度
64
int
paraLength
=
parameters.Length;
65
66
paraObjects
=
new
object
[paraLength
+
1
];
67
68
paraObjects[
0
]
=
macroName;
69
for
(
int
i
=
0
; i
<
paraLength; i
++
)
70
{
71
paraObjects[i
+
1
]
=
parameters[i];
72
}
73
}
74
75
//
创建Excel对象示例
76
Excel.ApplicationClass oExcel
=
new
Excel.ApplicationClass();
77
78
//
判断是否要求执行时Excel可见
79
if
(isShowExcel)
80
{
81
//
使创建的对象可见
82
oExcel.Visible
=
true
;
83
}
84
85
//
创建Workbooks对象
86
Excel.Workbooks oBooks
=
oExcel.Workbooks;
87
88
//
创建Workbook对象
89
Excel._Workbook oBook
=
null
;
90
91
//
打开指定的Excel文件
92
oBook
=
oBooks.Open(
93
excelFilePath,
94
oMissing,
95
oMissing,
96
oMissing,
97
oMissing,
98
oMissing,
99
oMissing,
100
oMissing,
101
oMissing,
102
oMissing,
103
oMissing,
104
oMissing,
105
oMissing,
106
oMissing,
107
oMissing
108
);
109
110
//
执行Excel中的宏
111
rtnValue
=
this
.RunMacro(oExcel, paraObjects);
112
113
//
保存更改
114
oBook.Save();
115
116
//
退出Workbook
117
oBook.Close(
false
, oMissing, oMissing);
118
119
#endregion
120
121
#region
释放对象
122
123
//
释放Workbook对象
124
System.Runtime.InteropServices.Marshal.ReleaseComObject(oBook);
125
oBook
=
null
;
126
127
//
释放Workbooks对象
128
System.Runtime.InteropServices.Marshal.ReleaseComObject(oBooks);
129
oBooks
=
null
;
130
131
//
关闭Excel
132
oExcel.Quit();
133
134
//
释放Excel对象
135
System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel);
136
oExcel
=
null
;
137
138
//
调用垃圾回收
139
GC.Collect();
140
141
#endregion
142
}
143
catch
(Exception ex)
144
{
145
throw
ex;
146
}
147
}
148
149
///
<summary>
150
///
执行宏
151
///
</summary>
152
///
<param name="oApp">
Excel对象
</param>
153
///
<param name="oRunArgs">
参数(第一个参数为指定宏名称,后面为指定宏的参数值)
</param>
154
///
<returns>
宏返回值
</returns>
155
private
object
RunMacro(
object
oApp,
object
[] oRunArgs)
156
{
157
try
158
{
159
//
声明一个返回对象
160
object
objRtn;
161
162
//
反射方式执行宏
163
objRtn
=
oApp.GetType().InvokeMember(
164
"
Run
"
,
165
System.Reflection.BindingFlags.Default
|
166
System.Reflection.BindingFlags.InvokeMethod,
167
null
,
168
oApp,
169
oRunArgs
170
);
171
172
//
返回值
173
return
objRtn;
174
175
}
176
catch
(Exception ex)
177
{
178
//
如果有底层异常,抛出底层异常
179
if
(ex.InnerException.Message.ToString().Length
>
0
)
180
{
181
throw
ex.InnerException;
182
}
183
else
184
{
185
throw
ex;
186
}
187
}
188
}
189
}
190
}
191
示例三个VBA宏方法:
1
Sub
getTime()
2
3
Sheet1.Cells(
1
,
1
)
=
Now
4
5
End Sub
6
7
8
Sub
getTime2(title
As
String
)
9
10
Sheet1.Cells(
2
,
1
)
=
title
&
"
:
"
&
Now
11
12
End Sub
13
14
Function
getTime3(title
As
String
) As String
15
16
getTime3
=
title
&
"
:
"
&
Now
17
18
End Function
19
对应的三个使用方法
1 不带参数的宏调用(兼演示执行过程显示Excel文件)
2 带参数的宏调用(兼演示执行过程不显示Excel文件)
3 有返回值的宏调用
1
private
void
btnExe_Click(
object
sender, EventArgs e)
2
{
3
try
4
{
5
//
返回对象
6
object
objRtn
=
new
object
();
7
8
//
获得一个ExcelMacroHelper对象
9
ExcelMacroHelper excelMacroHelper
=
new
ExcelMacroHelper();
10
11
//
执行指定Excel中的宏,执行时显示Excel
12
excelMacroHelper.RunExcelMacro(
13
@"
E:/csharp_study/DoVBAMacro/test.xls
"
,
14
"
getTime2
"
,
15
new
Object[] {
"
现在时刻
"
},
16
out
objRtn,
17
true
18
);
19
20
//
执行指定Excel中的宏,执行时不显示Excel
21
excelMacroHelper.RunExcelMacro(
22
@"
E:/csharp_study/DoVBAMacro/test.xls
"
,
23
"
getTime2
"
,
24
new
Object[] {
"
现在时刻
"
},
25
out
objRtn,
26
false
27
);
28
29
//
执行指定Excel中的宏,执行时显示Excel,有返回值
30
excelMacroHelper.RunExcelMacro(
31
@"
E:/csharp_study/DoVBAMacro/test.xls
"
,
32
"
getTime3
"
,
33
new
Object[] {
"
现在时刻
"
},
34
out
objRtn,
35
true
36
);
37
38
MessageBox.Show((
string
)objRtn);
39
40
}
41
catch
(System.Exception ex)
42
{
43
MessageBox.Show(ex.Message);
44
}
45
}
参考文献:
1、http://www.cnblogs.com/heekui/archive/2008/03/30/1129355.html
2、http://www.cnblogs.com/ruanbl/archive/2007/05/29/764277.html