简体   繁体   English

VBA 中 DATE AND TIME 与 APROXIMATE MATCH 等效的 Vlookup

[英]Vlookup equivalent in VBA for DATE AND TIME with APROXIMATE MATCH

Here is the summary:这是摘要: 这就是我要的 这是我迄今为止所取得的成就

Here is the problem in details:下面是问题的详细信息:

I have a high school class time table saved in a worksheet named shtSrc .我有一个保存在名为shtSrc的工作表中的高中课程时间表

The time table looks like this:时间表如下所示:

A一种 B C C D D E F F
1 1 Start Time开始时间 End Time时间结束 Day Period时期 Subject主题 Teacher老师
2 2 8:20:00 AM上午 8:20:00 9:10:00 AM上午 9:10:00 Sunday星期日 1 1 GEOGRAPHY地理 JE乙脑
3 3 9:10:00 AM上午 9:10:00 10:00:00 AM上午 10:00:00 Sunday星期日 2 2 HISTORY历史 SU
4 4 10:00:00 AM上午 10:00:00 10:40:00 AM上午 10:40:00 Sunday星期日 3 3 BUSINESS商业 SA
5 5 10:40:00 AM上午 10:40:00 11:40:00 AM上午 11:40:00 Sunday星期日 4 4 BREAK休息
6 6 11:40:00 AM上午 11:40:00 12:30:00 PM 12:30:00 下午 Sunday星期日 5 5 MATHS数学 SH上海
7 7 12:30:00 PM 12:30:00 下午 1:30:00 PM下午 1:30:00 Sunday星期日 6 6 SCIENCE科学 JU
8 8 1:30:00 PM下午 1:30:00 8:20:00 PM晚上 8:20:00 Sunday星期日 7 7 EXTRA CLASS额外课程
9 9 8:20:00 AM上午 8:20:00 9:10:00 AM上午 9:10:00 Monday周一 1 1 BUSINESS商业 SA
10 10 9:10:00 AM上午 9:10:00 10:00:00 AM上午 10:00:00 Monday周一 2 2 SCIENCE科学 SU
11 11 10:00:00 AM上午 10:00:00 10:40:00 AM上午 10:40:00 Monday周一 3 3 HISTORY历史 RE关于
12 12 10:40:00 AM上午 10:40:00 11:40:00 AM上午 11:40:00 Monday周一 4 4 BREAK休息
13 13 11:40:00 AM上午 11:40:00 12:30:00 PM 12:30:00 下午 Monday周一 5 5 MATHS数学 SH上海
14 14 12:30:00 PM 12:30:00 下午 1:30:00 PM下午 1:30:00 Monday周一 6 6 GEOGRAPHY地理 RE关于
15 15 1:30:00 PM下午 1:30:00 8:20:00 PM晚上 8:20:00 Monday周一 7 7 EXTRA CLASS额外课程
16 16 8:20:00 AM上午 8:20:00 9:10:00 AM上午 9:10:00 Tuesday周二 1 1 BUSINESS商业 SA
17 17 9:10:00 AM上午 9:10:00 10:00:00 AM上午 10:00:00 Tuesday周二 2 2 HISTORY历史 SU
18 18 10:00:00 AM上午 10:00:00 10:40:00 AM上午 10:40:00 Tuesday周二 3 3 GEOGRAPHY地理 JE乙脑
19 19 10:40:00 AM上午 10:40:00 11:40:00 AM上午 11:40:00 Tuesday周二 4 4 BREAK休息
20 20 11:40:00 AM上午 11:40:00 12:30:00 PM 12:30:00 下午 Tuesday周二 5 5 MATHS数学 SH上海
21 21 12:30:00 PM 12:30:00 下午 1:30:00 PM下午 1:30:00 Tuesday周二 6 6 SCIENCE科学 JU
22 22 1:30:00 PM下午 1:30:00 8:20:00 PM晚上 8:20:00 Tuesday周二 7 7 EXTRA CLASS额外课程

Here, the schedule is demonstrated for 3 working days.在这里,时间表显示为 3 个工作日。 7 time slots per day.每天7个时段。 Working hours 8:20 AM to 8:20 PM.工作时间上午 8:20 至晚上 8:20。 The order of subjects taught on a day is not the same everyday.一天教的科目顺序每天都不一样。

Classes may start on time, or 10-15 minutes later.课程可能准时开始,也可能晚 10-15 分钟。 The date and time when a class actually started was recorded in column A of a worksheet named shtDest .课程实际开始的日期和时间记录在名为shtDest的工作表的 A 列中。 The sheet looks like this:该表如下所示:

A一种 B C C D D E F F G G H H
1 1 Entry date and time入场日期和时间 Entry date入职日期 Entry day入场日 Entry time入场时间 Start Time开始时间 Period时期 Subject主题 Teacher老师
2 2 1/1/2021 8:25 2021/1/1 8:25
3 3 1/3/2021 9:25 2021/1/3 9:25
4 4 1/3/2021 10:20 1/3/2021 10:20
5 5 1/4/2021 13:30 1/4/2021 13:30
6 6 1/5/2021 0:00 1/5/2021 0:00

I filled up rest of the table using some excel formula and some VBA.我使用一些 excel 公式和一些 VBA 填写了表格的其余部分。 The shtDest finally looked like this: shtDest最终看起来像这样:

A一种 B C C D D E F F G G H H
1 1 Entry date and time入场日期和时间 Entry date入职日期 Entry day入场日 Entry time入场时间 Start Time开始时间 Period时期 Subject主题 Teacher老师
2 2 1/1/2021 8:25 2021/1/1 8:25 1/1/2021 1/1/2021 Friday星期五 8:25 AM上午 8:25
3 3 1/3/2021 9:25 2021/1/3 9:25 1/3/2021 1/3/2021 Sunday星期日 9:25 AM上午 9:25 9:10:00 AM上午 9:10:00 2 2 HISTORY历史 SU
4 4 1/3/2021 10:20 1/3/2021 10:20 1/3/2021 1/3/2021 Sunday星期日 10:20 AM上午 10:20 10:00:00 AM上午 10:00:00 3 3 BUSINESS商业 SA
5 5 1/4/2021 13:30 1/4/2021 13:30 1/4/2021 1/4/2021 Monday周一 1:30 PM下午 1:30 1:30:00 PM下午 1:30:00 7 7 EXTRA CLASS额外课程
6 6 1/5/2021 0:00 1/5/2021 0:00 1/5/2021 1/5/2021 Tuesday周二 12:00 AM 12:00 AM

The formula I used in E2 to get the start time:我在E2 中用来获取开始时间的公式:

=IFERROR(VLOOKUP(D2,IF(shtSrc!$C$2:$C$22=C2,shtSrc!$A$2:$F$22,""),1,TRUE),"")

For F2:H6 , I used a Vlookup alternative with VBA.对于F2:H6 ,我使用了 VBA 的 Vlookup 替代方案。 Here is the code:这是代码:

Option Explicit

Sub VlookupAlternative()
    Dim rngSrc As Range, rngDest As Range, celSrc As Range, celDest As Range
    

    With ThisWorkbook
        Set rngSrc = .Worksheets("shtSrc").Range("$A$1:$F$22")
        Set rngDest = .Worksheets("shtDest").Range("$F$2:$H$6")
        
        ' Compare top headers and left headers respectively. If matching, copy the value in destination table.
        For Each celDest In rngDest
            For Each celSrc In rngSrc
            
'         ***   This is the line I want as first line in the IF statement:
'         ***   If .Worksheets("shtSrc").Cells(celSrc.Row, 1).Value = Application.VLookup(Format(CLng(CDate(.Worksheets("shtDest").Cells(celDest.Row, 1).Value)), "h:mm:ss AM/PM"), rngSrc, 1, True) And _

                If .Worksheets("shtSrc").Cells(celSrc.Row, 1).Value = .Worksheets("shtDest").Cells(celDest.Row, 5).Value And _
                        .Worksheets("shtSrc").Cells(celSrc.Row, 3).Value = Format(.Worksheets("shtDest").Cells(celDest.Row, 1).Value, "DDDD") And _
                        .Worksheets("shtSrc").Cells(1, celSrc.Column).Value = .Worksheets("shtDest").Cells(1, celDest.Column).Value Then
                    celDest.Value = celSrc.Value
                End If
            Next celSrc
        Next celDest
    End With
End Sub

For this code I am thankful to this link: Index match match/vlookup in VBA对于此代码,我感谢此链接: VBA 中的索引匹配匹配/vlookup

The main issue is:主要问题是:

To run this code, I have to provide EXACT START TIME in column E. And to get the values in column E, I need 3 helper columns: B, C, D. I tried using Application.VLookup for column E but I failed with "Type Mismatch" Error.要运行此代码,我必须在 E 列中提供 EXACT START TIME。要获取 E 列中的值,我需要 3 个辅助列:B、C、D。我尝试将Application.VLookup用于 E 列,但失败了“类型不匹配”错误。

When I tried replacing the first line of the IF statement当我尝试替换 IF 语句的第一行时

If .Worksheets("shtSrc").Cells(celSrc.Row, 1).Value = .Worksheets("shtDest").Cells(celDest.Row, 5).Value And _

with this line用这条线

If .Worksheets("shtSrc").Cells(celSrc.Row, 1).Value = Application.VLookup(Format(CLng(CDate(.Worksheets("shtDest").Cells(celDest.Row, 1).Value)), "h:mm:ss AM/PM"), rngSrc, 1, True) And _

I got a "Type Mismatch" error.我收到“类型不匹配”错误。

