Excel VBA根据相对范围的最小值到最大值查找范围内的单元格地址

问题描述:

我正在研究算法基础工具;请帮助我解决以下问题。Excel VBA根据相对范围的最小值到最大值查找范围内的单元格地址

1.首先我根据一个标准(动态)找到行号。假定行数为5,它已设定值的来源:(:F1 B1)

3.Then我需要找到列号(B5 F5)

Set FindRow = SearchRange.Find(Sheet1.Cells(xRow, 2).Text, LookIn:=xlValues, lookat:=xlWhole)  
MyRow = FindRow.Row 

2.I具有数值头,即MyCol是最小值单元格的列号(B1:F1)

4.然后我测试一个标准,If Cells(MyRow,MyCol)="ABC" Then测试失败,我需要再找到下一个最小值(B1:F1)和列号,即MyCol,直到我符合条件。

我试过阵列,我无法找到解决方案,任何帮助将不胜感激。我提前致谢。

+0

请从您的方法发布代码。 – Limak

如果我理解正确,您需要的是索引排序。许多语言都将索引排序作为标准函数提供。 VBA既没有标准排序也没有索引排序。

使用传统的数组排序,值在数组内排序。例如:假设我有值的数组:

A  D  B  E  C 

如果我传递数组排序,则返回:

A  B  C  D  E 

但有时你可以在阵列不排序。在你的情况下,数组是一系列的列标题。您无法对这些标题进行排序,因为它们属于它们的列。您必须对列进行排序,因为列的顺序意味着某些内容,所以最好不切实际并且可能不可接受。

有了一个索引排序,您创建阵列按键和指标:

Keys A  D  B  E  C 
Indices 1  2  3  4  5 

这两个数组传递给叶键不变,排序排序指标给:

Indices 1  3  5  2  4 

随着定期排序,您可以按Array(1)访问排序的条目。 Array(2)等。使用索引排序,您可以访问排序条目Array(Indices(1))Array(Indices(2))等。

通过索引来获取排序条目可能有点难以理解,毫无疑问,直接进入源数组无疑是件小事。

下面我给你一个索引插入排序。插入排序简单易懂,但对于大量条目而言速度很慢。你只有五个条目进行排序,所以它的性能是可以接受的。查看“插入排序”的Wiki条目,了解它的工作原理。

DemoSortColumnHeadings显示了如何使用排序以及如何访问列标题。我用名称ColHeads而不是KeysColNums而不是Indices,因为我相信这会使DemoSortColumnHeadings更易于理解。排序的ColNums包含您需要的顺序中的列号。排序后,不再需要数组ColHeads

最后一点。 VBA是我所知道的唯一一种允许指定数组下限和上限的语言。大多数语言都要求下限为零。我利用这个来定义数组的维数为(2至6)而不是(0至4)。这就是为什么数组ColNums中的值是列号。对于大多数语言,我需要ColNums(N)+2来获取列号。

Option Explicit 
Sub DemoSortColumnHeadings() 

    Const ColFirst As Long = 2 ' Column B = column 2 
    Const ColLast As Long = 6 ' Column F = column 6 

    Dim ColCrnt As Long 
    Dim ColNums() As Long 
    Dim InxColNum As Long 
    Dim ColHeads() As String 

    With Worksheets("Test data") 

    ReDim ColHeads(ColFirst To ColLast) 
    ReDim ColNums(ColFirst To ColLast) 

    For ColCrnt = ColFirst To ColLast 
     ColHeads(ColCrnt) = .Cells(1, ColCrnt).Value 
     ColNums(ColCrnt) = ColCrnt 
    Next 


    Debug.Print "Initial sequence" 
    Debug.Print "|"; 
    For ColCrnt = ColFirst To ColLast 
     Debug.Print .Cells(1, ColCrnt).Value & "|"; 
    Next 
    Debug.Print 

    Call InsertionSort(ColNums, ColHeads) 

    Debug.Print "Final sequence" 
    Debug.Print "|"; 
    For InxColNum = LBound(ColNums) To UBound(ColNums) 
     ColCrnt = ColNums(InxColNum) 
     Debug.Print .Cells(1, ColCrnt).Value & "|"; 
    Next 
    Debug.Print 

    End With 


End Sub 
Public Sub InsertionSort(ByRef Indices() As Long, ByRef Keys() As String) 

    Dim Found As Boolean 
    Dim I As Long 
    Dim InxIFwd As Long 
    Dim InxIBack As Long 

    For InxIFwd = LBound(Indices) + 1 To UBound(Indices) 
    I = Indices(InxIFwd) ' Save value of current entry in Indices 
    ' Find first entry back, if any, such that Keys(I) >= Keys(Indices(InxIBack)) 
    ' If Keys(I) < Keys(Indices(InxIBack)), set Indices(InxIBack+1) to 
    ' Indices(InxIBack). That is move indices for keys greater that Keys(I) down 
    ' Indices leaving a space for I nearer the beginning. 
    Found = False 
    For InxIBack = InxIFwd - 1 To LBound(Indices) Step -1 
     If Keys(I) >= Keys(Indices(InxIBack)) Then 
     ' Keys(I) belongs after Keys(Indices(InxIBack)) 
     Indices(InxIBack + 1) = I 
     Found = True 
     Exit For 
     End If 
     Indices(InxIBack + 1) = Indices(InxIBack) 
    Next 
    If Not Found Then 
     ' Insertion point for I not found so it belongs at beginning of Indices 
     Indices(LBound(Indices)) = I 
    End If 
    Next 

End Sub 
+0

谢谢托尼! – Manish

+0

@Manish。不用谢。注意:我有一个使用相同技术的快速排序实现。在大多数情况下,快速排序是最快的排序,但它更难以理解。我的实现可以为54,000行工作表创建键和索引,并在1.5秒内对索引进行排序。如果需要对大数组进行排序索引,请记住这一点。 –