2012-03-28 35 views
0

我在 C#.NET4.0转换MFC C++ COM加载项的VSTO Excel加载项。有很多代码指的是C API。 这里是一个例子。我可能会使用Excel DNA来简化我的 转换任务。代码转换 - MFC C++到VSTO Excel加载项在C#

供参考: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#转换中是否有图表?

回答

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是什么,但我猜想类型xlr类型等效于Excel-DNA的ExcelReference类型,而不是您使用的COM范围类型(​​如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,您可以使用它来检查它有多少行。

+0

class xlr派生自xl0,派生自CObject。\t xlr(LPXLOPER xltypeRef_lpxloper,int idx,BOOL readData = FALSE); //通过一个不相交的索引的单个范围参考(通过一个基于零的索引) //可选择读取 – 2012-03-29 12:40:49

+0

中的数据好吧,它似乎包装了一个xltypeRef类型的XLOPER,因此ExcelReference将成为Excel-DNA的对应物。 – Govert 2012-03-29 12:54:49

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对象的工作,没有必要与参考操作和使用参考作为参数传递给函数。