2

EDIT: I may have spotted an issue as soon as posting it the myRange variables dont seem to be doing anything - so I'm feeling they were there from a method i was using ages ago and there decided to crop out

I'll remove the whole myRange variable and see what happens

 Set myRange = ActiveSheet.Range("1:1")
 Set myRange = ActiveSheet.Range("A:A")

EDIT 2: Ok so changing the numCols and numRows functions to only use

numCols = ActiveSheet.Cells(1, Columns.Count).End(xlToLeft).Column
numRows = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).row

They now return the correct row and Column numbers But now when I run selectBlock() it gives me runtime error 28 "Out of Stack Space"

Hello All, I've been writing code to be able to go through multiple sheets and copy the data across to a master workbook

Im coding this to work on any file depending what you pass to it - which has been fine

What im having problems with is the Functions I have made which find the last populated row for any sheet I pass to it

Sub test()

selectBlock().Select
End Sub


Function selectBlock() As Range

Dim row As Integer: row = numRows() 'Finds last populated row
Dim col As Integer: col = numCols() 'Finds last populated column

Set selectBlock() = Range("A2:" & Cells(row, col).Address)
'sets this area starting from cell A2 as the Range

End Function

Function numCols() As Integer

Dim myRange As Range
Set myRange = ActiveSheet.Range("1:1") 'Checks first row to see how many populated columns there are
numCols = ActiveSheet.Cells(1, Columns.Count).End(xlToLeft).Column

End Function

Function numRows() As Integer
Dim myRange As Range
Set myRange = ActiveSheet.Range("A:A") 'Checks first columns to see how many populated rows there are
numRows = Range("A" & Rows.Count).End(xlUp).row

End Function

When I call the test Sub it causes Excel to hang then crash with no error code So i imagine im creating some kind of loop or critical error that isnt handled by excel very well

Any help with this would be really appreciated

I can also understand if how im going about it is incredibly stupid I used to code in Java and maybe im using techniques or pitfalls that I never got rid of - Im self taught at VBA like most and so never learnt official coding practices for VBA

Siddharth Rout
  • 147,039
  • 17
  • 206
  • 250
Jacob Crux
  • 64
  • 2
  • 10

3 Answers3

4

Lot of things here

  1. Fully qualify your cells
  2. Use Long and not Integer when working with row and columns
  3. Use error handling. This will avoid the Excel crashing.

Try this

Sub test()
    On Error GoTo Whoa
    selectBlock().Select
    Exit Sub
Whoa:
    MsgBox Err.Description
End Sub

Function selectBlock() As Range
    Dim row As Long: row = numRows() 'Finds last populated row
    Dim col As Long: col = numCols() 'Finds last populated column

    Set selectBlock = ActiveSheet.Range("A2:" & ActiveSheet.Cells(row, col).Address)
End Function

Function numCols() As Long
    numCols = ActiveSheet.Cells(1, ActiveSheet.Columns.Count).End(xlToLeft).Column
End Function

Function numRows() As Long
    numRows = ActiveSheet.Range("A" & ActiveSheet.Rows.Count).End(xlUp).row
End Function
Siddharth Rout
  • 147,039
  • 17
  • 206
  • 250
  • 1
    :) you are using `Rows.Count` to find last row ? after I learned from the best to use `Find` ? :) – Shai Rado Apr 16 '18 at 10:35
  • 1
    .Find is to find the last row in the entire sheet :) Not sure if you have seen [THIS](https://stackoverflow.com/questions/11169445/error-in-finding-last-used-cell-in-vba/11169920#11169920) – Siddharth Rout Apr 16 '18 at 10:36
  • 1
    When you have to find the last row in a column, you can use `.Rows.Count).End(xlUp).row` but if you want to find the last row which has data in the entire sheet then `.Find` is useful :) – Siddharth Rout Apr 16 '18 at 10:42
  • Ahh this is really cool - For me the last row will always be in the first column as they are data extracts from a database. But for when the last data row is unsure of column this will be really useful ! – Jacob Crux Apr 16 '18 at 10:43
2

Replace

Set selectBlock() = Range("A2:" & Cells(row, col).Address)

to

Set selectBlock = Range("A2:" & Cells(row, col).Address)

it looks recursive :P

ingwarus
  • 413
  • 2
  • 11
  • This was it!!! AHHHH so frustrating - Im still learning how to call sub and function procedures. You legend, I can select this answer in a few minutes – Jacob Crux Apr 16 '18 at 10:35
1

There are safer ways to find the LastRow and LastCol, I like the Find function.

See more detailed in my code's comments.

Code

Sub test()

Dim Rng As Range

Set Rng = selectBlock
Rng.Select '<-- Not sure why you need to Select ?

End Sub

'============================================================

Function selectBlock() As Range

Dim LastRow As Long
Dim LastCol As Long

LastRow = FindLastRow(ActiveSheet) 'Finds last populated row
LastCol = FindLastCol(ActiveSheet) 'Finds last populated column

Set selectBlock = Range(Cells(2, "A"), Cells(LastRow, LastCol))

End Function

'============================================================

Function FindLastCol(Sht As Worksheet) As Long

' This Function finds the last col in a worksheet, and returns the column number
Dim LastCell As Range

With Sht
    Set LastCell = .Cells.Find(What:="*", After:=.Cells(1), Lookat:=xlPart, LookIn:=xlFormulas, _
                        SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False)
    If Not LastCell Is Nothing Then
        FindLastCol = LastCell.Column
    Else
        MsgBox "Error! worksheet is empty", vbCritical
        End
    End If
End With

End Function

'============================================================

Function FindLastRow(Sht As Worksheet) As Long

' This Function finds the last row in a worksheet, and returns the row number

Dim LastCell As Range
With Sht
    Set LastCell = .Cells.Find(What:="*", After:=.Cells(1), Lookat:=xlPart, LookIn:=xlFormulas, _
                        SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False)
    If Not LastCell Is Nothing Then
        FindLastRow = LastCell.row
    Else
        MsgBox "Error! worksheet is empty", vbCritical
        End
    End If
End With

End Function
Shai Rado
  • 33,032
  • 6
  • 29
  • 51
  • This looks really cool and far more thought through - for me the one line is convinient but I will be looking at this code in detail. Thanks for the help Shai! – Jacob Crux Apr 16 '18 at 10:41
  • 1
    @JacobCrux I know it's quite different that your original code, take your time to review it (a lot I've learned here), just trying to save you a few month of learning ;) – Shai Rado Apr 16 '18 at 10:43
  • Shai, this code is really interesting. Scanning each row and column for data and saving the last populated position of each. Its clever clean and safe as you said. I'll be using this in the future for sure, Means you never leave out any data :D woohooo – Jacob Crux Apr 17 '18 at 12:50
  • I already have dude, just not enough rep for it to show :D and same to you for me being so awesome right? – Jacob Crux Apr 17 '18 at 13:06