VBA: Есть два набора пользовательских входных данных. Нужно проверить, реплицируются ли какие-либо последовательные *пары* входных данных между двумя наборами, как я могу это сделать?

#excel #vba

Вопрос:

Я постараюсь свести это к общему смыслу. У меня есть лист Excel с двумя различными наборами ячеек, которые требуют ввода пользователем. В первом наборе 8 входов, во втором-5.

Допустим, наборы данных Один и два содержат вводимые пользователем буквы, например так:

 DataSetOne(0) = A DataSetOne(1) = B DataSetOne(2) = C DataSetOne(3) = D DataSetOne(4) = E DataSetOne(5) = F DataSetOne(6) = G DataSetOne(7) = H  DataSetTwo(0) = A DataSetTwo(1) = B DataSetTwo(2) = H DataSetTwo(3) = D DataSetTwo(4) = C  

Мне нужно проверить два набора на наличие реплицированных данных. Однако меня волнует только то, повторяются ли какие-либо два параллельных значения, а не только отдельные значения.

Например, первый набор данных содержит семь последовательных «пар» входных данных:

 Pair 1 = A, B Pair 2 = B, C Pair 3 = C, D Pair 4 = D, E Pair 5 = E, F Pair 6 = F, G Pair 7 = G, H  

И аналогично, второй набор данных содержит четыре дополнительные пары данных:

 Pair 8 = A, B Pair 9 = B, H Pair 10 = H, D Pair 12 = D, C  

Мне нужно посмотреть, совпадает ли какая-либо из этих пар. Порядок не имеет значения — до тех пор, пока две пары имеют одинаковые два отдельных входа, мне нужно принять решение в одну сторону. Если пары не содержат обоих совпадающих значений , то мое решение идет другим путем.

Поэтому в приведенном выше примере мне нужен мой код для распознавания совпадений между:

  • Пара 1 и пара 8
  • Пара 3 и пара 12

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

Комментарии:

1. Являются ли первые 2 записи в наборе данных 2 не последовательными?

2. Ваш вопрос уже содержит начало ответа: составьте два списка, одну из пар в DataSetOne и одну из них в DataSetTwo . Сохраните пары в виде строк, разделенных символом,который никогда не появится в самих записях,и сначала поместите более раннюю часть пары в алфавитном порядке, чтобы она была уникальной. (т. Е. Сохраните пару 10 как «D, H», а не «H, D», даже если H предшествовал D в списке. Затем просмотрите списки пар, чтобы увидеть, есть ли дубликаты.

3. @Nathan_Sav Извините, я не понимаю, что вы имеете в виду. Теоретически наборы данных могут быть в любом порядке, они зависят от ввода пользователем. Меня волнует только то, появятся ли две записи в любом наборе данных рядом друг с другом. Извините, я, наверное, плохо это объясняю. В моем примере набор A и B повторяется и является последовательным («рядом» друг с другом), поэтому мне нужно это определить. То же самое с C и D, хотя порядок отличается, они находятся «рядом» друг с другом в качестве входных данных.

4. @ChristopherHamkins Спасибо за вклад. Это именно то, что я думаю сделать в своей голове, наверное, я просто борюсь с кодом для этого. В основном, получение цикла для проверки равенства пар/строк.

Ответ №1:

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

Например:

 Public Sub SO70184805_find_duplicates()   Dim DataSetOne(0 To 7) As String  Dim DataSetTwo(0 To 4) As String    Const Delimiter As String = ", "    DataSetOne(0) = "A"  DataSetOne(1) = "B"  DataSetOne(2) = "C"  DataSetOne(3) = "D"  DataSetOne(4) = "E"  DataSetOne(5) = "F"  DataSetOne(6) = "G"  DataSetOne(7) = "H"    DataSetTwo(0) = "A"  DataSetTwo(1) = "B"  DataSetTwo(2) = "H"  DataSetTwo(3) = "D"  DataSetTwo(4) = "C"    Dim PairsOne(0 To 6) As String  Dim PairsTwo(0 To 3) As String    Dim I As Integer  Dim S1 As Variant  Dim S2 As Variant    'Make the lists of pairs  Debug.Print "Pairs from the first list:"  For I = 0 To 6  If (DataSetOne(I) lt; DataSetOne(I   1)) Then  PairsOne(I) = DataSetOne(I) amp; Delimiter amp; DataSetOne(I   1)  Else  PairsOne(I) = DataSetOne(I   1) amp; Delimiter amp; DataSetOne(I)  End If  Debug.Print (PairsOne(I))  Next I    Debug.Print  Debug.Print "Pairs from the second list:"  For I = 0 To 3  If (DataSetTwo(I) lt; DataSetTwo(I   1)) Then  PairsTwo(I) = DataSetTwo(I) amp; Delimiter amp; DataSetTwo(I   1)  Else  PairsTwo(I) = DataSetTwo(I   1) amp; Delimiter amp; DataSetTwo(I)  End If  Debug.Print (PairsTwo(I))  Next I    Debug.Print  Debug.Print ("Duplicates:"):    Dim NumberOfDuplicates As Integer  NumberOfDuplicates = 0  For Each S1 In PairsOne  For Each S2 In PairsTwo  If (S1 = S2) Then  Debug.Print (S1)  NumberOfDuplicates = NumberOfDuplicates   1  End If  Next  Next End Sub  

Это и есть результат:

 Pairs from the first list: A, B B, C C, D D, E E, F F, G G, H  Pairs from the second list: A, B B, H D, H C, D  Duplicates: A, B C, D    

Ответ №2:

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

 Sub datasets()  Dim datasetone(7) As String Dim datasettwo(4) As String Dim dicPairsOne As New Scripting.Dictionary Dim dicPairsTwo As New Scripting.Dictionary Dim l As Long Dim strPair As String  datasetone(0) = "A" datasetone(1) = "B" datasetone(2) = "C" datasetone(3) = "D" datasetone(4) = "E" datasetone(5) = "F" datasetone(6) = "G" datasetone(7) = "H"  datasettwo(0) = "A" datasettwo(1) = "B" datasettwo(2) = "H" datasettwo(3) = "D" datasettwo(4) = "C"  For l = 0 To UBound(datasetone) - 1   strPair = datasetone(l) amp; "," amp; datasetone(l   1)    If Not dicPairsOne.Exists(strPair) Then  dicPairsOne.Add strPair, 1  Else  dicPairsOne(strPair) = dicPairsOne(strPair)   1  End If    If Not dicPairsOne.Exists(StrReverse(strPair)) Then  dicPairsOne.Add StrReverse(strPair), 1  Else  dicPairsOne(StrReverse(strPair)) = dicPairsOne(StrReverse(strPair))   1  End If  Next l  For l = 0 To UBound(datasettwo) - 1   strPair = datasettwo(l) amp; "," amp; datasettwo(l   1)    If Not dicPairsTwo.Exists(strPair) Then  dicPairsTwo.Add strPair, 1  Else  dicPairsTwo(strPair) = dicPairsTwo(strPair)   1  End If  Next l  For l = 0 To dicPairsOne.Count - 1  If dicPairsTwo.Exists(dicPairsOne.Keys()(l)) Then  Debug.Print dicPairsOne.Keys()(l)  End If Next l  End Sub