Remove unused rows/columns at end of spreadsheet (Excel 2019)

RincewindWIZZ

Board Regular
Joined
Feb 22, 2005
Messages
81
In the good old days, Excel treated the work sheet as containing a limited number of cells bounded by the last cell you had manipulated (value, format etc). Then the scroll bar didn't go beyond this area (though you could move there with the cursor)
I have an spreadsheet (with 2000 active rows) showing the full 1M rows which makes the scroll bar useless
I've tried deleting the surplus rows; clearing the contents; clearing the formatting etc but I still get the full l 1M rows.
I even tried hiding them but then the vertical scroll bar fills (Goes from top to bottom) the entire worksheet so it is still useless

If I copy and paste the data into a new sheet, the scroll bars refer only to the pasted data but there are formulas that refer to specific worksheets and also some VBA code so I'd really prefer not to have to go down that route.

ANy suggestions on how I can make the current sheet ignore unused parts?
 
The following is some code that I put together a while back. Copy/paste the code into a new module in your workbook and then execute it. It will look at the active sheet and go about fixing it. The original file is not altered, the shortened file is saved to the same directory, same original file name with "_Shortened" added to the end of the file name.

I am sure it will make short work of your problematic file. :)

VBA Code:
Sub ExcelSheetSizeReducerV1()
'
'   *** FYI, Can't reduce the size of protected sheets. ;)
'
'-----------------------------------------------------------------------------------------------
'
    Dim startTime               As Single
    startTime = Timer                                                                               '   Start the stopwatch
'
    Application.ScreenUpdating = False                                                              '   Turn ScreenUpdating off
     Application.DisplayAlerts = False                                                              '   Turn DisplayAlerts off
'
'-----------------------------------------------------------------------------------------------
'
    Dim RowHeightsAltered           As Boolean
    Dim ArrayRow                    As Long
    Dim EndRangeRow                 As Long, RowHeightArrayRow          As Long, StartRangeRow  As Long
    Dim LastColumn                  As Long, LastRow                    As Long
    Dim LastColumnRowAddressFormula As Long, LastColumnRowAddressValue  As Long
    Dim LastRowColumnAddressFormula As Long, LastRowColumnAddressValue  As Long
    Dim ShapeTopLeftCellRow         As Long, ShapeTopLeftCellColumn     As Long
    Dim rng                         As Range
    Dim Shp                         As Shape
    Dim MaxRowHeight                As Single
    Dim RowHeightArray              As Variant
'
'-----------------------------------------------------------------------------------------------
'
    With ThisWorkbook.ActiveSheet
'
'-----------------------------------------------------------------------------------------------
'
        If .UsedRange.Rows.Count = Range("A" & Rows.Count).Row Then                                 ' If a problematic sheet is discovered then ...
'
'           Save row heights & the ranges of those row heights of current sheet into RowHeightArray
            Set rng = .Range("A1:A" & .Range("A" & .Rows.Count - 1).Row)                            '   Set the range to search through
'
            ReDim RowHeightArray(1 To rng.Rows.Count + 1, 1 To 2)                                   '   Set the # of rows/columns of RowHeightArray
'
            StartRangeRow = 1                                                                       '   Initialize StartRangeRow
            RowHeightArrayRow = 0                                                                   '   Initialize RowHeightArrayRow
'
            For EndRangeRow = 1 To rng.Rows.Count                                                   '   Loop through the cells of of the rows of column
                If .Range("" & "A" & EndRangeRow & "").Height <> .Range("" & _
                        "A" & EndRangeRow + 1 & "").Height Then                                     '       If this cell value <> next cell value then ...
                    RowHeightArrayRow = RowHeightArrayRow + 1                                       '           Increment the RowHeightArrayRow
                    RowHeightArray(RowHeightArrayRow, 1) = .Range("" & _
                            "A" & EndRangeRow & "").Height                                          '           Save cell value into 1st column of RowHeightArray
                    RowHeightArray(RowHeightArrayRow, 2) = "A" & _
                            StartRangeRow & ":" & "A" & EndRangeRow                                 '           Save Address range to 2nd column of RowHeightArray
                    StartRangeRow = EndRangeRow + 1                                                 '           Set the next StartRangeRow for next address
                End If
            Next                                                                                    '   Loop back
'
'           Get last set of values
            RowHeightArrayRow = RowHeightArrayRow + 1                                               '   Increment the RowHeightArrayRow
            RowHeightArray(RowHeightArrayRow, 1) = .Range("" & "A" & EndRangeRow & "").Height       '   Save cell value into 1st column of RowHeightArray
            RowHeightArray(RowHeightArrayRow, 2) = "A" & StartRangeRow & ":" & "A" & EndRangeRow    '   Save Address range to 2nd column of RowHeightArray
'
'           All different row heights as well as the ranges of those row heights of this sheet are now saved into 2D 1 based RowHeightArray RC
'
'-----------------------------------------------------------------------------------------------
'
'           Find Maximum row height in the array
            MaxRowHeight = 0#                                                                       '   Initialize MaxRowHeight
'
            For ArrayRow = 1 To RowHeightArrayRow                                                   '   Loop through the RowHeightArray saved heights
                If RowHeightArray(ArrayRow, 1) > MaxRowHeight Then                                  '     If a RowHeight is found > MaxRowHeight then ...
                    MaxRowHeight = RowHeightArray(ArrayRow, 1) + 1                                  '       Add 1 to the found RowHeight & Save it as MaxRowHeight
                End If
            Next                                                                                    '   Loop back
'
'-----------------------------------------------------------------------------------------------
'
'           Set all Row Heights to the same height
            On Error Resume Next                                                                    ' Ignore Protected sheet error
            .Cells.RowHeight = MaxRowHeight                                                         ' Set all row heights to same height
            RowHeightsAltered = True                                                                ' Turn RowHeightsAltered flag on
            On Error GoTo 0                                                                         ' Turn off Error ignore
        End If
'
'-----------------------------------------------------------------------------------------------
'
'       Resume normal script
        On Error Resume Next
        LastColumnRowAddressFormula = .Cells.Find("*", , xlFormulas, , xlByColumns, xlPrevious).Column  ' Address of Last row cell in Last Column
          LastColumnRowAddressValue = .Cells.Find("*", , xlValues, , xlByColumns, xlPrevious).Column    ' Address of Last row cell in Last Column
'
        LastRowColumnAddressFormula = .Cells.Find("*", , xlFormulas, , xlByRows, xlPrevious).Row        ' Address of Last column cell in Last Row
          LastRowColumnAddressValue = .Cells.Find("*", , xlValues, , xlByRows, xlPrevious).Row          ' Address of Last column cell in Last Row
        On Error GoTo 0
'
'-----------------------------------------------------------------------------------------------
'
'       Determine the last column
        LastColumn = LastColumnRowAddressFormula
'
        If LastColumnRowAddressValue <> 0 Then
            LastColumn = Application.WorksheetFunction.Max(LastColumn, LastColumnRowAddressValue)   '   Set LastColumn to the maximum value of the 2
        End If
'
'-----------------------------------------------------------------------------------------------
'
'       Determine the last row
        LastRow = LastRowColumnAddressFormula
'
        If LastRowColumnAddressValue <> 0 Then
            LastRow = Application.WorksheetFunction.Max(LastRow, LastRowColumnAddressValue)         '   Set LastRow to the maximum value of the 2
        End If
'
'-----------------------------------------------------------------------------------------------
'
'       Determine if any shapes are beyond the last row and last column
        For Each Shp In .Shapes
            ShapeTopLeftCellRow = 0
            ShapeTopLeftCellColumn = 0
'
            On Error Resume Next
            ShapeTopLeftCellRow = Shp.TopLeftCell.Row
            ShapeTopLeftCellColumn = Shp.TopLeftCell.Column
            On Error GoTo 0
'
            If ShapeTopLeftCellRow > 0 And ShapeTopLeftCellColumn > 0 Then
                Do Until .Cells(ShapeTopLeftCellRow, ShapeTopLeftCellColumn).Top > Shp.Top + Shp.Height
                    ShapeTopLeftCellRow = ShapeTopLeftCellRow + 1
                Loop
'
                If ShapeTopLeftCellRow > LastRow Then
                    LastRow = ShapeTopLeftCellRow
                End If
'
                Do Until .Cells(ShapeTopLeftCellRow, ShapeTopLeftCellColumn).Left > Shp.Left + Shp.Width
                    ShapeTopLeftCellColumn = ShapeTopLeftCellColumn + 1
                Loop
'
                If ShapeTopLeftCellColumn > LastColumn Then
                    LastColumn = ShapeTopLeftCellColumn
                End If
            End If
        Next
'
'-----------------------------------------------------------------------------------------------
'
'       Delete the columns & Rows
        On Error Resume Next                                                                            ' Ignore Protected sheet error
        If LastColumn < .Columns.Count Then .Range(.Cells(1, LastColumn + 1), _
                .Cells(.Rows.Count, .Columns.Count)).EntireColumn.Delete                                ' Delete Columns
        If LastRow < .Rows.Count Then .Range("A" & LastRow + 1 & ":A" & .Rows.Count).EntireRow.Delete   ' Delete Rows
        On Error GoTo 0                                                                                 ' Turn off Error ignore
    End With
'
'-----------------------------------------------------------------------------------------------
'
'   Check to see if we need to restore the previous sheet's original row heights
    If RowHeightsAltered = True Then                                                                    ' If the RowHeights had to be altered then ...
        For ArrayRow = 1 To RowHeightArrayRow                                                           '   Loop through the RowHeightArray
            Range("" & RowHeightArray(ArrayRow, 2) & "").RowHeight = RowHeightArray(ArrayRow, 1)        '       Return the row height back to original
        Next                                                                                            '   Loop back
'
        RowHeightsAltered = False                                                                       '   Turn RowHeightsAltered flag off
    End If
