最合适的软件包-VBA请求

时间:2020-02-04 07:01:07

标签: excel vba excel-formula

我以15、20、26、40的批次生产物品。

    - If I need to fit 80 items in these batches,
 guess the best fit would be to use 2 of 40 (batches) or 4 of 20 batches..

是否可以通过函数或公式动态获取最佳拟合,这样我才能知道最佳拟合...。

This the excel columns I have

2 个答案:

答案 0 :(得分:0)

您可以尝试以下方法:

表格结构:

enter image description here

代码:

Sub test()

    Dim rngBatches As Range, cell As Range
    Dim No_Items As Long
    Dim strResults As String

    With ThisWorkbook.Worksheets("Sheet1")

        Set rngBatches = .Range("B1:E1")
        No_Items = .Range("B2").Value

        For Each cell In rngBatches

            If No_Items / cell = Int(No_Items / cell) Then
                If strResults = "" Then
                    strResults = "Option(s):" & vbNewLine & No_Items / cell & " batches of " & cell & " items."
                Else
                    strResults = strResults & vbNewLine & No_Items / cell & " batches of " & cell & " items."
                End If
            End If
        Next cell

        MsgBox strResults

    End With

End Sub

答案 1 :(得分:0)

请测试此代码。 批次值将在“ B1:E1”范围内。仅批次值(15、20、26、40)。如果必须存在字符串“批处理”,则可以通过单元格格式添加字符串(“批处理” ###)。 它不会返回所有可能的变体。它尝试以最少的批次数返回最佳匹配。也许可以改进它,但不需要它,我也懒得那样做...

在模块代码上方:

Option Explicit
Private boolOff As Boolean

然后:

Sub testBatchOptimization()
  Dim sh As Worksheet, arrB As Variant, chkb As Double

  Set sh = ActiveSheet
  arrB = sh.Range("B1:E1").Value
  chkb = sh.Range("B2").Value
  MsgBox recursiveBatch(arrB, chkb, 1)
End Sub
Function recursiveBatch(arrB As Variant, chkb As Double, levelX As Long) As String
    Dim nrB As Long, nrBOld As Long, i As Long, Rez As Long, boolF As Boolean
    For i = 1 To UBound(arrB, 2)
        Select Case levelX
            Case 1
                If chkb = arrB(1, i) Then
                    Rez = arrB(1, i): nrB = 1: boolF = True: Exit For
                ElseIf chkb Mod arrB(1, i) = 0 Then 'fix division
                    If nrBOld = 0 Then
                        nrB = chkb / arrB(1, i): _
                               Rez = arrB(1, i): boolF = True
                    Else
                        If nrBOld >= chkb / arrB(1, i) Then _
                              nrB = chkb / arrB(1, i): _
                              Rez = arrB(1, i): boolF = True
                    End If
                    nrBOld = chkb / arrB(1, i)
                End If
            Case 2
                If i = UBound(arrB, 2) And chkb > arrB(1, UBound(arrB, 2)) + _
                    arrB(1, UBound(arrB, 2) - 1) Then recursiveBatch = recursiveBatch(arrB, chkb, 3)
                     If boolOff Then boolOff = False: Exit Function
                If arrB(1, i) >= chkb Then
                    recursiveBatch = "one batch of " & arrB(1, i)
                    Exit Function
                ElseIf arrB(1, i) < chkb And arrB(1, i + 1) And i < UBound(arrB, 2) >= chkb Then
                    recursiveBatch = "one batch of " & arrB(1, i + 1)
                    Exit Function
                ElseIf arrB(1, i) + arrB(1, i + 1) >= chkb And chkb > arrB(1, UBound(arrB, 2)) Then
                    If i = 3 And arrB(1, i + 1) + arrB(1, 1) >= chkb Then
                        recursiveBatch = "1 batch of " & arrB(1, 1) & " plus 1 batch of " & arrB(1, i + 1)
                        Exit Function
                    ElseIf i = 3 And arrB(1, i + 1) + arrB(1, 2) >= chkb Then
                        recursiveBatch = "1 batch of " & arrB(1, 2) & " plus 1 batch of " & arrB(1, i + 1)
                        Exit Function
                    Else
                        recursiveBatch = "1 batch of " & arrB(1, i) & " plus 1 batch of " & arrB(1, i + 1)
                        Exit Function
                    End If
                End If
            Case 3
                If chkb < arrB(1, 1) + arrB(1, 2) + arrB(1, 3) + arrB(1, 3) Then
                    If arrB(1, 4) + arrB(1, 3) + arrB(1, i) >= chkb Then
                        recursiveBatch = "1 batch of " & arrB(1, i) & " plus 1 batch of " & arrB(1, 3) & _
                                        " plus 1 batch of " & arrB(1, 4)
                        boolOff = True: Exit Function
                    End If
                Else
                   recursiveBatch = interpretCase(Rez, nrB, chkb)
                    boolOff = True: Exit Function
                End If
        End Select
    Next i
    If boolF Then
        If Rez = 20 Or Rez = 26 Then
            If nrB > 2 Then
                recursiveBatch = interpretCase(Rez, nrB, chkb)
                boolOff = True: Exit Function
            Else
                recursiveBatch = nrB & " batches of " & Rez
            End If
            Exit Function
        ElseIf Rez = 15 Then
            If nrB > 3 Then
                recursiveBatch = interpretCase(Rez, nrB, chkb)
                boolOff = True: Exit Function
            Else
                recursiveBatch = nrB & " batches of " & Rez
            End If
            Exit Function
        End If

    Else
        recursiveBatch = recursiveBatch(arrB, chkb, 2)
    End If
End Function
Private Function interpretCase(Rez As Long, nrB As Long, ByVal chkb As Long) As String
    Dim nr40 As Long, nr26 As Long, nr20 As Long, nr15 As Long, rest As Long
    nr40 = Int(chkb / 40)
    rest = chkb - (nr40 * 40)
    If rest <= 15 Then
        interpretCase = nr40 & IIf(nr40 = 1, " batch ", " batches ") & "of 40 and 1 batch of 15"
    ElseIf rest <= 20 Then
        interpretCase = nr40 & IIf(nr40 = 1, " batch ", " batches ") & "of 40 and 1 batch of 20"
    ElseIf rest <= 26 Then
        interpretCase = nr40 & IIf(nr40 = 1, " batch ", " batches ") & "of 40 and 1 batch of 26"
    Else
        interpretCase = nr40 + 1 & " batches of 40"
    End If
End Function

我对其进行了有限次数和值的测试。我没有发现任何错误,但是可能存在无法正确测试的问题……

我认为这很容易理解。我尝试了一些评论,但是开始变得浓密。