为啥直接用数组填充范围并按索引进行索引时会获得2个不同的结果?

Posted

技术标签:

【中文标题】为啥直接用数组填充范围并按索引进行索引时会获得2个不同的结果?【英文标题】:Why do I obtain 2 differents results when filling range directly with array and doing it index by index?为什么直接用数组填充范围并按索引进行索引时会获得2个不同的结果? 【发布时间】:2022-01-16 20:23:25 【问题描述】:

我有一个充满数据的数组,我想在工作表中写入。

我在执行此操作时获得了 2 个不同的结果:

1) 循环遍历索引

    For i = 0 To UBound(dataarray(), 1)

        For j = 0 To UBound(dataarray(), 2)

            With mWS_data
                .Cells(i + 2, j + 1) = dataarray(i, j)
            End With

        Next j

    Next i

2) 直接填充范围

        With mWS_data
            'Row + 2 because datarray starts from 0, and 1st row is titles, Column + 1 because same reason but no titles
            .Range(.Cells(2, 1), .Cells(UBound(dataarray(), 1) + 2, UBound(dataarray(), 2) + 1)) = dataarray()
        End With

使用相同的数据,在第一种情况下,我在工作表中拥有所有数据(正确的结果),在第二种情况下,我只有很少的数据(中间一列的所有正确信息和 1 个单元格在另一列上有正确的信息)。

上周五我的代码运行良好,代码完全没有变化,而今天却无法正常运行。

我习惯用第二种方式编码,因为处理时间要快得多。

Excel 设置是否可能会以某种方式干扰? 还是我写错了?

--- 编辑:---

这是完整的代码以及你给我的简化

Sub Load()
    
    Dim dataArray() As Variant
    Dim i As Long
    Dim j As Long
    Dim c_attribute As New Cls_attribute
    
    ReDim dataArray(mJobs.Count - 1, attributes.Count - 1)
    
    'Turns off screen updating and auto calculation
        DisplayCalculation False
        
    'For each item into collection
        For i = 1 To mJobs.Count
            
            Index = i
            
            'Get data from its variable name
                For j = 1 To attributes.Count
                    
                    Set c_attribute = attributes.Item(j)
                    
                    On Error Resume Next
                    dataArray(i - 1, j - 1) = CallByName(Me, c_attribute.name, VbGet)
                    On Error GoTo 0
                    
                    Set c_attribute = Nothing
                    
                Next j
            
        Next i
    
    With mWS_data
    
        'Remove previous data
            .Rows("2:" & Rows.Count).Delete
        
        'Data to worksheet '[VERSION THAT WORKS]
            For i = 0 To UBound(dataArray, 1)
        
                For j = 0 To UBound(dataArray, 2)
        
                    .Cells(i + 2, j + 1) = dataArray(i, j)
        
                Next j
        
            Next i
        
        'Data to worksheet '[VERSION THAT FAILS]
            '.Range("A2").Resize(UBound(dataArray, 1) + 1, UBound(dataArray, 2) + 1).Value = dataArray
    
    End With
    
    'Turns in screen updating and auto calculation
        DisplayCalculation True
    
End Sub

虽然我无法向您展示这些数据,因为它是机密的并且不符合 GDPR:

工作时:56行68列数据完成 失败时:填充相同的范围,但只有“AG”列和“AH44”单元格包含数据。

【问题讨论】:

看不到问题,但第二种方式可以更简单地写成.Range("A2").Resize(UBound(dataArray), UBound(dataArray, 2)) = dataArray 如果您正在填充您的数组,例如dataarray = Sheet3.Range("A1:B12"),那么数组从 1 开始,而不是 0。进行调整,它可能会解决您的问题。 CDP1802,感谢您的简化,我会检查一下。查理,我虽然是这样,但这不是问题,因为数组是“Redim”,然后从不同的集合和字典数据中按索引填充索引。 好的,您能否添加两个案例的结果快照,并展示dataarray 的填充方式和内容? 数组有多大? 【参考方案1】:

将二维零基数组写入工作表

Option Explicit

Sub WriteArrayToWorksheet()
    
    Dim DataArray As Variant: ReDim DataArray(0 To 4, 0 To 9) ' 5*10, 'A2:J6'
    Dim r As Long
    Dim c As Long
    For r = 0 To 4
        For c = 0 To 9
            DataArray(r, c) = (r + 1) * (c + 1)
        Next c
    Next r
    
    ' Remember: 'UBound(DataArray, 1)', 'UBound(DataArray,2)', 'DataArray'.
    ' Correct: .Range(.Cells(2, 1), .Cells(UBound(DataArray, 1) + 2, UBound(DataArray, 2) + 1)).Value = DataArray
    ' Wrong:   .Range(.Cells(2, 1), .Cells(UBound(DataArray(), 1) + 2, UBound(DataArray(), 2) + 1)) = DataArray()
    
    With mWS_data
        ' Row + 2 because DataArray starts from 0, and 1st row is titles, Column + 1 because same reason but no titles
        
        ' Correct:
        .Range(.Cells(2, 1), .Cells(UBound(DataArray, 1) + 2, UBound(DataArray, 2) + 1)).Value = DataArray
        
        ' I prefer using 'Resize':
        '.Range("A2").Resize(UBound(DataArray, 1) + 1, UBound(DataArray, 2) + 1).Value = DataArray
    
    End With

End Sub

【讨论】:

以上是关于为啥直接用数组填充范围并按索引进行索引时会获得2个不同的结果?的主要内容,如果未能解决你的问题,请参考以下文章

Vue数组更新,为啥不能通过索引直接设置一个值

致命错误:单击特定单元格进行 segue 时索引超出范围

表格视图单元格中的 uicollectionview 出现错误:索引超出范围,为啥?

为啥具有负索引的数组有效? [复制]

使用索引/范围对数组进行切片是不是会创建数组的副本

为啥 List<T> 的“索引超出范围”异常,但数组却没有?