近日的一系列工作是做网站的营运维护,因此做了大量的支持工具。有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更改后的内容

Java代码  收藏代码
  1.  1 using System;  
  2.   2 using System.Collections.Generic;  
  3.   3 using System.Text;  
  4.   4 using Excel = Microsoft.Office.Interop.Excel;  
  5.   5 using Microsoft.Office.Core;  
  6.   6 using System.IO;  
  7.   7   
  8.   8 namespace DoVBAMacro  
  9.   9 {  
  10.  10     /// <summary>  
  11.  11     /// 执行Excel VBA宏帮助类  
  12.  12     /// </summary>  
  13.  13     public class ExcelMacroHelper  
  14.  14     {  
  15.  15         /// <summary>  
  16.  16         /// 执行Excel中的宏  
  17.  17         /// </summary>  
  18.  18         /// <param name="excelFilePath">Excel文件路径</param>  
  19.  19         /// <param name="macroName">宏名称</param>  
  20.  20         /// <param name="parameters">宏参数组</param>  
  21.  21         /// <param name="rtnValue">宏返回值</param>  
  22.  22         /// <param name="isShowExcel">执行时是否显示Excel</param>  
  23.  23         public void RunExcelMacro(  
  24.  24                                             string excelFilePath,  
  25.  25                                             string macroName,  
  26.  26                                             object[] parameters,  
  27.  27                                             out object rtnValue,  
  28.  28                                             bool isShowExcel  
  29.  29                                         )  
  30.  30         {  
  31.  31             try  
  32.  32             {  
  33.  33                 #region 检查入参  
  34.  34   
  35.  35                 // 检查文件是否存在  
  36.  36                 if (!File.Exists(excelFilePath))  
  37.  37                 {  
  38.  38                     throw new System.Exception(excelFilePath + " 文件不存在");  
  39.  39                 }  
  40.  40   
  41.  41                 // 检查是否输入宏名称  
  42.  42                 if (string.IsNullOrEmpty(macroName))  
  43.  43                 {  
  44.  44                     throw new System.Exception("请输入宏的名称");  
  45.  45                 }  
  46.  46   
  47.  47                 #endregion  
  48.  48   
  49.  49                 #region 调用宏处理  
  50.  50   
  51.  51                 // 准备打开Excel文件时的缺省参数对象  
  52.  52                 object oMissing = System.Reflection.Missing.Value;  
  53.  53   
  54.  54                 // 根据参数组是否为空,准备参数组对象  
  55.  55                 object[] paraObjects;  
  56.  56   
  57.  57                 if (parameters == null)  
  58.  58                 {  
  59.  59                     paraObjects = new object[] { macroName };  
  60.  60                 }  
  61.  61                 else  
  62.  62                 {  
  63.  63                     // 宏参数组长度  
  64.  64                     int paraLength = parameters.Length;  
  65.  65   
  66.  66                     paraObjects = new object[paraLength + 1];  
  67.  67   
  68.  68                     paraObjects[0] = macroName;  
  69.  69                     for (int i = 0; i < paraLength; i++)  
  70.  70                     {  
  71.  71                         paraObjects[i + 1] = parameters[i];  
  72.  72                     }  
  73.  73                 }  
  74.  74   
  75.  75                 // 创建Excel对象示例  
  76.  76                 Excel.ApplicationClass oExcel = new Excel.ApplicationClass();  
  77.  77   
  78.  78                 // 判断是否要求执行时Excel可见  
  79.  79                 if (isShowExcel)  
  80.  80                 {  
  81.  81                     // 使创建的对象可见  
  82.  82                     oExcel.Visible = true;  
  83.  83                 }  
  84.  84   
  85.  85                 // 创建Workbooks对象  
  86.  86                 Excel.Workbooks oBooks = oExcel.Workbooks;  
  87.  87   
  88.  88                 // 创建Workbook对象  
  89.  89                 Excel._Workbook oBook = null;  
  90.  90   
  91.  91                 // 打开指定的Excel文件  
  92.  92                 oBook = oBooks.Open(  
  93.  93                                         excelFilePath,  
  94.  94                                         oMissing,  
  95.  95                                         oMissing,  
  96.  96                                         oMissing,  
  97.  97                                         oMissing,  
  98.  98                                         oMissing,  
  99.  99                                         oMissing,  
  100. 100                                         oMissing,  
  101. 101                                         oMissing,  
  102. 102                                         oMissing,  
  103. 103                                         oMissing,  
  104. 104                                         oMissing,  
  105. 105                                         oMissing,  
  106. 106                                         oMissing,  
  107. 107                                         oMissing  
  108. 108                                    );  
  109. 109   
  110. 110                 // 执行Excel中的宏  
  111. 111                 rtnValue = this.RunMacro(oExcel, paraObjects);  
  112. 112   
  113. 113                 // 保存更改  
  114. 114                 oBook.Save();  
  115. 115   
  116. 116                 // 退出Workbook  
  117. 117                 oBook.Close(false, oMissing, oMissing);  
  118. 118   
  119. 119                 #endregion  
  120. 120   
  121. 121                 #region 释放对象  
  122. 122   
  123. 123                 // 释放Workbook对象  
  124. 124                 System.Runtime.InteropServices.Marshal.ReleaseComObject(oBook);  
  125. 125                 oBook = null;  
  126. 126   
  127. 127                 // 释放Workbooks对象  
  128. 128                 System.Runtime.InteropServices.Marshal.ReleaseComObject(oBooks);  
  129. 129                 oBooks = null;  
  130. 130   
  131. 131                 // 关闭Excel  
  132. 132                 oExcel.Quit();  
  133. 133   
  134. 134                 // 释放Excel对象  
  135. 135                 System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel);  
  136. 136                 oExcel = null;  
  137. 137   
  138. 138                 // 调用垃圾回收  
  139. 139                 GC.Collect();  
  140. 140   
  141. 141                 #endregion  
  142. 142             }  
  143. 143             catch (Exception ex)  
  144. 144             {  
  145. 145                 throw ex;  
  146. 146             }  
  147. 147         }  
  148. 148   
  149. 149         /// <summary>  
  150. 150         /// 执行宏  
  151. 151         /// </summary>  
  152. 152         /// <param name="oApp">Excel对象</param>  
  153. 153         /// <param name="oRunArgs">参数(第一个参数为指定宏名称,后面为指定宏的参数值)</param>  
  154. 154         /// <returns>宏返回值</returns>  
  155. 155         private object RunMacro(object oApp, object[] oRunArgs)  
  156. 156         {  
  157. 157             try  
  158. 158             {  
  159. 159                 // 声明一个返回对象  
  160. 160                 object objRtn;  
  161. 161                   
  162. 162                 // 反射方式执行宏  
  163. 163                 objRtn = oApp.GetType().InvokeMember(  
  164. 164                                                         "Run",  
  165. 165                                                         System.Reflection.BindingFlags.Default |  
  166. 166                                                         System.Reflection.BindingFlags.InvokeMethod,  
  167. 167                                                         null,  
  168. 168                                                         oApp,  
  169. 169                                                         oRunArgs  
  170. 170                                                      );  
  171. 171   
  172. 172                 // 返回值  
  173. 173                 return objRtn;  
  174. 174   
  175. 175             }  
  176. 176             catch (Exception ex)  
  177. 177             {  
  178. 178                 // 如果有底层异常,抛出底层异常  
  179. 179                 if (ex.InnerException.Message.ToString().Length > 0)  
  180. 180                 {  
  181. 181                     throw ex.InnerException;  
  182. 182                 }  
  183. 183                 else  
  184. 184                 {  
  185. 185                     throw ex;  
  186. 186                 }  
  187. 187             }  
  188. 188         }  
  189. 189     }  
  190. 190 }  
  191. 191   

 

