I am looking to programmatically freeze the top row of an Excel worksheet from VBA. The end goal is to produce the same effect as the View > Freeze Panes > Freeze Top Row
command in Excel 2007 so that the top row of the worksheet is frozen and users can see the top row of the worksheet even as they scroll through the data.

- 20,365
- 9
- 72
- 105

- 875
- 2
- 9
- 13
6 Answers
Rows("2:2").Select
ActiveWindow.FreezePanes = True
Select a different range for a different effect, much the same way you would do manually. The "Freeze Top Row" really just is a shortcut new in Excel 2007 (and up), it contains no added functionality compared to earlier versions of Excel.

- 332,285
- 67
- 532
- 628
-
6Seems like ScreenUpdating has to be on for this to work, but otherwise great. Thanks! – LJ. Jul 12 '10 at 23:25
-
3I'm unclear on how you are freezing the top row by selecting the top row. To freeze the top row, the selection should be `Rows(2)` or `Rows("2:2")`. Selecting `Row("1:1")` results in a four quadrant split of the worksheet. – Jul 29 '15 at 15:10
-
7For a better solution see [This Answer](http://stackoverflow.com/a/34095034/445425) – chris neilsen May 23 '16 at 23:43
-
2@chrisneilsen thanks for that, that other answer is actually much better. – hammythepig Jan 04 '17 at 21:57
Tomalak already gave you a correct answer, but I would like to add that most of the times when you would like to know the VBA code needed to do a certain action in the user interface it is a good idea to record a macro.
In this case click Record Macro on the developer tab of the Ribbon, freeze the top row and then stop recording. Excel will have the following macro recorded for you which also does the job:
With ActiveWindow
.SplitColumn = 0
.SplitRow = 1
End With
ActiveWindow.FreezePanes = True

- 172,527
- 53
- 255
- 316
-
3Yes. This is the right answer. No need to select any part of the worksheet. – Joshua Stafford Feb 03 '15 at 16:58
-
2Good answer but I'm curious why the last statement wasn't tucked into the With ... End With statement. – Jul 29 '15 at 14:32
-
@Jeeped: This is just the raw output of the Excel macro recorder. Of course, you can include the line in the `With` block. – Dirk Vollmar Jul 29 '15 at 15:51
-
@Joshua Stafford: no this is not the "right" answer. One side effect of this technique is that it leaves the Split window state active so that, if you then decide to manually change the freeze-panes state to include a frozen column range on the left (for example), you can't do so unless you happen to notice that the Split state is active and know that you must first turn it off. In effect, that's a subtle "bug" in this technique, which can be very frustrating for the unaware or novice user. Some variation on Dannid's solution, below, avoids that problem. – pstraton Feb 03 '22 at 02:26
-
Man. I dealt with this 7 years ago. I no longer remember, so I'll defer to you. – Joshua Stafford Feb 04 '22 at 04:11
The problem with the recorded macro is the same as the problem with the built-in action: Excel chooses to freeze the top visible row, rather than the actual top row where the header information can be found.
The purpose of a macro in this case is to freeze the actual top row. When I am viewing row #405592 and I need to check the header for the column (because I forgot to freeze rows when I opened the file), I have to scroll to the top, freeze the top row, then find my way back to row #405592 again. Since I believe this is stupid behavior, I want a macro to correct it, but, like I said, the recorded macro just mimics the same stupid behavior.
I am using Office 2011 for Mac OS X Lion
Update (2 minutes later):
I found a solution here: http://www.ozgrid.com/forum/showthread.php?t=19692
Dim r As Range
Set r = ActiveCell
Range("A2").Select
With ActiveWindow
.FreezePanes = False
.ScrollRow = 1
.ScrollColumn = 1
.FreezePanes = True
.ScrollRow = r.Row
End With
r.Select

- 1,507
- 1
- 20
- 17
-
2For any other newbies like me: I was able to freeze the top 8 rows (where my report "dashboard" resides) by making the Range("A9") without changing anything else. – Sean Oct 24 '13 at 23:30
-
Beware: instead of **Range("A2").Select**, it may be tempting to to do something like **Range("1:1").Select** or **Rows(1).Select**, but doing so actually creates a quad-window freeze-panes state. (With no apparent usefulness, so maybe an old Excel bug?) – pstraton Feb 03 '22 at 01:45
Just hit the same problem... For some reason, the freezepanes command just caused crosshairs to appear in the centre of the screen. It turns oout I had switched ScreenUpdating off! Solved with the following code:
Application.ScreenUpdating = True
Cells(2, 1).Select
ActiveWindow.FreezePanes = True
Now it works fine.

- 91
- 1
- 1
To expand this question into the realm of use outside of Excel s own VBA, the ActiveWindow property must be addressed as a child of the Excel.Application object.
Example for creating an Excel workbook from Access:
Using the Excel.Application object in another Office application's VBA project will require you to add Microsoft Excel 15.0 Object library (or equivalent for your own version).
Option Explicit
Sub xls_Build__Report()
Dim xlApp As Excel.Application, ws As Worksheet, wb As Workbook
Dim fn As String
Set xlApp = CreateObject("Excel.Application")
xlApp.DisplayAlerts = False
xlApp.Visible = True
Set wb = xlApp.Workbooks.Add
With wb
.Sheets(1).Name = "Report"
With .Sheets("Report")
'report generation here
End With
'This is where the Freeze Pane is dealt with
'Freezes top row
With xlApp.ActiveWindow
.SplitColumn = 0
.SplitRow = 1
.FreezePanes = True
End With
fn = CurrentProject.Path & "\Reports\Report_" & Format(Date, "yyyymmdd") & ".xlsx"
If CBool(Len(Dir(fn, vbNormal))) Then Kill fn
.SaveAs FileName:=fn, FileFormat:=xlOpenXMLWorkbook
End With
Close_and_Quit:
wb.Close False
xlApp.Quit
End Sub
The core process is really just a reiteration of previously submitted answers but I thought it was important to demonstrate how to deal with ActiveWindow when you are not within Excel's own VBA. While the code here is VBA, it should be directly transcribable to other languages and platforms.
-
1You could also use `Set xlApp = New Excel.Application`, or even `Dim xlApp As New Excel.Application`. – Zev Spitz Oct 10 '16 at 15:28
Rows("2:2").Select
ActiveWindow.FreezePanes = True
This is the easiest way to freeze the top row. The rule for FreezePanes
is it will freeze the upper left corner from the cell you selected. For example, if you highlight C10, it will freeze between columns B and C, rows 9 and 10. So when you highlight Row 2, it actually freeze between Rows 1 and 2 which is the top row.
Also, the .SplitColumn
or .SplitRow
will split your window once you unfreeze it which is not the way I like.

- 4,115
- 3
- 25
- 33