+ Reply to Thread
Results 1 to 13 of 13

How to get Min / Max Row / Col in a non-contiguous range?

Hybrid View

  1. #1
    Forum Contributor
    Join Date
    10-10-2018
    Location
    Calgary, Canada
    MS-Off Ver
    2016
    Posts
    214

    How to get Min / Max Row / Col in a non-contiguous range?

    Right now I define it by rowing through each cell:

    for each c in someRange
    
    ..
    
    next
    and I achieve the results I want, but it seems to me to be a very inefficient way to do it. I don't want to row through millions of cells just to find the edges of this range!!!!

    There must be a better way? Thanks.

  2. #2
    Forum Contributor
    Join Date
    10-10-2018
    Location
    Calgary, Canada
    MS-Off Ver
    2016
    Posts
    214

    Re: How to get Min / Max Row / Col in a non-contiguous range?

    I've also tried:
    ' this gets the row of the last cell in the range.
        If SelectType = "Row" Then
            Max = Selection.Rows.Count
            MaxRow = MinRow + Max - 1
        ElseIf SelectType = "Col" Then
            Max = Selection.Columns.Count
            MaxCol = MinCol + Max - 1
        Else
    ' Selection.Count doesn't work if you're selecting the whole row or column.
            MaxRow = Selection(Selection.Count).Row
            MaxCol = Selection(Selection.Count).Column
        End If
    but this only works if the user selects continuous rows/columns

  3. #3
    Forum Expert romperstomper's Avatar
    Join Date
    08-13-2008
    Location
    East Sussex, UK
    MS-Off Ver
    365, varying versions/builds
    Posts
    21,331

    Re: How to get Min / Max Row / Col in a non-contiguous range?

    If you want the highest row number, loop through the Areas in the selection and check the row number of the last cell in each one, storing the max value.
    Everyone who confuses correlation and causation ends up dead.

  4. #4
    Forum Guru Kaper's Avatar
    Join Date
    12-14-2013
    Location
    Warsaw, Poland
    MS-Off Ver
    most often: Office 365 in Windows environment
    Posts
    8,678

    Re: How to get Min / Max Row / Col in a non-contiguous range?

    To extend Rory's answer a bit: try the following code in an empty sheet:

    Sub test()
    Dim rng As Range, rarea As Range
    Dim maxrow As Long, maxcol As Long, minrow As Long, mincol As Long
    'Set rng = Range("A1:C10")
    minrow = ActiveSheet.Rows.Count
    mincol = ActiveSheet.Columns.Count
    Set rng = Range("B3:E10,D5:G12,C5:D14,E3:F6")
    For Each rarea In rng.Areas
      rarea.Select
      maxrow = WorksheetFunction.Max(maxrow, rarea.Row + rarea.Rows.Count - 1)
      maxcol = WorksheetFunction.Max(maxcol, rarea.Column + rarea.Columns.Count - 1)
      minrow = WorksheetFunction.Min(minrow, rarea.Row)
      mincol = WorksheetFunction.Min(mincol, rarea.Column)
      Cells(Rows.Count, 1).End(xlUp).Offset(1, 0) = rarea.Address(False, False)
      Cells(Rows.Count, 1).End(xlUp).Offset(1, 0) = "rows: " & rarea.Row & ":" & rarea.Row + rarea.Rows.Count - 1
      Cells(Rows.Count, 1).End(xlUp).Offset(1, 0) = "columns: " & rarea.Column & ":" & rarea.Column + rarea.Columns.Count - 1
      DoEvents
      Application.Wait Now + TimeValue("0:00:01")
    Next rarea
    MsgBox "rows: " & minrow & ":" & maxrow & vbCrLf & "columns: " & mincol & ":" & maxcol
    End Sub
    And now you can drop all the displaying-related parts of the code and use it for your somerange
    Best Regards,

    Kaper

  5. #5
    Valued Forum Contributor
    Join Date
    02-02-2016
    Location
    Indonesia
    MS-Off Ver
    Office 365
    Posts
    1,018

    Re: How to get Min / Max Row / Col in a non-contiguous range?

    Just another way:

    Sub min_max()
    Dim c As Range
    Dim ary, arz
    Dim i As Long, j As Long
    
    Set c = Range("B3:E10,D5:G12,C5:D14,E3:F6")
    ary = Split(c.Address, "$")
    
    ReDim arz(1 To (UBound(ary)) / 2)
        For i = 2 To UBound(ary) Step 2
        j = j + 1: arz(j) = Val(ary(i))
        Next
    
    Debug.Print "Min row: " & Application.Min(arz)
    Debug.Print "Max row: " & Application.Max(arz)
    
    j = 0
        For i = 1 To UBound(ary) Step 2
        j = j + 1: arz(j) = Cells(1, ary(i)).Column
        Next
    
    Debug.Print "Min Column: " & Application.Min(arz)
    Debug.Print "Max Column: " & Application.Max(arz)
    
    End Sub

  6. #6
    Forum Expert
    Join Date
    11-24-2013
    Location
    Paris, France
    MS-Off Ver
    Excel 2003 / 2010
    Posts
    9,831

    Arrow

    Quote Originally Posted by superlative View Post
    There must be a better way?
    Mayve via the Range.Find method …

  7. #7
    Forum Guru Kaper's Avatar
    Join Date
    12-14-2013
    Location
    Warsaw, Poland
    MS-Off Ver
    most often: Office 365 in Windows environment
    Posts
    8,678

    Re: How to get Min / Max Row / Col in a non-contiguous range?

    Hi Marc,

    I think that Range.Find will look on whole (potentially not continous) range and locate specihic values (What:=) so I'm not sure how it could be used to find "smalles surrounding rectangle" address - I think this is what superlative looks for.

    PS. My code from above with removed side/demonstration parts seems to be still competitive compared to range.address and address splitting method:

    Sub test()
    Dim rng As Range, rarea As Range
    Dim maxrow As Long, maxcol As Long, minrow As Long, mincol As Long
    minrow = ActiveSheet.Rows.Count
    mincol = ActiveSheet.Columns.Count
    Set rng = Range("B3:E10,D5:G12,C5:D14,E3:F6")
    For Each rarea In rng.Areas
      maxrow = WorksheetFunction.Max(maxrow, rarea.Row + rarea.Rows.Count - 1)
      maxcol = WorksheetFunction.Max(maxcol, rarea.Column + rarea.Columns.Count - 1)
      minrow = WorksheetFunction.Min(minrow, rarea.Row)
      mincol = WorksheetFunction.Min(mincol, rarea.Column)
    Next rarea
    MsgBox "rows: " & minrow & ":" & maxrow & vbCrLf & "columns: " & mincol & ":" & maxcol
    End Sub

  8. #8
    Forum Expert
    Join Date
    11-24-2013
    Location
    Paris, France
    MS-Off Ver
    Excel 2003 / 2010
    Posts
    9,831

    Arrow


    I was thinking for cells containing data instead of an easy last column # from a range for example …

  9. #9
    Forum Contributor
    Join Date
    10-10-2018
    Location
    Calgary, Canada
    MS-Off Ver
    2016
    Posts
    214

    Re: How to get Min / Max Row / Col in a non-contiguous range?

    Hi everyone,

    thanks for all the great ideas!! I actually managed to find some code online very similar to kaper's and modified it according to my needs. Here it is:
    Sub Range_MinMax(sRange As Range, ByRef MinRow As Long, ByRef MaxRow As Long, ByRef MinCol As Long, ByRef MaxCol As Long)
        Dim c As Range, TempInt As Long, TempInt2 As Long, MinRange As Range, MaxRange As Range
        Dim subRange As Range, areaMaxRow As Long, areaMinRow As Long, areaMaxCol As Long, areaMinCol As Long, AreaCount As Long
        
        
        MinRow = 32000
        MaxRow = 1
        MinCol = 32000
        MaxCol = 1
        AreaCount = 0
        
        For Each subRange In sRange.Areas
            AreaCount = AreaCount + 1
            areaMaxRow = subRange.Rows(subRange.Rows.Count).Row
            areaMinRow = subRange.Rows(1).Row
            areaMaxCol = subRange.Rows(subRange.Columns.Count).Column
            areaMinCol = subRange.Columns(1).Column
            If areaMaxRow > MaxRow Then MaxRow = areaMaxRow
            If areaMinRow < MinRow Then MinRow = areaMinRow
            If areaMaxCol > MaxCol Then MaxCol = areaMaxCol
            If areaMinCol < MinCol Then MinCol = areaMinCol
        Next subRange
        
        If AreaCount = 1 Then
            Contiguous = True
        Else
            Contiguous = False
        End If
    
    End Sub
    using WorksheetFunction.Min appears cleaner, but is there a performance benefit? Anyone know? Thanks!
    Last edited by superlative; 11-06-2019 at 01:20 PM.

  10. #10
    Forum Expert romperstomper's Avatar
    Join Date
    08-13-2008
    Location
    East Sussex, UK
    MS-Off Ver
    365, varying versions/builds
    Posts
    21,331

    Re: How to get Min / Max Row / Col in a non-contiguous range?

    Quote Originally Posted by superlative View Post
    using WorksheetFunction.Min appears cleaner, but is there a performance benefit? Anyone know? Thanks!
    I would expect a call to Worksheetfunction to be slower, but you should test it.

  11. #11
    Forum Contributor
    Join Date
    10-10-2018
    Location
    Calgary, Canada
    MS-Off Ver
    2016
    Posts
    214

    Re: How to get Min / Max Row / Col in a non-contiguous range?

    Akuini: do you think your code is faster? I use this function extensively so I need it to be fast. Thanks!

  12. #12
    Valued Forum Contributor
    Join Date
    02-02-2016
    Location
    Indonesia
    MS-Off Ver
    Office 365
    Posts
    1,018

    Re: How to get Min / Max Row / Col in a non-contiguous range?

    Quote Originally Posted by superlative View Post
    Akuini: do you think your code is faster? I use this function extensively so I need it to be fast. Thanks!
    Well, you need to test it, you can try putting the codes in say 10K loops then see how long it takes, I'm guessing mine is a bit faster but I think the difference won't be noticeable in practice.
    I changed my code a bit & put it in 10K loops & used a range with more areas, it took 1.28125 seconds.

    Sub min_max1()
    'https://www.excelforum.com/excel-programming-vba-macros/1295394-how-to-get-min-max-row-col-in-a-non-contiguous-range.html
    Dim c As Range
    Dim ary, arz, arx
    Dim i As Long, j As Long
    
    t = Timer
    For n = 1 To 10000
        Set c = Range("$B$3:$B$6,$D$6:$D$12,$C$3:$F$7,$F$6:$G$11,$I$4:$J$9,$G$16:$J$19,$H$13:$C$16,$B$15:$D$22,$D$11:$G$18")
        ary = Split(c.Address, "$")
        j = 0
        ReDim arz(1 To (UBound(ary)) / 2)
            For i = 2 To UBound(ary) Step 2
            j = j + 1: arz(j) = Val(ary(i))
            Next
        
        ReDim arx(1 To (UBound(ary)) / 2)
        j = 0
            For i = 1 To UBound(ary) Step 2
            j = j + 1: arx(j) = Cells(1, ary(i)).Column
            Next
        
        MinRow = Application.Min(arz)
        MaxRow = Application.Max(arz)
        MinCol = Application.Min(arx)
        MaxCol = Application.Max(arx)
    
    Next
    
    Debug.Print "rows: " & MinRow & ":" & MaxRow & vbCrLf & "columns: " & MinCol & ":" & MaxCol
    Debug.Print Timer - t
    End Sub
    The result:
    rows: 3:22
    columns: 2:10
    1.28125

    Test your code by using the same set up, see how it goes.

  13. #13
    Valued Forum Contributor
    Join Date
    02-02-2016
    Location
    Indonesia
    MS-Off Ver
    Office 365
    Posts
    1,018

    Re: How to get Min / Max Row / Col in a non-contiguous range?

    I forgot something, using range address has a limit, the string address can't be longer than 255 characters, otherwise it will raise an error.
    So I think your code or Kaper's code is better.

    But actually how do you get the range? By selecting the range manually?
    Last edited by Akuini; 11-06-2019 at 09:03 PM.

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. non-contiguous named range - how to use in formulas, or how to convert to contiguous list
    By david killoran in forum Excel Programming / VBA / Macros
    Replies: 6
    Last Post: 06-23-2019, 03:33 AM
  2. [SOLVED] Copy range and paste into non contiguous range
    By amros in forum Excel Programming / VBA / Macros
    Replies: 19
    Last Post: 07-02-2017, 05:42 AM
  3. excel vba range property non contiguous range
    By Ramo13541 in forum Excel Programming / VBA / Macros
    Replies: 3
    Last Post: 03-02-2016, 08:23 PM
  4. [SOLVED] Using scripting dictionary to add contiguous group of items from non contiguous range
    By stnkynts in forum Excel Programming / VBA / Macros
    Replies: 3
    Last Post: 11-29-2014, 06:12 PM
  5. [SOLVED] How to delete multiple contiguous (and/or) non-contiguous rows, in an excel table
    By jimmalk in forum Excel Programming / VBA / Macros
    Replies: 7
    Last Post: 12-03-2012, 05:48 AM
  6. Contiguous "Range" from Non Contiguous Ranges
    By DonkeyOte in forum Excel Formulas & Functions
    Replies: 10
    Last Post: 01-03-2011, 03:23 PM
  7. Copy and Paste an array (contiguous & non contiguous ranges)
    By Xrull in forum Excel Programming / VBA / Macros
    Replies: 5
    Last Post: 05-09-2010, 09:17 AM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts

Search Engine Friendly URLs by vBSEO 3.6.0 RC 1