Критерии поиска VBA, если найдено совпадение, скопировать и вставить 2 разных набора данных в новую таблицу

Я создаю функцию, более похожую на substr, и используя идею @Dave.

function substr_full_word($str, $start, $end){
    $pos_ini = ($start == 0) ? $start : stripos(substr($str, $start, $end), ' ') + $start;
    if(strlen($str) > $end){ $pos_end = strrpos(substr($str, 0, ($end + 1)), ' '); } // IF STRING SIZE IS LESSER THAN END
    if(empty($pos_end)){ $pos_end = $end; } // FALLBACK
    return substr($str, $pos_ini, $pos_end);
}

Ps .: Полное сокращение длины может быть меньше, чем substr.

0
задан Pᴇʜ 6 March 2019 в 10:14
поделиться

2 ответа

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 reverse__BaseDirection.

В любом случае вы можете видеть, как синтаксис And обрабатывает более одного сравнения.

Вы также должны установить searchCol_AB для объекта диапазона.

Set searchCol_AB = wsSyn.Range("A3:B100")

Если второе решение верное с использованием Cell.Offest (0, 1). Значение, вам нужно только просмотреть столбец A. Смещение будет смотреть на столбец 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
0
ответ дан 6 March 2019 в 10:14
поделиться

Ниже приведен собственный код с комментариями. Извините, я не зашел так далеко, чтобы проверить, может ли он на самом деле делать то, что вы хотите, если это будет исправлено.

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
0
ответ дан Variatus 6 March 2019 в 10:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: