Извлекать уникальные значения из диапазона в Excel, не обращая внимания на конкретные значения - PullRequest
0 голосов
/ 28 августа 2018

У меня изначально была электронная таблица Excel, которая использовалась для записи значений идентификаторов JOB LOT ID (> 10000). Я использовал следующую формулу массива -

=INDIRECT(TEXT(MIN(IF(($C$3:$S$52<>"")*(COUNTIF($V$3:V3,$C$3:$S$52)=0),ROW($3:$52)*100+COLUMN($C$S),7^8)),"R0C00"),)&""

Данные:

| pallet    | Lot#      | Lot#      | Lot#      | Lot#      | Lot#      |
|--------   |-------    |-------    |--------   |-------    |--------   |
| 1         | 12345     | 12346     | 12345     | 12347     | 123456    |
| 2         | 12345     | 12346     | 12348     | 12348     | 12343     |
| 3         | 12345     | 12347     | 123456    | 12348     | 12348     |

Это работало нормально, если все ячейки в этом диапазоне представляли идентификаторы JOB LOT. Он будет записывать уникальные LOT #, как я скопировал это в диапазон результатов и в сочетании с формулой подсчета

(IF(LEN(V4)>0,COUNTIF($C$3:$S$52,V4),"")

в соседней ячейке. Возвращено:

Unique  
Value  Count
______ _____
12345    4   
12346    2   
12347    2  
123456   2 
12348    4 
12343    1

К сожалению, область действия задания и электронной таблицы изменилась так, что в электронную таблицу необходимо было включить столбцы перед каждой ячейкой JOB LOT, чтобы записать № дела в LOB JOB.

Мне нужна помощь, чтобы выяснить, как игнорировать данные дела #, которые всегда будут между 1 и 451, и рассчитывать только уникальные идентификаторы JOB LOT, которые всегда будут> 100000. В результате получается только уникальный список рабочих номеров. Используя ту же формулу массива с добавленным столбцом для Case #, также указываются номера Case, когда они не нужны или не нужны.

| pallet    | case#     | Lot#      | case#     | Lot#      | case#     | Lot#      | case#     | Lot#      | case#     | Lot#      |
|--------   |-------    |-------    |-------    |-------    |-------    |--------   |-------    |-------    |-------    |--------   |
| 1         | 1         | 12345     | 45        | 12346     | 356       | 12345     | 6         | 12347     | 7         | 123456    |
| 2         | 3         | 12345     | 35        | 12346     | 212       | 12348     | 23        | 12348     | 200       | 12343     |
| 3         | 54        | 12345     | 34        | 12347     | 450       | 123456    | 345       | 12348     | 367       | 12348     |

Результат

Unique
Value   Count
______  _____
12345     4  
45        1
12346     2 
356       1
6         1
12347     2 
7         1  
123456    2 
35        1 
212       1 
12348     4 
23        1 
200       1 
12343     1 
34        1 
450       1 
345       1 
367       1

Какие-нибудь Suugestions? Спасибо.

1 Ответ

0 голосов
/ 29 августа 2018

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

Данные считываются с листа, из столбца C до самого правого столбца, в массив, arr. arr зацикливается только при просмотре всех остальных столбцов, то есть столбцов Lot#. Содержимое словаря, то есть уникальные Lot# (Keys) и их количество (Items), записываются на лист2.

Предполагается, что ваши данные начинаются с A1 и имеют макет, указанный в вопросе.

Option Explicit
Public Sub GetUniqueValueByCounts()
    Dim arr(), i As Long, j As Long, dict As Object, lastColumn As Long, lastRow As Long
    Const NUMBER_COLUMNS_TO_SKIP = 2
    Set dict = CreateObject("Scripting.Dictionary")

    With ThisWorkbook.Worksheets("Sheet1")
        lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
        lastColumn = .Cells(1, .Columns.Count).End(xlToLeft).Column
        If lastColumn < 3 Or lastRow < 2 Then Exit Sub

        arr = .Range(.Cells(2, 3), .Cells(lastRow, lastColumn)).Value

        For i = LBound(arr, 2) To UBound(arr, 2) Step NUMBER_COLUMNS_TO_SKIP
            For j = LBound(arr, 1) To UBound(arr, 1)
               If arr(j, i) <> vbNullString Then
                   dict(arr(j, i)) = dict(arr(j, i)) + 1
               End If
            Next
        Next
    End With
    With Worksheets("Sheet2")
        .Range("A1").Resize(dict.Count, 1) = Application.WorksheetFunction.Transpose(dict.Keys)
        .Range("B1").Resize(dict.Count, 1) = Application.WorksheetFunction.Transpose(dict.Items)
    End With
End Sub

Заказанные результаты:

Вы можете использовать sortedList для получения упорядоченных результатов, хотя вы теряете приятные .Keys и .Items методы генерации массивов за один раз для записи на лист.

Option Explicit
Public Sub GetUniqueValueByCounts()
    Dim arr(), i As Long, j As Long, dict As Object, lastColumn As Long, lastRow As Long, list As Object
    Const NUMBER_COLUMNS_TO_SKIP = 2
    Set dict = CreateObject("Scripting.Dictionary")
    Set list = CreateObject("System.Collections.SortedList")
    With ThisWorkbook.Worksheets("Sheet1")
        lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
        lastColumn = .Cells(1, .Columns.Count).End(xlToLeft).Column
        If lastColumn < 3 Or lastRow < 2 Then Exit Sub

        arr = .Range(.Cells(2, 3), .Cells(lastRow, lastColumn)).Value

        For i = LBound(arr, 2) To UBound(arr, 2) Step NUMBER_COLUMNS_TO_SKIP
            For j = LBound(arr, 1) To UBound(arr, 1)
                If arr(j, i) <> vbNullString Then
                    With list
                        If Not .contains(arr(j, i)) Then
                            list.Add arr(j, i), 1
                        Else
                            list(arr(j, i)) = list(arr(j, i)) + 1
                        End If
                    End With
                End If
            Next
        Next i
    End With
    With Worksheets("Sheet2")
        For j = 0 To list.Count - 1
            .Cells(j + 1, 1) = list.GetKey(j)
            .Cells(j + 1, 2) = list.GetByIndex(j)
        Next
    End With
End Sub
...