Excel VBA set print area to last row with data

Question

I have an Excel table with a sheet "CR" where columns A to K are filled, with the first row being a header row.

Rows 1-1000 are formatted (borders) and column A contains a formula to autonumber the rows when data in column F is entered.

Sheet "CR" is protected to prevent users from entering data in column A (locked).

Using the Workbook_BeforePrint function, I'm trying to set the print area to columns A to K and to the last row of column A that contains a number.

My code (in object 'ThisWorkbook') is as follows:

Private Sub Workbook_BeforePrint(Cancel As Boolean)
Dim ws As Worksheet
Dim lastRow As Long

Set ws = ThisWorkbook.Sheets("CR")

' find the last row with data in column A
lastRow = .Cells(.Rows.Count, 1).End(xlUp).Row

ws.PageSetup.PrintArea = ws.Range("A1:K" & lastRow).Address
End Sub

However, when I click File -> Print, the range of columns A to K up to row 1000 is displayed instead of only the rows that have a number in column A. What am I doing wrong?


Show source
| vba   | excel   | area   | printing   2016-11-13 17:11 2 Answers

Answers ( 2 )

  1. 2016-11-13 18:11

    Change:

    lastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
    

    To:

    lastRow = [LOOKUP(2,1/(A1:A65536<>""),ROW(A1:A65536))]
    
  2. 2016-11-13 18:11

    .End(...) will act like ctrl + arrow-key. if the cell has a formula (which looks empty due to the formula, then it will still stop there... another way would be the use of evaluate (if you do not want to loop) like this:

    lastRow = .Evaluate("MAX(IFERROR(MATCH(1E+100,A:A,1),0),IFERROR(MATCH(""zzz"",A:A,1),0))")
    

    This will give the last row (which has a value in column A).

    Also check if there are hidden values (looking empty due number format or having characters you can't see directly. Try to go below row 1000 in column A (select a cell after A1000 in column A) and hit ctrl+up to validate where it stops (and why).

    EDIT:
    (regarding your comment)

    "" still leads to a "stop" for the .End(...)-command. So either use my formula, translate the formula into vba or loop the cells it get the last value. Also Find is a good tool (if not doing it over and over for countless times).

    lastRow = .Cells.Find("*", .Range("B1"), xlValues, , xlByColumns, xlPrevious).Row
    
◀ Go back