在列表中查找不同行的最大值和最小值VBA excel

我很难把我的思维过程转化为有形的代码,老实说,我不知道从哪里开始的代码。 我有一个数据集有两个适用的列,为了简单起见,我们会说A和B. A包含三个首字母缩写,后跟一个数字,例如。 JFD3,JFD2,JFD6,EUW1,YMG2,YMG3。 B列有一个值。 我需要find每组首字母的最高到最低值的范围,这是我思考最大最小的解决scheme。 首字母缩写词不一定按顺序排列,可能有一组缩写词(净方差为0,即OK)或最多8组首字母,数字不一定是连续的。 我在想一些比赛(左(3)),但我不认为这将包括一切。

任何想法从哪里开始将不胜感激。 如果有任何问题,我很乐意澄清。

您可以使用Scripting Runtime中的字典轻松完成此操作。 使用其中的两个键的首字母作为键,其中一个保持find的最小值,另一个保持find的最大值。

添加对Microsoft脚本运行时的引用(工具 – >添加引用…,然后选中“Microsoft Scripting Runtime”旁边的checkbox)或者延迟绑定(请参阅下面的说明)。 像这样的事情应该做的伎俩,假设在第1列,第2列的值,没有标题:

Private Sub MinMax() Dim mins As Dictionary Dim maxes As Dictionary Dim sheet As Worksheet Set sheet = ActiveSheet Set mins = New Dictionary Set maxes = New Dictionary Dim row As Long For row = 1 To sheet.UsedRange.Rows.Count Dim key As Variant Dim val As Integer key = sheet.Cells(row, 1).Value2 If Len(key) >= 3 Then key = Left$(sheet.Cells(row, 1).Value2, 3) val = sheet.Cells(row, 2).Value2 If Not mins.Exists(key) Then mins.Add key, val Else If mins(key) > val Then mins(key) = val End If If Not mins.Exists(key) Then maxes.Add key, val Else If maxes(key) < val Then maxes(key) = val End If End If Next row For Each key In mins.Keys Debug.Print key & ": Min = "; mins(key) & " Max = "; maxes(key) Next key End Sub 

要使用后期绑定,代码与这些例外完全相同。 将mins和max声明为Dictionary,而不是将它们声明为Object:

  Dim mins As Object Dim maxes As Object 

而不是将它们设置为新词典,使用CreateObject:

  Set sheet = ActiveSheet Set mins = CreateObject("Scripting.Dictionary") Set maxes = CreateObject("Scripting.Dictionary") 

使用数据透视表。 将您的列A字段*放在Row Labels ,然后将列B放入两次值中。 将SumSum更改为Min ,将另一个从Sum更改为Max

*不确定是否需要由JFD对所有JFDx或每个JFDx 。 如果你需要用3个首字母来分组,可以把C =left("A1",3) ,然后用你的

解决这个问题的方法可能是:

  1. 按字母顺序排列AB范围内的数据。 为此,您可以在执行此操作时录制macros,并编辑代码使其每次都能dynamic工作。 这是使下面的解决scheme起作用所必需的 ,对于许多其他类似的方法来说更好
  2. 使用While块来运行解决scheme。 我让你花时间来构build和testing一个工作代码,但这是这个想法:

     startSubset = 2 '<-- we start getting the key from row 2 'build the key to define the subset keyStart = 1 currentKey = "" Do While Not IsNumeric(Right(Left(Range("A" & startSubset),keyStart),1)) 'while the last char of the key is not numeric, let's add it to the key currentKey = currentKey & Right(Left(Range("A" & startSubset),keyStart),1) keyStart = keyStart + 1 Loop 

之后,密钥存储在variablescurrentKey 。 如果第一个单元格是JFD213等,那么它将是JFD 。因此,直到这个子集的末尾存储最大值和最小值两个variables:

  min = 0 max = 0 Do While Left(Range("A" & startSubset),Len(currentKey)) = currentKey If Range("B" & startSubset) < min Then min = Range("B" & startSubset) If Range("B" & startSubset) > max Then max = Range("B" & startSubset) startSubset = startSubset + 1 Loop 
  1. 一旦完成,您只需将值转换为集合,例如:

     myObs.Add(currentKey) myObs.Add(min) myObs.Add(max) '<-- you will get something like myObs = ("DJF", 0, 100) 

然后把这个对象放到一个更大的集合中:

  allValues.Add(myObs) '<-- at the end you will have something like this: 'allValues = [("DJF",0,100), ("ABC", 1, 75), ...] 

并重新设置值让它们继续:

  currentKey = "" keyStart = 1 

以上所有内容都应该在While循环中运行,当数据结束时将会中断。

请注意,上面的代码不能独立工作,但这是一个可能的解决方法,您需要重新处理数据以使其在现实生活中运行。