excel vba冻结窗格没有选择

时间:2015-12-04 17:52:24

标签: excel-vba vba excel

我在Excel中有一个VBA脚本冻结了Excel工作表的窗格,但我很想知道如果没有先选择一个范围,这是否可行。现在通过代码冻结第1行到第7行:

ActiveSheet.Range("A8").Select
ActiveWindow.FreezePanes = True

有什么建议吗?

7 个答案:

答案 0 :(得分:31)

使用视图►冻结窗格►冻结顶行命令记录自己,这是.FreezePanes获得的。

With ActiveWindow
    If .FreezePanes Then .FreezePanes = False
    .SplitColumn = 0
    .SplitRow = 1
    .FreezePanes = True
End With

因此,无论.SplitColumn是什么,修改.SplitRow和/或ActiveCell property属性都应该为您完成。

答案 1 :(得分:2)

冻结窗格有很多错误。我添加了自己的答案,因此可以在这里找到它,而下次无需重新发明它。

Public Sub FreezePanesAt(rngDataTopLeft As Range)
    Dim wndCurrent As Window: For Each wndCurrent In rngDataTopLeft.Worksheet.Parent.Windows
        With wndCurrent
            .FreezePanes = False
            If Not ((rngDataTopLeft.Row = 1) And (rngDataTopLeft.Column = 1)) Then
                .ScrollRow = 1
                .ScrollColumn = 1
                .SplitRow = rngDataTopLeft.Row - 1
                .SplitColumn = rngDataTopLeft.Column - 1
                .FreezePanes = True
            End If
        End With
    Next
End Sub

用法示例:

FreezePanesAt ThisWorkbook.Worksheets("Sheet1").Range("B3")
FreezePanesAt ThisWorkbook.Names("Header").RefersToRange
  • 输入参数是右下方窗格的左上方单元格;我认为这是最常见的用例:您知道要拆分的范围,而不必关心它位于哪个工作簿/工作表/窗口中
  • 如果输入参数在第一行/第一个单元格中,但不在A1中,则将只有两个窗格; A1是一种特殊情况,但是,Excel会在当前视图的中心拆分窗口,所以我避免了这种情况,因为我无法想到这种情况是什么
  • 遍历工作簿/工作表附带的所有Windows;如果您对同一工作簿有更多窗口(名称将为“ MyWorkbook:1”),或者尝试使用Excel(通常会失败),则索引到Application.WindowsWindows(Thisworkbook.Name))不会导致错误。崩溃后修复工作簿(名称为“ MyWorkbook [Repaired]”)
  • 考虑到窗格可能已经冻结,并且用户/另一个宏可能已经滚动到工作簿中的某个位置,并且窗口左上角的单元格不是A1

答案 2 :(得分:1)

我发现先前的答案仅在loopingtabs时适用于某些工作表。我发现以下代码对我tab到的每个looped都有效(目标是单个workbook),尽管workbookactiveworkbook

它的简称:

With Application.Windows(DataWKB.Name) 
    Application.Goto ws.Cells(4, 5)
    .SplitColumn = 4
    .SplitRow = 3
    .FreezePanes = True
End With

Sub中的代码:(请注意,我在此子代码中做了很多格式化,我试图将其删除,只保留此处所需的代码)

Sub Format_Final_Report()
Dim DataWKB As Workbook
Set DataWKB = Workbooks("Report.xlsx")
Dim ws As Worksheet

Dim tabCNT As Long
Dim tabName As String
tabCNT = DataWKB.Sheets.Count

For i = 1 To tabCNT
    Set ws = DataWKB.Worksheets(i)
    tabName = ws.Name


    With Application.Windows(DataWKB.Name)
        Application.Goto ws.Cells(4, 5)
        .SplitColumn = 4
        .SplitRow = 3
        .FreezePanes = True
    End With

Next i

End Sub

希望这将为将来节省一些研究时间。

答案 3 :(得分:1)

是的,如果您的可见窗口不包含单元格 A1,则 ActiveWindow.ScrollRow = 1ActivWindow.ScrollColumn = 1 是 FreezePanes 必须的。

如果您通过选择第 4 行或单元格 A4 以 1:3 的比例冻结行,并且单元格 A3 不可见,则 FreezePanes 函数会将窗口冻结在可见窗口的中心。

