2015-10-02 3 views
-1

Я сейчас в процессе анализа данных из Excel и хотел бы сделать сравнения данных в столбце A и столбце B, идентифицируя повторяющиеся данные. Я использую следующий код:Сравнение данных из столбца A и столбца B Как только

Sub Find_Matches() 
Dim CompareRange As Variant, x As Variant, y As Variant 
Set CompareRange = Range("c2", Range("c2").End(xlUp)) 

For Each x In Selection 
    For Each y In CompareRange 
     If x = y Then x.Offset(0, 1) = x 
    Next y 
Next x 
End Sub 

Этот код был взят из MSDN, поэтому, если он находит соответствие в колонке C против колонка А, он будет отображать совпадающее число в колонке B. По большей части это делает то, что мне нужно. Однако я хочу изменить этот код, чтобы он соответствовал только одному числу в списке.

Пример того, что в данный момент делает код:

A2 B2 C2 
1 1 1 
1 1 2 
1 1 3 

Так, по существу, так как число 1 появляется один раз в колонке C, Колонка А продолжает находить совпадения.

Что я хотел бы это сделать, это:

A2 B2 C2 
1 1 1 
1  2 
1  3 

Так, так как число 1 появляется только в колонке C один раз, он должен быть согласован только один раз против чисел в колонке А.

I Предполагая, что это, вероятно, что-то простое, но я не могу определить логику. Может ли кто-нибудь указать мне в правильном направлении, пожалуйста?

+0

Я могу понять, почему этот вопрос получил нижний предел. Когда вы говорите что-то вроде «я не могу определить логику», вам действительно следует следовать за ней «и вот что я пробовал ...» И да, вы разместили какой-то код, но он выглядит как немного больше, чем вырезать и вставить из MSDN. Тем не менее, вы, вероятно, чувствуете, что пытались удовлетворить дух этикета вопросов, поэтому я отправил вам ответ. – Ambie

+0

@Ambie, Большое спасибо за ваш ответ и мои извинения, если вопрос был за пределами обычного этикета. Я совершенно не знаком с VBA, поэтому код, который я использовал, был взят с веб-сайта MSDN, и, к сожалению, я не был уверен, с чего начать; будьте уверены, что я трал через потоки Stackoverflow в поисках разрешения. Перемещение, спасибо за код, указанный ниже. Я попытался реализовать его в текущей форме, но получаю ошибку несоответствия типа. Я попытался исправить ошибку, чтобы отлаживать, но затем получить ожидаемую ошибку массива. Я все еще возился, но еще раз спасибо! –

+0

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

ответ

1

Тестирование дубликатов может быть простым или сложным в зависимости от того, насколько быстро вы хотите, чтобы ваша процедура была и насколько велики наборы данных.

Я лично одобряю объект Collection, потому что он имеет уникальный ключ и тестирование на наличие этого ключа очень быстро, особенно если набор данных большой. Уникальный тест выполняется, если код вызывает ошибку при опросе Collection для конкретного ключа. Некоторые из них философски возражают против тестирования ошибок - я должен сказать, что я один, поэтому я фактически предпочитаю объект Dictionary, но для задачи это обыденное, я не буду выполнять шаги, чтобы ссылаться на это.

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

Const SOURCE_COL As String = "A" 
Const SOURCE_START_ROW As Long = 2 
Const COMPARE_COL As String = "C" 
Const COMPARE_START_ROW As Long = 2 
Const OUTPUT_COL As String = "B" 

Dim ws As Worksheet 
Dim sourceValues As Variant 
Dim compareValues As Variant 
Dim outputValues() As Variant 
Dim sourceIndex As Long 
Dim compareIndex As Long 
Dim uniques As Collection 
Dim val As Variant 
Dim key As String 
Dim exists As Variant 

Set ws = ThisWorkbook.Worksheets("Sheet1") 
sourceValues = ws.Range(ws.Cells(SOURCE_START_ROW, SOURCE_COL), _ 
         ws.Cells(Rows.Count, SOURCE_COL).End(xlUp)).Value2 

compareValues = ws.Range(ws.Cells(COMPARE_START_ROW, COMPARE_COL), _ 
         ws.Cells(Rows.Count, COMPARE_COL).End(xlUp)).Value2 

Set uniques = New Collection 
ReDim outputValues(1 To UBound(sourceValues, 1), 1 To 1) 

For sourceIndex = 1 To UBound(sourceValues, 1) 

    val = sourceValues(sourceIndex, 1) 
    key = CStr(val) 
    exists = Empty 
    On Error Resume Next 
    exists = uniques(key) 
    On Error GoTo 0 

    If IsEmpty(exists) Then 

     For compareIndex = 1 To UBound(compareValues, 1) 
      If val = compareValues(compareIndex, 1) Then 
       outputValues(sourceIndex, 1) = val 
       uniques.Add val, key 
       Exit For 
      End If 
     Next 

    End If 

Next 

ws.Cells(SOURCE_START_ROW, OUTPUT_COL).Resize(UBound(outputValues, 1)).Value = outputValues 
+0

Привет Ambie, согласно комментарий выше, сообщение об ошибке я получаю является: Run-Time Error '13': Тип Несовпадение Ошибка на Ln 27 «Redim outputValues ​​(1 Для UBound (sourceValues, 1) , 1 до 1)) « На этом этапе я изменил значение sourceValues ​​на значение Integer (не уверен, почему? Я просто играл), а затем получил ошибку« Ожидаемый массив ». Я занимаюсь поиском в Интернете между MSDN и SO, пробую разные предложения, но безрезультатно. Еще раз большое спасибо за помощь. –

+0

Итак, это проблема с переменной 'sourceValues'. Скорее всего, вариант пуст. Проверьте константы 'SOURCE_COL' и' SOURCE_START_ROW' правильные - я установил их в ячейку A2. Затем проверьте, что на листе фактически есть некоторые значения в столбце 'SOURCE_COL'. Наконец, измените на две строки 'sourceValues' и' compareValues' от '... Rows.Count ...' до '... ws.Rows.Count ...' – Ambie

+0

Я изменил 'SOURCE_COL' и'SOURCE_START_ROW' для A1, то же для двух других констант (C1), а также для добавления 'ws.' до' Rows.Count' в обоих случаях. Проблема все еще остается, к сожалению. Не знаете, что происходит неправильно, поскольку данные присутствуют на листе и находятся в правильном формате? Кроме того, это только сравнение с значением 1? Невозможно ли проанализировать все числа в WS для сравнения с использованием объекта 'collection'? –

Смежные вопросы