tbo*_*one 0 c# vba vsto excel-dna
我正在研究如何通过Excel-DNA将Excel.Range对象从Excel中的VBA传递到C#的正确/最佳方式,然后通过传递的引用与Excel对象模型进行交互.
示例代码:
'***************** VBA code ********************
Sub test2()
Dim rng As Excel.Range
Set rng = Worksheets("test_output").Range("D9")
Dim myDLL As New XLServer.MyClass
Call myDLL.test_ExcelRangePassedAsObject(rng)
Call myDLL.test_ExcelRangePassedAsRange(rng)
End Sub
//**************** C# Code **********************
using System;
using ExcelDna.Integration;
using ExcelDna.ComInterop;
using System.Runtime.InteropServices;
using Microsoft.Office.Interop;
using Excel = Microsoft.Office.Interop.Excel;
namespace XLServer
{
[ComVisible(false)]
class ExcelAddin : IExcelAddIn
{
public void AutoOpen()
{
ComServer.DllRegisterServer();
}
public void AutoClose()
{
ComServer.DllUnregisterServer();
}
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class MyClass
{
public void test_ExcelRangePassedAsObject(object range)
{
Excel.Range rng = (Excel.Range)range;
rng.Worksheet.Cells[1, 1].Value = "Specified range was: " + rng.Address.ToString();
}
public void test_ExcelRangePassedAsRange(Excel.Range range)
{
Excel.Range rng = range;
rng.Worksheet.Cells[2, 1].Value = "Specified range was: " + rng.Address.ToString();
}
Run Code Online (Sandbox Code Playgroud)
当我运行这个时,我得到预期的输出:
A1:指定范围是:$ D $ 9
A2:指定范围是:$ D $ 9
在花了大量时间谷歌搜索Excel-DNA问题并且没有任何结果之后,我只是写了这篇文章并且实际上感到惊讶的是它没有任何问题.
所以我想我的问题是那些在这方面经验丰富的人...... 这是正确/最好的方式吗?
例如,我遇到了许多与此相似的帖子:https:
//groups.google.com/forum/#!topic /exceldna/zqzEIos7ma0
....人们在处理ExcelReference对象并且不得不使用令人难以置信的模糊代码将它们转换为Excel.Range对象时,它几乎感觉就像我缺少的东西?
是的,这是正确的方法,只要你:
确保您的库项目未标记为"注册COM互操作".您不希望构建进程以直接将.dll注册为XLServer.MyClassCOM类型的COM服务器,而是将.xll用作COM服务器.这将确保您的COM对象与其他加载项位于同一AppDomain中.
将ComServer属性添加到<ExternalLibrary>.dna文件中的标记,因此
<ExternalLibrary Path="XlServer.dll" ComServer="true" ... />.
处理所有COM接口版本控制规则.
关于这个主题的最佳参考是MikaelKatajamäki的演练文章,我认为你发现:
现在有一些背景介绍Google小组讨论的背景:
大多数Excel-DNA内部都与Excel C API(由Excel SDK定义)有关,这对于制作高性能工作表UDF非常有用.在此设置中,描述工作表引用的C API结构是ExcelDna.Integration.ExcelReference类型中的包装器.这是一个包含表单指针(称为SheetId)的小数据结构,以及引用的范围.ExcelReference对象可以安全地用在多线程UDF中,并且可以来回传递给C API.可以将Excel-DNA工作表函数配置为ExcelReference在适当时接收对象作为输入.
该RangeCOM对象是完全不同的事情.它是这种工作表引用的COM对象包装器,受所有COM线程,生命周期和其他限制的约束.Microsoft不支持Range在.xll中定义的UDF函数中使用COM对象模型(以及因此对象),虽然它主要起作用,但尝试在多线程函数中使用它们可能会导致严重的问题.
在ExcelAsyncUtil.QueueAsMacro放入Excel-DNA加载项的宏或功能区回调(作为启动的异步触发宏)中,您可以安全地使用C API和COM对象模型.
从瘦ExcelReference对象转换为COM Range对象非常困难,但这取决于您是否要支持多区域范围.如果没有,它就像:
static Range ReferenceToRange(ExcelReference xlref)
{
string refText = (string)XlCall.Excel(XlCall.xlfReftext, xlref, true);
dynamic app = ExcelDnaUtil.Application;
return app.Range[refText];
}
Run Code Online (Sandbox Code Playgroud)
这个帮助程序不属于该ExcelReference类型的唯一原因是Excel-DNA仍然支持.NET 2.0,并且只有.NET 4.0才能使用可以理解这一点的COM类型统一
| 归档时间: |
|
| 查看次数: |
4326 次 |
| 最近记录: |