C#调用Excel VBA宏

近日的一系列工作是做网站的营运维护,因此做了大量的支持工具。有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中不能被识别。

C#调用Excel VBA宏

执行Excel VBA宏帮助类,注释比较详细,不再累赘代码过程。最核心部分其实就是通过反射方式调用Excel VBA宏,oBook.Save()这句话也很重要,否则即使执行了VBA宏调用,也不会保存Excel更改后的内容

  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宏方法:

  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 有返回值的宏调用

  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         }

示例工程下载

上一篇:Linux安装php扩展memcache


下一篇:Win10 局域网共享的基本操作