Загрузка данных
Sub РазбитьПоФИО() Dim ws1 As Worksheet, ws2 As Worksheet, ws3 As Worksheet Dim dict As Object, dictSmen As Object, fio As Variant, sm As Variant Dim lastRow As Long, i As Long, outRow As Long, startRow As Long Dim smena As String
' === 6 префиксов заявок ===
Dim pref(1 To 6) As String
pref(1) = "ACM": pref(2) = "CIM": pref(3) = "DCM"
pref(4) = "EVM": pref(5) = "RSM": pref(6) = "TR"
Dim cntZap(1 To 6) As Long
Dim errZap(1 To 6) As Long
Dim okZap(1 To 6) As Long
Dim idxPos(1 To 6) As Long
Dim zap As String, p As Long, k As Long
Dim maxZap As Long
Dim pctOk As Double
' === переменные для Листа3 ===
Dim lastRow3 As Long, j As Long
Dim rolStr As String, regStr As String
Dim fioNorm As String, fio3Norm As String
' === счётчики ошибочных/правильных заявок (общие) ===
Dim okCnt As Long, errCnt As Long
Dim hVal As Variant
Dim isErr As Boolean
Dim hdr As String, totSmen As String
Set ws1 = ThisWorkbook.Sheets("Лист1")
Set ws2 = ThisWorkbook.Sheets("Лист2")
Set ws3 = ThisWorkbook.Sheets("Лист3")
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
ws2.Cells.Clear
lastRow = ws1.Cells(ws1.Rows.Count, 1).End(xlUp).Row
lastRow3 = ws3.Cells(ws3.Rows.Count, 1).End(xlUp).Row
' Уникальные ФИО (столбец G Листа1)
Set dict = CreateObject("Scripting.Dictionary")
For i = 2 To lastRow
If Trim(CStr(ws1.Cells(i, 7).Value)) <> "" Then
dict(Trim(CStr(ws1.Cells(i, 7).Value))) = 1
End If
Next i
outRow = 1
For Each fio In dict.Keys
' ============================================
' Поиск роли и региона на Листе3 (A=ФИО, B=Роль, C=Регион)
' ============================================
rolStr = "—"
regStr = "—"
fioNorm = UCase(Trim(CStr(fio)))
For j = 2 To lastRow3
fio3Norm = UCase(Trim(CStr(ws3.Cells(j, 1).Value)))
If fio3Norm = fioNorm Then
If Trim(CStr(ws3.Cells(j, 2).Value)) <> "" Then
rolStr = CStr(ws3.Cells(j, 2).Value)
End If
If Trim(CStr(ws3.Cells(j, 3).Value)) <> "" Then
regStr = CStr(ws3.Cells(j, 3).Value)
End If
Exit For
End If
Next j
' ============================================
' Подсчёт смен, заявок по префиксам, ошибочных (общих и по категориям)
' ============================================
Set dictSmen = CreateObject("Scripting.Dictionary")
For p = 1 To 6
cntZap(p) = 0
errZap(p) = 0
okZap(p) = 0
Next p
okCnt = 0
errCnt = 0
For i = 2 To lastRow
If Trim(CStr(ws1.Cells(i, 7).Value)) = fio Then
' --- смена ---
smena = UCase(Trim(ws1.Cells(i, 2).Value))
If smena = "П" Then smena = "ПО"
If smena <> "" Then
If dictSmen.Exists(smena) Then
dictSmen(smena) = dictSmen(smena) + 1
Else
dictSmen(smena) = 1
End If
End If
' --- заявка: определяем категорию ---
zap = UCase(Trim(CStr(ws1.Cells(i, 4).Value)))
isErr = False
hVal = ws1.Cells(i, 8).Value
If IsNumeric(hVal) Then
If CDbl(hVal) > 0 Then isErr = True
End If
If zap <> "" Then
For p = 1 To 6
If Left(zap, Len(pref(p))) = pref(p) Then
cntZap(p) = cntZap(p) + 1
If isErr Then
errZap(p) = errZap(p) + 1
Else
okZap(p) = okZap(p) + 1
End If
Exit For
End If
Next p
End If
' --- ошибочная/правильная общая по столбцу H ---
If IsNumeric(hVal) Then
If CDbl(hVal) > 0 Then
errCnt = errCnt + 1
Else
okCnt = okCnt + 1
End If
Else
If Trim(CStr(hVal)) = "" Then
okCnt = okCnt + 1
End If
End If
End If
Next i
' ============================================
' Заголовок блока: ФИО (Регион) + смены + Роль
' ============================================
hdr = fio & " (" & regStr & ")"
If dictSmen.Count > 0 Then
hdr = hdr & " "
For Each sm In dictSmen.Keys
hdr = hdr & sm & " - " & dictSmen(sm) & " "
Next sm
End If
hdr = hdr & " | Роль: " & rolStr
With ws2.Cells(outRow, 1)
.Value = hdr
.Font.Bold = True
.Font.Size = 12
.Interior.Color = RGB(220, 230, 245)
End With
outRow = outRow + 1
' ============================================
' Итоговая строка: смены + всего + правильно/ошибка
' ============================================
totSmen = ""
For Each sm In dictSmen.Keys
totSmen = totSmen & sm & " - " & dictSmen(sm) & " "
Next sm
With ws2.Cells(outRow, 1)
.Value = "Итого по " & fio & ": " & totSmen & _
"Всего заявок - " & (cntZap(1) + cntZap(2) + cntZap(3) + cntZap(4) + cntZap(5) + cntZap(6)) & _
" | Выполнено правильно - " & okCnt & _
" | Выполнено с ошибкой - " & errCnt
.Font.Bold = True
.Font.Italic = True
.Interior.Color = RGB(255, 235, 156)
End With
outRow = outRow + 1
' ============================================
' Заявки по 6 столбцам-префиксам (В СТОЛБИК)
' ============================================
' Шапка категорий
For p = 1 To 6
ws2.Cells(outRow, p) = pref(p)
Next p
ws2.Range(ws2.Cells(outRow, 1), ws2.Cells(outRow, 6)).Font.Bold = True
ws2.Range(ws2.Cells(outRow, 1), ws2.Cells(outRow, 6)).Interior.Color = RGB(230, 240, 230)
outRow = outRow + 1
' Высота блока = максимум заявок в любой категории
maxZap = 0
For p = 1 To 6
If cntZap(p) > maxZap Then maxZap = cntZap(p)
Next p
If maxZap = 0 Then maxZap = 1
startRow = outRow
For p = 1 To 6
idxPos(p) = 0
Next p
' Запись заявок сразу в ячейки
For i = 2 To lastRow
If Trim(CStr(ws1.Cells(i, 7).Value)) = fio Then
zap = UCase(Trim(CStr(ws1.Cells(i, 4).Value)))
If zap <> "" Then
For p = 1 To 6
If Left(zap, Len(pref(p))) = pref(p) Then
idxPos(p) = idxPos(p) + 1
ws2.Cells(startRow + idxPos(p) - 1, p) = ws1.Cells(i, 4).Value
Exit For
End If
Next p
End If
End If
Next i
outRow = startRow + maxZap
' 1. Строка с количеством
For p = 1 To 6
ws2.Cells(outRow, p) = "Кол-во: " & cntZap(p)
Next p
ws2.Range(ws2.Cells(outRow, 1), ws2.Cells(outRow, 6)).Font.Italic = True
ws2.Range(ws2.Cells(outRow, 1), ws2.Cells(outRow, 6)).Font.Color = RGB(0, 80, 160)
outRow = outRow + 1
' 2. Строка с ошибочными
For p = 1 To 6
ws2.Cells(outRow, p) = "Ошибочных: " & errZap(p)
Next p
ws2.Range(ws2.Cells(outRow, 1), ws2.Cells(outRow, 6)).Font.Italic = True
ws2.Range(ws2.Cells(outRow, 1), ws2.Cells(outRow, 6)).Font.Color = RGB(180, 0, 0)
outRow = outRow + 1
' 3. Строка с процентами
For p = 1 To 6
If cntZap(p) > 0 Then
pctOk = okZap(p) / cntZap(p) * 100
Else
pctOk = 0
End If
ws2.Cells(outRow, p) = "% правильных: " & Format(pctOk, "0.0") & "%"
Next p
ws2.Range(ws2.Cells(outRow, 1), ws2.Cells(outRow, 6)).Font.Italic = True
ws2.Range(ws2.Cells(outRow, 1), ws2.Cells(outRow, 6)).Font.Color = RGB(0, 120, 0)
outRow = outRow + 1
outRow = outRow + 2 ' отступ между блоками
Next fio
ws2.Columns("A:F").AutoFit
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.
ScreenUpdating = True
MsgBox "Готово! Обработано сотрудников: " & dict.Count
End Sub