我正在尝试做多列匹配的事情。我什至不知道该怎么称呼,所以我什至不知道如何搜索。 “化合物匹配” ...?
我在工作表(称为“ RPT-保质期”的工作表)中有一堆“候选”数字(每个数字都是25个字符)。在一个不同的工作表(顺便说一句,“ MasterSheet”,它包含数千行或数万行)中,我想确定是否存在以下条件:
是否存在D列等于CANDIDATE_NUMBER且F列=“香蕉”或“橙色”的行? (答案可以是MasterSheet中的行值)
(注意:F列中将包含“香蕉”或“橙色”以外的值,我必须忽略它们。)
现在,我以非常愚蠢的方式做到这一点:
' Now loop through each of the candidates and hunt for TRANSACTION TYPES that match the ScanID,
' and are either SCHEDULED or DEPLOYED. These are items that ARE NOT STALE. Repair their flags.
Dim LastRowOfCandidates As Long
Dim ShelfAgeCounter As Long
Dim MastersheetTransactionRowIndex As Long
Dim CandidateScanID As Long
Dim ItemResolved As Boolean
LastRowOfCandidates = Worksheets("RPT - Shelf Age").Cells(Rows.Count, 1).End(xlUp).Row
MsgBox ("There are " & LastRowOfCandidates & " rows of complete data in this report." & vbCrLf)
For ShelfAgeCounter = 3 To LastRowOfCandidates ' cycle through each candidate
ItemResolved = False
TargetRow = 2
MastersheetTransactionRowIndex = Worksheets("RPT - Shelf Age").Cells(ShelfAgeCounter, 1) ' this is the row in which the candidate appears on the MasterSheet
CandidateScanID = MastersheetTransactionRowIndex = Worksheets("RPT - Shelf Age").Cells(ShelfAgeCounter, 4) ' the ScanID to hunt for
'Search the MasterSheet for any occurrence of CandidateScanID where the action is SCHEDULE or DEPLOYED
Do Until Worksheets("MasterSheet").Cells(TargetRow, 1) = "" Or ItemResolved = True
If Worksheets("MasterSheet").Cells(TargetRow, 4) = CandidateScanID And Worksheets("MasterSheet").Cells(TargetRow, 6) = "Scheduled for Delivery" Then
'Worksheets("MasterSheet").Cells(MastersheetTransactionRowIndex, 37) = ""
ItemResolved = True
End If
If Worksheets("MasterSheet").Cells(TargetRow, 4) = CandidateScanID And Worksheets("MasterSheet").Cells(TargetRow, 6) = "Equipment Deployed" Then
Worksheets("MasterSheet").Cells(MastersheetTransactionRowIndex, 37) = ""
ItemResolved = True
End If
TargetRow = TargetRow + 1
Loop ' finished looking for a match on MasterSheet
Next
现在,这可行,但是ho,这需要很长时间。
考虑到这是Excel,它可能有非常快的方法来查找其自己的表中的数据,有没有一种方法不需要要求最长搜索时间=候选数* MasterSheet行数?
谢谢你!
-=-=-=-=-=-=-
附录:
这是整个子项,包括尝试使用AUTOFILTER:
Private Sub Worksheet_Activate()
Worksheets("RPT - Shelf Age").Rows("3:5000").EntireRow.Delete ' I REALLY hope there aren't more than 5000 stale items!
Worksheets("RPT - Shelf Age").Range("A3").Activate
Dim CurrentReportRow As Long
Dim TargetRow As Long
CurrentReportRow = 3
TargetRow = 2
' Pull in all the CANDIDATE items from the Master Sheet that have perhaps not yet been reconciled
' This is not a full data set because I only need a few values to scrub through Candidates.
Do Until Worksheets("MasterSheet").Cells(TargetRow, 1) = ""
If Worksheets("MasterSheet").Cells(TargetRow, 37) = 1 Then
Worksheets("RPT - Shelf Age").Cells(CurrentReportRow, 1) = TargetRow
Worksheets("RPT - Shelf Age").Cells(CurrentReportRow, 2) = Left(Worksheets("MasterSheet").Cells(TargetRow, 4), 10)
Worksheets("RPT - Shelf Age").Cells(CurrentReportRow, 3) = Mid(Worksheets("MasterSheet").Cells(TargetRow, 4), 12, 11)
Worksheets("RPT - Shelf Age").Cells(CurrentReportRow, 4) = Worksheets("MasterSheet").Cells(TargetRow, 4)
CurrentReportRow = CurrentReportRow + 1
End If
TargetRow = TargetRow + 1
Loop
MsgBox ("Hold up there a sec, hoss!") ' I include this test stop to let me review the table before proceeding.
Dim wb As Workbook
Dim wsMaster As Worksheet
Dim wsRPT As Worksheet
Dim rFound As Range
Dim aCandidateIDs As Variant
Dim vID As Variant
Set wb = ActiveWorkbook
Set wsMaster = wb.Worksheets("MasterSheet")
Set wsRPT = wb.Worksheets("RPT - Shelf Age")
With wsRPT.Range("D3", wsRPT.Cells(wsRPT.Rows.Count, "D").End(xlUp))
If .Row < 3 Then Exit Sub ' No data
If .Cells.Count = 1 Then
ReDim aCandidateIDs(1 To 1, 1 To 1)
aCandidateIDs(1, 1) = .Value
Else
aCandidateIDs = .Value
End If
End With
With wsMaster.Range("D1:F" & wsMaster.Cells(wsMaster.Rows.Count, "D").End(xlUp).Row)
For Each vID In aCandidateIDs
.AutoFilter 1, vID 'Filter column D for the ID
.AutoFilter 3, "Scheduled for Delivery", xlOr, "Equipment Deployed" 'Filter column F for the two other strings
' Check if there are any results
On Error Resume Next
Set rFound = .Offset(1).SpecialCells(xlCellTypeVisible).Cells(1) ' This assumes you only want the first match found. For all matches, leave off the .Cells(1)
On Error GoTo 0
.AutoFilter 'Remove the filter
If Not rFound Is Nothing Then
' Found a match, do something with it here
' Because we only returned the first match, no need to iterate over rFound because it will only be 1 cell
MsgBox "Candidate ID: " & vID & Chr(10) & "Match found on MasterSheet at row: " & rFound.Row
End If
Next vID
End With
' Now loop through each of the candidates and hunt for TRANSACTION TYPES that match the ScanID,
' and are either SCHEDULED or DEPLOYED. These are items that ARE NOT STALE. Repair their flags.
'Dim LastRowOfCandidates As Long
'Dim ShelfAgeCounter As Long
'Dim MastersheetTransactionRowIndex As Long
'Dim CandidateScanID As Long
'Dim ItemResolved As Boolean
'LastRowOfCandidates = Worksheets("RPT - Shelf Age").Cells(Rows.Count, 1).End(xlUp).Row
' MsgBox ("There are " & LastRowOfCandidates & " rows of complete data in this report." & vbCrLf)
'For ShelfAgeCounter = 3 To LastRowOfCandidates ' cycle through each candidate
'ItemResolved = False
'TargetRow = 2
'MastersheetTransactionRowIndex = Worksheets("RPT - Shelf Age").Cells(ShelfAgeCounter, 1) ' this is the row in which the candidate appears on the MasterSheet
'CandidateScanID = MastersheetTransactionRowIndex = Worksheets("RPT - Shelf Age").Cells(ShelfAgeCounter, 4) ' the ScanID to hunt for
' Search the MasterSheet for any occurrence of CandidateScanID where the action is SCHEDULE or DEPLOYED
'Do Until Worksheets("MasterSheet").Cells(TargetRow, 1) = "" Or ItemResolved = True
'If Worksheets("MasterSheet").Cells(TargetRow, 4) = CandidateScanID And Worksheets("MasterSheet").Cells(TargetRow, 6) = "Scheduled for Delivery" Then
'Worksheets("MasterSheet").Cells(MastersheetTransactionRowIndex, 37) = ""
'ItemResolved = True
'End If
'If Worksheets("MasterSheet").Cells(TargetRow, 4) = CandidateScanID And Worksheets("MasterSheet").Cells(TargetRow, 6) = "Equipment Deployed" Then
'Worksheets("MasterSheet").Cells(MastersheetTransactionRowIndex, 37) = ""
'ItemResolved = True
'End If
'TargetRow = TargetRow + 1
'Loop ' finished looking for a match on MasterSheet
'Next
' Empty out this table
Worksheets("RPT - Shelf Age").Rows("3:5000").EntireRow.Delete ' I REALLY hope there aren't more than 5000 stale items!
Worksheets("RPT - Shelf Age").Range("A3").Activate
' Pull in all the items from the Master Sheet that are still scheduled or deployed.
CurrentReportRow = 3
TargetRow = 2
Worksheets("RPT - Shelf Age").Columns(5).Interior.Color = xlNone
Do Until Worksheets("MasterSheet").Cells(TargetRow, 1) = ""
If Worksheets("MasterSheet").Cells(TargetRow, 37) = 1 Then
Worksheets("RPT - Shelf Age").Cells(CurrentReportRow, 1) = TargetRow ' Transaction ID
Worksheets("RPT - Shelf Age").Cells(CurrentReportRow, 2) = Left(Worksheets("MasterSheet").Cells(TargetRow, 4), 10) ' REQ
Worksheets("RPT - Shelf Age").Cells(CurrentReportRow, 3) = Mid(Worksheets("MasterSheet").Cells(TargetRow, 4), 12, 11) ' RITM
Worksheets("RPT - Shelf Age").Cells(CurrentReportRow, 4) = Worksheets("MasterSheet").Cells(TargetRow, 7) ' Depot timestamp
Worksheets("RPT - Shelf Age").Cells(CurrentReportRow, 5) = Now - Worksheets("RPT - Shelf Age").Cells(CurrentReportRow, 4) ' Age in days
If Worksheets("RPT - Shelf Age").Cells(CurrentReportRow, 5) > 3 Then ' if the item is older than 1 day, highlight the cell
Worksheets("RPT - Shelf Age").Cells(CurrentReportRow, 5).Interior.Color = RGB(255, 0, 0)
End If
CurrentReportRow = CurrentReportRow + 1
End If
TargetRow = TargetRow + 1
Loop
Worksheets("RPT - Shelf Age").Columns(4).NumberFormat = "mmm d, yyyy at h:mm AM/PM"
' Sort the table by that age -- oldest presenting first.
Dim lastrow As Long
lastrow = Cells(Rows.Count, 1).End(xlUp).Row
With Workbooks("Equipment_Transactions.xlsm").Sheets("RPT - Shelf Age")
With .Range("a3").CurrentRegion
.Sort key1:=.Cells(5), order1:=xlDescending, Header:=xlYes
End With
End With
End Sub
编辑(截至2019年5月28日):
是否可以注入一个单元级函数来满足此问题?例如,当我放置在最初的“从仓库中移出”行时,我在AK列中手动添加了“ 1”标志,但也许我可以添加一个单元格级别的命令,该命令的基本内容是“使此单元格自动计算”。如果此工作表上还有其他一行的D列值与此行的D列相同,并且该匹配行的F列具有“预定”或“已部署”,则该值应为空,但否则,该单元格应包含1。“
然后,我可以过滤AK列包含1的所有项目,并且我知道它们已经被对帐了。
答案 0 :(得分:0)
使用自动过滤器避免循环并找到您的匹配项,如下所示:
<div class="btn-toolbar justify-content-between">
<form action="{{ route('orders.destroy', ['id' => $order->id]) }}" method="post">
{{ method_field('UPDATE') }}
{{ csrf_field() }}
<div class="btn-group-sm">
<button type="submit" class="btn btn-success">ok</button>
<button type="submit" class="btn btn-danger">del</button>
</div>
</form>
</div>
答案 1 :(得分:0)
好吧!
首先,感谢所有帮助我探索想法的人。这一切都有帮助。感谢@Chris,他为正确的方向提供了最后的推动。
解决方案结果是:
通过系统的初始时间大约为45秒。通过将所有数据铲入一个数组,然后遍历该数组而不是表,我将其减少了大约五秒钟。我可以进一步削减它,但是说实话,五秒钟循环浏览所有数据可能已经足够了!
赢!