Excel 如何查找一行中字符串的第一个和最后一个匹配项?
我有一个有几千行的工作簿,我需要为每一行识别第一个和最后一个出现的“Y”。(这些字符与特定日期绑定,具体取决于它们所属的列)。我必须找到这些字符的开始和结束,因为它会给我每个任务的开始和结束日期。到目前为止,我已经尝试过:Excel 如何查找一行中字符串的第一个和最后一个匹配项?,excel,vba,Excel,Vba,我有一个有几千行的工作簿,我需要为每一行识别第一个和最后一个出现的“Y”。(这些字符与特定日期绑定,具体取决于它们所属的列)。我必须找到这些字符的开始和结束,因为它会给我每个任务的开始和结束日期。到目前为止,我已经尝试过: Public Sub import_gbs() Dim wb As Workbook Dim gbs_wb As Workbook Dim gbs_bg As Worksheet Dim gbs_drivers As Worksheet Dim bg As Worksheet
Public Sub import_gbs()
Dim wb As Workbook
Dim gbs_wb As Workbook
Dim gbs_bg As Worksheet
Dim gbs_drivers As Worksheet
Dim bg As Worksheet
Dim dict As Scripting.Dictionary
Dim date_array() As String
Dim x As Long
Dim i As Long
Dim switch As Integer
Dim start_position As Integer
Dim stop_position As Integer
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
Application.TransitionNavigKeys = False
Set wb = ThisWorkbook
Set bg = wb.Sheets("Current EDGE")
Application.AutomationSecurity = msoAutomationSecurityForceDisable
Set gbs_wb = Workbooks.Open("C:\SOME PATH HERE\")
Application.AutomationSecurity = msoAutomationSecurityByUI
Set gbs_bg = gbs_wb.Sheets("CC Input")
Set gbs_drivers = gbs_wb.Sheets("Drivers")
Set dict = New Scripting.Dictionary '''
dict.Add "SU YN Start", gbs_drivers.Cells(9, 5).Value
dict.Add "SU YN Stop", gbs_drivers.Cells(9, 6).Value
dict.Add "EPMP1 YN Start", gbs_drivers.Cells(10, 5).Value
dict.Add "EPMP1 YN Stop", gbs_drivers.Cells(10, 6).Value
dict.Add "EPMP2 YN Start", gbs_drivers.Cells(11, 5).Value
dict.Add "EPMP2 YN Stop", gbs_drivers.Cells(11, 6).Value
dict.Add "RC YN Start", gbs_drivers.Cells(12, 5).Value
dict.Add "RC YN Stop", gbs_drivers.Cells(12, 6).Value
dict.Add "ON YN Start", gbs_drivers.Cells(13, 5).Value
dict.Add "ON YN Stop", gbs_drivers.Cells(13, 6).Value
dict.Add "FU YN Start", gbs_drivers.Cells(14, 5).Value
dict.Add "FU YN Stop", gbs_drivers.Cells(14, 6).Value
dict.Add "DB Lock YN Start", gbs_drivers.Cells(15, 5).Value
dict.Add "DB Lock YN Stop", gbs_drivers.Cells(15, 6).Value
dict.Add "CO/Reporting YN Start", gbs_drivers.Cells(16, 5).Value
dict.Add "CO/Reporting YN Stop", gbs_drivers.Cells(16, 6).Value
i = 2
For x = 3 To 9543
If gbs_bg.Cells(x, 25).Value > 0 Then
start_position = gbs_bg.Range("AI" & x & ":" & "AP" & x).Find(what:="Y", lookat:=xlWhole, searchdirection:=xlNext).Column
stop_position = gbs_bg.Range("AI" & x & ":" & "AP" & x).Find(what:="Y", lookat:=xlWhole, searchdirection:=xlPrevious).Column
Select Case start_position
Case 35
gbs_bg.Cells(x, 65).Value = dict("SU YN Start")
Case 36
gbs_bg.Cells(x, 65).Value = dict("EPMP1 YN Start")
Case 37
gbs_bg.Cells(x, 65).Value = dict("EPMP2 YN Start")
Case 38
gbs_bg.Cells(x, 65).Value = dict("RC YN Start")
Case 39
gbs_bg.Cells(x, 65).Value = dict("ON YN Start")
Case 40
gbs_bg.Cells(x, 65).Value = dict("FU YN Start")
Case 41
gbs_bg.Cells(x, 65).Value = dict("DB Lock YN Start")
Case 42
gbs_bg.Cells(x, 65).Value = dict("CO/Reporting YN Start")
End Select
Select Case stop_position
Case 35
gbs_bg.Cells(x, 66).Value = dict("SU YN Stop")
Case 36
gbs_bg.Cells(x, 66).Value = dict("EPMP1 YN Stop")
Case 37
gbs_bg.Cells(x, 66).Value = dict("EPMP2 YN Stop")
Case 38
gbs_bg.Cells(x, 66).Value = dict("RC YN Stop")
Case 39
gbs_bg.Cells(x, 66).Value = dict("ON YN Stop")
Case 40
gbs_bg.Cells(x, 66).Value = dict("FU YN Stop")
Case 41
gbs_bg.Cells(x, 66).Value = dict("DB Lock YN Stop")
Case 42
gbs_bg.Cells(x, 66).Value = dict("CO/Reporting YN Stop")
End Select
i = i + 1
End If
Next x
所以这对我来说大部分时间都很有效。在少数几行中有一些非常奇怪的实例,其中第35列中有一个“Y”,但find没有找到它,并在该行中拾取下一个“Y”实例。在7000多行中,这种情况只发生了少数几次,并且总是在第35列中发生(但大多数情况下,如果有,它会在该行的该列中找到“Y”)。这显然把我的日期弄乱了。我不知道会是什么。我已经尝试过通过检查单元格的长度和值进行调试,其中“Y”表示找不到。但它返回为1,值为“Y”。我尝试过在搜索值和公式之间切换,但也不起作用
所以我需要找到一种新的方法来发现这些事件。我在想,既然我知道vba能正确识别每个单元格值的长度,我就可以用它来构建。但我不知道如何开始。任何帮助都将不胜感激。谢谢 最简单的方法是创建一个小型for循环,以遍历8列数据(AI到AP),找到“Y”的第一个和最后一个匹配项,并检查这是否非常耗时。但是,手动计算和屏幕更新关闭后,时间应该不会太长。 在下面,您可以找到准备好进行测试的简单sub
Option Explicit
Sub test()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim t#: t = Timer
Dim wbs As Worksheet
Dim x As Long
Dim col As Integer
Dim startposition As Integer
Dim endposition As Integer
Set wbs = ActiveSheet
With wbs
For x = 1 To 7000
startposition = 0
For col = 35 To 42
If .Range(.Cells(x, col), .Cells(x, col)).Value = "Y" And startposition = 0 Then
startposition = col
ElseIf .Range(.Cells(x, col), .Cells(x, col)).Value = "Y" And startposition <> 0 Then
endposition = col
End If
Next col
Next x
End With
Debug.Print Timer - t
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
选项显式
子测试()
Application.ScreenUpdating=False
Application.Calculation=xlCalculationManual
Dim t#:t=定时器
将wbs设置为工作表
暗x等长
作为整数的Dim col
Dim startposition作为整数
Dim endposition作为整数
设置wbs=ActiveSheet
使用wbs
对于x=1到7000
起始位置=0
对于col=35至42
如果.Range(.Cells(x,col),.Cells(x,col)).Value=“Y”和startposition=0,则
起始位置=列
ElseIf.Range(.Cells(x,col),.Cells(x,col)).Value=“Y”和起始位置0
结束位置=列
如果结束
下一列
下一个x
以
打印计时器-t
Application.ScreenUpdating=True
Application.Calculation=xlCalculationAutomatic
端接头
我的分数是0,57秒,在空纸上。您可以分析该代码并可能实现该循环。For x循环只是对7000行的模拟。最简单的方法是创建一个小For循环,以遍历8列数据(AI到AP),找到“Y”的第一个和最后一个匹配项,并检查这是否非常耗时。但是,手动计算和屏幕更新关闭后,时间应该不会太长。 在下面,您可以找到准备好进行测试的简单sub
Option Explicit
Sub test()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim t#: t = Timer
Dim wbs As Worksheet
Dim x As Long
Dim col As Integer
Dim startposition As Integer
Dim endposition As Integer
Set wbs = ActiveSheet
With wbs
For x = 1 To 7000
startposition = 0
For col = 35 To 42
If .Range(.Cells(x, col), .Cells(x, col)).Value = "Y" And startposition = 0 Then
startposition = col
ElseIf .Range(.Cells(x, col), .Cells(x, col)).Value = "Y" And startposition <> 0 Then
endposition = col
End If
Next col
Next x
End With
Debug.Print Timer - t
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
选项显式
子测试()
Application.ScreenUpdating=False
Application.Calculation=xlCalculationManual
Dim t#:t=定时器
将wbs设置为工作表
暗x等长
作为整数的Dim col
Dim startposition作为整数
Dim endposition作为整数
设置wbs=ActiveSheet
使用wbs
对于x=1到7000
起始位置=0
对于col=35至42
如果.Range(.Cells(x,col),.Cells(x,col)).Value=“Y”和startposition=0,则
起始位置=列
ElseIf.Range(.Cells(x,col),.Cells(x,col)).Value=“Y”和起始位置0
结束位置=列
如果结束
下一列
下一个x
以
打印计时器-t
Application.ScreenUpdating=True
Application.Calculation=xlCalculationAutomatic
端接头
我的分数是0,57秒,在空纸上。您可以分析该代码并可能实现该循环。For x循环只是对7000行的模拟。使用一些示例数据和预期结果,这将更容易理解。你能提供这个吗?
InStr
首先提供给你,InStrRev
最后提供给你。通过一些示例数据和预期结果,这将更容易理解。你能提供这个吗?InStr
先给你,InStrRev
最后给你。