VBA使用recrusive而不是循环

时间:2014-06-16 22:22:51

标签: excel algorithm vba recursion sum

我想请求您帮助解决我正在构建算法的问题。

  • 可用数据

我们有一个包含10行30列的数据表。

每一行对应一个与特定参数相关的变量(例如苹果的重量,梨的重量,橘子的重量...... Paramter10)

每列对应于变量可以采用的值。

我们如何为每个变量/参数提供30个可能的值。

  • 算法的目标 给出这些参数的所有可能组合的总和(苹果+梨+橘子+ ... +参数10),通常应该有30 ^ 10种可能的组合

  • 我的算法版本说明

    1. 创建一个10的数组,比方说索引。每个索引对应于变量/参数。每个索引由30个可能值中的一个填充。

    2. 创建一个循环遍历同一行中的列。表中单元格的每个值都放在相应的索引中(第1行,索引1)

    3. 每个更改对应于同一行中的下一个可用值(右侧),但具有不同的列。当列终止时,算法开始对下一行执行相同操作。

    4. 数组变量中的每个更改都必须为结果提供一个新的总和,复制到表格中的某个新单元格中。

Sub AlgoSum()

Dim rw As Long, column1 As Long
Dim Sum1(9) As Long 'The array with 10 index 'First difficulty is to find a way how to synchornize the sum with every change in array Sum1.
    Do While i <= 8 'My version is to place it in first but not sure it is right
            For rw = 1 To 9
                For column1 = 1 To 30
                    If Not IsEmpty(Worksheets("Sheet1").Cells(rw, column1)) Then 'verify that the cell is not empty
                        Sum1(i) = Worksheets("Sheet1").Cells(rw, column1).Value
                        Worksheets("Sheet1").Cells(rw+30, column1+30).Value = Application.WorksheetFunction.Sum(Sum1)

                    Else 'normally if it is empty it should move to the next value but I didn't find the appropriate way to do it, this why I thought about this compromise
                        Sum1(i) = 0
                        Worksheets("Sheet1").Cells(rw+30, column1+30).Value = Application.WorksheetFunction.Sum(Sum1)
                    End If
                Next column1
            Next rw
        i = i + 1
    Loop

End Sub

此代码未给出适当的结果。它没有给出数组中每个变化的总和,也没有按照它的方式对数组进行更改。

我已经看到了递归的可能解决方案,但没有找到正确的方法。

非常欢迎一些帮助!

提前谢谢!

2 个答案:

答案 0 :(得分:0)

试试这个。它是递归的(虽然它也使用循环)。

  • 使用顶部的常量来调整数据。
  • 尝试使用几行和几列。
  • 当前常量假设您的数据在单元格A1中开始,并且有3个“变量”和2个“值”。
  • 它会将结果打印到即时窗口,但您可以将其调整为存储在数组中或打印到另一张纸上。

' number of "variables"
Const ROWS As Integer = 3
' number of "values"
Const COLS As Integer = 2
' upper left cell of table
Const CELL_UPPER_LEFT As String = "A1"

' Recursive method to sum the values of all the combinations of all the rows.
' Method will print the result in the immediate window for now.
' @param    row_number  Integer     Number of rows of data
' @param    sum               Double    Running sum of previous rows

Private Sub recursiveSum(ByVal row_number As Integer, ByVal sum As Double)

    ' if we've reached the bottom, then print the result and go back up
    If row_number = ROWS Then
        Debug.Print sum
        Exit Sub
    End If

    ' loop over the number of columns
    Dim col_number As Integer
    For col_number = 0 To COLS - 1

        ' make a recursive call, increasing the sum by the current row and increasing the row number by 1
        recursiveSum row_number + 1, Range(CELL_UPPER_LEFT).Offset(row_number, col_number).Value + sum
        ' when we return from the recursive call we will be here - ready to start the next time through the loop

    Next

End Sub

' Wrapper function for the recursive method.
Public Sub recursiveSumWrapper()

    ' make the initial recursive call
    recursiveSum 0, 0

End Sub

答案 1 :(得分:0)

非常感谢您的回复。您的解决方案与debug.print完美配合!

我能够添加表格的自动尺寸标注:

' number of "variables"
Dim ROWS As Integer
' number of "values"
Dim COLS As Integer
' upper left cell of table
Const CELL_UPPER_LEFT As String = "A1"

ROWS = Worksheets("Sheet1").UsedRange.ROWS.Count  
COLS = Worksheets("Sheet1").UsedRange.Columns.Count
a = (ROWS) ^ (COLS) 'The number of possible combinations

但是我花了整个上午的时间来更改debug.print以获取另一个选项:

If row_number = ROWS Then
       Debug.Print sum
       Exit Sub
End If

为了以下使用获得的数据更方便的可能性

If row_number = ROWS Then
    For i = 1 To a
        Worksheets("Sheet2").Cells(20, a).Value = sum
        Exit Sub
    Next
End If

据我所知,这不是使用循环的正确位置,因为我收到错误:«下标超出范围»。我的直觉告诉我,它与ROWS不对应。

你对这个细节有什么看法吗?是否可以直接使用debug.print信息?