0

我正在将 MFC C++ COM 插件转换为 C# .NET4.0 中的 VSTO Excel 插件。里面有很多引用 C API 的代码。这是一个例子。我可能会使用 Excel DNA 来简化我的转换任务。

仅供参考:xlr 是 XLSDK 中的一个类。

//allocate local storage for the reference
m_pControllerReference = new xlr( controllerRange ) ;

//get the name of the book and sheet with the reference
   g->Excel.fn( xlSheetNm, *m_pControllerReference ) ; 

   if ( g->Excel.resultXltype() != xltypeErr )
   {
       m_referenceSheetName = g->Excel.resultCString() ;

//    and get the sheet ID
       g->Excel.fn( xlSheetId, xl(m_referenceSheetName) ) ; 

       if ( g->Excel.resultXltype() != xltypeErr )
       {
           m_controllerSheetId = g->Excel.resultSheetId() ;

           xlr theRange( m_pControllerReference->GetLPXLOPER(),
0, TRUE ) ;

           if(theRange.nRows() >6)

           ........etc

这样转换吗?

          m_pControllerReference = (Excel.Range)controllerRange;

          m_referenceSheetName =
(string)XlCall.Excel(XlCall.xlSheetNm, m_pControllerReference );

          m_controllerSheetId =  XlCall.Excel(XlCall.xlSheetId,
m_referenceSheetName);    // and get the sheet ID

          //how to convert this ?
          //xlr theRange( m_pControllerReference->GetLPXLOPER(),
0, TRUE ) ;

或者有没有更好的方式来转换而不求助于第三方实用程序?我可以在 VSTO 中做所有事情吗?是否有 C API 到 C# 转换的图表?

4

2 回答 2

1

“Everyting”是一个大词,但你可以在 VSTO 中做很多事情 :-)。

您的 C# 代码可能有效,但此语法不是您通常在 VSTO 中使用的语法。你可以这样做:

Range controllerRange = <your code here> //... get your range
string referenceSheetName = controllerRange.Worksheet.Name;
// I'm not aware of any sheet ID in VSTO
if (controllerRange.Rows.Count > 6)
... etc...

如您所见,您可以直接处理 Range 对象,无需使用引用并将引用用作函数的参数。

于 2012-03-28T14:30:00.417 回答
1

Excel-DNA确实应该使您的 Excel C++ 到 .NET 的转换更加容易。

你应该小心尝试混合 VSTO 和 Excel-DNA。它们不能在同一个插件中愉快地生活在一起,所以你应该基于 Excel-DNA(它允许你访问 C API 和 COM 接口),或者制作两个单独的插件(VSTO 有一些丝带和其他方便的高级包装纸。)

如您所见,要从 Excel-DNA 访问 C API,您需要使用 XlCall 类以及 ExcelReference 类,该类包含来自引用类型 XLOPER 的信息。使用 Excel-DNA,您无需显式处理 XLOPER,所有类型转换都会在您进行 XlCall.Excel(...) 调用时自动完成。

您不应将 C API 帮助程序类型 ExcelReference 与 COM 类型 Range 混淆。您可以来回转换,但它们不可互换。对于 C API 调用,您需要 ExcelReference 类型。

转到您的示例,尚不清楚 controllerRange 是什么,但我猜 type xlr type 相当于 Excel-DNA 的 ExcelReference 类型,而不是您使用的 COM Range 类型(如 Excel.Range)。这是一篇关于在 ExcelReference 和 Range 之间进行转换的帖子:http ://groups.google.com/group/exceldna/browse_frm/thread/7a16e20e9067d3d2 。

当您有 ExcelReference 时,您的调用是正确的。所以这应该工作:

  m_pControllerReference = new ExcelReference(0,0,0,0, "Sheet1"); // Cell A1
  m_referenceSheetName = (string)XlCall.Excel(XlCall.xlSheetNm, m_pControllerReference ); 
  m_controllerSheetId =  XlCall.Excel(XlCall.xlSheetId, m_referenceSheetName);
  // or just: 
  m_controllerSheetId =  m_pControllerReference.SheetId;

现在我不确定你的最后一行是做什么的——它似乎创建了另一个 xlr 对象。ExcelReference 具有属性 RowFirst、RowLast,您可以使用它们来检查它有多少行。

于 2012-03-28T19:24:58.327 回答