Как удалить повторяющиеся элементы из двух столбцов в Excel - PullRequest
0 голосов
/ 31 января 2020

У меня есть два столбца, например:

A      B

1      2

1      3

1      5

3      4

2      1

4      3

Я хочу, чтобы вывод получился следующим образом:

A      B

1      2

1      3

1      5

3      4

Я хочу удалить данные, которые повторяются от 1 столбца до еще один. Есть ли в Excel какая-либо функция для этого?

Ответы [ 4 ]

0 голосов
/ 31 января 2020

Если у вас есть формула массива Dyanmi c UNIQUE, используйте это:

=TRIM(MID(SUBSTITUTE(UNIQUE(IF($A$1:$A$6<$B$1:$B$6,$A$1:$A$6,$B$1:$B$6)&"|"&IF($A$1:$A$6>=$B$1:$B$6,$A$1:$A$6,$B$1:$B$6)),"|",REPT(" ",999)),(COLUMN(A1)-1)*999+1,999))

Поместите это в первую выходную ячейку и перетащите на один столбец.

enter image description here

0 голосов
/ 31 января 2020

Это может вам помочь

Option Explicit

Sub test()

    Dim LastRow As Long, i As Long, j As Long
    Dim strA_I As String, strB_I As String, strA_J As String, strB_J As String, strDelete As String
    Dim varDelete As Variant

    strDelete = ""

    With ThisWorkbook.Worksheets("Sheet1")

        LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row

        For i = 1 To LastRow

            strA_I = .Range("A" & i).Value
            strB_I = .Range("B" & i).Value

            For j = i + 1 To LastRow

                strA_J = .Range("A" & j).Value
                strB_J = .Range("B" & j).Value

                If ((strA_I = strA_J) Or (strA_I = strB_J)) And ((strB_I = strA_J) Or (strB_I = strB_J)) Then

                    If strDelete = "" Then
                        strDelete = j
                    Else
                        strDelete = strDelete & "," & j
                    End If

                End If

            Next j

        Next i

        varDelete = Split(strDelete, ",")

        For i = LastRow To 1 Step -1

            For j = LBound(varDelete) To UBound(varDelete)

                If i = varDelete(j) Then

                    Rows(i).EntireRow.Delete
                    Exit For

                End If

            Next j

        Next i

    End With

End Sub
0 голосов
/ 31 января 2020

Это на самом деле довольно легко сделать, , но .... Есть небольшая проблема, У нас нет полного определения проблемы.

"Я хочу удалить данные, которые повторяются из одного столбца в другой."

Что происходит, когда левый и правый столбцы идентичны? В настоящее время это не определено.


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

Если вы сохранили первую пару, то вы также сохраните и эту пару, поэтому поменяйте местами столбцы, чтобы построить обратную строку и поместить ее в Второй элемент массива.

Перейти к следующему ряду. Проверьте на эквивалентность, если хотите, создайте свою строку. Добавляйте строку в массив только в том случае, если она уникальна.

Создайте обратную строку и добавьте ее в массив, если она уникальна.

Удалите строку, если в массиве существует какая-либо строка.

Повторите все до самого верха.

0 голосов
/ 31 января 2020

Следующий код загрузит Range в массив. Затем он будет по очереди go проходить через каждую строку массива, сортировать значения в строке и сравнивать их с уже обработанными строками.

Если он новый, он добавляется в выходные данные и обрабатывается Ряды - если он уже существует, он игнорируется. Наконец, он выведет массив обратно в исходный диапазон

. Это немного сложнее, чем нужно, чтобы сохранить порядок элементов в первой строке для каждой комбинации - a более простым способом было бы отсортировать столбцы каждой строки по порядку, а затем просто использовать «Удалить дубликаты».

Код ArrayDimension набран из здесь , поэтому пожалуйста, подумайте о том, чтобы прогуляться, чтобы набрать Emeka Eya

