如何在Excel 2007 VBA中通过编程方式冻结Excel工作表的顶部行?

48

我希望能够通过VBA编程方式冻结Excel工作表的顶部行。最终目标是产生与Excel 2007中 查看 > 冻结窗格 > 冻结顶部行 命令相同的效果,使工作表的顶部行被冻结,并且用户可以在滚动数据时看到工作表的顶部行。

6个回答

45
Rows("2:2").Select
ActiveWindow.FreezePanes = True

选择不同的范围会产生不同的效果,就像您手动操作一样。"冻结顶部行"仅是Excel 2007(及以上版本)中的快捷方式,与早期版本相比没有额外的功能。


6
看起来必须打开 ScreenUpdating 才能让这个工作,但除此之外非常好。谢谢! - LJ.
3
我不明白你是如何通过选择顶部行来冻结它。要冻结顶部行,选择应为“Rows(2)”或“Rows("2:2")”。选择"Rows("1:1")"会导致工作表被分成四个象限。 - user4039065
7
为了更好的解决方案,请查看此答案 - chris neilsen
2
@chrisneilsen 谢谢您,那个其他的答案实际上更好。 - hammythepig

22

Tomalak已经给了您一个正确的答案,但我想补充说,大多数情况下,当您想知道执行特定操作所需的VBA代码时,记录宏是一个好主意。

在这种情况下,在Ribbon的“开发人员”选项卡上单击录制宏,冻结顶部行,然后停止录制。 Excel将为您记录以下宏,该宏也会完成工作:

With ActiveWindow
    .SplitColumn = 0
    .SplitRow = 1
End With
ActiveWindow.FreezePanes = True

3
是的,这是正确答案。不需要选择工作表的任何部分。 - Joshua Stafford
2
好的答案,但我很好奇为什么最后一条语句没有放在 With ... End With 语句中。 - user4039065
@Jeeped:这只是Excel宏记录器的原始输出。当然,您可以将该行包含在With块中。 - Dirk Vollmar
@Joshua Stafford:不,这不是“正确”的答案。这种技术的一个副作用是它保持了分割窗口状态的活动性,因此,如果您随后决定手动更改冻结窗格状态以包括左侧的冻结列范围(例如),除非您注意到分割状态处于活动状态并知道必须先关闭它,否则无法这样做。实际上,这是这种技术中微妙的“错误”,对于不知情或新手用户来说可能非常令人沮丧。 Dannid 的解决方案的某些变化可以避免这个问题。 - pstraton
人。我7年前处理过这个问题。我已经不记得了,所以我就交给你了。 - Joshua Stafford

15
记录的宏存在与内置操作同样的问题:Excel选择冻结顶部可见行,而不是实际的顶部行,其中包含标题信息。
在这种情况下,宏的目的是冻结实际的顶部行。当我查看第405592行并需要检查列的标题时(因为我打开文件时忘记冻结行),我必须滚动到顶部,冻结顶部行,然后再回到第405592行。由于我认为这是愚蠢的行为,因此我想要一个宏来纠正它,但是像我说的那样,记录的宏只是模仿了相同的愚蠢行为。
我正在使用Mac OS X Lion的Office 2011
更新(2分钟后):
我在这里找到了解决方案: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 

2
对于像我这样的新手:我能够通过将Range(“A9”)设置为固定行,而不改变其他任何内容来冻结前8行(我的报告“仪表板”所在的位置)。 - Sean
警告:代替 Range("A2").Select,使用 Range("1:1").SelectRows(1).Select 等操作是很诱人的,但这实际上会创建一个四个窗口的冻结窗格状态。(似乎没有任何用处,所以可能是旧版 Excel 的错误?) - pstraton

10

我遇到了同样的问题... 由于某种原因,冻结窗格命令只会使十字线出现在屏幕中心。原来是我关闭了ScreenUpdating! 用以下代码解决:

Application.ScreenUpdating = True
Cells(2, 1).Select
ActiveWindow.FreezePanes = True

现在它很好用。


7
要将这个问题扩展到Excel的VBA之外的使用领域,必须将ActiveWindow属性作为Excel.Application对象的子代进行处理。
从Access创建Excel工作簿的示例:

在其他Office应用程序的VBA项目中使用Excel.Application对象需要添加Microsoft Excel 15.0对象库(或您自己版本的等效物)。

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

核心流程实际上只是先前提交答案的重复,但我认为演示如何处理ActiveWindow在不在Excel自己的VBA中非常重要。虽然这里的代码是VBA,但它应该可以直接转录到其他语言和平台。


1
你也可以使用 Set xlApp = New Excel.Application,或者甚至是 Dim xlApp As New Excel.Application - Zev Spitz

3
Rows("2:2").Select
ActiveWindow.FreezePanes = True

这是冻结顶部行最简单的方法。FreezePanes规则是冻结从您选择的单元格的左上角开始的区域。例如,如果您突出显示了C10,则会在B和C列、9和10行之间冻结。因此,当您突出显示第2行时,它实际上会在第1行和第2行之间冻结,即顶部行。
另外,SplitColumn或SplitRow将在取消冻结后拆分您的窗口,这不是我喜欢的方式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接