惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
Stack Overflow Blog
Stack Overflow Blog
Hugging Face - Blog
Hugging Face - Blog
博客园_首页
T
The Blog of Author Tim Ferriss
博客园 - 叶小钗
N
Netflix TechBlog - Medium
腾讯CDC
C
Check Point Blog
P
Proofpoint News Feed
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI
S
SegmentFault 最新的问题
F
Fortinet All Blogs
美团技术团队
U
Unit 42
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 司徒正美
F
Full Disclosure
Recorded Future
Recorded Future
D
DataBreaches.Net
博客园 - 【当耐特】
Martin Fowler
Martin Fowler
J
Java Code Geeks
I
InfoQ
Y
Y Combinator Blog
A
About on SuperTechFans
AI
AI
爱范儿
爱范儿
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Forbes - Security
Forbes - Security
W
WeLiveSecurity
M
MIT News - Artificial intelligence
雷峰网
雷峰网
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Simon Willison's Weblog
Simon Willison's Weblog
Schneier on Security
Schneier on Security
The GitHub Blog
The GitHub Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
aimingoo的专栏
aimingoo的专栏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
G
GRAHAM CLULEY
Know Your Adversary
Know Your Adversary
Latest news
Latest news
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
D
Docker
Recent Commits to openclaw:main
Recent Commits to openclaw:main
量子位
V2EX - 技术
V2EX - 技术
Project Zero
Project Zero

博客园 - 网际浪人

.Net Framework 4.0 中利用Task实现并行处理、串并行混合处理 C# Process调用应用程序失败时应注意的问题 程序员的幽默 To腾讯:强行收集用户个人隐私的行为不可饶恕 VS2005打开VS2008项目的2种方法(转) 【转】Oracle Conversion Functions 晨星、银河基金业绩排行榜数据转换工具 ORACLE纯SQL实现多行合并一行 ASP.NET项目添加Log4Net后,发布后无法写日志 “必应”不应、“谷歌”不歌 你好2009,再见2008,牛年犇犇犇 一种在SQLServer中实现Sequence的高效方法 oledb使用Access更新和插入操作的注意点 5.12大地震——小学二年级小表妹谢可欣的诗 GridView自动排序 [转]SQL Server 2005链接字符串 对HtmlEncode的增强——HtmlEntitiesEncode GridView中使用DataKeyNames存储数据键值 封装SoapException处理Webservice异常
C#调用Excel VBA宏
网际浪人 · 2008-03-30 · via 博客园 - 网际浪人

近日的一系列工作是做网站的营运维护,因此做了大量的支持工具。有Excel中写VBA的,也有直接C#做的工具。有时需要在C#中执行Excel VBA宏,甚至有时还需要在执行了VBA宏之后,获取返回值再进行相应的处理。为了使用方便,我写了一个执行Excel VBA宏的帮助类 。放在博客里做个备份也希望对有类似需求的朋友有所帮助。

帮助类仅提供了一个方法:

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(11= Now
 4 
 5 End Sub
 6 
 7 
 8 Sub getTime2(title As String)
 9 
10     Sheet1.Cells(21= 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         }

帮助类需添加引用:Microsoft Excel 11.0 Object Library

示例工程下载