(感觉同事小皮 + 。。。的提醒)
使用场景:
1.老板让你做个工具,其中需求之是:调用Office的接口(VBA),并且做一些操作。你完成后,客户觉得有点慢,BossSay:能更快一点吗?
2.如果你是一个VBA的爱好者,发现以前在Office中写VBA时,运行速度还不错,但为了给没有装VBA封装成一个exe后,发现速度看起来慢了一些?
为什么会这样?
1.两个COM对象在交互时,其中的耗时是巨大的,如果在COM内部交互,则耗时是比较小。
2.所以,我们在外部调用时,如果要提高速度,最好的方式就是将其核心部分(即与Office交互的部分)做成com加载项。这样,进程内调用速度就会快很多。
使用数字来说话。
代码:
C#
using Microsoft.Office.Interop.Excel;using System.Diagnostics;using System;namespace onion_autotest{ class Program { static void Main(string[] args) { Console.WriteLine(string.Format("外部调用的时间是: {0} 毫秒", ExternalFill())); Console.WriteLine(string.Format("ComAddin调用的时间是: {0} 毫秒", ComAddInFill())); Console.Read(); } static long ComAddInFill() { Application app = new Application(); app.Visible = true; app.Workbooks.Add(); Worksheet sht = app.ActiveWorkbook.Worksheets[1] as Worksheet; Stopwatch watch = new Stopwatch(); watch.Start();//VBA的用法: application.COMAddIns("V8Test.Helper").Object.FillTest Object obj = app.COMAddIns.Item("V8Test.Helper").Object; obj.GetType().InvokeMember("FillTest", System.Reflection.BindingFlags.InvokeMethod, null, obj, null); watch.Stop(); return watch.ElapsedMilliseconds; } static long ExternalFill() { Application app = new Application(); app.Visible = true; app.Workbooks.Add(); Worksheet sht = app.ActiveWorkbook.Worksheets[1] as Worksheet; Stopwatch watch = new Stopwatch(); watch.Start(); for (int r = 1; r < 100; r++) for (int c = 1; c < 25; c++) sht.Cells[r, c] = "onion_autotest"; watch.Stop(); return watch.ElapsedMilliseconds; } }}
VB:
Public Sub FillTest() Dim sht, r, c Set sht = g_obj_App.ActiveWorkbook.Worksheets(1) For r = 1 To 100 For c = 1 To 25 sht.Cells(r, c) = "onion_autotest" Next Next End Sub
如图:
注意:
1.以上代码,我们没有去优化代码,只是说明问题,如在VBA或C#代码上是完全可以优化的,比较数组的填充肯定比一个一个填的快,等。仅是为了说明问题。
2.如果与COM交互比较少时,速度不会有快6倍的差距,但如果交互越多,则速度提高越明显。
游手好闲会使人心智生锈