示例三个VBA宏方法:

Java代码  收藏代码
  1. 1 Sub getTime()  
  2.  2   
  3.  3     Sheet1.Cells(1, 1) = Now  
  4.  4   
  5.  5 End Sub  
  6.  6   
  7.  7   
  8.  8 Sub getTime2(title As String)  
  9.  9   
  10. 10     Sheet1.Cells(2, 1) = title & " : " & Now  
  11. 11   
  12. 12 End Sub  
  13. 13   
  14. 14 Function getTime3(title As String)  As String  
  15. 15   
  16. 16     getTime3 = title & " : " & Now  
  17. 17   
  18. 18 End Function  
  19. 19   

 

对应的三个使用方法 1 不带参数的宏调用(兼演示执行过程显示Excel文件) 2 带参数的宏调用(兼演示执行过程不显示Excel文件) 3 有返回值的宏调用

 

Java代码  收藏代码
  1.  1         private void btnExe_Click(object sender, EventArgs e)  
  2.  2         {  
  3.  3             try  
  4.  4             {  
  5.  5                 // 返回对象  
  6.  6                 object objRtn = new object();  
  7.  7   
  8.  8                 // 获得一个ExcelMacroHelper对象  
  9.  9                 ExcelMacroHelper excelMacroHelper = new ExcelMacroHelper();  
  10. 10   
  11. 11                 // 执行指定Excel中的宏,执行时显示Excel  
  12. 12                 excelMacroHelper.RunExcelMacro(  
  13. 13                                                     @"E:\csharp_study\DoVBAMacro\test.xls",  
  14. 14                                                     "getTime2",  
  15. 15                                                     new Object[] { "现在时刻" },  
  16. 16                                                     out objRtn,  
  17. 17                                                     true  
  18. 18                                               );  
  19. 19   
  20. 20                 // 执行指定Excel中的宏,执行时不显示Excel  
  21. 21                 excelMacroHelper.RunExcelMacro(  
  22. 22                                                     @"E:\csharp_study\DoVBAMacro\test.xls",  
  23. 23                                                     "getTime2",  
  24. 24                                                     new Object[] { "现在时刻" },  
  25. 25                                                     out objRtn,  
  26. 26                                                     false  
  27. 27                                                );  
  28. 28   
  29. 29                 // 执行指定Excel中的宏,执行时显示Excel,有返回值  
  30. 30                 excelMacroHelper.RunExcelMacro(  
  31. 31                                                     @"E:\csharp_study\DoVBAMacro\test.xls",  
  32. 32                                                     "getTime3",  
  33. 33                                                     new Object[] { "现在时刻" },  
  34. 34                                                     out objRtn,  
  35. 35                                                     true  
  36. 36                                                );  
  37. 37   
  38. 38                 MessageBox.Show((string)objRtn);  
  39. 39   
  40. 40             }  
  41. 41             catch(System.Exception ex)  
  42. 42             {  
  43. 43                 MessageBox.Show(ex.Message);  
  44. 44             }  
  45. 45         }  

 示例工程下载

posted on 2014-07-04 08:40  GC2013  阅读(5672)  评论(1编辑  收藏  举报