[英]Using VBA to loop through different ranges and compare partial strings
我遇到的问题如下。 我正在尝试根据众多标准将“价格和日期”从导入页面剪切到新表中。 我有一个规格表,我比较这些标准必须是什么。
在导入页面上,我首先必须满足 3 个标准(这些更改基于用户输入:
这些与看起来如下的表进行比较:(此表没有太大变化。最多可能会更新 Origin 和 Key,或者可能会添加另一行)
对于水果、类型和颜色匹配的每一行,我们都必须考虑另一个因素。 水果是从“超市”还是“农夫”购买的。 在导入表上,我们有下表,每个月都会更改。
在超市购买水果时,我想使用与满足“水果”、“类型”和“颜色”正确标准的行相对应的正确键。 所以在上面的这个例子中,我想使用与“Apple”、“Fresh”、“Red”对应的键。 在此示例中,这只是第一行。 对应的键是“Supermarket ID 1”,我们在导入表中有几行数据。 我想将这些行中的“价格”和“日期”剪切并粘贴到一个新表中。
对于那些从农民那里购买的水果,它有点不同,因为 1) 可比较的键与超市一列在不同的列中,并且 2) 键只是导入页面的整个字符串的一部分(总是如此) . 在这里,我也想将“价格”和“日期”切成不同的表格。
希望有人理解这个问题。 到目前为止,我编写的代码如下:
Sub Fruits1()
Dim Criteria1 As Variant, Criteria2 As Variant, Criteria3 As Variant, Criteria4 As Variant, Criteria5 As Variant
Dim rng As Range, cell As Range
Dim wsImport As Worksheet: Set wsImport = Sheets("Import")
Dim wsSpec As Worksheet: Set wsSpec = Sheets("Specificaties")
Dim primarykey As String, comparingkey As String
Criteria1 = wsImport.Range("C3")
Criteria2 = wsImport.Range("C4")
Criteria3 = wsImport.Range("C5")
Set rng = wsSpec.Range("H3:H" & (wsSpec.Cells(Rows.Count, 8).End(xlUp).Row))
For Each cell In rng
If cell.Value = Criteria1 And cell.Offset(0, 1).Value = Criteria2 And cell.Offset(0, 2).Value = Criteria3 Then
If cell.Offset(0, 3) = "Supermarket" Then
import_lastrow = wsImport.Range("E" & Rows.Count).End(xlUp).Row
For i = import_lastrow To 2 Step -1
primarykey = cell.Offset(0, 4).Value
comparingkey = wsImport.Cells(i, 13).Value
If InStr(primarykey, comparingkey) > 0 Then
MsgBox "cut Price and Data into new table"
End If
Next i
ElseIf cell.Offset(0, 4) = "Farmer" Then
For i = import_lastrow To 2 Step -1
primarykey = cell.Offset(0, 4).Value
comparingkey = wsImport.Cells(i, 8).Value
If InStr(primarykey, comparingkey) > 0 Then
MsgBox "cut Price and Data into new table"
End If
Next i
End If
End If
Next cell
End Sub
我相信的问题在于我试图遍历不同的范围并且做得不对。
逻辑:
代码:
好的,这是您正在尝试的吗? (未经测试)。 我很快就写了这个。 如果您有任何错误,请告诉我?
Option Explicit
Dim wsImport As Worksheet
Sub Sample()
Dim wsSpec As Worksheet
Set wsImport = ThisWorkbook.Sheets("Import")
Set wsSpec = ThisWorkbook.Sheets("Specificaties")
Dim CriteriaA As String, CriteriaB As String, CriteriaC As String
Dim aCell As Range, bCell As Range
Dim origin As String, KeyToFind As String
With wsSpec
CriteriaA = .Range("C3").Value2
CriteriaB = .Range("C4").Value2
CriteriaC = .Range("C5").Value2
'~~> Using .Find to look for CriteriaA
Set aCell = .Columns(8).Find(What:=CriteriaA, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
'~~> Check if found or not
If Not aCell Is Nothing Then
Set bCell = aCell
'~~> Secondary checks
If aCell.Offset(, 1).Value2 = CriteriaB And _
aCell.Offset(, 2).Value2 = CriteriaC Then '<~~ If match found
'~~> Get the origin and the key
origin = aCell.Offset(, 3).Value2
KeyToFind = aCell.Offset(, 4).Value2
Else '<~~ If match not found then search for next match
Do
Set aCell = .Columns(8).FindNext(After:=aCell)
If Not aCell Is Nothing Then
If aCell.Address = bCell.Address Then Exit Do
If aCell.Offset(, 1).Value2 = CriteriaB And _
aCell.Offset(, 2).Value2 = CriteriaC Then
origin = aCell.Offset(, 3).Value2
KeyToFind = aCell.Offset(, 4).Value2
Exit Do
End If
Else
Exit Do
End If
Loop
End If
'~~> Check the origin
If origin = "Supermarket" Then
CopyRows "F", KeyToFind, False
ElseIf origin = "Farmer" Then
CopyRows "H", KeyToFind, True
Else
MsgBox "Please check origin. Supermarket/Farmer not found. Exiting..."
End If
Else
MsgBox "Criteria A match was not found. Exiting..."
End If
End With
End Sub
'~~> Autofilter and copy filtered data
Private Sub CopyRows(Col As String, SearchString As String, PartialString As Boolean)
Dim copyFrom As Range
Dim lRow As Long
With wsImport
'~~> Remove any filters
.AutoFilterMode = False
lRow = .Range(Col & .Rows.Count).End(xlUp).Row
With .Range(Col & "1:" & Col & lRow)
If PartialString = False Then
.AutoFilter Field:=1, Criteria1:=SearchString
Else
.AutoFilter Field:=1, Criteria1:="=*" & SearchString & "*"
End If
Set copyFrom = .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow
End With
'~~> Remove any filters
.AutoFilterMode = False
End With
'~~> Some sheet where you want to paste the output
Dim SomeSheet As Worksheet
Set SomeSheet = ThisWorkbook.Sheets("Output")
If Not copyFrom Is Nothing Then
'~~> Copy and paste to some sheet
copyFrom.Copy SomeSheet.Rows(1)
'After copying, delete the unwanted columns (OPTIONAL)
End If
End Sub
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.