Загрузка данных


Sub CalculateAndSortStudents()
    Dim ws As Worksheet
    Dim wsRank As Worksheet
    Dim lastRow As Long
    Dim lastCol As Long
    Dim c As Long, r As Long
    Dim plusCount As Long, minusCount As Long
    Dim studentName As String
    
    ' Сбор данных для рейтинга
    Dim students() As String
    Dim scoresPlus() As Long
    Dim scoresMinus() As Long
    Dim studentCount As Long
    
    Set ws = ActiveSheet
    
    ' 1. Определяем границы таблицы
    ' Имена детей в строке 2, даты в столбце A (строка 1 — заголовки)
    lastCol = ws.Cells(2, ws.Columns.Count).End(xlToLeft).Column
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    
    If lastCol < 2 Or lastRow < 3 Then
        MsgBox "Таблица пуста или неверно заполнена!", vbExclamation, "Ошибка"
        Exit Sub
    End If
    
    studentCount = lastCol - 1
    ReDim students(1 To studentCount)
    ReDim scoresPlus(1 To studentCount)
    ReDim scoresMinus(1 To studentCount)
    
    ' 2. Считаем плюсы и минусы для каждого ребенка
    For c = 2 To lastCol
        studentName = ws.Cells(2, c).Value ' Имя ребенка во 2-й строке
        students(c - 1) = studentName
        
        plusCount = 0
        minusCount = 0
        
        ' Идем по строкам с датами (с 3-й строки до последней даты)
        For r = 3 To lastRow
            If ws.Cells(r, c).Value = "+" Then
                plusCount = plusCount + 1
            ElseIf ws.Cells(r, c).Value = "-" Then
                minusCount = minusCount + 1
            End If
        Next r
        
        scoresPlus(c - 1) = plusCount
        scoresMinus(c - 1) = minusCount
        
        ' Записываем итоги на следующей строке после дат
        ws.Cells(lastRow + 1, c).Value = plusCount & " (+)"
        ws.Cells(lastRow + 2, c).Value = minusCount & " (-)"
    Next c
    
    ' Подписи для итогов в столбце A
    ws.Cells(lastRow + 1, 1).Value = "Всего плюсов"
    ws.Cells(lastRow + 2, 1).Value = "Всего минусов"
    
    ' 3. Сортировка учеников (метод пузырька) для рейтинга
    Dim i As Long, j As Long
    Dim tempName As String, tempPlus As Long, tempMinus As Long
    
    For i = 1 To studentCount - 1
        For j = i + 1 To studentCount
            ' Критерий: больше плюсов. Если плюсов поровну — меньше минусов.
            If (scoresPlus(i) < scoresPlus(j)) Or _
               (scoresPlus(i) = scoresPlus(j) And scoresMinus(i) > scoresMinus(j)) Then
                
                ' Меняем местами имена
                tempName = students(i)
                students(i) = students(j)
                students(j) = tempName
                
                ' Меняем местами плюсы
                tempPlus = scoresPlus(i)
                scoresPlus(i) = scoresPlus(j)
                scoresPlus(j) = tempPlus
                
                ' Меняем местами минусы
                tempMinus = scoresMinus(i)
                scoresMinus(i) = scoresMinus(j)
                scoresMinus(j) = tempMinus
            End If
        Next j
    Next i
    
    ' 4. Вывод рейтинга на отдельный лист
    On Error Resume Next
    Set wsRank = Sheets("Рейтинг класса")
    On Error GoTo 0
    
    If wsRank Is Nothing Then
        Set wsRank = Sheets.Add(After:=Sheets(Sheets.Count))
        wsRank.Name = "Рейтинг класса"
    Else
        wsRank.Cells.Clear
    End If
    
    ' Заголовки на листе рейтинга
    wsRank.Cells(1, 1).Value = "Место"
    wsRank.Cells(1, 2).Value = "Имя ученика"
    wsRank.Cells(1, 3).Value = "Плюсы"
    wsRank.Cells(1, 4).Value = "Минусы"
    
    ' Заполняем таблицу лидерами
    For i = 1 To studentCount
        wsRank.Cells(i + 1, 1).Value = i
        wsRank.Cells(i + 1, 2).Value = students(i)
        wsRank.Cells(i + 1, 3).Value = scoresPlus(i)
        wsRank.Cells(i + 1, 4).Value = scoresMinus(i)
    Next i
    
    wsRank.Columns("A:D").AutoFit
    ws.Activate
    
    MsgBox "Подсчет завершен! Создан лист 'Рейтинг класса'.", vbInformation, "Успех"
End Sub