I want to:我想要:

I want to achieve the same output without any formula, without any helper columns, using only VBA .我想在没有任何公式、没有任何辅助列、仅使用 VBA 的情况下实现相同的输出。 Is approximate match possible using arrays or dictionaries ?是否可以使用数组或字典进行近似匹配? My shtSrc has 20,000+ entries.我的 shtSrc 有 20,000 多个条目。 Can you suggest any way alternative to VLOOKUP WITH APPROXIMATE MATCH without using Application.VLookup ?你能建议任何方法替代 VLOOKUP WITH APPROXIMATE MATCH 而不使用Application.VLookup吗?

The Vlookup statement I wanted to include finally worked when I converted Timevalue to Double .当我将Timevalue转换为 Double时,我想要包含的Vlookup 语句终于起作用了。 The Vlookup statement now is: Vlookup 语句现在是:

        If .Worksheets("shtSrc").Cells(celSrc.Row, 1).Value = Application.IfError(Application.VLookup(CDbl(TimeValue(.Worksheets("shtDest").Cells(celDest.Row, 1).Value)), rngSrc, 1, True), "") And _

With a dynamic range selection using last row and last column, The final VBA code is:通过使用最后一行和最后一列的动态范围选择,最终的 VBA 代码是:

Option Explicit

Sub VlookupAlternative()
    
    Const INPUT_SHT = "shtSrc"
    Const OUTPUT_SHT = "shtDest"
    
    
    Dim wb As Workbook, wsIn As Worksheet, wsOut As Worksheet
    Dim rngSrc As Range, rngDest As Range, celSrc As Range, celDest As Range
    Dim rLastIn As Long, cLastIn As Long
    Dim rLastOut As Long, cLastOut As Long

    Application.Calculation = xlCalculationManual
    Application.DisplayStatusBar = False
    Application.EnableEvents = False
    Application.ScreenUpdating = False

    On Error Resume Next
    
    Set wb = ThisWorkbook
    Set wsIn = wb.Sheets(INPUT_SHT)
    Set wsOut = wb.Sheets(OUTPUT_SHT)
    
    
    rLastIn = lastRow(wsIn)
    cLastIn = LastCol(wsIn)
    
    rLastOut = lastRow(wsOut)
    cLastOut = LastCol(wsOut)
    
    With wb

        Set rngSrc = wsIn.Range("$A$2:$F$" & rLastIn)
        Set rngDest = wsOut.Range("$B$2:$D$" & rLastOut)
        
        
        ' Compare top headers and left headers respectively. If matching, copy the value in destination table.
        For Each celDest In rngDest
            For Each celSrc In rngSrc
                If wsIn.Cells(celSrc.Row, 1).Value = Application.IfError(Application.VLookup(CDbl(TimeValue(wsOut.Cells(celDest.Row, 1).Value)), rngSrc, 1, True), "") And _
                    wsIn.Cells(celSrc.Row, 3).Value = Format(wsOut.Cells(celDest.Row, 1).Value, "DDDD") And _
                    wsIn.Cells(1, celSrc.Column).Value = wsOut.Cells(1, celDest.Column).Value Then
                    celDest.Value = celSrc.Value
                End If
            Next celSrc
        Next celDest
    End With
    
    Application.Calculation = xlCalculationAutomatic
    Application.DisplayStatusBar = True
    Application.EnableEvents = True
    Application.ScreenUpdating = True

End Sub


Function lastRow(sh As Worksheet)
    On Error Resume Next
    lastRow = sh.Cells.Find(What:="*", _
                            After:=sh.Range("A1"), _
                            Lookat:=xlPart, _
                            LookIn:=xlFormulas, _
                            SearchOrder:=xlByRows, _
                            SearchDirection:=xlPrevious, _
                            MatchCase:=False).Row
    On Error GoTo 0
End Function


Function LastCol(sh As Worksheet)
    On Error Resume Next
    LastCol = sh.Cells.Find(What:="*", _
                            After:=sh.Range("A1"), _
                            Lookat:=xlPart, _
                            LookIn:=xlFormulas, _
                            SearchOrder:=xlByColumns, _
                            SearchDirection:=xlPrevious, _
                            MatchCase:=False).Column
    On Error GoTo 0
End Function

Final output:最终输出:

A一种 B C C D D
1 1 Entry date and time入场日期和时间 Period时期 Subject主题 Teacher老师
2 2 1/1/2021 8:25 2021/1/1 8:25
3 3 1/3/2021 9:25 2021/1/3 9:25 2 2 HISTORY历史 SU
4 4 1/3/2021 10:20 1/3/2021 10:20 3 3 BUSINESS商业 SA
5 5 1/4/2021 13:30 1/4/2021 13:30 7 7 EXTRA CLASS额外课程
6 6 1/5/2021 0:00 1/5/2021 0:00

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM