如何知道当前的schema级别?大纲级别?

问题描述 投票:0回答:1

Excel 允许您使用

Outline.ShowLevels
建立显示轮廓的级别。

有什么方法可以知道当前方案中显示的级别吗? 像

levels = Outline.Levels

之类的东西

似乎没有这方面的任何信息。

excel vba
1个回答
0
投票

鉴于官方帮助页面上令人困惑的信息,我进行了自己的测试,之后我得出以下结论:

'OUTLINE OF GROUPINGS OF A RANK:
'===============================

'In the Excel ribbon:
'Data/Scheme/Group-Ungroup-Subtotal

'In VBA:
'ActiveSheet.Outline


'Show/Hide outline bar:
'----------------------
'ActiveWindow.DisplayOutline = True 'False


'Expand or Collapse Groupings of the entire sheet:
'-------------------------------------------------
'ActiveSheet.Outline.ShowLevels([RowLevels], [ColumnLevels])


'Collapse Groupings of the entire sheet:
'--------------------------------------
'ActiveSheet.Outline.ShowLevels 1


'Group a range: _
  The specified range must be a row or a column, _
  or a range of rows or columns.
'---------------------------------------------------
'Range.Group
'Range.EntireRow.Group
'Range(Rows(r1), Rows(r2)).Group


'Reduce the grouping level of a range by one level. _
  The specified range must be a row or a column, _
  or a range of rows or columns.
'------------------------------------------------- --------
'Range.Ungroup
'Range.OutlineLevel = Range.OutlineLevel - 1


'Completely ungroup a range:
'---------------------------
'Range.ClearOutline 'Clears the outline of the specified range.
'Range.OutlineLevel = 1
'Rows.Hidden = False 'You need to show hidden rows after ungrouping!


'OUTLINE LEVEL OF A RANGE:
'-------------------------
'Returns or sets the schema level of a range:
'Moves a range (grouped or not) through the different levels of the outline.
'Read and write Variant.

'Range.OutlineLevel = level
'Range.EntireRow.OutlineLevel = level
'Rows(r).OutlineLevel = level
'Range(Rows(r1), Rows(r2)).OutlineLevel = level

'IMPORTANT: It seems that the maximum number of possible levels in a outline is 8

'Level 1:
'--------
'It is the default outline level of a range when it has no groupings.
'If we set the range outline level to 1, grouping is removed from the range.
'---------------------------------------------------------------------------
'Range.OutlineLevel = 1 'Remove range grouping!



'EXPAND AND COLLAPSE GROUPS (ShowDetail: show/hide detail of the grouped range)
'------------------------------------------------- ---------------------
'NOTE: only works if the range grouping level is within _
       the visible levels set for the sheet by _
       ActiveSheet.Outline.ShowLevels level
'------------------------------------------------- -------------------
'EXPAND GROUP: Show hidden rows within the group:
'Range.ShowDetail = True

'COLLAX GROUP: Hides the rows of the group except the first:
'Range.ShowDetail = False

'CHECK: Know if a group is contracted or expanded:
'expanded = Range.ShowDetail

'IMPORTANT: It can be applied to any row in the group.
'------------------------------------------------- ---------------------


'THE FOLLOWING DOES NOT WORK:
'-------------------------
'Locking and unlocking the outline bar when the sheet is protected:
'------------------------------------------------------------------
'ActiveSheet.EnableOutlining 'Reading and writing
'ActiveSheet.EnableOutlining = True 'Not working!!!!!



'Conditional formatting based on outline level:
'------------------------------------------------- ---
'Requires the use of a VBA helper function that _
  we will use with the definition of the conditional format:
'=OutlineLevelFunc(CELL("row",A1)) = i

Function OutlineLevelFunc(ByVal r As Long) As Integer
On Error Resume Next

OutlineLevel = Rows(r).OutlineLevel

End Function 'OutlineLevelFunc

不同范围的分组顺序很重要,以及控制不同级别组的重叠也很重要。

由于解释起来有些复杂,我添加以下通用过程作为实际示例,以建立具有 3 个架构级别的范围的分组。

它需要一个列范围作为参数,其中每行的级别用字符串(“l1”,“l2”,“l3”)标记,以及用作数据引用的第二列范围(在本例中)文本),以及定义每个级别对应的标记的三个参数。

Sub MakeOutlineLevels(ByVal rangeRef As Range, _
                      ByVal levelsRange As Range, _
                      ByVal level1 As String, _
                      ByVal level2 As String, _
                      ByVal level3 As String)
'Use: _
MakeOutlineLevels rangeRef, levelsRange, "l1", "l2", "l3" '...
Dim wsheet As Worksheet
Dim selectedRange As Range
Dim currentCell As Range
Dim r As Long
Dim maxRow As Long
Dim level As String
Dim l1_start As Long
Dim l1_end As Long
Dim l2_start As Long
Dim l2_end As Long
Dim l3_start As Long
Dim l3_end As Long

On Error Resume Next

Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual '-4135
Application.EnableEvents = False

Set wsheet = rangeRef.Worksheet

With wsheet

'Show all rows:
.Rows.ClearOutline
If .FilterMode Then .UsedRange.AutoFilter
Set selectedRange = Selection
.UsedRange.EntireRow.Select
Selection.EntireRow.Hidden = False
selectedRange.Select

ResetUsedRange rangeRef 'See below.

