VSTO与VBA相比性能下降

时间:2012-07-19 21:42:39

标签: c# performance excel vba vsto

我是stackoverflow的新手,因此我将直接从我的问题开始。

我有几年通过集成VBA开发Excel宏的经验,半年前我开始学习新语言C#。我喜欢它,它的可能性,我也找到了通过Visual Studio直接在C#中开发Office插件的选项(需要VSTO)。我遇到的问题是,在进行多次测试后,我尝试比较使用C#创建的插件的速度和使用VBA创建的宏(例如,将字符串“测试字符串”粘贴到A1到A10 000的每个单元格中)。问题是集成的VBA比使用Visual Studio(C#)创建的Addin快几倍。我当时决定不打扰这个问题,但是后来我遇到了同样的问题,但是这次代替cca 10秒(VBA)过程耗时超过2分钟!

在对谷歌进行研究后,我发现VSTO在性能方面表现不佳,尤其是当您需要应用程序与Excel交互时(因此有多种方法可以解决问题,例如将数据保存到动态数组中,然后直接将整个数组填充到activesheet中);但是有些情况下,你只需要与excel进行交互(就像我必须动态地取消保护工作簿中的许多工作表......在这里你只需要说ActiveSheet.Unprotect)

我的问题是,除了缓慢的VSTO,如何创建(可能是其他一些软件)Addins for Excel / Word /其他可轻松部署的Office产品? 非常感谢你。

此致 罗伯特

2 个答案:

答案 0 :(得分:5)

VSTO-Excel的性能问题是由于需要在Com接口上添加Interop层到VBA / VB6使用的Excel。因此,使用此方法与Excel进行VSTO交互总是很慢。

可以使用带有C#的XLL接口,使用Excel DNA(免费)和Addin Express(非免费)等产品。使用这个界面会很快,但它比Com界面更有限。

以下是用于开发UDF的various technologies的一个比较。

分发VBA代码非常简单 - 创建一个在应用程序级别运行的Addin(XLA / XLAM),或者为具有特定于文档的解决方案分发带有嵌入式VBA代码的工作簿。

答案 1 :(得分:5)

单独填充10000个单元会让您觉得VSTO非常慢。我可以用你提到的动态数组方法在很短的时间内完成它:

static public void PopulateABigNumberOfCells(Excel.Application xlApp, DataTable dataTable)
{
//Turn off Excel updating
SwitchApplicationSettings(xlApp,false);

//Populate a 2D array - via a DataTable in this example
object[,] values = (object[,])Array.CreateInstance(typeof(object), new int[2] { dataTable.Rows.Count, dataTable.Columns.Count }, new int[2] { 1, 1 });
for (int i = 0; i < dataTablea.Rows.Count; i++)
{
 for (int j = 0; j < dataTable.Columns.Count; j++)
 {
  values[i + 1, j + 1] = dataTable.Rows[i][j] == DBNull.Value ? 0 : dataTable.Rows[i][j];
 }
}

//Populate all cells in one swoop 
leftCellNum = XlHelper.ColumnNameToNumber(leftColumn);
string rightBottom = XlHelper.ColumnNumberToName(leftCellNum + dataTable.Columns.Count - 1);
using (var targetRange = xlApp.Range[leftColumn + (startingRow) + ":" + rightBottom + (startingRow + dataTable.Rows.Count - 1)].WithComCleanup())
{
targetRange.Resource.Value2 = values;
}

//Turn on Excel updating
SwitchApplicationSettings(xlApp,true);
}

static public void SwitchApplicationSettings(Excel.Application xlApp, bool on)
{
xlApp.ScreenUpdating = on;
xlApp.DisplayAlerts = on;
xlApp.Calculation = on ? XlCalculation.xlCalculationAutomatic : XlCalculation.xlCalculationManual;;
xlApp.UserControl = on;
xlApp.EnableEvents = on;
}

我使用VSTO Contrib获得更好的内存mgt。

使用对象模型并不比VBA慢12倍,除非你专门讨论单独填充数千个单元格。