跳转到内容

User:Hycheun3/沙盒

维基百科,自由的百科全书

Sub CreateResultSheetWithColorFormatting()

    Dim wsData As Worksheet, wsNameList As Worksheet, wsResult As Worksheet

    Dim lastRowData As Long, lastRowName As Long, i As Long, j As Long

    Dim resultRow As Long, currentRow As Long, lastRow As Long

    Dim nameToFind As String, startDate As Date, endDate As Date

    Dim dataDate As Date

    Dim currentColor As Long

    Dim seriesNumber As Long

    Dim hasMatch As Boolean

   

    ' Color constants

    Const COLOR1 As Long = &HC6EFCE   ' Light green

    Const COLOR2 As Long = &HFFFFFF   ' White

   

    ' Set worksheets

    Set wsData = ThisWorkbook.Sheets("Data")

    Set wsNameList = ThisWorkbook.Sheets("name list")

   

    ' Create result sheet

    Application.DisplayAlerts = False

    On Error Resume Next

    ThisWorkbook.Sheets("Result").Delete

    On Error GoTo 0

    Application.DisplayAlerts = True

   

    Set wsResult = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))

    wsResult.Name = "Result"

   

    ' Set headers with new Series Number column

    With wsResult

        .Range("A1:F1").Value = wsData.Range("A1:F1").Value

        .Range("G1").Value = "Start Date"

        .Range("H1").Value = "End Date"

        .Range("I1").Value = "Series Number"

        .Range("A1:I1").Interior.Color = RGB(200, 200, 200) ' Gray background

        .Range("A1:I1").Font.Bold = True

    End With

   

    ' Get last rows

    lastRowData = wsData.Cells(wsData.Rows.Count, "A").End(xlUp).Row

    lastRowName = wsNameList.Cells(wsNameList.Rows.Count, "A").End(xlUp).Row

   

    ' Initialize variables

    resultRow = 2

   

    ' Optimize performance

    Application.ScreenUpdating = False

    Application.Calculation = xlCalculationManual

   

    ' Process each name in name list

    For i = 2 To lastRowName

        nameToFind = Trim(wsNameList.Cells(i, 1).Value)

        startDate = wsNameList.Cells(i, 2).Value

        endDate = wsNameList.Cells(i, 3).Value

        seriesNumber = wsNameList.Cells(i, 4).Value ' Get series number (numerical)

       

        ' Determine color based on series number

        currentColor = IIf(seriesNumber Mod 2 = 1, COLOR1, COLOR2)

       

        hasMatch = False

       

        ' Search data sheet for matches

        For j = 2 To lastRowData

            If Trim(wsData.Cells(j, 2).Value) = nameToFind Then

                dataDate = wsData.Cells(j, 1).Value

               

                ' Check date range

                If (startDate = 0 Or dataDate >= startDate) And _

                   (endDate = 0 Or dataDate <= endDate) Then

                   

                    ' Copy matching row

                    wsData.Rows(j).Copy Destination:=wsResult.Rows(resultRow)

                   

                    ' Add date range, series number and formatting

                    With wsResult

                        .Cells(resultRow, 7).Value = startDate

                        .Cells(resultRow, 8).Value = endDate

                        .Cells(resultRow, 9).Value = seriesNumber

                        .Rows(resultRow).Interior.Color = currentColor

                    End With

                   

                    resultRow = resultRow + 1

                    hasMatch = True

                End If

            End If

        Next j

       

        ' Handle no-match case

        If Not hasMatch Then

            With wsResult

                .Cells(resultRow, 1).Value = nameToFind

                .Range(.Cells(resultRow, 2), .Cells(resultRow, 6)).Merge

                .Cells(resultRow, 2).Value = "no data found"

                .Cells(resultRow, 2).HorizontalAlignment = xlCenter

                .Cells(resultRow, 7).Value = startDate

                .Cells(resultRow, 8).Value = endDate

                .Cells(resultRow, 9).Value = seriesNumber

                .Rows(resultRow).Interior.Color = currentColor

            End With

            resultRow = resultRow + 1

        End If

    Next i

   

    ' Final formatting

    lastRow = wsResult.Cells(wsResult.Rows.Count, "A").End(xlUp).Row

   

    ' Set borders (extended to column I)

    With wsResult.Range("A1:I" & lastRow).Borders

        .LineStyle = xlContinuous

        .Color = RGB(100, 100, 100)

        .Weight = xlThin

    End With

   

    ' Format merged cells and dates

    For currentRow = 2 To lastRow

        If wsResult.Cells(currentRow, 2).Value = "no data found" Then

            wsResult.Range("B" & currentRow & ":F" & currentRow).Merge

            wsResult.Cells(currentRow, 2).HorizontalAlignment = xlCenter

        End If

    Next currentRow

   

    ' Auto-fit and format columns (include column I)

    With wsResult

        .Columns("A:I").AutoFit

        .Columns("A").NumberFormat = "dd-mm-yyyy"

        .Columns("G:H").NumberFormat = "dd-mm-yyyy"

        .Columns("I").NumberFormat = "0" ' Format series number as plain number

    End With

   

    ' Restore settings

    Application.ScreenUpdating = True

    Application.Calculation = xlCalculationAutomatic

   

    MsgBox "Processing complete. " & (resultRow - 2) & " rows processed.", vbInformation

End Sub


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Sub InsertCompensationWithTotalNegative()

    Dim ws As Worksheet

    Set ws = ThisWorkbook.Sheets("Sheet1") ' Change to your sheet name

   

    ' Find last row starting from row 3

    Dim lastRow As Long

    lastRow = ws.Cells(ws.Rows.Count, "C").End(xlUp).Row

    If lastRow < 3 Then Exit Sub ' No data

   

    ' Collection to store group information

    Dim groups As Collection

    Set groups = New Collection

   

    ' Identify consecutive name groups and calculate negative sums

    Dim groupStart As Long

    groupStart = 3 ' Data starts at row 3

    Dim currentName As String

    currentName = Trim(ws.Cells(3, "C").Value)

    Dim groupData As Object

   

    For i = 4 To lastRow + 1

        Dim nameVal As String

        If i <= lastRow Then nameVal = Trim(ws.Cells(i, "C").Value)

       

        ' Process group when name changes or at end of data

        If i > lastRow Or nameVal <> currentName Then

            Set groupData = CreateObject("Scripting.Dictionary")

            groupData.Add "startRow", groupStart

            groupData.Add "endRow", i - 1

            groupData.Add "name", currentName

           

            ' Calculate total negative for group

            Dim totalNegative As Double

            totalNegative = 0

            For j = groupStart To i - 1

                Dim colIVal As Variant

                colIVal = ws.Cells(j, "I").Value

                If IsNumeric(colIVal) And colIVal < 0 Then

                    totalNegative = totalNegative + colIVal

                End If

            Next j

            groupData.Add "totalNegative", totalNegative

           

            groups.Add groupData

           

            If i > lastRow Then Exit For

            groupStart = i

            currentName = nameVal

        End If

    Next i

   

    ' Insert compensation rows from last group to first

    Dim groupIdx As Long

    For groupIdx = groups.Count To 1 Step -1

        Set groupData = groups(groupIdx)

        totalNegative = groupData("totalNegative")

       

        If totalNegative < 0 Then

            Dim insertRow As Long

            insertRow = groupData("endRow") + 1

           

            ' Insert new row

            ws.Rows(insertRow).Insert Shift:=xlDown

           

            ' Copy ID, Name, Team, Rank from first group row

            ws.Range("B" & groupData("startRow") & ":E" & groupData("startRow")).Copy _

                Destination:=ws.Range("B" & insertRow)

           

            ' Set compensation values

            With ws.Rows(insertRow)

                .Cells(6).Value = "time earn compensate by time earn" ' Reason (F)

                .Cells(7).Value = Abs(totalNegative)                 ' Time earn (G)

                .Cells(8).Value = totalNegative                      ' DSOA (H)

                .Cells(9).ClearContents                              ' Clear minus DSOA (I)

                .Cells(1).ClearContents                              ' Clear SN (A)

            End With

        End If

    Next groupIdx

   

    MsgBox "Inserted " & groups.Count & " compensation rows."

End Sub