另外,如果单元格 B4 被选中,并且 A 列不可见,那么只有 1:3 的行会被冻结(A 列不会被冻结)。同样,如果 1:3 行不可见,则只有 A 列会被冻结。如果 A 列和 1:3 行都不可见,则 FreezePanes 函数会将窗口冻结在可见窗口的中心。

答案 4 :(得分:0)

我知道这已经过时但是我遇到了这个可能有用的信息...... 正如ChrisB所述,SplitColumn / SplitRow值表示当前可见窗口的分割BUT上方/左侧的最后一个单元格。所以,如果您碰巧有这样的代码:

Application.Goto Worksheets(2).Range("A101"), True
With ActiveWindow
 .SplitColumn = 0
 .SplitRow = 10
 .FreezePanes = True
End With

分割将在行110和111之间而不是10和11之间。

编辑以澄清并添加更多信息:
我的观点是,值是左上角单元格的偏移量,而不是单元格的地址。因此,如果第1行在Activewindow中可见,ChrisB在2015年12月4日18:34评论下的主要答案仍然有效。

其他几点:

  1. 使用Application.goto不一定会把你的任何一个单元格 正试图进入左上角
  2. 使用.goto时, 放在左上角的单元格可以依赖 关于excel窗口的大小,当前缩放级别等(非常随意)
  3. 可以放置分割,以便您看不到 它们甚至在可见窗口中滚动(如果.FreezePanes = 真正)。例如:
  4. Application.Goto Worksheets(1).Range("A1"), True  
    With ActiveWindow  
     .SplitColumn = 100  
     .SplitRow = 100  
     .FreezePanes = True  
    End With  
    

    CETAB可能正在回答这个问题。

答案 5 :(得分:0)

我需要能够正确地重新冻结窗格(特别是在创建新窗口时),而不会丢失活动单元格或弄乱可见范围。花费了很多时间,但我认为我有一些可行的方法:

Sub FreezePanes(nbLignes As Integer, nbColonnes As Integer, Optional ByVal feuille As Worksheet)
    If feuille Is Nothing Then Set feuille = ActiveSheet Else feuille.Activate
    Error GoTo erreur
    With ActiveWindow
        If .View = xlNormalView Then
            If .FreezePanes Then .FreezePanes = False
            If .Split Then .Split = False

            .SplitColumn = nbColonnes
            .SplitRow = nbLignes

            If .Panes.Count = 4 Then 'rows and columns frozen
                .Panes(1).ScrollRow = 1
                .Panes(1).ScrollColumn = 1
                .Panes(2).ScrollRow = 1 'top right pane
                .Panes(3).ScrollColumn = 1 'bottom left pane
            ElseIf nbLignes > 0 Then .Panes(1).ScrollRow = 1
            ElseIf nbColonnes > 0 Then .Panes(1).ScrollColumn = 1
            Else: GoTo erreur
            End If

            .FreezePanes = True
        End If
    End With
    Exit Sub
erreur:
    Debug.print "Erreur en exécutant le sub 'FreezePanes " & nbLignes & ", " & nbColonnes & ", '" & feuille.Name & "' : code #" & Err.Number & Err.Description
End Sub

答案 6 :(得分:0)

这是我使用的...

Public Sub FreezeTopRowPane(ByRef MyWs As Excel.Worksheet, _
                            Optional ByVal AfterRowNr As Integer = 1)

Dim SavedWS As Worksheet
Dim SavedUpdating As Boolean

SavedUpdating = Application.ScreenUpdating      'save current screen updating mode

Set SavedWS = ActiveSheet                       'save current active sheet

Application.ScreenUpdating = False              'turn off screen updating
MyWs.Activate                                   'activate worksheet for panes freezing
ActiveWindow.FreezePanes = False                'turn off freeze panes in case 
With ActiveWindow
    .SplitColumn = 0                            'set no column to split
    .SplitRow = AfterRowNr                      'set the row to split, default = row 1
End With
ActiveWindow.FreezePanes = True                 'trigger the new pane freezing

SavedWS.Activate                                'restore previous (saved) ws as active

Application.ScreenUpdating = SavedUpdating      'restore previous (saved) updating mode

End Sub