数组计算顺序问题-为什么我不能模仿在excel中容易完成的事情?

问题描述

我正在尝试模仿我在VBA数组中在Excel中轻松完成的操作,但是我无法使其运行。我认为这与计算的性质有关,后者取决于行的计算顺序。我将用VBA代码附加一个excel工作表,但也会在此处包括它。

此简化示例是具有约50行80列计算的更大数组的替代品。一个特定的列具有一组计算,该计算取决于行相对于所选行的位置-如果行号较高,则应用一组计算,该计算将借鉴PREVIoUS行的值;如果行号较小,则应用另一组计算,该计算使用NEXT行中的值。这个简化的示例如下所示:

enter image description here

三个蓝色列来自VBA。接下来的两列是在Excel中完成的相同计算(它们执行起来更快!)。

您可以看到第二个蓝色列具有一组值,这些值是在第4行上方向上计算而在第4行下方向下计算的。基本上,单元格C2中有一个称为“选择行”的输入,该输入确定“中间”行是哪个,并且它将在该行中输入单元格C3(46)中输入的值,然后在随后的每一行中,将PREVIoUS行的值乘以相同的46。换一种方式,对于“中间”行以下的每一行,每行乘以NEXT按46行。这是许多其他复杂触发计算的替代。这对于Excel来说是微不足道的,它似乎并不在乎哪个单元格取决于什么,它只是返回正确的值,但是在VBA中这是非常困难的-无论如何对我来说。

我已经能够通过迭代整个计算列足够多次来填充依赖于NEXT行值的单元格的值来解决这一问题,因为NEXT行值在第一遍是空的,因为NEXT行没有还没有价值。我可能没有以最有效的方式完成此操作,如果您有更好的主意,不胜感激。

但是真正的问题是,我想在另一列中使用过程返回的值。在第3个蓝色列的Excel版本中,F列中的每一行都从E列中NEXT行中的值减去E列中该行的值(F中的第一个单元格与正在使用的两个单元格一起突出显示为黄色)。无论行相对于“选择行”输入数字的位置在哪里,它都会执行此操作。我无法在VBA的数组中创建适用于该数组的版本。

我尝试了多种方法,但是我似乎无济于事。以某种方式循环遍历数组时,从属列3从不返回值,并且出现下标超出范围错误。我尝试了几种策略,但都没有奏效,而且我没有主意。我已经附上了我使用过的VBA代码

Sub SimplifiedExample()

Dim myArray(1 To 10,1 To 3) As Double
    'for this example the first column is just the index value i,the second is a calculation that depends on the row,and the third refers to another calculation based on the result of the second
Dim selectrow As Integer
    'represents an input value from a User Form,but just coded in here for this example
Dim valuefromAnotherArray As Double
    'represents something calculated elsewhere and referenced here

Dim n As Integer 'iteration counter
Dim i As Integer 'index counter
Dim x As Integer 'yet another counter!


    selectrow = Range("C2") 'user input
    valuefromAnotherArray = Range("C3") 'represents the result of a calculation elsewhere
    
'Because some of the rows depend on the value in the NEXT row which hasn't been calculated yet,'the sub needs to be repeated as many times as there are rows < select row
'so there is an iteration counter and a normal row counter
For n = LBound(myArray) To selectrow
    For i = LBound(myArray) To UBound(myArray)
        myArray(i,1) = i
        
        Select Case myArray(i,1)
        'This bit does the up and down calculation that depends on the row's position relative to select row
            Case Is = selectrow
                myArray(i,2) = valuefromAnotherArray
            Case Is > selectrow
                myArray(i,2) = myArray(i - 1,2) * valuefromAnotherArray 'represents a complex calculation
            Case Is < selectrow
                myArray(i,2) = myArray(i + 1,2) * valuefromAnotherArray
        End Select

        'Approach A - This doesn't work in this position. It throws a Subscript Out Of Range error.
        'myArray(i,3) = myArray(i + 1,2) - myArray(i,2)
        
        Debug.Print myArray(i,1),myArray(i,2) ',myarray(i,3) doesn't work yet
        Cells(i + 5,2).Value = myArray(i,1)
        Cells(i + 5,3).Value = myArray(i,2)
        Cells(i + 5,4).Value = myArray(i,3) 'doesn't work
    Next i
Next n

'Approach B
'Tried adding another counter to cycle through the values produced above and actually use them in the rest of the array
'but throws another Subscript Out Of Range error,so it doesn't work here either
    'For x = LBound(myArray) To UBound(myArray)
    '    myArray(x,3) = myArray(x + 1,2) - myArray(x,2)
    '    Cells(x + 5,4).Value = myArray(x,3)
    'Next x

 End Sub

这是其中包含VBA的Excel文件链接Link to Simplified Example in Excel 我认为可能有比我在此显示方法更简单的方法来完成所有这些操作。非常感谢您能提供的任何帮助,并谨记我希望将其集成到50 x 80 2D阵列中。谢谢!

解决方法

这不会达到相同的目的吗?

编辑第3列

Sub test()
    Dim ws As Worksheet
    Dim i As Long,startRow As Long,inputRow As Long
    Dim inputFromOtherArray As Double
    
    Set ws = ThisWorkbook.Worksheets("sheet_name")
    
    startRow = 15
    inputFromOtherArray = 46
    inputRow = 4
    With ws
        For i = 0 To 9
            .Cells(startRow + i,3).Value = inputFromOtherArray ^ (Abs(inputRow - (i + 1)) + 1)
        Next i
        
        For i = 0 To 8
            .Cells(startRow + i,4).Value = .Cells(startRow + i + 1,3).Value - .Cells(startRow + i,3).Value
        Next i
        
        .Cells(startRow + 9,4).Value = -.Cells(startRow + i,3).Value
    End With
End Sub