【发布时间】:2021-10-22 03:53:10
【问题描述】:
我正在 VS2019 上编写一个 Windows 窗体应用程序,它将打开一个 excel 文件并执行嵌套循环。
基本上,有两个整数列表。代码将遍历每一行以检查单元格 A 的值是否存在于任何列表中,然后将字符串分配给单元格 B。
原始代码中的列表大约有 400 个元素,但我将其删减到此处发布。然后有趣的事情发生了。当我使用 400 多个元素运行原始代码时,它会循环该行并中途停止,然后它给了我“HRESULT 异常:0x800AC472”。但是,当我运行下面的代码时,它没有错误。
所以我想如果是庞大的列表是问题所在。我想知道你们中是否有人遇到过这种情况以及如何解决它。
[更新] 我已向列表中添加了更多元素并尝试运行它。它确实抛出了同样的异常。我还尝试减少元素的数量并再次运行,它没有错误地工作。所以我猜是因为元素的数量。
Private Sub generateZone(ByVal worksheet As Object)
'Initialise Excel Object
xlsApp = New Excel.Application
'Open file
xlsWorkBook = xlsApp.Workbooks.Open("File location")
'Open worksheet(according to the spreadsheet)
xlsWorkSheet = xlsWorkBook.Worksheets("sheet1")
'Excel interaction setting
With xlsApp
.Visible = True
.Application.Visible = True
.DisplayAlerts = False
.EnableEvents = False
End With
Dim emZone1 As New List(Of Integer)(New Integer() {87371, 87390, 94614, 92000, 82898, 96500, 99124, 93260, 82496, 97858, 90323, 88083, 80770, 84186, 86318, 91922, 85987, 80635, 84079, 96691, 85578, 83108, 96081, 87642, 96703, 96692, 99193, 93039, 97003, 89374, 99252, 82305, 87907, 90966, 80517, 88471, 92395, 86109, 87112, 92849, 93853, 91136, 90512, 97143, 96105, 93966, 81136, 97218, 97816, 82525, 97714, 98175, 94940, 97262, 81750, 92075, 98905, 96199, 94072, 83841, 88243, 98375, 84142, 92818, 83527, 97446, 88632, 86542, 84768, 86283, 84910, 88986, 92802, 99145, 81487, 84729, 80010, 90896, 99418, 87545, 95937, 89904, 88073, 85255, 87285, 88442, 86325, 90223, 92048, 85160, 98768, 80283, 91273, 92077, 91043, 81409, 96042, 82536, 92726, 91980})
Dim emZone2 As New List(Of Integer)(New Integer() {86634, 92330, 95970, 95577, 87510, 89481, 94248, 93860, 81857, 82810, 93228, 80095, 94437, 84887, 88766, 92706, 92264, 88109, 91992, 82751, 94767, 95397, 96066, 91667, 94059, 89419, 82796, 82310, 86961, 85681, 93969, 81736, 81009, 97445, 80741, 92154, 84923, 86182, 91660, 90665, 81388, 87722, 94031, 94678, 84074, 80550, 82953, 81317, 95132, 92163})
'get last row
Dim lastRow As Integer
lastRow = worksheet.UsedRange.Rows.Count
'loop through every row
For i As Integer = 1 To lastRow
'get pronvice from column J
Dim province As String = worksheet.Range("J" & i).Value
If province = "Sabah" Or province = "Sarawak" Then
'check zone1
For Each zone1 As Integer In emZone1
If emZone1.Contains(worksheet.Range("L" & i).Value) Then
worksheet.Range("M" & i).Value = "Zone 1"
Else
'check zone2
For Each zone2 As Integer In emZone2
If emZone2.Contains(worksheet.Range("L" & i).Value) Then
worksheet.Range("M" & i).Value = "Zone 2"
' Exception from HRESULT: 0x800AC472 shows here
Else
'if not in both zone
worksheet.Range("M" & i).Value = "EM"
End If
Next
End If
Next
Else
'if not sabah and sarawak
worksheet.Range("M" & i).Value = "WM"
End If
Next
'releaseObject(xlsWorkSheet)
'releaseObject(xlsWorkBook)
'releaseObject(xlsApp)
End Sub
【问题讨论】:
-
你的逻辑有点奇怪。您正在循环
emZone1和emZone2,但在每个中重复一组固定的逻辑(未使用索引变量zone1和zone2)。看起来您可能最初是在实现自己的Contains逻辑,但是当您切换到使用Contains时忘记取出循环? -
-
@Craig 我的意图是先循环遍历 emZone1,如果 emZone1 中不存在“L & i”值,则继续循环遍历 emZone2,如果该值仍然不存在,它将显示“EM”。这是我在我的知识水平上设法产生的:')
-
我做了很多这样的 Excel 交互,我发现最好将数据加载到 customObject 列表中并尽快处理 Excel。然后在列表而不是文档上执行您的逻辑。它可以帮助解决这些异常,并加快您的代码速度。
-
为了扩展 @djv 的评论,我推荐 EPPlus(通过 NuGet 在 Visual Studio 中添加参考)。它比 Office Interop 好多了。
标签: excel vb.net visual-studio-2019