Подтвердить что ты не робот

Excel vba заморозить панель без выбора

У меня есть VBA script в Excel, который замораживает панели листа Excel, но мне любопытно узнать, возможно ли это без предварительного выбора диапазона. Здесь по коду, который замораживает строки с 1 по 7:

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

Любые предложения?

4b9b3361

Ответ 1

Запишите себя, используя панель View ► Freeze Panes ► Freeze Top Row, и это то, что вы получите для .FreezePanes.

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

Таким образом, изменение свойств .SplitColumn и/или .SplitRow должно сделать это для вас независимо от того, что свойство ActiveCell.

Ответ 2

Я нашел предыдущие ответы только работали с некоторыми листами, когда looping через tabs. Я нашел следующий код работал на каждой tab я looped через (цель была одна workbook), несмотря на это, workbook была activeworkbook.

Суть этого:

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

Код, как он есть в моем Sub: (имейте в виду, я делаю гораздо больше форматирования в этом 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

Есть много вещей, которые могут ошибаться при заморозке окон. Я добавил свой собственный ответ, чтобы найти его здесь, и мне не придется изобретать его в следующий раз.

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, тогда будет только две панели; А1 - это особый случай, однако, Excel разбил бы окно в центре текущего представления, я предотвратил это, потому что я не могу вспомнить ни одного случая, где это было бы предназначено
  • Он перебирает все окна, прикрепленные к книге/рабочему листу; индексирование в Application.Windows (Windows(Thisworkbook.Name)) не вызовет ошибку, если у вас будет больше окон для одной и той же книги (имя будет "MyWorkbook: 1"), или Excel попытался (как правило, не удается) восстановить книгу после сбой (имя будет "MyWorkbook [Восстановлено]")
  • Принимается во внимание, что панели могут быть уже заморожены, и пользователь/другой макрос мог прокрутиться до местоположения в книге, а верхняя левая ячейка в окне - не A1

Ответ 4

Я знаю, что это старый, но я наткнулся на этот кусок, который может быть полезным... как указано в ChrisB, значения SplitColumn/SplitRow представляют последнюю ячейку выше/слева от разделенного НО текущего видимого окна. Так что если у вас есть такой код:

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

Разделение будет между строками 110 и 111 вместо 10 и 11.

отредактировано для уточнения и добавления дополнительной информации:
Я хочу сказать, что значения являются смещениями верхней левой ячейки, а не адресом ячейки. Следовательно, ChrisB 4 декабря '15 в 18:34 комментарий под основным ответом действителен только в том случае, если строка 1 видна в окне Activewindow.

Несколько других замечаний по этому поводу:

  1. использование Application.goto не обязательно ставит ячейку пытаются перейти в верхнем левом углу
  2. ячейка, которая помещается в верхнем левом углу при использовании .goto может зависеть о размере окна Excel, текущем уровне масштабирования и т.д. (довольно условно)
  3. можно разместить расщепления так, чтобы вы не могли видеть их или даже прокручивать в видимом окне (если .FreezePanes = правда). например:
Application.Goto Worksheets(1).Range("A1"), True  
With ActiveWindow  
 .SplitColumn = 100  
 .SplitRow = 100  
 .FreezePanes = True  
End With  

CETAB может иметь дело с этим в своем ответе.

Ответ 5

Мне нужно иметь возможность правильно замораживать панели (особенно при создании новых окон), не теряя активную ячейку и не портя видимый диапазон. Это заняло много времени, но я думаю, что у меня есть что-то хорошее, что работает:

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