簡體   English   中英

Excel VBA根據對應范圍的最小值到最大值查找范圍內的單元格地址

[英]Excel VBA Find cell address in range based on min to max value of correspoding range

我正在研究基於算法的工具; 請協助我解決以下問題。

1.首先,我根據一個條件(動態)找到行號。 假設行號是5,並且它有一組Value From(B5:F5)

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

2.我有帶數字值的標題(B1:F1)

3.然后我需要找到列號,即MyCol是(B1:F1)中最小值單元格的列號

4.然后,我使用If Cells(MyRow,MyCol)="ABC" Then測試一個條件, If Cells(MyRow,MyCol)="ABC" Then測試失敗,再次需要在(B1:F1)和列號中找到下一個最小值,即MyCol,直到滿足條件。

我試過數組,我找不到解決方案,任何幫助將不勝感激。 提前謝謝。

如果我理解正確,那么您需要的是索引排序。 許多語言都將索引排序作為標准函數提供。 VBA既沒有排序標准也沒有索引排序標准。

使用常規的數組排序,值將在數組內排序。 例如:假設我有一個帶有值的數組:

A     D     B     E     C

如果我將該數組傳遞給排序,則返回為:

A     B     C     D     E

但是有時您無法對數組進行排序。 在您的情況下,數組是一系列列標題。 您無法對這些標題進行排序,因為它們屬於其列。 您將不得不對列進行排序,這是最不切實際的,並且可能是不可接受的,因為列的順序將有意義。

使用索引排序,您可以創建數組鍵和索引:

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

這兩個數組都傳遞給使Key保持不變並對Indices進行排序的排序,以給出:

Indices 1     3     5     2     4

使用常規排序,您可以將已排序的條目作為Array(1) Array(2)等。 通過索引排序,您可以以Array(Indices(1))形式訪問排序后的條目。 Array(Indices(2))等。

剛開始時,通過索引來獲取排序的條目可能有點困難,並且直接轉到源數組無疑是擺弄。

下面,我為您提供了索引化的插入排序。 插入排序很簡單易懂,但是輸入大量條目卻很慢。 您只有五個條目可以排序,因此其性能是可以接受的。 在Wiki上的“插入排序”條目中查看其工作方式的圖形演示。

DemoSortColumnHeadings展示了如何使用排序以及如何訪問列標題。 我使用名稱ColHeads代替Keys ,使用ColNums代替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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM