您当然可以使用 VBA 和/或 Power Query 来做到这一点,尽管正如其他人所写并且您知道的那样,公式是一个可行的选择。
源数据
对于 VBA:
- 将源数据读入 VBA 数组以获得最快的处理速度
- 创建一个类模块来保存最小值和最大值
- 使用字典对范围进行分组,字典又包含类对象
- 创建一个结果数组并将其写入工作表。
类模块
'ReNAME this "cGroup"
Option Explicit
Private pMin As Long
Private pMax As Long
Public Property Get Min() As Long
Min = pMin
End Property
Public Property Let Min(Value As Long)
pMin = Value
End Property
Public Property Get Max() As Long
Max = pMax
End Property
Public Property Let Max(Value As Long)
pMax = Value
End Property
常规模块
'Set reference to Microsoft Scripting Runtime
Option Explicit
Sub generateRanges()
Dim wsSrc As Worksheet, wsRes As Worksheet, rRes As Range
Dim vSrc As Variant, vRes As Variant, v As Variant
Dim I As Long
Dim D As Dictionary, sKey As String
Dim cG As cGroup
'set the source and results worksheets
Set wsSrc = ThisWorkbook.Worksheets("sheet1")
Set wsRes = ThisWorkbook.Worksheets("sheet2")
Set rRes = wsRes.Cells(1, 1)
'read source data into vba array
With wsSrc
vSrc = Range(.Cells(1, 1), .Cells(.Rows.Count, 2).End(xlUp))
End With
'set dictionary to collect the data
Set D = New Dictionary
D.CompareMode = TextCompare
'iterate through the data
'pull out the min and max of the range
For I = 2 To UBound(vSrc, 1)
sKey = vSrc(I, 1)
Set cG = New cGroup
If Not D.Exists(sKey) Then
cG.Max = vSrc(I, 2)
cG.Min = vSrc(I, 2)
D.Add Key:=sKey, Item:=cG
Else
With D(sKey)
.Max = IIf(.Max > vSrc(I, 2), .Max, vSrc(I, 2))
.Min = IIf(.Min < vSrc(I, 2), .Min, vSrc(I, 2))
End With
End If
Next I
'create the results array
ReDim vRes(0 To D.Count, 1 To 2)
'Column Headers
vRes(0, 1) = "Range"
vRes(0, 2) = "Value"
I = 0
For Each v In D.Keys
I = I + 1
vRes(I, 1) = v & " Range"
vRes(I, 2) = D(v).Min & "-" & D(v).Max
Next v
'write results to results worksheet
With rRes.Resize(UBound(vRes, 1) + 1, UBound(vRes, 2))
.EntireColumn.Clear
.NumberFormat = "@"
.Value = vRes
.Style = "Output" 'not internationally aware
.EntireColumn.AutoFit
End With
End Sub
或者,使用 Windows Excel 2010+ 和 Office 365 中提供的 Power Query (我更喜欢它,因为它更短且更易于编程):
- 选择数据表中的某个单元格
Data => Get&Transform => from Table/Range
- 当 PQ 编辑器打开时:
Home => Advanced Editor
- 记下第 2 行中的表 Name
- 粘贴下面的 M 代码代替您看到的内容
- 将第 2 行中的表名称更改回最初生成的名称。
- 阅读 cmets 并探索
Applied Steps 以了解算法
M 码
let
//Read in the table
// Change Table name in next line to actual table name
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
//type the data
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Group", type text}, {"Value", Int64.Type}}),
//Group by "Group"
// then generate the min-max string
#"Grouped Rows" = Table.Group(#"Changed Type", {"Group"}, {{"Value",
each Text.From(List.Min([Value])) & "-" & Text.From(List.Max([Value])), Text.Type }
}),
//Add the word " Range" to the Group
addRange = Table.TransformColumns(#"Grouped Rows",{"Group", each _ & " Range", Text.Type})
in
addRange
从您的数据中产生相同的结果: