在多个工作表中抓取每个组的第一个和最后一个匹配项

问题描述 投票:0回答:1

问题描述

我有几个工作表显示每组(轨道)的开放和关闭值。所有行都带有日期。我想遍历所有工作表并获取列Open的最旧值和列Close的最新值。伪代码:

  1. 第一个工作表的每组最新和最新值

按工作表,获取Open的最旧值和每组关闭的最新值

  1. 转到下一个工作表并比较值

接下来,转到下一个工作表,并将最旧值和新值与先前捕获的值进行比较。如果当前工作表中的日期较旧,则每组使用当前工作表中的相应值覆盖最旧的值。如果当前工作表中的日期更新,则使用相应的值覆盖最近的值。

  1. 重复步骤2,直到我们遍历所有工作表。

我已经能够捕获每个工作表中最旧和最新的值。但是,我无法弄清楚如何遍历所有工作表并在所有工作表中获取每组最旧和最新的值。

我是Excel VBA的入门者,并希望按照我当前的代码坚持使用简单的循环。我想“按原样”遍历工作表,这意味着在运行任何代码之前没有重命名并且没有合并到一个工作表中(总共可能有超过一百万行)。

获取每个工作表的值的当前代码:

Sub top_one()

Dim WS As Worksheet
Dim group_start As Double
Dim track As String
Dim start_date, end_date As Long
Dim opening, closing As Double

For Each WS In ThisWorkbook.Worksheets
    If WS.Name <> "1" And WS.Name <> "Expected" Then
    WS.Select
    With WS
        LastRow = Cells(.Rows.Count, "A").End(xlUp).Row
        For i = 2 To LastRow
            group_start = 2
            If .Cells(i + 1, "A").Value <> .Cells(i, "A").Value Then
                group_start = i - group_counter
                track = .Cells(i, "A")
                start_date = .Cells(group_start, "B")
                opening = .Cells(group_start, "C")
                end_date = .Cells(i, "B")
                closing = .Cells(i, "D")
                'lastRowTotal = Sheets("1").Cells(.Rows.Count, "P").End(xlUp).Row
                Sheets("1").Cells(j + 2, "A") = .Cells(i, "A") 'trck
                'If opening_date < Sheets("1").Cells(j + 2, "B") Then
                    Sheets("1").Cells(j + 2, "B") = opening_date
                'Else
                'End If
                Sheets("1").Cells(j + 2, "B") = .Cells(group_start, "B") 'start date
                Sheets("1").Cells(j + 2, "C") = .Cells(i, "B") 'end date
                Sheets("1").Cells(j + 2, "D") = .Cells(group_start, "C") 'opening
                Sheets("1").Cells(j + 2, "E") = .Cells(i, "D") 'closing
                j = j + 1
                group_counter = 0
            Else
                group_counter = group_counter + 1
            End If
        Next
        j = 0
    End With
    End If
Next WS
End Sub

Screendumps

工作表数据

工作表名为2018

Track   Date        Open    Close
A       20180101    1       5
A       20180102    4       8
A       20180103    4       5
B       20180104    12      1
B       20180105    2       4
C       20180106    5       2
C       20180107    2       5
E       20180108    8       9

工作表称为

Track   Date        Open    Close
A       20170101    5       6
A       20170102    6       6
B       20170103    2       1
B       20170104    1       2
C       20170105    5       9
C       20170106    9       7
D       20170107    5       5
D       20170108    5       8
D       20170109    7       2

工作表名为145jki

Track   Date        Open    Close
A       20160101    8       5
A       20160102    4       5
B       20160103    11      5
B       20160104    8       9
C       20160105    10      3
C       20160106    5       7

预期结果

Track   Start date  End date    First Open  Last Close
A       20160101    20180103            8           5
B       20160103    20180105            11          4
C       20160105    20180107            10          5
D       20170107    20170109            5           2
E       20180108    20180108            8           9
excel-vba vba excel
1个回答
1
投票

试试这个代码

Sub Grab_First_Last_Occurence_Per_Group_Across_Worksheets()
Dim ws          As Worksheet
Dim a()         As Variant
Dim temp        As Variant
Dim prev        As Variant
Dim f           As Boolean
Dim i           As Long
Dim p           As Long

Application.ScreenUpdating = False
    For Each ws In ThisWorkbook.Worksheets
        With ws
            If .Name <> "1" And .Name <> "Expected" Then
                temp = ws.Range("A2:D" & ws.Cells(Rows.Count, 1).End(xlUp).Row).Value
                If f Then
                    a = ArrayJoin(a, temp)
                Else
                    a = temp
                    f = True
                End If
            End If
        End With
    Next ws

    BubbleSort a, 2
    BubbleSort a, 1
    ReDim b(1 To UBound(a, 1), 1 To 5)

    For i = 1 To UBound(a, 1)
        If a(i, 1) <> prev Then
            p = p + 1
            b(p, 1) = a(i, 1)
            b(p, 2) = a(i, 2)
            b(p, 3) = a(i, 2)
            b(p, 4) = a(i, 3)
            b(p, 5) = a(i, 4)
            If p > 1 Then
                b(p - 1, 3) = a(i - 1, 2)
                b(p - 1, 5) = a(i - 1, 4)
            End If
            prev = a(i, 1)
        End If
    Next i

    With Sheets("1")
        .Range("A1").Resize(1, 5).Value = Array("Track", "Start Date", "End Date", "First Open", "Last Close")
        .Range("A2").Resize(p, UBound(b, 2)).Value = b
    End With
Application.ScreenUpdating = True
End Sub

Function ArrayJoin(ByVal a, ByVal b)
Dim i           As Long
Dim ii          As Long
Dim ub          As Long

ub = UBound(a, 1)
a = Application.Transpose(a)
ReDim Preserve a(1 To UBound(a, 1), 1 To ub + UBound(b, 1))
a = Application.Transpose(a)

For i = LBound(b, 1) To UBound(b, 1)
    For ii = 1 To UBound(b, 2)
        a(ub + i, ii) = b(i, ii)
    Next ii
Next i

ArrayJoin = a
End Function

Function BubbleSort(arr() As Variant, sortIndex As Long)
Dim b           As Boolean
Dim i           As Long
Dim j           As Long

ReDim v(LBound(arr, 2) To UBound(arr, 2)) As Variant

Do
    b = True
    For i = LBound(arr) To UBound(arr) - 1
        If arr(i, sortIndex) > arr(i + 1, sortIndex) Then
            b = False
            For j = LBound(v) To UBound(v)
                v(j) = arr(i, j)
                arr(i, j) = arr(i + 1, j)
                arr(i + 1, j) = v(j)
            Next
        End If
    Next i
Loop While Not b
End Function
© www.soinside.com 2019 - 2024. All rights reserved.