Sub RemoveDuplicateRows(Target As Range, Optional Permutations As Boolean = False)
'Target: Range to remove duplicate rows from
'Permutations: If FALSE then ignore the order of elements in the row
    Dim InputArray As Variant, ArrayPointer As Long

    If Permutations Then
        'This is just a normal RemoveDuplicates
        ReDim InputArray(0 To (Target.Columns.Count - 1))

        For ArrayPointer = 1 To Target.Columns.Count
            InputArray(ArrayPointer - 1) = ArrayPointer
        Next ArrayPointer

        Target.RemoveDuplicates Columns:=InputArray, Header:=xlNo
    Else
        Dim RowArray As Variant, ArrayBinding As Long
        Dim OutputArray As Variant, OutputRow As Variant
        Dim ProcessedRows As Variant, CurrentRow As String
        Dim TransferColumn As Long

        InputArray = Target.Value
        ArrayBinding = LBound(InputArray, 1)
        OutputRow = ArrayBinding

        'Empty array the same size as the input, and a 1D array the same height
        ReDim OutputArray(LBound(InputArray, 1) To UBound(InputArray, 1), LBound(InputArray, 1) To UBound(InputArray, 1))
        ReDim ProcessedRows(LBound(InputArray, 1) To UBound(InputArray, 1))

        For ArrayPointer = ArrayBinding To UBound(InputArray, 1)
            'Get 1D array containing just this specific row
            RowArray = Application.Transpose(Application.Transpose(Application.Index(InputArray, ArrayPointer + 1 - ArrayBinding, 0)))

            'Sort the Array and Flatten into a string for Searching
            CurrentRow = SortArrayAndFlatten(RowArray)

            'If the row is new, then add it
            If UBound(Filter(ProcessedRows, CurrentRow)) < 0 Then
                For TransferColumn = LBound(RowArray) To UBound(RowArray)
                    OutputArray(OutputRow, TransferColumn) = RowArray(TransferColumn)
                Next TransferColumn
                'Mark the row as already processed
                ProcessedRows(OutputRow) = CurrentRow
                OutputRow = OutputRow + 1
            End If
        Next ArrayPointer

        Target.Clear
        Target.Value = OutputArray
    End If
End Sub

Private Function SortArrayAndFlatten(ByVal TargetArray As Variant) As String
'This will output a String of the Sorted Elements of the Array
    If Not IsArray(TargetArray) Then Exit Function
'Only work on 1D arrays
    If ArrayDimension(TargetArray) > 1 Then Exit Function

    Dim OuterLoop As Long, InnerLoop As Long, StoppingPoint As Long, HoldingBucket As Variant, NoSwaps As Boolean
    StoppingPoint = LBound(TargetArray) + 1
    For OuterLoop = UBound(TargetArray) To StoppingPoint Step -1
        NoSwaps = True
        For InnerLoop = OuterLoop To StoppingPoint Step -1
            If TargetArray(InnerLoop) > TargetArray(InnerLoop - 1) Then
                'Swap the elements
                HoldingBucket = TargetArray(InnerLoop)
                TargetArray(InnerLoop) = TargetArray(InnerLoop - 1)
                TargetArray(InnerLoop - 1) = HoldingBucket
                NoSwaps = False
            End If
        Next InnerLoop
        If NoSwaps Then Exit For
    Next OuterLoop
    SortArrayAndFlatten = Join(TargetArray, "|")
End Function

Function ArrayDimension(ByRef ArrayX As Variant) As Long
    Dim i As Long, a As String, arDim As Long
    On Error Resume Next
    i = 0
    Do
        a = CStr(ArrayX(0, i))
        If Err.Number > 0 Then
            arDim = i
            On Error GoTo 0
            Exit Do
        Else
             i = i + 1
        End If
    Loop
    If arDim = 0 Then arDim = 1
    ArrayDimension = arDim
End Function
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...