#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