2016-11-05 271 views
0

我正在研究算法基礎工具;請幫助我解決以下問題。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

回答

0

如果我理解正確,您需要的是索引排序。許多語言都將索引排序作爲標準函數提供。 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秒內對索引進行排序。如果需要對大數組進行排序索引,請記住這一點。 –

相關問題