Here is a macro that will reorder the data you have into a more useable format as recommended by @ashleedawg. The macro makes use of two Classes to help with orgainizing, and the self-documenting feature will be useful for future modifications.
After you have reordered your data, you can then apply pivot tables to generate whatever type of report you wish. For the 4,83 multiplier, you can add a Calculated Field to the Pivot Table.
And, you can even record a macro to automate the generation of the Pivot Table, if you wish.
For information on Classes, take a look at Chip Pearson's Introduction to Classes
As noted in the comments in the various modules:
- Be sure to set a Reference to
Microsoft Scripting Runtime
- Be sure to rename the Class Modules
- Be sure your worksheets for the original and results data are named appropriately in the
reOrder
macro
Class Module
Option Explicit
'RENAME cShiftData
Private pCodigo As Long
Private pNom As String
Private pDt As Date
Private pDNI As String
Private pGP As Double
Private pGF As Double
Private pSD As cShiftData
Private pDts As Dictionary
Public Property Get Codigo() As Long
Codigo = pCodigo
End Property
Public Property Let Codigo(Value As Long)
pCodigo = Value
End Property
Public Property Get Nom() As String
Nom = pNom
End Property
Public Property Let Nom(Value As String)
pNom = Value
End Property
Public Property Get Dt() As Date
Dt = pDt
End Property
Public Property Let Dt(Value As Date)
pDt = Value
End Property
Public Property Get DNI() As String
DNI = pDNI
End Property
Public Property Let DNI(Value As String)
pDNI = Value
End Property
Public Property Get GP() As Double
GP = pGP
End Property
Public Property Let GP(Value As Double)
pGP = Value
End Property
Public Property Get GF() As Double
GF = pGF
End Property
Public Property Let GF(Value As Double)
pGF = Value
End Property
Public Property Get Dts() As Dictionary
Set Dts = pDts
End Property
Public Function addDtsItem(dat As Date)
If Dts.Exists(dat) Then
MsgBox "Duplicate key will not be added"
Else
Dim V
Set pSD = New cShiftData
With pSD
.GF = Me.GF
.GP = Me.GP
End With
Dts.Add dat, pSD
End If
End Function
Private Sub Class_Initialize()
Set pDts = New Dictionary
End Sub
Class Module
Option Explicit
'RENAME cDateData
Private pGP As Double
Private pGF As Double
Public Property Get GP() As Double
GP = pGP
End Property
Public Property Let GP(Value As Double)
pGP = Value
End Property
Public Property Get GF() As Double
GF = pGF
End Property
Public Property Let GF(Value As Double)
pGF = Value
End Property
Regular Module
Option Explicit
'SET REFERENCE TO: Microsoft Scripting Runtime
Sub reOrder()
Dim wsSrc As Worksheet, wsRes As Worksheet, rRes As Range
Dim vSrc As Variant, vRes As Variant
Dim cSD As cShiftData, dSD As Dictionary
Dim I As Long, J As Long
Dim V As Variant, W As Variant
'set source and results worksheets
'read data into array
Set wsRes = Worksheets("sheet2")
Set rRes = wsRes.Cells(1, 1)
Set wsSrc = Worksheets("Sheet1")
V = LastRowCol(wsSrc.Name)
With wsSrc
vSrc = .Range(.Cells(1, 1), .Cells(V(0), V(1)))
End With
'collect the data
Set dSD = New Dictionary
For I = 1 To UBound(vSrc, 1)
If Not vSrc(I, 1) Like "*CODIGO*" And _
Len(vSrc(I, 1)) > 0 Then 'start of a new codigo
Set cSD = New cShiftData
With cSD
.Codigo = vSrc(I, 1)
.Nom = vSrc(I, 2)
.DNI = vSrc(I, 3)
dSD.Add Key:=.Codigo, Item:=cSD
End With
ElseIf Len(vSrc(I, 1)) = 0 Then
With cSD
.Dt = vSrc(I, 2)
.GP = vSrc(I, 4)
.GF = vSrc(I, 5)
dSD(.Codigo).addDtsItem (.Dt)
End With
End If
Next I
'create results array
'one line for each date
I = 0
For Each V In dSD.Keys
I = I + dSD(V).Dts.Count
Next V
ReDim vRes(0 To I, 1 To 6)
'Header row
vRes(0, 1) = "CODIGO NOMINA"
vRes(0, 2) = "NOM"
vRes(0, 3) = "D.N.I."
vRes(0, 4) = "FECHA"
vRes(0, 5) = "GP"
vRes(0, 6) = "GF"
I = 0
For Each V In dSD.Keys
With dSD(V)
For Each W In .Dts
I = I + 1
vRes(I, 1) = .Codigo
vRes(I, 2) = .Nom
vRes(I, 3) = .DNI
vRes(I, 4) = W
vRes(I, 5) = .Dts(W).GP
vRes(I, 6) = .Dts(W).GF
Next W
End With
Next V
'write the results
Application.ScreenUpdating = False
Set rRes = rRes.Resize(rowsize:=UBound(vRes, 1) + 1, columnsize:=UBound(vRes, 2))
With rRes
.EntireColumn.Clear
.Value = vRes
With .Rows(1)
.Font.Bold = True
.HorizontalAlignment = xlCenter
End With
.Columns(4).NumberFormat = "dd/mm/yyyy"
.Columns(1).HorizontalAlignment = xlCenter
With .EntireColumn
.ColumnWidth = 255
.AutoFit
End With
End With
myPivot wsRes
Application.ScreenUpdating = True
End Sub
Function LastRowCol(Worksht As String) As Long()
Application.Volatile
Dim WS As Worksheet, R As Range
Dim LastRow As Long, LastCol As Long
Dim L(1) As Long
Set WS = Worksheets(Worksht)
With WS
Set R = .Cells.Find(what:="*", after:=.Cells(1, 1), _
LookIn:=xlValues, searchorder:=xlByRows, _
searchdirection:=xlPrevious)
If Not R Is Nothing Then
LastRow = R.Row
LastCol = .Cells.Find(what:="*", after:=.Cells(1, 1), _
LookIn:=xlValues, searchorder:=xlByColumns, _
searchdirection:=xlPrevious).Column
Else
LastRow = 1
LastCol = 1
End If
End With
L(0) = LastRow
L(1) = LastCol
LastRowCol = L
End Function
Original Data

reOrdered Data (after running macro)

Example Pivot Table
