Я создаю функцию, более похожую на 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.
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
Ниже приведен собственный код с комментариями. Извините, я не зашел так далеко, чтобы проверить, может ли он на самом деле делать то, что вы хотите, если это будет исправлено.
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