Как сравнить два массива по нескольким столбцам (строка со строкой)

У меня есть две таблицы в одной электронной таблице. оба имеют одинаковые столбцы - Имя, Город, Провинция. Моя цель - сравнить оба, и если три из трех значений в строке совпадают, то вытяните "Да", если нет, вытащите "Нет". Я сравниваю строки со строками в этих двух таблицах (не случайные ячейки).

Я не нашел подходящей формулы, поэтому, вероятно, нужно ее закодировать.

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

Sub Compare()
    Dim row As Integer
    row = 2
    Dim firstColumn As String
    firstColumn = "H"
    Dim lastColumn As String
    lastColumn = "J"
    Dim resultsColumn As String
    resultsColumn = "M"
    Dim isFoundText As String
    isFoundText = "YES"
    Dim isNotFoundText As String
    isNotFoundText = "NO"

    Do While Range("B" & row).Value <> ""

        Dim startChar As Integer
        startChar = Asc(firstColumn)
        Dim endChar As Integer
        endChar = Asc(lastColumn)
        Dim i As Integer
        Dim hasMatch As Boolean
        hasMatch = False

        For i = startChar To endChar
            If Range(Chr(i) & row).Value = Range(Chr(i + 1) & row).Value Then
                hasMatch = True
            End If
            If Range(Chr(startChar) & row).Value = Range(Chr(i + 1) & row).Value Then
                hasMatch = True
            End If
        Next i

        If (hasMatch) Then
            Range(resultsColumn & row).Value = isFoundText
        Else
            Range(resultsColumn & row).Value = isNotFoundText
        End If
        row = row + 1
    Loop

End Sub
Преобразование HTML-таблицы в профессиональный документ Excel
Преобразование HTML-таблицы в профессиональный документ Excel
Это самый простой способ создания Excel из HTML-таблицы.
Импорт excel в laravel в базу данных
Импорт excel в laravel в базу данных
Здравствуйте, дорогой читатель, в этой статье я расскажу практическим и быстрым способом, как импортировать файл Excel в вашу базу данных с помощью...
0
0
308
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Добавляем отступы, чтобы мы могли прочитать это:

Sub Compare()
    Dim firstColumn As String, lastColumn As String, resultsColumn As String, isFoundText As String, isNotFoundText As String, 
    Dim row As Integer, startChar As Integer, endChar As Integer, i As Integer
    Dim hasMatch As Boolean
    row = 2
    firstColumn = "H"
    lastColumn = "J"
    resultsColumn = "M"
    isFoundText = "YES"
    isNotFoundText = "NO"
    Do While Range("B" & row).Value <> ""
        startChar = Asc(firstColumn)
        endChar = Asc(lastColumn)
        hasMatch = False
        For i = startChar To endChar
            If Range(Chr(i) & row).Value = Range(Chr(i + 1) & row).Value Then
                hasMatch = True
            End If
            If Range(Chr(startChar) & row).Value = Range(Chr(i + 1) & row).Value Then
                hasMatch = True
            End If
        Next i
        If (hasMatch) Then
            Range(resultsColumn & row).Value = isFoundText
        Else
            Range(resultsColumn & row).Value = isNotFoundText
        End If
        row = row + 1
    Loop
End Sub

Теперь, чтобы начать вносить изменения... Похоже, вы можете очистить свой код с помощью более простого цикла, например (непроверенного):

Dim lri as long, lrj as long, i as long, j as long
lri = cells(rows.count,"H").end(xlup).row
lrj = range(columns("B"),columns("D")).Find("*", , , , xlByRows, xlPrevious).Row
For i = 2 to lri
    For j = 2 to lrj
        If Cells(j,"B").Value = cells(i,"J").Value AND Cells(j,"C").Value = Cells(i,"I").Value AND Cells(j,"D").Value = Cells(i,"H").Value Then
        Cells(i,"M").Value = "Yes" 'don't need variables for these anymore
        'may want to put an exit to j loop if True
    Else 
        Cells(i,"M").Value = "No"
    End If
    row = row + 1
Loop

Это сравнивает значения в каждой из ячеек с соответствующим разделом (от B до J, от C до I и от D до H).

