Выбрать дату в календареВыбрать дату в календаре

Страницы: 1
[ Закрыто] Проверить макрос, исправит расчеты
 
Это главная часть которую я сделал. там много других расчетов. я в этой неуверен насчет расчетов  
[ Закрыто] Проверить макрос, исправит расчеты
 
проверить и исправит расчеты не нарушая саму архитектуру. Окраску ячеек границы таблицы.  Private Sub ToggleButton13_Click()

   If Me.ToggleButton13.Value = False Then Exit Sub
   Me.ToggleButton13.Value = False

   Dim wsBase As Worksheet, wsInput As Worksheet, wsSal As Worksheet
   Dim lastRow As Long, targetRow As Long, i As Long, c As Long, d As Long, s As Integer
   Dim managerName As String, accountantName As String, startDate As Date, endDate As Date
   Dim groupName As String, vCol As Variant, cols As Variant
   Dim currentDate As Date, isHoliday As Boolean, dailyHours As Double
   Dim sickDays As Long, vacDays As Long, sickPay As Double, vacPay As Double
   Dim empExperience As Variant, kExperience As Double, cellVal As String
   Dim rate As Double, planHours As Double, salarySum As Double
   
   Dim rowHolidayHours As Double, rowWeekdayOvertime As Double
   Dim daysDetail As String, dayAbbr As String

   ' --- БЛОК НАСТРОЕК ---
   Dim nonWorkCodes As String, deductCodes As String
   nonWorkCodes = "обс,пг,ог,до,у,к"
   deductCodes = "обс,пг"

   On Error Resume Next
   Set wsBase = ThisWorkbook.Sheets("База")
   Set wsInput = ThisWorkbook.Sheets("форма_ввода")
   On Error GoTo 0
   
   If wsBase Is Nothing Or wsInput Is Nothing Then
       MsgBox "Ошибка: Листы 'База' или 'форма_ввода' не найдены!": Exit Sub
   End If
   
   managerName = InputBox("Введите ФИО ответственного:", "Подпись", "Иванова Н.В.")
   accountantName = InputBox("Введите ФИО бухгалтера:", "Подпись", "Петрова А.С.")
   
   On Error Resume Next
   startDate = CDate(InputBox("Начальная дата (ДД.ММ.ГГГГ):", "Период", "01.02.2026"))
   endDate = CDate(InputBox("Конечная дата (ДД.ММ.ГГГГ):", "Период", "28.02.2026"))
   On Error GoTo 0
   If startDate = 0 Then Exit Sub

   Set wsSal = ThisWorkbook.Sheets("Начисления")
   If wsSal Is Nothing Then
       Set wsSal = ThisWorkbook.Sheets.Add(After:=wsBase): wsSal.Name = "Начисления"
   End If
   
   Application.ScreenUpdating = False

   With wsSal
       ' Сохранение коэффициентов
       Dim vNDFL As Double, vP15 As Double, vP20 As Double, vVP20 As Double, vNight As Double
       vP15 = .Range("Q5").Value: vP20 = .Range("R5").Value: vVP20 = .Range("S5").Value
       vNight = .Range("T5").Value: vNDFL = .Range("U5").Value

       Application.DisplayAlerts = False
       .Cells.UnMerge: .Rows("6:" & .Rows.Count).Clear
       Application.DisplayAlerts = True

       ' Шапка (теперь до AG - 33 столбца)
       .Range("A1:AG1").Merge: .Range("A1").Value = "ТЕСТОВАЯ КОМПАНИЯ": .Range("A1").Font.Bold = True: .Range("A1").HorizontalAlignment = xlCenter
       .Range("A2:AG2").Merge: .Range("A2").Value = "Начисление зарплаты за период с " & Format(startDate, "dd.mm.yyyy") & " по " & Format(endDate, "dd.mm.yyyy")
       .Range("A2").Font.Color = vbRed: .Range("A2").HorizontalAlignment = xlCenter: .Range("A2").Font.Bold = True
       
       With .Range("P4:P5"): .Merge: .Value = "Коэф=>": .Font.Bold = True: .HorizontalAlignment = xlRight: End With
       .Range("Q4:U4").Value = Array("перераб 1.5", "перераб 2.0", "вых/празд 2.0", "Над. Ночь", "НДФЛ")
       .Range("Q5").Value = IIf(vP15 <= 0, 1.5, vP15): .Range("R5").Value = IIf(vP20 <= 0, 2#, vP20)
       .Range("S5").Value = IIf(vVP20 <= 0, 2#, vVP20): .Range("T5").Value = IIf(vNight <= 0, 40, vNight): .Range("U5").Value = IIf(vNDFL <= 0, 0.13, vNDFL)
       .Range("P4:U5").Borders.LineStyle = xlContinuous: .Range("P4:U5").Borders.Weight = xlMedium

       ' Цветные блоки (Добавлен AG в последний блок)
       Dim rngs, clrs, idx As Integer
       rngs = Array("K6:L7", "M6:N7", "O6:S7", "T6:W7", "X6:AA7", "AB6:AE7", "AF6:AG7")
       clrs = Array(RGB(221, 235, 247), RGB(221, 235, 247), RGB(226, 239, 218), RGB(255, 242, 204), RGB(228, 242, 213), RGB(242, 220, 219), RGB(255, 255, 153))
       For idx = 0 To UBound(rngs)
           With .Range(rngs(idx))
               .Merge: .Interior.Color = clrs(idx): .Font.Bold = True: .HorizontalAlignment = xlCenter: .VerticalAlignment = xlCenter: .Borders.LineStyle = xlContinuous: .Borders.Weight = xlMedium
           End With
       Next idx
       
       .Range("K6").Value = "По графику": .Range("M6").Value = "Переработка": .Range("O6").Value = "Учет переработок"
       .Range("T6").Value = "Расчет зар. платы": .Range("X6").Value = "Начисления": .Range("AB6").Value = "Удержания": .Range("AF6").Value = "Выплаты"

       ' Подписи колонок 1-10
       Dim h1: h1 = Array("Н/П", "Таб. №", "Сотрудник (Ф.И.О)", "должность", "оплата", "сумма (руб)", "норм.дн/ч", "план.дн", "час/мес", "Время работы")
       For c = 1 To 10
           With .Range(.Cells(6, c), .Cells(8, c))
               .Merge: .Value = h1(c - 1): .Interior.Color = RGB(255, 255, 204): .Font.Bold = True: .Borders.LineStyle = xlContinuous: .Borders.Weight = xlMedium: .HorizontalAlignment = xlCenter: .VerticalAlignment = xlCenter: .WrapText = True
           End With
       Next c

       ' Подписи колонок 11-33 (Добавлен AG - надбавка 2)
       Dim hSub: hSub = Array("час(отр)", "дн(отр)", "часов", "дней", "баланс", "Какие дни", "1.5 (1-е 2ч)", "2.0 (след)", "вых./пр.", "З/П", "перераб", "больнич", "отпуск", "премия", "надбавка", "прочие", "НДФЛ", "штраф", "исп.лист", "удерж", "аванс", "К ВЫПЛАТЕ", "надбавка 2")
       For idx = 0 To UBound(hSub)
           With .Cells(8, idx + 11)
               .Value = hSub(idx): .Borders.LineStyle = xlContinuous: .Borders.Weight = xlThin: .HorizontalAlignment = xlCenter: .VerticalAlignment = xlCenter: .Font.Size = 8: .Font.Bold = True
           End With
       Next idx
   End With

   ' --- ЦИКЛ ---
   lastRow = wsBase.Cells(wsBase.Rows.Count, 3).End(xlUp).Row
   targetRow = 9
   ' Список колонок для объединения (Добавлен 33)
   cols = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33)

   For i = 7 To lastRow
       If wsBase.Cells(i, 1).Interior.Color = RGB(217, 217, 217) Then
           groupName = IIf(wsBase.Cells(i, 1).Value <> "", wsBase.Cells(i, 1).Value, wsBase.Cells(i, 3).Value)
           With wsSal.Range("A" & targetRow & ":AG" & targetRow)
               .Merge: .Value = groupName: .Font.Bold = True: .Interior.Color = RGB(217, 217, 217): .HorizontalAlignment = xlCenter: .Borders.LineStyle = xlContinuous: .Borders.Weight = xlMedium
           End With
           targetRow = targetRow + 1
           
       ElseIf wsBase.Cells(i, 10).Value = "День" Then
           planHours = val(wsBase.Cells(i, 9).Value): salarySum = val(wsBase.Cells(i, 6).Value)
           rate = IIf(planHours > 0, salarySum / planHours, 0)
           
           ' Вычеты за прогулы
           Dim missingDays As Long: missingDays = 0
           For d = 11 To 41
               cellVal = LCase(Trim(CStr(wsBase.Cells(i, d).Value)))
               If InStr(deductCodes, cellVal) > 0 And cellVal <> "" Then missingDays = missingDays + 1
           Next d
           
           Dim planDaysNorm As Double: planDaysNorm = IIf(planHours > 0, planHours / 8, 1)
           Dim actualSalary As Double: actualSalary = salarySum - ((salarySum / planDaysNorm) * missingDays)

           ' Больничные и отпуска
           sickDays = 0: vacDays = 0
           For s = 0 To 2
               For d = 11 To 41
                   cellVal = LCase(Trim(CStr(wsBase.Cells(i + s, d).Value)))
                   If cellVal = "б" Then sickDays = sickDays + 1
                   If cellVal = "от" Then vacDays = vacDays + 1
               Next d
           Next s
           
           If sickDays > 0 Then
               empExperience = InputBox("Введите стаж сотрудника " & wsBase.Cells(i, 3).Value & ":", "Больничный", 8)
               kExperience = IIf(val(empExperience) >= 8, 1, IIf(val(empExperience) >= 5, 0.8, 0.6))
               sickPay = Round((salarySum / 30) * kExperience * sickDays, 2)
           Else: sickPay = 0: End If
           vacPay = Round((salarySum / 29.3) * vacDays, 2)

           wsSal.Range("A" & targetRow & ":H" & targetRow).Value = wsBase.Range("A" & i & ":H" & i).Value
           wsSal.Range("K" & targetRow & ":L" & targetRow).Value = wsBase.Range("AP" & i & ":AQ" & i).Value
           wsSal.Cells(targetRow, 10).Resize(3, 1).Value = Application.Transpose(Array("День", "Вечер", "Ночь"))

           ' Переработки по сменам
           For s = 0 To 2
               rowHolidayHours = 0: rowWeekdayOvertime = 0: daysDetail = ""
               For d = 11 To 41
                   currentDate = DateSerial(Year(startDate), Month(startDate), d - 10)
                   If currentDate >= startDate And currentDate <= endDate Then
                       cellVal = LCase(Trim(CStr(wsBase.Cells(i + s, d).Value)))
                       isHoliday = (Weekday(currentDate, vbMonday) > 5) Or Not IsError(Application.Match(CLng(currentDate), wsInput.Range("AS7:AS47"), 0)) Or (cellVal = "пр")
                       dayAbbr = Choose(Weekday(currentDate, vbMonday), "Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс")
                       
                       If IsNumeric(cellVal) And cellVal <> "" Then
                           dailyHours = CDbl(cellVal)
                           If isHoliday Then
                               rowHolidayHours = rowHolidayHours + dailyHours
                               daysDetail = daysDetail & "(" & Format(currentDate, "dd") & "," & dayAbbr & "," & dailyHours & ") "
                           Else
                               Dim ovt As Double: ovt = IIf(s = 0, IIf(dailyHours > 8, dailyHours - 8, 0), dailyHours)
                               rowWeekdayOvertime = rowWeekdayOvertime + ovt
                               If ovt > 0 Then daysDetail = daysDetail & "(" & Format(currentDate, "dd") & "," & dayAbbr & "," & ovt & ") "
                           End If
                       ElseIf InStr(nonWorkCodes, cellVal) > 0 And cellVal <> "" Then
                           daysDetail = daysDetail & "(" & Format(currentDate, "dd") & "," & dayAbbr & "," & UCase(cellVal) & ") "
                       End If
                   End If
               Next d
               
               Dim curR As Long: curR = targetRow + s
               wsSal.Cells(curR, 13).Value = rowWeekdayOvertime + rowHolidayHours
               wsSal.Cells(curR, 14).Value = (rowWeekdayOvertime + rowHolidayHours) / 8
               wsSal.Cells(curR, 15).Value = rowWeekdayOvertime + rowHolidayHours
               wsSal.Cells(curR, 16).Value = Trim(daysDetail)
               wsSal.Cells(curR, 17).Value = Round(IIf(rowWeekdayOvertime > 2, 2, rowWeekdayOvertime) * rate * wsSal.Range("Q5").Value, 2)
               wsSal.Cells(curR, 18).Value = Round(IIf(rowWeekdayOvertime > 2, rowWeekdayOvertime - 2, 0) * rate * wsSal.Range("R5").Value, 2)
               wsSal.Cells(curR, 19).Value = Round(rowHolidayHours * rate * wsSal.Range("S5").Value, 2)
           Next s

           ' Итоговые суммы
           Dim r As Long: r = targetRow
           wsSal.Cells(r, 9).Value = planHours
           wsSal.Cells(r, 20).Value = Round(actualSalary, 2)
           wsSal.Cells(r, 22).Value = sickPay
           wsSal.Cells(r, 23).Value = vacPay
           wsSal.Cells(r, 21).FormulaR1C1 = "=SUM(R[0]C[-4]:R[2]C[-2])"
           
           Dim tSum As Double: tSum = val(wsSal.Cells(r, 20).Value) + val(wsSal.Cells(r, 21).Value) + val(wsSal.Cells(r, 22).Value) + val(wsSal.Cells(r, 23).Value)
           wsSal.Cells(r, 27).Value = Round(tSum * wsSal.Range("U5").Value, 0)
           wsSal.Cells(r, 32).FormulaR1C1 = "=SUM(RC20:RC26, RC33) - SUM(RC27:RC30) - RC31" ' Теперь включает RC33 (AG)

           ' Оформление
           Application.DisplayAlerts = False
           For Each vCol In cols
               With wsSal.Range(wsSal.Cells(r, CInt(vCol)), wsSal.Cells(r + 2, CInt(vCol)))
                   .Merge: .VerticalAlignment = xlCenter: .HorizontalAlignment = xlCenter: .Borders.LineStyle = xlContinuous: .Borders.Weight = xlThin
               End With
           Next vCol
           wsSal.Range("A" & r & ":AG" & r + 2).BorderAround Weight:=xlMedium
           Application.DisplayAlerts = True
           
           targetRow = targetRow + 3
       End If
   Next i

   ' Подвал
   With wsSal
       .Cells(targetRow, 31).Value = "ИТОГО:": .Cells(targetRow, 31).Font.Bold = True
       .Cells(targetRow, 32).Formula = "=SUM(AF9:AF" & targetRow - 1 & ")"
       With .Range(.Cells(targetRow, 31), .Cells(targetRow, 32))
           .Borders.LineStyle = xlContinuous: .Borders.Weight = xlMedium: .Interior.Color = RGB(255, 255, 153)
       End With
       
       .Cells(targetRow + 2, 2).Value = "Ответственный: ________________ /" & managerName & "/"
       .Cells(targetRow + 4, 2).Value = "Бухгалтер: ________________ /" & accountantName & "/"
       .Range(.Cells(targetRow + 2, 2), .Cells(targetRow + 4, 2)).Font.Bold = True
       
       .Columns("AF:AG").NumberFormat = "#,##0"
       .Range("Q9:AE" & targetRow).NumberFormat = "#,##0.00"
       .Columns("C").ColumnWidth = 28
   End With

   wsSal.Activate: Application.ScreenUpdating = True
   MsgBox "Расчет завершен! Столбец AG добавлен.", vbInformation
End Sub
Изменено: alex_tixi - 18.02.2026 13:08:20
откорректировать макрос, непечатается шапка на листе результат только данные
 
в шапу не попадает первая строка поиска ели нашел 2 попадает одна
откорректировать макрос, непечатается шапка на листе результат только данные
 
непечатается шапка на листе результат только данные выбираются нужно подкорректировать макрос
найти ошибку в макросе, невиыбирает данные на листе база по выбранным критериям
 
критери  поиска меняются  
найти ошибку в макросе, невиыбирает данные на листе база по выбранным критериям
 
не выбирает данные с листа база. Критерии поиска задаются на листе поиск  
Страницы: 1
Наверх