Объединить строки ячеек, когда условие соответствует, и удалить дубликаты? - PullRequest
0 голосов
/ 23 марта 2020

Я над головой, но надеюсь, что кто-то может помочь.

Хотел бы, чтобы C3 отображал все строки от C15 до C60 для строк, где столбец E соответствует B3, и удалял дубликаты / отображал только уникальные .

Кроме того, я бы хотел, чтобы D3 отображал строки от D15 до D60 в качестве предыдущего вопроса, однако ячейки потенциально содержат значения, разделенные запятыми - есть ли способ, который я могу сделать, как описано выше, но обрабатывать значения, разделенные запятыми в виде отдельных строк?

снимок экрана и электронная таблица для загрузки .

Заранее спасибо всем, кто взглянул.

Джо

Ответы [ 3 ]

0 голосов
/ 23 марта 2020

Извлечение возможно разделенных уникальных данных

Использование:

Скопируйте код в стандартный модуль и в Excel используйте следующие формулы:

in Ячейка C3 =CritJoe(C$15:C$60,$E$15:$E$60,$B3)

в ячейке D3 =CritJoe(D$15:D$60,$E$15:$E$60,$B3,",")

Код

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose:  Retrieves unique ((comma) separated) (ResultSeparator) data
'           determined by a criteria (Criteria) in a specified column
'           (CriteriaRange) from another specified column (SourceRange)
'           possibly containing (comma) separated (StringSeparator) strings.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function CritJoe(SourceRange As Range, CriteriaRange As Range, _
  Criteria As String, Optional StringSeparator As String = "", _
  Optional ResultSeparator As String = ", ") As String

    Dim vntS            ' Source Array (1-based, 2-dimensional)
    Dim vntC            ' Criteria Array (1-based, 2-dimensional)
    Dim vntSS           ' Source String Array (0-based, 1-dimensional)
    Dim vntR            ' Resulting Array (0-based, 1-dimensional)
    Dim i As Long       ' Source & Criteria Array Elements Counter
    Dim j As Long       ' Resulting Array Elements Counter
    Dim k As Long       ' Source String Array Elements Counter
    Dim UB As Long      ' Current Resulting Array's Upper Bound
    Dim strS As String  ' Current Source String
    Dim strR As String  ' Resulting String

    ' Check if SourceRange and CriteriaRange have the same number of rows and
    ' have the same first row number.
    If SourceRange.Rows.Count <> CriteriaRange.Rows.Count Or _
      SourceRange.Rows(1).Row <> CriteriaRange.Rows(1).Row Then GoTo RowsError
    ' Note:  The relevant data has to be in the first column of each range
    ' if (accidentally) more columns have been selected.

    ' Copy first column of the Ranges to Arrays.
    vntS = SourceRange.Cells(1).Resize(SourceRange.Rows.Count)
    vntC = CriteriaRange.Cells(1).Resize(CriteriaRange.Rows.Count)

    ' Write relevant data to Resulting Array.
    For i = 1 To UBound(vntS)
        ' To avoid "Case/Space issues", "parts" of the following can be used:
        ' If Upper(Trim(vntC(i, 1))) = Upper(Trim(Criteria)) Then
        ' ... instead of the following line:
        If vntC(i, 1) = Criteria Then
            strS = vntS(i, 1)
            If StringSeparator <> "" Then
                ' Write Resulting String to Resulting Array using
                ' StringSeparator.
                GoSub SplitString
            Else
                ' Write Resulting String to Resulting Array without
                ' using StringSeparator.
                GoSub StringToArray
            End If
        End If
    Next

    ' Write relevant data from Resulting Array to Resulting String.
    If IsArray(vntR) Then
        strR = vntR(0)
        If UBound(vntR) > 0 Then
            For j = 1 To UBound(vntR)
                strR = strR & ResultSeparator & vntR(j)
            Next
        End If
    End If

    CritJoe = strR

Exit Function

