Excel VBA 中的数组。在某些时候它用 NA 代替值

Arrays in Excel VBA. At some point it puts NA instead of the value

我正在尝试在 Excel VBA 中进行一个简单的模拟,我们掷两个骰子。得到“1”+“2”或“1”+“3”的概率是多少?

这是我的代码:

 Sub ProbabilityMeyerArray()
    Dim i As Long
    Dim ArrayDices(1 To 100000, 1 To 2) As Variant
    Dim ArrayResult(1 To 100000) As Variant
    
    'Simulation
    For i = 1 To 100000
        ArrayDices(i, 1) = WorksheetFunction.RandBetween(1, 6)
        ArrayDices(i, 2) = WorksheetFunction.RandBetween(1, 6)


        If (ArrayDices(i, 1) = 1 And ArrayDices(i, 2) = 3) _
            Or (ArrayDices(i, 1) = 1 And ArrayDices(i, 2) = 2) _
            Or (ArrayDices(i, 1) = 3 And ArrayDices(i, 2) = 1) _
            Or (ArrayDices(i, 1) = 2 And ArrayDices(i, 2) = 1) Then
            
            ArrayResult(i) = 1
            
        Else
            ArrayResult(i) = 0
        End If
    Next i
    
    
    'print the values to cells
    Range("A1:B100000").Value = ArrayDices
    Range("C1:C100000").Value = WorksheetFunction.Transpose(ArrayResult)
    
    'Calculate the probability
    Probability = Application.WorksheetFunction.Sum(ArrayResult) / 100000
    
    MsgBox "The Probability is " & Probability
    
End Sub

问题是,当我将数组中的值打印到单元格时,C 列中有 0 和 1(应该是),但是从第 34465 行我得到 NA。这是屏幕截图:

https://ibb.co/7jsjjJC

因此,出于某种原因,它开始使用 NA 而不是 0 和 1。计算也无法正常工作,因为概率太低,我猜这是因为它只计算前 34464 个零和一, 同时除以 100 000。你能帮我理解这里出了什么问题吗?这似乎是(我对)数组的问题,因为我可以 运行 没有数组的类似模拟(通过简单地使用单元格),并且它有效。

提前致谢!

正如@RaymondWu 在评论中所说,问题在于 Transpose 函数对其可以操作的数组长度有限制。此限制介于 65k 和 66k 列之间。

确实,您的代码将 运行 达到预期的 65k 次迭代。

您可以轻松避免使用 transpose,老实说,我一开始并没有看到使用它的理由。

不是将数组声明为 Dim ArrayResult(1 To 100000) As Variant,默认情况下它是 1 row x 100000 columns,您可以这样声明它:

Dim ArrayResult(1 To 100000, 1 To 1) As Variant

这将使它成为 100000 rows x 1 columns,现在可以像这样轻松地将其写在 excel 的列中:

Range("C1:C100000").Value = ArrayResult

当然,您还需要根据需要相应地更改代码:

 ArrayResult(i,1) = 1
            
        Else
            ArrayResult(i,1) = 0

其他一些提示:

  1. 始终在代码的最顶部使用 Option Explicit。它使变量声明成为强制性的,有助于避免错误
  2. 始终使用显式引用。引用 Ranges 时,最佳做法是定义它们所属的工作表,例如ThisWorkbook.Worksheets("Sheet1").Range("C1:C100000").Value = ArrayResult