'
'-----------------------------------------------------------------------------------------------
'
    PathFromFileToFix = Application.ThisWorkbook.Path                                                   ' Get file path of current file

    OriginalFileName = Left(ActiveWorkbook.Name, InStrRev(ActiveWorkbook.Name, ".") - 1)                '   Save the UserFilePath with NoExtension
    UserFileExtension = Right(ActiveWorkbook.Name, Len(ActiveWorkbook.Name) - _
            InStrRev(ActiveWorkbook.Name, ".") + 1)                                                     '   Save the UserFileExtension

    ActiveWorkbook.SaveAs Filename:=PathFromFileToFix & "\" & OriginalFileName & "_Shortened" & UserFileExtension              '   Automatically save the 'shortened' size workbook
'
'-----------------------------------------------------------------------------------------------
'
    Application.DisplayAlerts = True                                                                    ' Turn DisplayAlerts back on
    Application.ScreenUpdating = True                                                                   ' Turn ScreenUpdating back on
'
    Debug.Print "Time to complete = " & Timer - startTime & " seconds."                                 ' about xx.xx seconds
'
MsgBox "Completed!"                                                                                     ' Let user know that the process is complete
End Sub
 
Upvote 0

Excel Facts

Did you know Excel offers Filter by Selection?
Add the AutoFilter icon to the Quick Access Toolbar. Select a cell containing Apple, click AutoFilter, and you will get all rows with Apple
The following is some code that I put together a while back. Copy/paste the code into a new module in your workbook and then execute it. It will look at the active sheet and go about fixing it. The original file is not altered, the shortened file is saved to the same directory, same original file name with "_Shortened" added to the end of the file name.
Well it certainly reduced the size of the workbook to a much more reasonable 103k.
But end->down still goes to row 1M+ rendering the scroll bar unusable
Running the resetlast cell code suggested above (then exit with save, reload) made no difference
 
Upvote 0
Johnny's code saved the file to a new name. Did you definitey open the "_Shortened.xlsm" version of the file ?

If yes then is it a big issue if we set all rows to a height of 14.5 ?
If not try this in the immediate window and then check your end of sheet.
(The issue in the file you sent a link to is definitely the inconsistent row heights.)
VBA Code:
ActiveSheet.Rows.RowHeight = 14.5 : ActiveSheet.UsedRange
 
Upvote 0
Yes definitley _shortened.
Not an issue setting cells to 14.5. The sheet is used to import from a web page which screws up row height, merged etc etc (All other sheets deleted in the dropbox version)
Ran code in immediate window.
Save
Close
Open and the scrool bar shows the bottom of the spreadsheet to be row 1180 which is fine (I think it was the active cell with I kicked off the line of code.)
BUT
end->down still goes to row 1M+
end->up then goes to bottom of data and the scroll bar operates normally over the span of cells 1 to 1157 (as opposed to 1 to 1M+) which is just fine

I dont know if end->down is supposed to respect last used cell (but it clearly doesn't) but that, as they say, is someone else's problem :)!

Thanks to everyone for their help

I'll reinstate the full spreadsheet and apply this fix to all sheets where the scroll bar misbehaves. If they are not fixed, I'll report back
 
Upvote 0
I find Ctrl+Down Arrow easier than end down.
If in I am in column H on a data row in your file and I hit ctrl+downarrow it takes me to 1157. If I am on 1157 then it takes me to 1048576
This is how it normally works, not sure if you are saying yours is behaving differently.

In the immediate window the following including the question mark will show you the used range, if you want to check it before and after you make any changes.
On your spreadsheet the Before version showed A:S with no row numbers indicating it was including all the rows.
VBA Code:
? ActiveSheet.UsedRange.Address
 
Upvote 0
I find Ctrl+Down Arrow easier than end down.
If in I am in column H on a data row in your file and I hit ctrl+downarrow it takes me to 1157. If I am on 1157 then it takes me to 1048576
This is how it normally works, not sure if you are saying yours is behaving differently.

In the immediate window the following including the question mark will show you the used range, if you want to check it before and after you make any changes.
On your spreadsheet the Before version showed A:S with no row numbers indicating it was including all the rows.
VBA Code:
? ActiveSheet.UsedRange.Address
That is how mine works - and it seems entirely logical. The Scroll bar was the important feature and that is now properly functional ignoring everything from end of data to 1M+
 
Upvote 0
Here is some code to test the active sheet for problems with the rows:

VBA Code:
Sub RowsChecker()
'
    MsgBox "Actual last used address is " & Cells.Find("*", , xlValues, , xlByRows, xlPrevious).Address(0, 1) & vbCrLf & _
            vbCrLf & "Excel sees the last used Column/Row as " & _
            ActiveSheet.Range("A1").SpecialCells(xlLastCell).Address(0, 1) & vbCrLf & vbCrLf & _
            "Row numbers should be the same. If they are different then their is a problem with the sheet."
End Sub
 
Upvote 0

Forum statistics

Threads
1,223,897
Messages
6,175,269
Members
452,628
Latest member
dd2

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top