VB6迁移.NET时ADODB Recordset转ADO.NET索引越界问题求助
问题根因
你的推测是正确的,索引异常确实由手动维护的x/y变量导致,核心问题如下:
- 外层每次遍历
gItemArray时,未重置x/y的数值,多次循环后变量值会超过dtSum.Rows的最大有效索引,触发越界错误 For Each遍历过程中对x/y的计数逻辑和实际行索引不匹配,无法正确对应找到的行位置- 原有ADODB逻辑每次内层查找都从记录集首行开始,手动累计的索引完全不符合该逻辑
修正方案
你完全可以不用手动维护索引变量,直接复用遍历到的DataRow对象即可,既符合原逻辑又能规避索引错误,修正后代码如下:
Dim bFound As Boolean Dim lFootage As Integer Dim iRow As Short Dim lPlcHoldr As Long = 0 ' 可根据业务需求调整默认初始值 If gItemCnt > 0 Then For iRow = 1 To gItemCnt sSpecies = Mid(gItemArray(iRow), 15, 2) bFound = False Dim targetRow As DataRow = Nothing ' 遍历查找匹配的Species行 For Each row In dtSum.Rows If row("Species").ToString() = sSpecies Then targetRow = row bFound = True Exit For End If Next ' 未找到则新增行 If Not bFound Then targetRow = dtSum.NewRow() targetRow("SpeciesSort") = GetDesc(gSpeciesCodes, sSpecies, 3, 1) targetRow("Species") = sSpecies ' 初始化其他默认字段 targetRow("DlyShipFootage") = lPlcHoldr targetRow("DlyRemanFootage") = lPlcHoldr targetRow("DlyClaimFootage") = lPlcHoldr targetRow("MTDShipFootage") = lPlcHoldr targetRow("MTDRemanFootage") = lPlcHoldr targetRow("MTDClaimFootage") = lPlcHoldr dtSum.Rows.Add(targetRow) End If ' 统一更新Footage字段,无需拆分分支,和原ADODB逻辑完全对齐 lFootage = cPrint.GetItemArrayFootage(iRow, True) ' 注意:如果字段允许为空,需要先处理DBNull再做计算,例如: ' targetRow("MTDShipFootage") = Convert.ToInt32(targetRow("MTDShipFootage")) + lFootage targetRow("MTDShipFootage") = targetRow("MTDShipFootage") + lFootage ' 若要严格对齐原ADODB每次修改就更新的逻辑可以保留该行,也可以全部循环结束后统一调用一次提升性能 daSum.Update(ds, "tblTmpDlySum") Debug.WriteLine(lFootage) Next iRow End If
关键修改说明
- 移除了手动维护的
x/y索引变量,直接用targetRow存储匹配到的/新增的行对象,完全规避索引越界风险 - 合并了原来拆分的更新逻辑,和原ADODB的处理流程完全对齐,减少逻辑出错概率
- 增加了显式的变量初始化,避免未赋值变量导致的隐藏问题
- 补充了DBNull处理的提示,避免字段为空时的类型转换错误
内容的提问来源于stack exchange,提问作者CircleDot
相关产品推荐
相关产品推荐

