2

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

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

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

我对你们的问题是,除了缓慢的 VSTO 之外,还有其他方法吗,如何为易于部署的 Excel/Word/其他 Office 产品创建(可能是其他一些软件)插件?非常感谢你。

问候,罗伯特

4

2 回答 2

6

VSTO-Excel 的性能问题是由于需要在 VBA/VB6 使用的 Excel 的 Com 接口之上添加 Interop 层。所以 VSTO 使用这种方法与 Excel 交互总是会很慢。

可以使用 Excel DNA(免费)和 Addin Express(非免费)等产品将 XLL 接口与 C# 一起使用。使用这个接口会很快,但它比 Com 接口更受限制。

这是用于开发 UDF的各种技术的比较。

分发 VBA 代码很容易 - 要么创建一个在应用程序级别运行的插件 (XLA/XLAM),要么分发一个带有嵌入式 VBA 代码的工作簿,用于特定于文档的解决方案。

于 2012-07-20T07:56:37.553 回答
6

单独填充 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来获得更好的内存管理。

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

于 2012-11-09T04:36:39.743 回答