我已经在这个问题上停留了两周,我正在就下一步的工作寻求帮助和指导,希望最终能找到解决方案。通过该网站进行搜索提供了很多很棒的解决方案,但我无法正常工作。
任务:
通过A和B列搜索位于K3和L4列的搜索条件
如果存在匹配项,请将列D-F和N3-P3复制粘贴到新表(K9-P9)中
我正在尝试做的视觉屏幕截图:
当前代码:
Option Explicit
Dim base_Position, reverse__BaseDirection As Range
Dim searchCol_AB, rangeUnion_Copy, rangeUnion_Paste As Range
Dim Cell As Object
Dim wsSyn As Worksheet
Set wsSyn = Sheets("Syn_Calc")
Set base_Position = wsSyn.Range("K3")
Set reverse__BaseDirection = wsSyn.Range("L4")
searchCol_AB = wsSyn.Range("A3:B100")
Set rangeUnion_Copy = Union(Cells(, 4), Cells(, 5), Cells(, 6))
Set rangeUnion_Paste = Union(Cells(, 11), Cells(, 12), Cells(, 13))
For Each Cell In searchCol_AB
If Cell.Value = UCase(base_Position) And UCase(reverse__BaseDirection) Then
rangeUnion_Copy.Copy rangeUnion_Paste.Address
End If
Next
End Sub
问题:
我不确定当前使用的解决方案是否可以执行我想要的操作。我认为使用Ucase可能会有更好的选择。
注意:由于我无法使第一部分正常工作,因此我尚未包括从N3:P3复制数据的代码。
任何帮助将不胜感激。
预先感谢 四月
答案 0 :(得分:0)
If Cell.Value = UCase(base_Position) And UCase(reverse__BaseDirection) Then
以上语法是错误的,但您没有提供足够的信息来提供解决方案,仅是建议。
'If the text in base_Position equals Cell.Value and the text in reverse__BaseDirection equals Cell.Value
'this is unlikely because Cell.Value probably shouldn't be equal to both
If Cell.Value = UCase(base_Position) And Cell.Value = UCase(reverse__BaseDirection) Then
'If the text in base_Position equals Cell.Value and the text in reverse__BaseDirection equals Cell.Offest(0, 1).Value
'this is likely because Cell.Value equal one and the cell next to it equals the other
If Cell.Value = UCase(base_Position) And Cell.Offset(0, 1).Value = reverse__BaseDirection Then
您的图片中没有出现需要UCase反向__BaseDirection的情况。
无论如何,您都可以看到And语法如何处理多个比较。
还应该将searchCol_AB设置为范围对象。
Set searchCol_AB = wsSyn.Range("A3:B100")
如果第二个解决方案使用Cell.Offest(0,1).Value是正确的,那么您只需要查看A列。Offset将查看B列。
Set searchCol_AB = wsSyn.Range("A3:A100")
把所有东西都弄成这样(见评论)。
Option Explicit
Sub basePositionPairs()
'these only need to be strings, not range objects
Dim base_Position As String, reverse__BaseDirection As String
'you need to specify each one or they end up as default variants
Dim searchCol_AB As Range, rangeUnion_Copy As Range, rangeUnion_Paste As Range
Dim Cell As Range
Dim wsSyn As Worksheet
Set wsSyn = Worksheets("Syn_Calc")
base_Position = UCase(wsSyn.Range("K3").Value)
reverse__BaseDirection = wsSyn.Range("L4").Value
'look through column A and Offset to look at column B
searchCol_AB = wsSyn.Range("A3:A100")
'these full columns will be used with Intersect later
Set rangeUnion_Copy = wsSyn.Range("D:F")
'Start the paste at K9 (only top-left is required)
Set rangeUnion_Paste = wsSyn.Range("K9")
For Each Cell In searchCol_AB
If Cell.Value = base_Position And Cell.Offset(0, 1).Value = reverse__BaseDirection Then
'copy the intersection of the full columns and Cell's row
Intersect(Cell.EntireRow, rangeUnion_Copy).Copy _
Destination:=rangeUnion_Paste
'second copy from N3:P3
wsSyn.Range("N3:P3").Copy _
Destination:=rangeUnion_Paste.Offset(0, 4)
'advance rangeUnion_Paste down one row
Set rangeUnion_Paste = rangeUnion_Paste.Offset(1, 0)
End If
Next
End Sub
答案 1 :(得分:0)
请在您自己的代码下方找到完整注释。抱歉,我无法检查如果更正后它是否真的可以执行您想要的操作。
Sub CurrentCode()
Dim wsSyn As Worksheet
' Dim base_Postion, reverse__BaseDirection As Range
Dim base_Position, reverse__BaseDirection As Range
Dim searchCol_AB, rangeUnion_Copy, rangeUnion_Paste As Range
Dim Cell As Object
Set wsSyn = Sheets("Syn_Calc")
' Since base_Position is a variant the line below assigns a range to it.
Set base_Position = wsSyn.Range("K3")
' reverse__BaseDirection is declared as a range.
' Therefore this cariable is assigned a range as well
Set reverse__BaseDirection = wsSyn.Range("L4")
' ==================================================
' The above concept is probably wrong.
' If you wish to search for the values in K3 and L4
' you should have declared both variables as Strings or Variants
' and assigns the respective ranges' Values to them, such
' base_Position = wsSyn.Range("K3").Value
' ==================================================
' searchCol_AB is declared as a Variant and can therefore be assigned anything.
' If you wanted to assign a range to it, the Set statement would be required, like
' Set searchCol_AB = wsSyn.Range("A3:B100")
' since you omit the Set statement VBA will presume that you mean to
' assign the property of wsSyn.Range("A3:B100").
' Since you don't specify which property you mean, VBA will assign
' the default property which is Value.
searchCol_AB = wsSyn.Range("A3:B100")
' ==================================================
' The above facts propbably don't fit your intentions.
' Since searchCol_AB is intended to be searched it should be a range.
' Therefore: Dim searchCol_AB As Range
' and Set searchCol_AB = wsSyn.Range("A3:B100")
' ==================================================
' rangeUnion_Copy is dimensioned as a Variant
' Yes, you can assign a range object to it but why not declare it as a Range?
Set rangeUnion_Copy = Union(Cells(, 4), Cells(, 5), Cells(, 6))
Set rangeUnion_Paste = Union(Cells(, 11), Cells(, 12), Cells(, 13))
' ==================================================
' Cells(, 4) misses the row number.
' VBA will correct the error and insert 1 instead.
' Therefore, Union(Cells(, 4), Cells(, 5), Cells(, 6))
' is equivalent to Union(Cells(1, 4), Cells(1, 5), Cells(1, 6))
' is equivalent to Range("D1:F1")
' Application.Union creates a range consisting of incontiguous cells
' like Union(Cells(1, 4), Cells(1, 6))
' Range("D1:F1") is just a normal range, not a Union.
' you might use Set rangeUnion_Copy = Range(Cells(1, 4), Cells(1, 6))
' if you need to change thr rows in a loop that might look like
' Set rangeUnion_Copy = Range(Cells(R, 4), Cells(R, 6))
' where R is the For ... Next loop counter
' ==================================================
' your code fails on the next line because
' searchCol_AB holds the values of range wsSyn.Range("A3:B100"),
' not the range itself.
For Each Cell In searchCol_AB
' ==================================================
' A range can have many cells.
' the smallest range has a single cell.
' Ergo, a cell is a range.
' True, a range is an object.
' By declaring Cell as an Object you are employing what
' is called "late binding", meaning VBA only finds out
' which kind of object (Range) it is when it is used.
' You might find late binding beyond the scope of your current
' knowledge and therefore declare a range as a range for the time being.
' ==================================================
If Cell.Value = UCase(base_Position) And UCase(reverse__BaseDirection) Then
' base_Position is a variable of variant type to which a range was assigned.
' Therefore base_Position is a range object.
' UCase([Range object]) is impossible.
' Therefore VBA executes UCase([Range_object.Value])
' That gives the result you intend but in a way you didn't understand.
' Better to avoid the use of default properties.
' ==================================================
' If Cell.Value = UCase(base_Position) And UCase(reverse__BaseDirection) Then
' is a common logical error. The correct syntax is
' If Cell.Value = UCase(base_Position) And Cell.Value = UCase(reverse__BaseDirection) Then
' some programmers would add parentheses for better clarity, thus:-
' If (Cell.Value = UCase(base_Position)) And (Cell.Value = UCase(reverse__BaseDirection)) Then
' Note that each expressions is evaluated to True or False.
' ==================================================
' The Copy command requires specification of a Destination cell.
' Destination is either a single cell (better, since less prone to errors)
' or a range of equal size to the copied range.
' It can't be a string, such as rangeUnion_Paste.Address
' (The Address property always holds a String)
rangeUnion_Copy.Copy rangeUnion_Paste.Address
' ==================================================
' The way you have set rangeUnion_Paste it is of equal size
' to rangeUnion_Copy. Therefore either of the following would work.
' rangeUnion_Copy.Copy Destination:= Range(rangeUnion_Paste.Address)
' rangeUnion_Copy.Copy Destination:= rangeUnion_Paste
' rangeUnion_Copy.Copy Destination:= rangeUnion_Paste.Cells(1)
' ==================================================
End If
Next Cell ' better specify which "Next" is called
End Sub