maxRow = ActiveSheet.UsedRange.Rows.Count

For r = .Range(CR_LímiteEdición).Row + 1 To maxRow
    
    Set currentCell = Cells(r, rangeRef.Column)
    
    currentCell.Select
    ActiveWindow.ScrollRow = currentCell.Row - 1

    level = Cells(r, levelsRange.Column)

   'Level 1:
    If level = level1 Then
       
      'If there is level 3 pending grouping:
       If l3_start <> 0 Then
         'Add empty hidden row to close group:
          If currentCell.Offset(-1) <> nStr Then
             currentCell.EntireRow.Insert
             ActiveCell.RowHeight = 0
          End If
          l3_end = r - 2
         .Range(.Rows(l3_start), .Rows(l3_end)).Group
       End If
       
      'If there is level 2 pending grouping:
       If l2_start <> 0 Then
         'Add empty hidden row to close group:
          If currentCell.Offset(-1) <> nStr Then
             currentCell.EntireRow.Insert
             ActiveCell.RowHeight = 0
          End If
          l2_end = r - 2
         .Range(.Rows(l2_start), .Rows(l2_end)).Group
       End If
          
      'Start of level 1:
       If l1_start = 0 Then
          l1_start = r + 1
      'End of level 1:
       Else
           l1_end = r - 1
          .Range(.Rows(l1_start), .Rows(l1_end)).Group
           l1_start = r + 1
       End If
       
      'When grouping level 1, reset counters of lower levels:
       l2_start = 0
       l3_start = 0
       
   'Level 2:
    ElseIf level = level2 Then
                  
          'If there is level 3 pending grouping:
           If l3_start <> 0 Then
           
             'Add empty hidden row to close group:
              If currentCell.Offset(-1) <> nStr Then
                 currentCell.EntireRow.Insert
                 ActiveCell.RowHeight = 0
              End If
              l3_end = r - 2
             .Range(.Rows(l3_start), .Rows(l3_end)).Group
              l3_start = 0
           
           End If
       
          'Start of level 2:
           If l2_start = 0 Then
       
             'First level 2 group within level 1, group rows after the start of level 1:
                'Add empty hidden row to close group:
                 If currentCell.Offset(-1) <> nStr Then
                    currentCell.EntireRow.Insert
                    ActiveCell.RowHeight = 0
                 End If
                 l2_start = l1_start
                 l2_end = r - 1
                .Range(.Rows(l2_start), .Rows(l2_end)).Group
           
              l2_start = r + 1
              
          'End of level 2:
           Else
               l2_end = r - 1
              .Range(.Rows(l2_start), .Rows(l2_end)).Group
               l2_start = r + 1
           End If
       
          'When grouping level 2, we reset counters of the lower levels:
           l3_start = 0
       
   'Level 3:
    ElseIf level = level3 Then
       
          'Start of level3:
           If l3_start = 0 Then
       
             'First level 3 group within level 2, group rows after the start of level 2:
                'Add empty hidden row to close group:
                 If currentCell.Offset(-1) <> nStr Then
                    currentCell.EntireRow.Insert
                    ActiveCell.RowHeight = 0
                 End If
                 l3_start = l2_start
                 l3_end = r - 1
                .Range(.Rows(l3_start), .Rows(l3_end)).Group
           
              l3_start = r + 1
          
          'End of level3 (agrupar):
           Else
           
               l3_end = r - 1
              .Range(.Rows(l3_start), .Rows(l3_end)).Group
              
               l3_start = r + 1
           
           End If

   'Last row:
    ElseIf r = maxRow Then
       
          'If there is level 3 pending grouping:
           If l3_start <> 0 Then
              l3_end = r
             .Range(.Rows(l3_start), .Rows(l3_end)).Group
           End If
           
          'If there is level 2 pending grouping:
           If l2_start <> 0 Then
              l2_end = r
             'If there is level 3 pending grouping:
              If l3_start <> 0 Then l2_end = l2_end + 1
             .Range(.Rows(l2_start), .Rows(l2_end)).Group
           End If
           
          'If there is level 1 pending grouping:
           If l1_start <> 0 Then
              l1_end = r
             'If there is level 3 pending grouping:
              If l3_start <> 0 Then l1_end = l1_end + 1
             'If there is level 2 pending grouping:
              If l2_start <> 0 Then l1_end = l1_end + 1
             .Range(.Rows(l1_start), .Rows(l1_end)).Group
           End If

    End If
    
Next

Application.CutCopyMode = False

.Calculate

End With

Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic '-4105
Application.EnableEvents = True

End Sub 'MakeOutlineLevels






Sub ResetUsedRange(Optional ByVal ref As Range)
'Reset .UsedRange to adjust it to the area actually used in the active sheet!
Dim r As Long
Dim c As Integer

On Error Resume Next
    
Application.ActiveSheet.UsedRange
'NOTE: This do not clear blank rows at the end of the range used!

If ref Is Nothing Then Exit Sub

With ref.Worksheet

c = ref.Column

'Eliminar filas en blanco:
For r = .UsedRange.Rows.Count To 2 Step -1
    If .Cells(r, c) = vbNullString Then
       .Rows(r).Delete
    Else
        Exit For
    End If
Next

End With

End Sub 'ResetUsedRange

板材结构:

© www.soinside.com 2019 - 2024. All rights reserved.