【问题标题】:Excel worksheet in Windows form application without opening Excel applicationWindows 表单应用程序中的 Excel 工作表,无需打开 Excel 应用程序
【发布时间】:2013-03-29 02:49:07
【问题描述】:

我正在将几个 VBA 项目转换为 Windows 窗体应用程序。我唯一的问题是 Excel 的某些功能对于应用程序来说是必不可少的,例如 R1C1 公式。我不想实例化 Excel 应用程序或访问已保存的工作表。所有数据都是通过查询 Oracle 数据库来检索的。二维数组不是一个选项,因为列包含不同的数据类型,并且 DataGridView 太慢而无法使用。

我认为简单地调暗 Microsoft.Office.Interop.Excel.Worksheet 对象就足够了,但程序一直失败,在调试模式下检查对象的元素后,我发现每个值都表示:

{“无法将类型为“Microsoft.Office.Interop.Excel.WorksheetClass”的 COM 对象转换为接口类型“Microsoft.Office.Interop.Excel._Worksheet”。此操作失败,因为 COM 组件上的 QueryInterface 调用由于以下错误,IID 为“{000208D8-0000-0000-C000-000000000046}”的接口失败:不支持此类接口(HRESULT 异常:0x80004002 (E_NOINTERFACE))。"}

如果有人能够告诉我如何在不打开 Excel 的情况下获取工作表对象,或者至少提供一个合理的替代方案,我将不胜感激。

【问题讨论】:

  • 您的开发 PC 上是否安装了 Excel?如何在代码中实例化 Worksheet 对象?
  • 是的。我有 Excel 2007。公共 Sheet1 作为 Microsoft.Office.Interop.Excel.Worksheet
  • 这是一个声明,不是实例化!
  • 对,对不起。在表单的加载子中:Sheet1 = New Microsoft.Office.Interop.Excel.Worksheet
  • 我试图在下面的回答中解决这个问题。

标签: vb.net interop excel-interop


【解决方案1】:

您可能需要正确地实例化您的对象。工作表需要 Excel COM 对象,因此您通常先实例化它,然后再访问工作表。下面是一些示例代码:

Dim xl As Microsoft.Office.Interop.Excel.Application
xl = New Microsoft.Office.Interop.Excel.Application
Dim wb As Microsoft.Office.Interop.Excel.Workbook
wb = xl.Workbooks.Add()
Dim ws As Microsoft.Office.Interop.Excel.Worksheet
ws = wb.ActiveSheet

现在您可以使用您的ws。请注意,我没有使用 Dim .. as New 实例化它。

通过这样做,您将在后台运行一个不可见的 Excel 实例。完成后必须显式关闭应用程序,以防止它留在内存中:

/// after your are finished
xl.Quit()
Marshal.ReleaseComObject(xl)

如果您在某种循环中使用它,这一点尤其重要。

【讨论】:

  • 这是打开 Excel 应用程序的一个实例,还是对用户完全不可见?而且因为它没有打开现有的工作簿,我假设不需要做任何特殊的工作来处理它?
  • 使用 Marshal.ReleaseComObject() 需要什么参考?说“未宣布名称‘元帅’”。
  • System.Runtime.InteropServices,见这里:msdn.microsoft.com/en-us/library/…
  • 谢谢。通过循环遍历记录集的记录来填充工作表,如下所示:Sheet1.Cells(a, 1) =recordset1.Fields("column1").Value Sheet1.Cells(a, 2) =recordset1.Fields("column2")。 Value Sheet1.Cells(a, 3) = recordsset1.Fields("column3").Value Sheet1.Cells(a, 4) = recordset1.Fields("column4").Value ...尝试访问任何单元格... MsgBox(Sheet1.Cells("B2")) -> HRESULT 异常:0x800A03EC
  • 我想通了。问题是我试图访问细胞的方式。而不是 "Sheet1.Cells("B2")" 来获取单元格中的值,您必须使用 "Sheet1.Range("B2").Value"... 非常感谢您的帮助。
【解决方案2】:

也许你已经解决了这个问题,但这是我的解决方案,我使用了你发布的内容以及我从另一篇文章中找到的内容,所以我可以告诉你这很好,这是我的示例:

    Dim xlApp As New Microsoft.Office.Interop.Excel.Application

    Dim oldCI As System.Globalization.CultureInfo = System.Threading.Thread.CurrentThread.CurrentCulture
    System.Threading.Thread.CurrentThread.CurrentCulture = New System.Globalization.CultureInfo("en-US")
    xlApp.Workbooks.Add()
    xlApp.ActiveSheet.Delete()
    xlApp.ActiveSheet.Delete()

    With xlApp
        With .ActiveSheet.QueryTables.Add("ODBC;DRIVER=SQL Server;SERVER=" & DAO.GetNombreServidor & ";UID=" & DAO.GetLoginUsuario & ";PWD=" & DAO.GetPassUsuario & ";WSID=RICARDO2;DATABASE=" & DAO.GetNombreBaseDeDatos & "", xlApp.Range("A1"))
            .CommandText = "SELECT * FROM ESTADOS"
            .FieldNames = True
            .RowNumbers = False
            .FillAdjacentFormulas = False
            .PreserveFormatting = True
            .RefreshOnFileOpen = False
            .BackgroundQuery = True
            '.RefreshStyle = xlOverwriteCells
            'xlInsertDeleteCells
            .SavePassword = False
            .SaveData = False
            .AdjustColumnWidth = True
            .RefreshPeriod = 0
            .PreserveColumnInfo = False
            .Refresh(False)
        End With
    End With

    System.Threading.Thread.CurrentThread.CurrentCulture = oldCI

    xlApp.Visible = True

希望对你有帮助!

【讨论】:

  • 这个问题在一年半前就解决了,我几乎没有接触过 .NET(从那时起的新工作),但我喜欢学习做事的新方法,所以我当我有机会时,我会看看这个解决方案是否有效。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-11
  • 2013-06-21
  • 2017-08-30
  • 2013-12-23
  • 1970-01-01
  • 2016-06-19
  • 2011-06-02
相关资源
最近更新 更多