在Excel中查找总和的多种组合

时间:2018-11-04 23:03:52

标签: excel vba excel-vba

我一直试图在Excel中做一些事情来查找总和的多个组合。

我有一个数字列表,需要将这些数字加在一起才能在500-510或450-460范围内。

只能使用列表中的两个数字来求和。不能重复使用这些数字。并给出多个结果的组合会很棒。如果不使用数字就可以了。

我已经尝试了该求解器加载项以及从此站点发现的其他一些技巧,但找不到能给出多个答案的东西。

有人知道这是否可能吗?

3 个答案:

答案 0 :(得分:3)

我将其分为2个任务。首先是简单地生成所有索引对以在输入数组中进行测试。递归过程相对简单。这个使用私有的Type来存储对,但是它可以适应使用其他一些存储对的方法:

Private Type Tuple
    ValueOne As Long
    ValueTwo As Long
End Type

Private Sub FindCombinations(elements As Long, ByRef results() As Tuple, _
                             Optional ByVal iteration As Long = 0)
    If iteration = 0 Then ReDim results(0)
    Dim idx As Long
    For idx = iteration To elements - 1
        Dim combo As Tuple
        With combo
            .ValueOne = iteration
            .ValueTwo = idx
        End With
        results(UBound(results)) = combo
        If iteration <> elements And idx <> elements Then
            ReDim Preserve results(UBound(results) + 1)
        End If
    Next

    If iteration < elements Then FindCombinations elements, results, iteration + 1
End Sub

然后,您使用“入口点”过程生成索引组合,使用这些索引组合到源数组中,并应用选择条件:

Private Sub FindMatchingSets(testSet() As Long)
    Dim indices() As Tuple
    FindCombinations UBound(testSet) + 1, indices

    Dim idx As Long, results() As Tuple

    For idx = LBound(indices) To UBound(indices)
        Dim tupleSum As Long
        tupleSum = testSet(indices(idx).ValueOne) + testSet(indices(idx).ValueTwo)
        If indices(idx).ValueOne <> indices(idx).ValueTwo And _
           ((tupleSum >= 500 And tupleSum <= 510) Or _
           (tupleSum >= 450 And tupleSum <= 460)) Then
            Debug.Print testSet(indices(idx).ValueOne) & " + " & _
                testSet(indices(idx).ValueTwo) & " = " & tupleSum
        End If
    Next
End Sub

目前尚不清楚您打算对结果做什么,因此仅将计算出的值输出到立即窗口。调用代码示例:

Private Sub Example()
    Dim test(4) As Long
    test(0) = 100
    test(1) = 200
    test(2) = 250
    test(3) = 260
    test(4) = 400

    FindMatchingSets test
End Sub

答案 1 :(得分:1)

可以根据您的需要进行修改并尝试

Sub test()
Dim X, Y, TRw, GotNum, First, Second As Long
TRw = 1
With ThisWorkbook.ActiveSheet
For X = 1 To 100                   ' assumed col A1 to A100 is the list
GotNum = .Cells(X, 1).Value
    If (GotNum >= 450 And GotNum <= 460) Or (GotNum >= 500 And GotNum <= 510) Then
    .Cells(X, 1).Font.Color = RGB(255, 0, 0)
    First = GotNum
        For Y = X + 1 To 100
        GotNum = .Cells(Y, 1).Value
            If (GotNum >= 450 And GotNum <= 460) Or (GotNum >= 500 And GotNum <= 510) Then
            Second = GotNum
            TRw = TRw + 1
            .Cells(TRw, 3).Value = First     ' write 1st Number in Col C
            .Cells(TRw, 4).Value = Second    ' write 2nd Number in Col D
            .Cells(TRw, 5).Value = First + Second   ' write Sum of 1st & 2nd in Col C
            End If
        Next Y
    End If
Next X
End With
End Sub

答案 2 :(得分:1)

我认为您的问题需要从预期输出(您想要一份连击列表,还是只是为了查看结果?)方面更清楚一点,但这是我的解决方案。

combination of sums - potential solution

我在Y列中放置了20个数字的列表,并在X列中为它们分配了所有字母(从a到t)

然后我建立了一个由a到t的组合的矩阵,并输入了以下公式(以下是C3单元格,但是可以将其复制并粘贴到矩阵的所有部分中)

=IF(C$2=$B3,"x",VLOOKUP(C$2,$X:$Y,2,FALSE)+VLOOKUP($B3,$X:$Y,2,FALSE))

然后,我使用条件格式设置了单元格的颜色(如果它们符合您的总和标准)-您可以通过突出显示所有总和(单元格C3:V22)并转到

主页/条件格式/新规则...

选择规则类型仅格式化包含以下内容的单元格

,然后在下拉菜单中选择单元格值 / 介于 / 您的高范围

然后选择一种格式(通常填充背景色)

对“高”总和执行一次,对“低”总和执行一次。您可以根据想要看到的颜色来使颜色相同或不同。

作为参考,我还引用了第1行和A列中的数字。第1行的公式是(例如C1,但可以复制)。

=VLOOKUP(C2,$X:$Y,2,FALSE)

A列的公式为(A3的示例)=VLOOKUP(B3,$X:$Y,2,FALSE)

这种方法的优点是全部都在excel中(不需要代码),但是缺点是很难获得结果列表。您可以使用不同的公式来在满足其中一个条件时返回总和(例如,返回文本“ 205 + 298”),但是将其从矩阵中取出仍然很麻烦格式化并合并为一个列表。使用VBA容易得多