“Givers have to set limits because takers rarely do.” [Irma Kurtz]

Beispiel

Nehmen Sie, Ihr Unternehmen befindet sich mitten in seinem jährlichen Planungsprozess für Einnahmen und Ausgaben. Sie sind der Bereichsleiter von 6 Abteilungen (A bis F). Ihre Abteilungsleiter haben ein Budget von 2000, 1900, 2000, 2000, 600 und 2000 € beantragt, aber Ihnen wurde lediglich ein Gesamtbudget in Höhe von 9500 € zur Verfügung gestellt. Ihre Abteilungen tragen gewichtet 30%, 20%, 15%, 15%, 10% und 10% zu den Unternehmenseinnahmen bei.

Wie würden Sie Ihr Budget verteilen? Sicherlich würden Sie niemanden mehr geben als beantragt wurde:

sbDistBudget

Appendix Programmcode sbDistBudget

Bitte den Haftungsausschluss im Impressum beachten.

Option Explicit

Function sbDistBudget(dBudget As Double, _
    vRequest As Variant, _
    vWeight As Variant) As Variant
'Distribute a budget fairly upon Ubound(vRequest)
'requestors according to their weight vWeight(i)
'but do not give them more than they requested.
'Iterative solution.
'Source (EN): https://www.sulprobil.de/sbdistbudget_en/
'Source (DE): https://www.berndplumhoff.de/sbdistbudget_de/
'(C) (P) by Bernd Plumhoff 03-Dec-2012 PB V0.22
Dim dSumRequest As Double
Dim dSumWeight As Double
Dim dSumDist As Double
Dim dBudgetRest As Double
Dim dMinRest As Double
Dim i As Long, lc As Long, lgtNull As Long
With Application
lc = vRequest.Count
If lc <> vWeight.Count Then
    sbDistBudget = CVErr(xlErrValue)
    Exit Function
End If
ReDim dWeight(1 To lc) As Double
ReDim vR(1 To lc) As Variant 'Result vector
ReDim vT(1 To lc) As Variant 'Temp vector
dSumRequest = .Sum(vRequest)
If dSumRequest <= dBudget Then
    'Easy case: budget >= requests
    For i = 1 To lc
        vR(i) = vRequest(i)
    Next i
    sbDistBudget = vR
    Exit Function
End If
'Initialize budget distribution
dBudgetRest = dBudget
For i = 1 To lc
    dWeight(i) = vWeight(i)
Next i
'Distribute budget
Do While dBudget > dSumDist
    dSumWeight = .Sum(dWeight)
    If dSumWeight > 0# Then
        For i = 1 To lc
            vT(i) = dWeight(i) * dBudgetRest / dSumWeight
            If vT(i) + vR(i) >= vRequest(i) Then
                vT(i) = vRequest(i) - vR(i)
                dWeight(i) = 0#
            End If
            vR(i) = vR(i) + vT(i)
        Next i
    Else
        lgtNull = 0
        dMinRest = dBudgetRest
        For i = 1 To lc
            vT(i) = .Max(vRequest(i) - vR(i), 0#)
            If vT(i) > 0# Then
                lgtNull = lgtNull + 1
                If dMinRest > vT(i) Then
                    dMinRest = vT(i)
                End If
            End If
        Next i
        If lgtNull = 0 Then Exit Do
        If dMinRest > dBudgetRest / lgtNull Then
            dMinRest = dBudgetRest / lgtNull
        End If
        For i = 1 To lc
            If vT(i) > 0# Then
                vR(i) = vR(i) + dMinRest
                vT(i) = dMinRest
            End If
        Next i
    End If
    dBudgetRest = dBudgetRest - .Sum(vT)
    dSumDist = .Sum(vR)
Loop
End With
sbDistBudget = vR
End Function

Download

sbDistBudget.xlsm [19 KB Excel Datei, ohne jegliche Gewährleistung]