“Ein diverses Team ist nicht immer besser.” [Simone Menne]

Abstract

Nehmen Sie an, in Ihrem Unternehmen müssen Sonderaufgaben durchgeführt werden, die von jedem Mitarbeiter getätigt werden können. Sie wollen alle Teams fairerweise auf Basis ihrer Mitarbeiteranzahl belasten.

Für diese Auswahl bietet sich die benutzerdefinierte Excel Funktion RoundToSum an.

Da nicht davon ausgegangen werden kann, dass für jede Sonderaufgabe jedes Team prozentual zu seiner Teamgröße belastet werden kann, sollte der Aufruf von RoundToSum eine Rückschau über vergangene Mitarbeiterabstellungen enthalten.

RoundToSum verwendet das Hare-Niemeyer Verfahren, welches das Mandatszuwachsparadoxon aufweist. Wenn ein Mitarbeiter mehr ausgewählt wird, kann es vorkommen, dass ein Team weniger Mitarbeiter als zuvor abstellen muss. Da dies nicht rückwirkend geschehen kann, muss dieser Effekt ausgeglichen werden, sobald er auftritt.

Beispiel

Am 1. Januar 2023 existieren die folgenden Teams:

sbFairStaffSelection_Teams

Über drei Monate hinweg werden die folgenden Mitarbeiter für Sonderaufgaben benötigt und ausgewählt:

sbFairStaffSelection_Allocation

Am 1 Februar 2023 hätte das Hare-Niemeyer Verfahren insgesamt 184, 125, 13 und 2 Mitarbeiter für die Teams A, B, C und D ausgewählt. Da aber am 1. Januar Team C bereits 14 Mitarbeiter bereitgestellt hatte und keine rückwirkenden Anpassungen möglich sind, muss Team A oder B einen Mitarbeiter weniger geben. Der implementierte Algorithmus schaut von links nach rechts, ob angepasst werden kann, also trifft es hier Team A.

Am 1. März 2023 werden genau alle restlichen Mitarbeiter aller Teams benötigt. Der Algorithmus wählt insgesamt für jedes Team genau die Gesamtzahl der Mitarbeiter aus, weil die Rückschau alle Anforderungs-Datensätze umfasst.

Appendix – Programmcode sbFairStaffSelection

Bitte beachten dass sbFairStaffSelection RoundToSum benötigt und aufruft.

Bitte den Haftungsausschluss im Impressum beachten.

Option Explicit

Enum TeamColums
    tc_Date = 1
    tc_TeamStart
End Enum

Enum AllocationColumns
    ac_Date = 1
    ac_Demand
    ac_Comment
    ac_TeamStart
End Enum

Sub sbFairStaffSelection()
'Based on the weights defined in tab Teams this program allocates
'a "fair" selection (the number given in column Demand of tab
'Allocation) of staff from these teams. This program uses (calls) RoundToSum
'which applies the largest remainder method, so the Alabama paradoxon
'must be taken care of. It also applies a lookback up to the topmost
'allocation data row.
'In case of negative selection counts (i. e. the Alabama paradoxon)
'the negative values will be set to zero and the necessary amendments
'(reductions) will be applied from left to right. Please order your
'teams with ascending sizes or descending sizes to account for this.
'Source (EN): https://www.sulprobil.de/sbfairstaffselection_en
'Source (DE): https://www.bplumhoff.com/sbfairstaffselection_de
'(C) (P) by Bernd Plumhoff 09-Mar-2023 PB V0.1

Dim bLookBack                As Boolean
Dim bReCalc                  As Boolean

Dim i                        As Long
Dim j                        As Long
Dim k                        As Long
Dim m                        As Long
Dim lAmend                   As Long
Dim lCellResult              As Long
Dim lDemand                  As Long
Dim lRowSum                  As Long
Dim lSum                     As Long
Dim lTotal                   As Long 'Most recent total number of staff in all teams

Dim sComment                 As String

Dim vAlloc                   As Variant
Dim vTeams                   As Variant

Dim state                    As SystemState

Set state = New SystemState

With Application.WorksheetFunction

vTeams = .Transpose(.Transpose(Range(wsT.Cells(1, 1).End(xlDown).Offset(0, tc_TeamStart - 1), _
          wsT.Cells(1, 1).End(xlDown).End(xlToRight))))
j = UBound(vTeams)
ReDim dAlloc(1 To j) As Double
lTotal = .Sum(vTeams)

bReCalc = False
i = 2
lDemand = wsA.Cells(i, ac_Demand)
Do While lDemand > 0

    lRowSum = .Sum(Range(wsA.Cells(i, ac_TeamStart), wsA.Cells(i, ac_TeamStart + j)))
    
    If lDemand <> lRowSum Then bReCalc = True
    
    If bReCalc Or wsA.Cells(i + 1, ac_Demand) = 0 Then
    
        sComment = "Recalc " & Format(Now(), "DD.MM.YYYY HH:nn:ss") & ". "
        bLookBack = False
        k = i - 1
        If k > 1 Then
            bLookBack = True
            lDemand = 0
            lSum = 0
            ReDim lTeamSum(1 To j) As Long
            Do While k > 1
                lSum = lSum + wsA.Cells(k, ac_Demand)
                lDemand = wsA.Cells(i, ac_Demand) + lSum
                For m = 1 To j
                    lTeamSum(m) = lTeamSum(m) + wsA.Cells(k, m + ac_TeamStart - 1)
                Next m
                'If lSum >= lTotal Then Exit Do 'Uncomment if lookback should be restricted
                                                'to total staff number
                k = k - 1
            Loop
        End If
        
        For m = 1 To j
            dAlloc(m) = lDemand * vTeams(m) / lTotal
        Next m
        
        vAlloc = RoundToSum(vInput:=dAlloc, lDigits:=0)
        
        If bLookBack Then
            For m = 1 To j
                lCellResult = vAlloc(m) - lTeamSum(m)
                If lCellResult < 0 Then
                    'The Alabama Paradoxon: we have to reduce other parties'
                    'allocations because we cannot have negative allocations
                    lAmend = lAmend - lCellResult
                End If
                vAlloc(m) = lCellResult
            Next m
            If lAmend > 0 Then
                For m = 1 To j
                    lCellResult = vAlloc(m)
                    If lCellResult < 0 Then
                        vAlloc(m) = 0
                        sComment = sComment & "Allocation for " & m & " set to 0. "
                    ElseIf lCellResult > 0 And lAmend > 0 Then
                        If lCellResult > lAmend Then
                            vAlloc(m) = lCellResult - lAmend
                            lAmend = 0
                        Else
                            vAlloc(m) = 0
                            lAmend = lAmend - lCellResult
                        End If
                        sComment = sComment & "Allocation for " & m & " amended to " & _
                                   vAlloc(m) & ". "
                    End If
                Next m
            End If
        End If
        wsA.Cells(i, ac_Comment) = sComment
        For m = 1 To j
            wsA.Cells(i, ac_TeamStart + m - 1) = vAlloc(m)
        Next m
        
    End If
    
    i = i + 1
    lDemand = wsA.Cells(i, ac_Demand)
    
Loop

Range(wsT.Cells(1, tc_TeamStart), wsT.Cells(1, 250)).Copy Destination:=wsA.Cells(1, ac_TeamStart)

End With

End Sub

Download

Bitte den Haftungsausschluss im Impressum beachten.

sbFairStaffSelection.xlsm [51 KB Excel Datei, ohne jegliche Gewährleistung]