Вместо циклического перемещения по диапазону ваш макрос будет работать намного быстрее, если вы используете метод Range.Find
.
В своем коде вы не проверяли, чтобы все ваши наборы из Process | Title | 180 Days
завершено. Я добавил это в приведенный ниже код, убедившись, что строки Process
и Title
были найдены после предыдущей строки 180 day
(или перед строкой 180 day
для первого экземпляра).
В своем коде вы не проверяли, действительно ли ячейки, в которые вы хотите вывести эту информацию, пусто . Если вы действительно хотите это сделать, вы можете легко изменить этот код, чтобы проверить эти ячейки, прежде чем писать в них.
Надеемся, что благодаря комментариям и использованию значимых имен переменных вы сможете понять, что такое продолжается. Но вы также можете прочитать справку VBA для метода Range.Find
.
В общем, мы ищем вниз, чтобы найти строку 180 day
, затем ищем оттуда, чтобы найти связанный Process
и Title
строки.
Если предшествующая строка Process
или Title
должна быть перед предыдущей строкой 180 day
, то мы имеем неполный набор, выводим сообщение об ошибке и завершаем процедуру.
При необходимости вы можете разработать процедуры для обработки неполных наборов данных.
Option Explicit
Sub Info()
Dim searchRng As Range, C As Range, cProcessPlan As Range, cOperTitle As Range
Dim firstAddress As String 'to check when we are done
Dim lastAddress As String 'to check for incomplete data sets
'Where are we looking?
Set searchRng = ThisWorkbook.Worksheets("Sheet1").Columns(3)
With searchRng
Set C = .Find(what:="180 Days", after:=.Cells(1, 1), LookIn:=xlValues, _
lookat:=xlPart, searchorder:=xlByRows, _
searchdirection:=xlNext, MatchCase:=False)
If Not C Is Nothing Then
firstAddress = C.Address
lastAddress = C.Address
Set cOperTitle = .Find(what:="Oper Title", after:=C, searchdirection:=xlPrevious)
Set cProcessPlan = .Find(what:="Process Plan", after:=C, searchdirection:=xlPrevious)
If Not cOperTitle Is Nothing Or Not cProcessPlan Is Nothing Then
'check for full set
If cOperTitle.Row > Range(lastAddress).Row Or cProcessPlan.Row > Range(lastAddress).Row Then
MsgBox "Incomplete Data Set" & vbLf & "Before: " & C.Address
Exit Sub
End If
C.Offset(0, -1) = cOperTitle.Offset(1, 0)
C.Offset(0, -2) = cProcessPlan
Else
MsgBox "Title or Process Plan not found"
Exit Sub
End If
Do
Set C = .Find(what:="180 Days", after:=C, LookIn:=xlValues, _
lookat:=xlPart, searchorder:=xlByRows, _
searchdirection:=xlNext, MatchCase:=False)
If C.Address = firstAddress Then Exit Do
Set cOperTitle = .Find(what:="Oper Title", after:=C, searchdirection:=xlPrevious)
Set cProcessPlan = .Find(what:="Process Plan", after:=C, searchdirection:=xlPrevious)
'check for a full set
If cOperTitle.Row < Range(lastAddress).Row Or cProcessPlan.Row < Range(lastAddress).Row Then
MsgBox "Incomplete Data Set" & vbLf & "Between: " & lastAddress & " and " & C.Address
Exit Sub
End If
C.Offset(0, -1) = cOperTitle.Offset(1, 0)
C.Offset(0, -2) = cProcessPlan
lastAddress = C.Address
Loop
End If
End With
'next stuff
End Sub