#excel #vba
#excel #vba
Вопрос:
Я пытаюсь решить проблему в VBA и после долгого просмотра веб-страниц в поисках решений я действительно надеюсь, что кто-нибудь сможет мне помочь.
На самом деле это не очень сложная задача, но с очень небольшим знанием программирования и VBA, как новичок, я надеюсь, что смогу найти полезный совет или решение с помощью сообщества.
Итак, моя проблема заключается в следующем:
У меня есть таблица с 3 столбцами, первый заполнен числом для использования в качестве идентификатора. Столбцы 2 и 3 имеют разные значения, которые необходимо сравнить:
Что я хотел бы сделать, так это выбрать диапазон строк столбцов столбцов 2 и 3 на основе одного и того же идентификатора. После того, как я выбрал соответствующие диапазоны столбцов, я хочу сравнить, совпадает ли одно имя столбца 2 с одним именем столбца 3.
Таким образом, нет необходимости совпадать со всеми именами желаемых диапазонов столбцов. Достаточно одного совпадения имен. Если имя совпадает, оно должно автоматически заполнить новый столбец «результат» с 1 для совпадения (0 для отсутствия совпадения).
У вас есть идея, как я могу выбрать определенные ячейки столбца на основе идентификатора?
Dim ID_counter As Long
ID_counter = 1
If Cell.Value = ID_counter IN Range("Column1")
Then Range("Column2").Select
AND Range("Column3").Select
WHERE ID_counter is the same
In Column4 (If one Cell.Value IN Range("Column2-X:Column2-Y")
IS IDENTICAL TO Range("Column3-X:Column3-Y"), return 1, else return 0
End Sub
Заранее большое спасибо за вашу помощь!
Комментарии:
1. Я не думаю, что для этого вам нужен VBA (конечно, не нужно ничего выбирать). Я думаю, это можно сделать с помощью формулы COUNTIFS.
2. @SJR Не уверен в этом, потому что диапазоны отличаются по размеру, поэтому я думаю, что необходимо выбрать диапазон. И набор данных, который у меня есть, слишком длинный, чтобы решить это вручную…
3. Вы имеете в виду, что столбцы B и C имеют разную длину? Я тоже не думаю, что это имеет значение. Просто включите проверку того, что B не является пустым.
4. @SJR, некоторые ячейки B на самом деле пустые, например B4, B6 и B9, как показано на рисунке. Длина B и C не отличается, но на основе идентификатора в столбце A диапазон B и C, который необходимо сравнить, каждый раз отличается… надеюсь, это понятно…
5. Возможно, опубликовать образец немного большего размера? Почему нет 1 в строке 3 или 10 — это важно?
Ответ №1:
Это работает для вашего примера, поэтому, возможно, вы можете обобщить его. Формула в D2
=IF(A2=A1,"",MAX(IF($A$2:$A$10=A2,COUNTIF($B$2:$B$10,$C$2:$C$10))))
и является формулой массива, поэтому его необходимо подтвердить с помощью CTRL, SHIFT и ENTER.
Комментарии:
1. Спасибо @SJR! Ваше решение действительно работает, хотя в какой-то момент оно не только выдает 0 = not true, 1 = true, но по какой-то причине оно также выдает число 1087… Должно быть связано с базовыми данными. Большое спасибо за вашу помощь!!
Ответ №2:
Альтернатива массива с помощью Match()
функции
Этот подход сравнивает строковые элементы столбцов B
и C
, передавая два массива (именованные b
, c
) в качестве аргументов (см. раздел c.f. [1]
):
chk = Application.Match(b, c, 0)
Результирующий chk
массив отражает все результаты поиска элементов первого массива через (основанные на 1) индексы позиций соответствующих элементов во втором массиве.
Не-результаты возвращают Error 2042
значение (см. раздел ); предполагается, что данные сгруппированы по [2]b)
идентификатору.
Sub OneFindingPerId()
'[0]get data
Dim data: data = Sheet1.Range("A1:D10") ' << project's sheet Code(Name)
Dim b: b = Application.Index(data, 0, 2) ' 2nd column (B)
Dim c: c = Application.Index(data, 0, 3) ' 3rd column (C)
'[1]get position indices of identic strings via Match() function
Dim chk: chk = Application.Match(b, c, 0) ' found row nums of a items in b
'[2]loop found position indices (i.e. no error 2042)
Dim i As Long
For i = 2 To UBound(chk) ' omit header row
'a) define start index of new id and initialize result with 0
If data(i, 1) <> data(i - 1, 1) Then
Dim newId As Long: newId = i
data(newId, 4) = 0
End If
'b) check if found row index corresponds to same id
If Not IsError(chk(i, 1)) Then ' omit error 2042 values
If data(chk(i, 1), 1) = data(i, 1) Then ' same ids?
If data(newId, 4) = 0 Then data(newId, 4) = 1 ' ~> result One if first occurrence
End If
End If
Next i
'[3]write results
Sheet1.Range("A1").Resize(UBound(data), UBound(data, 2)) = data
End Sub
Ответ №3:
Сначала введите эту пользовательскую функцию в стандартный модуль:
Public Function zool(r1, r2, r3) As Integer
Dim i As Long, v1 As Long, v2 As String
Dim top As Long, bottom As Long
zool = 0
v1 = r1.Value
top = r1.Row
' determine limits to check
For i = top To 9999
If v1 <> r1.Offset(i - top, 0).Value Then
Exit For
End If
Next i
bottom = i - 1
For i = top To bottom
v2 = Cells(i, "B").Value
If v2 <> "" Then
For j = top To bottom
If v2 = Cells(j, "C").Value Then zool = 1
Next j
End If
Next i
End Function
Затем в D2 введите:
=IF(OR(A2="",A2=A1),"",zool(A2,B2,C2))
и скопируйте вниз:
(это предполагает, что данные сначала были отсортированы или упорядочены по идентификатору)
Комментарии:
1. к вашему сведению, альтернатива массиву путем
Match()
сравнения обоих массивов столбцов 🙂2. @Gary’Sstudent Спасибо за вашу помощь! Очень признателен!