Страницы: 1
RSS
Перенос данных с отчета посещения в зарплатный табель с привязкой к дате и фамилии
 
Добрый день. Необходимо осуществить перенос данных (приход\уход) с Отчет2.xls в месячный отчет отработанных часов Учет рабочего времени.xlsm с привязкой к ФИО и дате. С похожим отчетом для Отчет1.xls мне помог товарищ МатросНаЗебре. Пытался приспособить написанный им макрос к данному отчету, но из-за формата даты "Дата" данный макрос не хочет работать да и адресацию я написал коряво (с кодом не дружу совершенно).
Собственно сам макрос для аналогичного переноса Отчет1.xls:
Код
Option Explicit
 
Const SKUD_XLSX = "Отчет1.xls"
Const TABL_XLSX = "Учет рабочего времени.xlsm"
 
Sub ИзОтчетаВТабель()
    Dim wbS As Workbook
    Dim wbT As Workbook
    On Error Resume Next
    Set wbS = Workbooks("Отчет1.xls")
    Set wbT = Workbooks("Учет рабочего времени.xlsm")
    On Error GoTo 0
    If wbS Is Nothing Then
        MsgBox "Не найден файл " & SKUD_XLSX, vbInformation
    Else
        If wbT Is Nothing Then
            MsgBox "Не найден файл " & TABL_XLSX, vbInformation
        Else
            Dim arrSkud As Variant
            arrSkud = GetArrSkud(wbS.Sheets(1))
             
            Dim dicY As Object
            Dim dicX As Object
            GetDic wbT.Sheets(1), dicY, dicX
             
            PrintResult wbT.Sheets(1), wbS.Sheets(1), arrSkud, dicY, dicX
        End If
    End If
End Sub
 
Sub PrintResult(sh As Worksheet, shSKUD As Worksheet, arrSkud As Variant, dicY As Object, dicX As Object)
    Dim Application_Calculation As Long
    Application_Calculation = Application.Calculation
    Application.Calculation = xlCalculationManual
    Application.EnableEvents = False
    With sh
        Dim rep As Variant
        ReDim rep(1 To UBound(arrSkud, 1), 1 To 1)
         
        Dim i As Byte
        Dim x As Integer
        Dim y As Long
        Dim ySkud As Long
        For ySkud = 1 To UBound(arrSkud, 1)
            If arrSkud(ySkud, 1) <> "" Then
                rep(ySkud, 1) = "-"
                If dicY.Exists(arrSkud(ySkud, 1)) Then
                    If dicX.Exists(arrSkud(ySkud, 2)) Then
                        rep(ySkud, 1) = "+"
                        y = dicY.Item(arrSkud(ySkud, 1))
                        x = dicX.Item(arrSkud(ySkud, 2))
                        For i = 0 To 1
                            If arrSkud(ySkud, 5 + i) <> "" Then
                                .Cells(y, x + i).Value = arrSkud(ySkud, 5 + i)
                            End If
                        Next
                    End If
                End If
            End If
        Next
    End With
     
    shSKUD.Cells(1, 15).Resize(UBound(rep, 1), UBound(rep, 2)) = rep
    Application.EnableEvents = True
    Application.Calculation = Application_Calculation
End Sub
 
Function GetArrSkud(sh As Worksheet)
    With sh
        Dim arr As Variant
        Dim y As Long
        y = .Cells(.Rows.Count, 3).End(xlUp).Row
        GetArrSkud = .Range(.Cells(1, 3), .Cells(.Cells(.Rows.Count, 3).End(xlUp).Row, 8))
    End With
End Function
 
Sub GetDic(sh As Worksheet, dicY As Object, dicX As Object)
    With sh
        Dim arr As Variant
        Dim y As Long
         
        y = .Cells(.Rows.Count, 2).End(xlUp).Row
        arr = .Range(.Cells(1, 2), .Cells(y, 2 - (y = 1)))
        Set dicY = CreateObject("Scripting.Dictionary")
        For y = 1 To UBound(arr, 1)
            Select Case arr(y, 1)
            Case "", "ФИО"
            Case Else
                dicY.Item(arr(y, 1)) = y
            End Select
        Next
         
        y = .Cells(2, .Columns.Count).End(xlToLeft).Column
        arr = .Range(.Cells(2, 1), .Cells(2 - (y = 1), y))
        Set dicX = CreateObject("Scripting.Dictionary")
        For y = 1 To UBound(arr, 2)
            Select Case arr(1, y)
            Case "", "№ п/п", "ФИО", "Отдел"
            Case Else
                dicX.Item(CStr(arr(1, y))) = y
            End Select
        Next
    End With
End Sub
 
Код
Option Explicit
 
Const SKUD_XLS1 = "Отчет1.xls"
Const SKUD_XLS2 = "Отчет2.xls"
Const TABL_XLSX = "Учет рабочего времени.xls"
 
Sub ИзОтчетаВТабель()
    Dim wbS As Workbook
    Dim wb2 As Workbook
    Dim wbT As Workbook
    On Error Resume Next
    Set wbS = Workbooks(SKUD_XLS1)
    Set wb2 = Workbooks(SKUD_XLS2)
    Set wbT = Workbooks("Учет рабочего времени.xls")
    On Error GoTo 0
    If wbS Is Nothing And wb2 Is Nothing Then
        MsgBox "Не найдены файлы " & vbCrLf & SKUD_XLS1 & vbCrLf & SKUD_XLS2, vbInformation
    Else
        If wbT Is Nothing Then
            MsgBox "Не найден файл " & TABL_XLSX, vbInformation
        Else
            
            Dim dicY As Object
            Dim dicX As Object
            GetDic wbT.Sheets(1), dicY, dicX
            
            Dim arrSkud As Variant
            If Not wbS Is Nothing Then
                arrSkud = GetArrSkud1(wbS.Sheets(1))
                PrintResult wbT.Sheets(1), wbS.Sheets(1), arrSkud, dicY, dicX
            End If
            If Not wb2 Is Nothing Then
                arrSkud = GetArrSkud2(wb2.Sheets(1))
                PrintResult wbT.Sheets(1), wb2.Sheets(1), arrSkud, dicY, dicX
            End If
        End If
    End If
End Sub
 
Sub PrintResult(sh As Worksheet, shSKUD As Worksheet, arrSkud As Variant, dicY As Object, dicX As Object)
    Dim Application_Calculation As Long
    Application_Calculation = Application.Calculation
    Application.Calculation = xlCalculationManual
    Application.EnableEvents = False
    With sh
        Dim rep As Variant
        ReDim rep(1 To UBound(arrSkud, 1), 1 To 1)
         
        Dim i As Byte
        Dim x As Integer
        Dim y As Long
        Dim ySkud As Long
        For ySkud = 1 To UBound(arrSkud, 1)
            If arrSkud(ySkud, 1) <> "" Then
                rep(ySkud, 1) = "-"
                If dicY.Exists(arrSkud(ySkud, 1)) Then
                    If dicX.Exists(CStr(arrSkud(ySkud, 2))) Then
                        rep(ySkud, 1) = "+"
                        y = dicY.Item(arrSkud(ySkud, 1))
                        x = dicX.Item(CStr(arrSkud(ySkud, 2)))
                        For i = 0 To 1
                            If arrSkud(ySkud, 3 + i) <> "" Then
                                .Cells(y, x + i).Value = arrSkud(ySkud, 3 + i)
                            End If
                        Next
                    End If
                End If
            End If
        Next
    End With
     
    shSKUD.Cells(1, 15).Resize(UBound(rep, 1), UBound(rep, 2)) = rep
    Application.EnableEvents = True
    Application.Calculation = Application_Calculation
End Sub
 
Function GetArrSkud1(sh As Worksheet) As Variant
    Dim arr As Variant
    Dim brr As Variant
    Dim y As Long
    
    With sh
        y = .Cells(.Rows.Count, 3).End(xlUp).Row
        arr = .Range(.Cells(1, 3), .Cells(.Cells(.Rows.Count, 3).End(xlUp).Row, 8))
    End With
    ReDim brr(1 To UBound(arr, 1), 1 To 4)
    For y = 1 To UBound(arr, 1)
        brr(y, 1) = arr(y, 1)
        brr(y, 2) = arr(y, 2)
        brr(y, 3) = arr(y, 5)
        brr(y, 4) = arr(y, 6)
    Next
    GetArrSkud1 = brr
End Function
 
Function GetArrSkud2(sh As Worksheet) As Variant
    Dim arr As Variant
    Dim brr As Variant
    Dim y As Long
    
    With sh
        y = .Cells(.Rows.Count, 1).End(xlUp).Row
        arr = .Range(.Cells(1, 1), .Cells(.Cells(.Rows.Count, 3).End(xlUp).Row, 7))
    End With
    ReDim brr(1 To UBound(arr, 1), 1 To 4)
    For y = 1 To UBound(arr, 1)
        brr(y, 1) = arr(y, 2)
        brr(y, 2) = arr(y, 1)
        brr(y, 3) = arr(y, 5)
        brr(y, 4) = arr(y, 7)
    Next
    GetArrSkud2 = brr
End Function

Sub GetDic(sh As Worksheet, dicY As Object, dicX As Object)
    With sh
        Dim arr As Variant
        Dim y As Long
         
        y = .Cells(.Rows.Count, 2).End(xlUp).Row
        arr = .Range(.Cells(1, 2), .Cells(y, 2 - (y = 1)))
        Set dicY = CreateObject("Scripting.Dictionary")
        For y = 1 To UBound(arr, 1)
            Select Case arr(y, 1)
            Case "", "ФИО"
            Case Else
                dicY.Item(arr(y, 1)) = y
            End Select
        Next
         
        y = .Cells(2, .Columns.Count).End(xlToLeft).Column
        arr = .Range(.Cells(2, 1), .Cells(2 - (y = 1), y))
        Set dicX = CreateObject("Scripting.Dictionary")
        For y = 1 To UBound(arr, 2)
            Select Case arr(1, y)
            Case "", "№ п/п", "ФИО", "Отдел"
            Case Else
                dicX.Item(CStr(arr(1, y))) = y
            End Select
        Next
    End With
End Sub
 
МатросНаЗебре, Огромное спасибо. Все работает замечательно.
Страницы: 1
Наверх