从 excel 范围内提取唯一值,同时忽略特定值
Extract unique values from a range in excel while disregarding specific values
我最初有一个 Excel 电子表格,用于记录 JOB LOT ID 的值(>10000)。我使用了以下数组公式 -
=INDIRECT(TEXT(MIN(IF(($C:$S<>"")*(COUNTIF($V:V3,$C:$S)=0),ROW(:)*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 ID,则此方法工作正常。
当我将其复制到结果范围并与计数公式相结合时,它会记录唯一的 LOT #'s
(IF(LEN(V4)>0,COUNTIF($C:$S,V4),"")
在相邻的单元格中。它返回:
Unique
Value Count
______ _____
12345 4
12346 2
12347 2
123456 2
12348 4
12343 1
不幸的是,作业和电子表格的范围发生了变化,因此电子表格需要在每个作业批次单元格之前包含列以记录作业批次的案例编号。
我需要帮助的是弄清楚如何忽略 case# 数据,它总是在 1 到 451 之间,并且只计算唯一的 JOB LOT ID,它总是 > 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
有什么建议吗?
谢谢。
您可以使用字典将唯一的 Lot#
作为键保存,并在每次再次遇到该键时将与该键关联的值加一。
数据从sheet,从C列到最右边的列读入一个数组,arr
。 arr
循环只查看每隔一列,即 Lot#
列。字典的内容,即唯一的 Lot#
(Keys
) 和它们的计数 (Items
),被写到 sheet2。
它假定您的数据从 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
一次性生成数组的方法来写入 sheet .
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
我最初有一个 Excel 电子表格,用于记录 JOB LOT ID 的值(>10000)。我使用了以下数组公式 -
=INDIRECT(TEXT(MIN(IF(($C:$S<>"")*(COUNTIF($V:V3,$C:$S)=0),ROW(:)*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 ID,则此方法工作正常。 当我将其复制到结果范围并与计数公式相结合时,它会记录唯一的 LOT #'s
(IF(LEN(V4)>0,COUNTIF($C:$S,V4),"")
在相邻的单元格中。它返回:
Unique
Value Count
______ _____
12345 4
12346 2
12347 2
123456 2
12348 4
12343 1
不幸的是,作业和电子表格的范围发生了变化,因此电子表格需要在每个作业批次单元格之前包含列以记录作业批次的案例编号。
我需要帮助的是弄清楚如何忽略 case# 数据,它总是在 1 到 451 之间,并且只计算唯一的 JOB LOT ID,它总是 > 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
有什么建议吗? 谢谢。
您可以使用字典将唯一的 Lot#
作为键保存,并在每次再次遇到该键时将与该键关联的值加一。
数据从sheet,从C列到最右边的列读入一个数组,arr
。 arr
循环只查看每隔一列,即 Lot#
列。字典的内容,即唯一的 Lot#
(Keys
) 和它们的计数 (Items
),被写到 sheet2。
它假定您的数据从 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
一次性生成数组的方法来写入 sheet .
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