如何查找哪个值创建最大组合 - Excel VBA

时间:2013-09-17 05:17:46

标签: excel excel-vba excel-formula combinations vba

我需要找到哪个值创建Excel Vba中显示的最大组合

假设, 我有这样的组合

a   a+b a+b+c   1   1+2 1+2+1   3   4
b   a+c a+b+d   2   1+1 1+2+3   2   6
c   a+d a+b+e   1   1+3 1+2+2   4   5
d   a+e a+c+d   3   1+2 1+1+3   3   5
e   b+c a+c+e   2   2+1 1+1+2   3   4
    b+d a+d+e       2+3 1+3+2   5   6
    b+e b+c+d       2+2 2+1+3   4   6
    c+d b+c+e       1+3 2+1+2   4   5
    c+e b+d+e       1+2 2+3+2   3   7
    d+e c+d+e       3+2 1+3+2   5   6

我需要找到哪些组合创建最大值,在这种情况下,值“7”是最大值,由2,3,2创建。因此,我希望这些值作为唯一单元格中的输出。 我可能有数千种组合,因此我希望这些组合能够自动找到并自动输出到独特的单元格中并进一步运行程序。 请帮忙。

由于 巴拉吉

2 个答案:

答案 0 :(得分:1)

概念:

一组n中m个值的最大总和是m个较大值的总和。 一旦值按降序排序,解决方案就很简单了。

这是一个纯Excel解决方案,没有VBA。

设计&实施:

用户输入(变量名称和值)位于C4:D8。

这个想法如下:

  1. 确定数据的顺序。为此,我在B列中使用RANK
  2. 然后在G和H列中使用VLOOKUP根据排名对数据进行排序。
  3. 然后,最大总和很容易计算:n个较大数的总和。
  4. 以下是代码:

         A                      B    C     D E    F                              G                              H I         J                                                      K
    1                                            
    2                           User input        Sorted by rank                                                            Maximum sums        
    3    Rank                   name value   Rank name                           value                                      name                                                   value
    4    =RANK.EQ(C4;$C$4:$C$8) a    45      1    =VLOOKUP(E4;$A$4:$C$8;2;FALSE) =VLOOKUP(E4;$A$4:$C$8;3;FALSE)   2 numbers =CONCATENATE($F$4;"+";$F$5)                            =$G$4+$G$5
    5    =RANK.EQ(C5;$C$4:$C$8) b    1       2    =VLOOKUP(E5;$A$4:$C$8;2;FALSE) =VLOOKUP(E5;$A$4:$C$8;3;FALSE)   3 numbers =CONCATENATE($F$4;"+";$F$5;"+";$F$6)                   =$G$4+$G$5+$G$6
    6    =RANK.EQ(C6;$C$4:$C$8) c    2       3    =VLOOKUP(E6;$A$4:$C$8;2;FALSE) =VLOOKUP(E6;$A$4:$C$8;3;FALSE)   4 numbers =CONCATENATE($F$4;"+";$F$5;"+";$F$6;"+";$F$7)          =$G$4+$G$5+$G$6+$G$7
    7    =RANK.EQ(C7;$C$4:$C$8) d    12      4    =VLOOKUP(E7;$A$4:$C$8;2;FALSE) =VLOOKUP(E7;$A$4:$C$8;3;FALSE)   5 numbers =CONCATENATE($F$4;"+";$F$5;"+";$F$6;"+";$F$7;"+";$F$8) =$G$4+$G$5+$G$6+$G$7+$G$8
    8    =RANK.EQ(C8;$C$4:$C$8) e    33      5    =VLOOKUP(E8;$A$4:$C$8;2;FALSE) =VLOOKUP(E8;$A$4:$C$8;3;FALSE)                
    

    结果如下:

         A       B    C     D  E   F    G    H    I            J          K
    1                                            
    2            User input        Sorted by rank              Maximum sums        
    3    Rank    name value   Rank name value                  name       value
    4    1       a    45      1    a    45        2 numbers    a+e        78
    5    5       b    1       2    e    33        3 numbers    a+e+d      90
    6    4       c    2       3    d    12        4 numbers    a+e+d+c    92
    7    3       d    12      4    c    2         5 numbers    a+e+d+c+b  93
    8    2       e    33      5    b    1                
    

    请注意,它可以很容易地扩展到更多变量。

答案 1 :(得分:1)

扩展d-stroyer的答案,并将其转换为VBA:

创建UDF:

Option Explicit

Function GetMax(RNames As Range, RVals As Range, MaxNums As Long) As String
Dim i As Long
Dim j As Long
Dim tmpName As String
Dim tmpVals As Long
Dim Names()
Dim Vals()

Names = RNames
Vals = RVals

For i = 1 To UBound(Names) - 1 'bubble sort
    For j = i + 1 To UBound(Names)
        If Vals(i, 1) < Vals(j, 1) Then 'largest first
            tmpName = Names(i, 1)
            Names(i, 1) = Names(j, 1)
            Names(j, 1) = tmpName
            tmpVals = Vals(i, 1)
            Vals(i, 1) = Vals(j, 1)
            Vals(j, 1) = tmpVals
        End If
    Next j
Next i

For i = 1 To MaxNums
    If Vals(i, 1) <= 0 Then Exit For 
    'adding zero, or negative numbers will lower the total
Next i

For j = 1 To i - 1
    GetMax = GetMax & Names(j, 1) & ","
    'now we know how many values to use (from previous loop)
    'make the string up
Next j

If Len(GetMax) > 0 Then
    GetMax = Left(GetMax, Len(GetMax) - 1)
    'remove the final comma
Else
    GetMax = "No result found"
End If

End Function

使用=getmax(A1:A5,D1:D5,3)致电 结果将是 d,b,e

我将把剩下的部分留给你检查错误条件,例如在范围内传递超过1列,或者大小不等的范围,或者返回的最大项数大于范围大小