' Write Resulting String to Resulting Array using StringSeparator.
SplitString:
    vntSS = Split(strS, StringSeparator)
    For k = 0 To UBound(vntSS)
        strS = Trim(vntSS(k))
        GoSub StringToArray
    Next
    Return

' Write Resulting String to Resulting Array.
StringToArray:
    If IsArray(vntR) Then
        ' Handle all except the first element in Resulting Array.
        UB = UBound(vntR)
        For j = 0 To UB
            If vntR(j) = strS Then Exit For
        Next
        If j = UB + 1 Then
            ReDim Preserve vntR(j): vntR(j) = strS
        End If
    Else
        ' Handle only first element in Resulting Array.
        ReDim vntR(0): vntR(0) = strS
    End If
    Return

RowsError:
    CritJoe = "Rows Error!"

End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
0 голосов
/ 23 марта 2020

Как я уже писал, с Power Query, доступным в Excel 2010+, все относительно просто. Это займет больше времени, чтобы набрать шаги, а затем создать его: -).

Все можно сделать из пользовательского интерфейса

  • Удалить столбцы Scene и Video
  • Разделение столбца Cast по разделителю comma
  • Выберите столбцы Location и Cast и Transform/Trim для удаления ненужных пробелов
  • Выберите все три столбца и Remove Rows/Duplicates
  • Group By Recording Block Operation:= All Rows
    • Имя столбца Grouped

enter image description here

  • Добавить пользовательский столбец для расположений: Формула =

    List.Distinct(Table.Column([Grouped],"Location"))

    • запишите имя нового столбца в диалоговое окно

enter image description here

  • Добавить еще один пользовательский столбец для Cast: Formula =

    List.Distinct(Table.Column([Grouped],"Cast"))

enter image description here

  • Выберите двуглавую стрелку вверху из новых столбцов

    • Extract Values из выпадающего списка и выберите разделитель - я использовал Custom --> com ма пробел
  • Закрыть и загрузить в нужное место на листе.

enter image description here

Следует отметить, что эту рабочую книгу можно сохранить в виде файла xlsx.

Для интереса, здесь сгенерирован M-код.

M код

    Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Video", Int64.Type}, {"Scene", Int64.Type}, {"Location", type text}, {"Cast", type text}, {"Recording Block", type text}}),
    #"Removed Columns" = Table.RemoveColumns(#"Changed Type",{"Video", "Scene"}),
    #"Split Column by Delimiter" = Table.ExpandListColumn(Table.TransformColumns(#"Removed Columns", {{"Cast", Splitter.SplitTextByDelimiter(",", QuoteStyle.Csv), let itemType = (type nullable text) meta [Serialized.Text = true] in type {itemType}}}), "Cast"),
    #"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Cast", type text}}),
    #"Trimmed Text" = Table.TransformColumns(#"Changed Type1",{{"Cast", Text.Trim, type text}, {"Location", Text.Trim, type text}}),
    #"Removed Duplicates" = Table.Distinct(#"Trimmed Text"),
    #"Grouped Rows" = Table.Group(#"Removed Duplicates", {"Recording Block"}, {{"Grouped", each _, type table [Location=text, Cast=text, Recording Block=text]}}),
    #"Added Custom" = Table.AddColumn(#"Grouped Rows", "Locations", each List.Distinct(Table.Column([Grouped],"Location"))),
    #"Added Custom1" = Table.AddColumn(#"Added Custom", "Cast", each List.Distinct(Table.Column([Grouped],"Cast"))),
    #"Extracted Values" = Table.TransformColumns(#"Added Custom1", {"Cast", each Text.Combine(List.Transform(_, Text.From), ", "), type text}),
    #"Extracted Values1" = Table.TransformColumns(#"Extracted Values", {"Locations", each Text.Combine(List.Transform(_, Text.From), ", "), type text})
in
    #"Extracted Values1"
0 голосов
/ 23 марта 2020

Excel имеет функцию удаления дубликатов данных, вы пробовали это?

просто скопируйте ваши исходные данные, а затем удалите дубликаты.

enter image description here

...