Большое спасибо Кириллу за помощь в очередной раз! У меня эта строка выделена Set rng = Cells(row, "H") с комментарием «Ошибка определения приложения или объекта» - не могли бы вы посоветовать, что я могу исправить в коде?

Irina 29.05.2019 20:19

@Irina странно, что я только что получил ваш комментарий, несмотря на то, что вы отправили его 44 минуты назад, а я обновил свой ответ 24 минуты назад. Пожалуйста, посмотрите мое обновление, в котором используются петли для i и j.

Cyril 29.05.2019 21:05

Спасибо Кирилл! Код спотыкается об это lrj = last(1, Range(Columns("B"), Columns("D"))), говоря, что ~last~ здесь не определен

Irina 29.05.2019 21:18

@Irina Взгляните на обновление lrj... я использовал .Find("*", , , , xlByRows, xlPrevious).Row

Cyril 29.05.2019 22:04

@Irina Рад, что это сработало для вас ... искал другой ваш пост после проблем с неработающими формулами. надеюсь, это соответствует всем требованиям (плохой рейтинг на момент принятия). дайте мне знать, если есть что-то еще не так с этим ответом

Cyril 29.05.2019 22:36
Ответ принят как подходящий

Для этого типа задач лучше переместить эти данные в Массивы вариантов и выполнить цикл по ним (много быстрее). Кроме того, сопоставление с образцом может быть обобщено вне данных, что делает решение более пригодным для повторного использования и разделение задач.

Функция сравнения

Private Function CompareColumns(Table1 As Range, Table2 As Range, ColPairs() As Variant, Optional IsMatch As Variant = True, Optional NoMatch As Variant = False) As Variant
    Dim Table1Data As Variant
    Dim Table2Data As Variant
    Dim OutputData As Variant
    Dim rw1 As Long, rw2 As Long
    Dim Col As Long
    Dim FoundMatch As Boolean

    ' Move data to variant arrays
    Table1Data = Table1.Value2
    Table2Data = Table2.Value2

    ' Size return array
    ReDim OutputData(1 To UBound(Table1Data, 1), 1 To 1)

    ' Loop the arrays
    For rw2 = 1 To UBound(Table2Data, 1)
        OutputData(rw2, 1) = NoMatch ' initialise
        For rw1 = 1 To UBound(Table1Data, 1)
            FoundMatch = True
            For Col = LBound(ColPairs, 1) To UBound(ColPairs)
                If Table1Data(rw1, ColPairs(Col, 1)) <> Table2Data(rw2, ColPairs(Col, 2)) Then
                    FoundMatch = False ' column not a match, move to next row
                    Exit For
                End If
            Next
            If FoundMatch Then ' found a match
                OutputData(rw2, 1) = IsMatch
                Exit For ' exit Table2 loop when match found
            End If
        Next
    Next
    ' Return result to caller
    CompareColumns = OutputData
End Function

Используйте это так

Sub Compare()
    Dim ws As Worksheet
    Dim Table1 As Range
    Dim Table2 As Range
    Dim Output As Range
    Dim OutputTable As Variant
    Dim ColPairs() As Variant

    Set ws = ActiveSheet ' update to suit your needs

    ' Set up ranges by any means you choose
    With ws
        Set Table1 = .Range(.Cells(2, 1), .Cells(.Rows.Count, 3).End(xlUp))
        Set Table2 = .Range(.Cells(2, 10), .Cells(.Rows.Count, 8).End(xlUp))
        Set Output = .Cells(2, 13).Resize(Table2.Rows.Count, 1)
    End With

    'Specify columns to compare
    ReDim ColPairs(1 To 3, 1 To 2)
    ColPairs(1, 1) = 1: ColPairs(1, 2) = 3
    ColPairs(2, 1) = 2: ColPairs(2, 2) = 2
    ColPairs(3, 1) = 3: ColPairs(3, 2) = 1

    ' Call Match function
    OutputTable = CompareColumns(Table1, Table2, ColPairs, "Yes", "No")

    ' Place Output on sheet
    Output = OutputTable
End Sub

Другие вопросы по теме