【问题标题】:Exception from HRESULT: 0x800A03EC excel.rangeHRESULT 异常:0x800A03EC excel.range
【发布时间】:2020-12-10 08:55:05
【问题描述】:

我在 excel.range 中收到此错误 Exception from HRESULT: 0x800A03EC。
这是我的以下代码

    Private Sub excelInsertData(rowIndex As Integer, ColIndex As Integer, EDT As DataTable)
    Try

        Dim arr As Object(,) = New Object(EDT.Rows.Count - 1, EDT.Columns.Count - 1) {}

        For r As Integer = 0 To EDT.Rows.Count - 1
            Dim dr As DataRow = EDT.Rows(r)

            For c As Integer = 0 To EDT.Columns.Count - 1
                arr(r, c) = dr(c)
            Next
        Next

        Dim c1 As Excel.Range = CType(xlWorkSheet.Cells(rowIndex, ColIndex), Excel.Range)
        Dim c2 As Excel.Range = CType(xlWorkSheet.Cells(rowIndex + EDT.Rows.Count - 1, EDT.Columns.Count + ColIndex - 1), Excel.Range)
        Dim range As Excel.Range = xlWorkSheet.Range(c1, c2)
        range.Value = arr '---------ERROR THROWN HERE

    Catch ex As Exception
        MsgBox(ex.toString)
    Finally
        EDT.Rows.Clear() : EDT.Columns.Clear()
    End Try
End Sub

我正在尝试将数据从数据表(在本例中为 EDT)传输到 Excel 模板。

以下是值范围、arr 和 EDT。


range.Value - 长度为 5


长度与范围相同


我的数据表中的值(EDT)

另外,如果需要,我可以附上我的 3b.xlsm 文件的模板。

请询问我是否遗漏了任何需要提供的信息。

【问题讨论】:

  • 请查看:New Object (EDT.Rows.Count - 1, EDT.Columns.Count - 1) 和 For r As Integer = 0 To EDT.Rows.Count - 1
  • 那要检查什么?那只是数组大小声明。 @Dang D. Khanh
  • 我认为可能是:Dim arr (EDT.Rows.Count - 1, EDT.Columns.Count - 1) As Object。
  • 如果我真的说,我从堆栈中复制了这个以搜索“如何使用范围将数据插入到 excel”,所以我可以按照你的建议尝试这个,但我认为这不是问题。 @DangD.Khanh
  • 肯定有其他事情发生。在我使用您发布的代码进行的测试中,我没有遇到您描述的错误,并且代码在几秒钟内成功运行了一个包含 10 列和 100 行的数据表。您说原始文件是带有宏的模板,在我的测试中,这没有什么区别。您是否使用可能不同的文件测试了此代码,以至少消除该文件的问题?

标签: excel vb.net excel-interop


【解决方案1】:

第一行只是从函数中获取数据表。您也可以只向 Sub 添加一个参数并传入一个参数。此代码创建一个新的 Excel 文件。第一个循环添加列名,第二个循环添加数据。

Private Sub FillExcelFromDataTable()
    Dim dt = GetWorksheetData()
    Dim oExcel As New Excel.Application
    Dim oBook = oExcel.Workbooks.Add
    Dim oSheet = DirectCast(oBook.Worksheets.Add, Excel.Worksheet)
    Dim ColumnIndex = 1 'in Excel worksheet
    For Each col As DataColumn In dt.Columns 'This loop adds the header row
        oSheet.Cells(1, ColumnIndex) = col.ColumnName
        ColumnIndex += 1
    Next
    ColumnIndex = 1 'The columns and rows in the spreadsheet
    Dim RowIndex = 2 'The columns and rows in the spreadsheet
    For rowI = 0 To dt.Rows.Count - 1
        For Each col As DataColumn In dt.Columns
            oSheet.Cells(RowIndex, ColumnIndex) = dt(rowI)(col)
            ColumnIndex += 1
        Next
        ColumnIndex = 1 'Reset back to the first column
        RowIndex += 1
    Next
    oBook.Save()
    oBook.SaveAs(Filename:="ExcelDat.xlsx") 'Saved to "C:\Users\xxx\Documents\ExcelDat.xlsx"
    oBook.Close()
    oExcel.Quit()
End Sub

【讨论】:

  • 这是我一开始尝试的。您所做的是一次为特定单元格添加价值。我这样做了,但微软互操作服务太慢了。我有一个 SSD,填充 20x10 (rowsxcolumns) 的数据大约需要 5 分钟。所以我研究了互联网并知道使用范围添加数据而不是像这样使用。具有讽刺意味的是,我的代码运行良好,在我声明的其他方法中没有错误。主要问题是我无法理解错误想说什么。如果我没有抓住它,那么它就会通过并且文件会完美生成,但这并不好。我还有一个宏文件 .xlsm。
  • 同意。互操作不是最好的。看看 EPPlus。 epplussoftware.com你可以免费试用。我认为它有一个有用的方法。 ws.Cells["A1"].LoadFromDataTable(dataTable, true);
  • 我尝试了 EPPlus、OpenXML、ClosedXML(使用 ClosedXML 很长时间了,但最近的更新开始出现损坏我的模板文件的问题。我还在 ClosedXML git 上打开了一个问题)除了我的模板文件之外的所有内容让我很头疼。我必须转向互操作,因为它不会损坏文件。我发现最好的方法是 Range to transfer。它传输更快。所有数据传输大约需要 3-4 分钟。
  • 但是这个ws.Cells["A1"].LoadFromDataTable(dataTable, true) 会调整数据表的列和行吗?就像我想从 B11 单元格开始,一行到 F11 那么它会写在下一行吗?问是因为我害怕接触当前的代码。
猜你喜欢
  • 2011-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多