因此,现在我正在开发VBA宏,它将只能选择满足指定条件的单元格。问题是我有多个级别单元格的嵌套列表。每个级别由合并的列的数量确定。因此,级别 0 是ABCDE
,级别 1 包含合并列BCDE
,级别 2的单元格仅合并CDE
,级别 3 DE
和级别 4 仅E
。请查看随附的图片,以获得更好的可视化效果。问题是我不能只选择列,因为它会一次选择所有级别。
因此,假设我只选择 1级单元格(因此是从BCDE
列合并的单元格)-如何在VBA中做到这一点?
谢谢
*) ABCD
在原始帖子中(见评论)
答案 0 :(得分:2)
此过程使您可以选择任何给定范围以及要选择的级别。它通过将给定范围内的列数作为“级别0”所需的列数来确定行的级别,并从中减去最后一列的合并范围内的列数。
为帮助说明其工作原理,我添加了一个可选变量以写出每一行的级别(在选定范围之后的两列)。默认情况下,该选项不显示级别。
还添加了T.M.检查oSelectRange的建议,以防止选择时崩溃。谢谢:)
Sub Test()
Call GetRowLevel(Sheet1.Range("A1:E8"), 4, True)
End Sub
Private Sub GetRowLevel(ByVal SearchRange As Range, ByVal Level As Integer, Optional ShowLevel As Boolean = False)
Dim oLevel0 As Integer ' Number of columns in Level 0
oLevel0 = SearchRange.Columns.Count
Dim oRowCounter As Long
Dim oSelectRange As Range
Set oSelectRange = Nothing
For oRowCounter = 1 To SearchRange.Rows.Count
If oLevel0 - SearchRange.Cells(oRowCounter, SearchRange.Columns.Count).MergeArea.Columns.Count = Level Then
If oSelectRange Is Nothing Then
Set oSelectRange = SearchRange.Cells(oRowCounter, SearchRange.Columns.Count).MergeArea
Else
Set oSelectRange = Application.Union(oSelectRange, SearchRange.Cells(oRowCounter, SearchRange.Columns.Count).MergeArea)
End If
End If
'Testing: Show Levels
If ShowLevel Then
Sheet1.Cells(oRowCounter, SearchRange.Columns.Count + 2).Value = oLevel0 - SearchRange.Cells(oRowCounter, SearchRange.Columns.Count).MergeArea.Columns.Count
End If
Next
If Not oSelectRange Is Nothing Then oSelectRange.Select
End Sub
答案 1 :(得分:1)
选择定义的级别
” ...因此,级别0 为
ABCDE
,级别1 包含合并列BCDE
,级别2 仅合并CDE
,级别 3DE
和级别4 仅合并E
。”
此方法使用Level
和MergeCells
属性选择给定MergeArea
(如上定义的 )的所有项,以检查定义的合并单元格Level
通过辅助功能bIsLevel()
。
应用的方法
基本上是
c
*)是否属于合并的单元格范围(If c.MergeCells Then ...
),c.MergeArea.Address
,bIsLevel()
根据所需的级别x地址检查找到的地址在第一个循环条件下最近编辑的注释
*)由于MergeArea.Addresses
仅显示第一个包含的范围(合并范围的顶部/左侧单元格),因此可以将搜索范围从例如.UsedRange
到其中对应于Level + 1
的列;因此,我将For Each c In Intersect(.UsedRange, .Columns(Level + 1))
编辑为新的循环条件。
调用主过程SelectLevel
过程SelectLevel
有两个可选参数:(1)OP定义的所需级别,(2)合格的工作表名称。可以通过以下示例语句来调用它(注意:,如果您未分配第一个参数,则 level 0
是假设默认情况下,第二个参数默认为您选择的工作表名称,并且应更改为当前工作表名称)。
SelectLevel 1 ' e.g. level 1 selects all merged cells of columns B:E
主要过程SelectLevel
Sub SelectLevel(Optional Level& = 0, Optional ByVal SheetName$ = "MySheet")
Dim c As Range, rng As Range, i&
With ThisWorkbook.Worksheets(SheetName)
For Each c In Intersect(.UsedRange, .Columns(Level + 1))
If c.MergeCells Then
If c.Address = Left(c.MergeArea.Address, Len(c.Address)) Then
If bIsLevel(c, Level) Then
If rng Is Nothing Then
Set rng = c
Else
Set rng = Application.Union(rng, c)
End If
End If
End If
End If
Next
End With
' Execute selection of wanted level
If Not rng Is Nothing Then
rng.Select
Else
MsgBox "Found no LEVEL" & Level & " items.", vbExclamation, "No Selection"
End If
End Sub
辅助功能bIsLevel()
Function bIsLevel(currCell As Range, ByVal lvl&) As Boolean
Dim LevelAddress$, CellAddress$
Dim arr(): arr = Array("A", "B", "C", "D", "E")
LevelAddress = arr(lvl) & ":" & arr(UBound(arr)) ' define Level columns due to OP
CellAddress = Split(currCell.MergeArea.Address, "$")(1) & ":" & _
Split(currCell.MergeArea.Address, "$")(3)
bIsLevel = (LevelAddress = CellAddress)
'If bIsLevel Then Debug.Print "cell " & currCell.Address & " in currcell.MergeArea " & currCell.MergeArea.Address & _
" (" & CellAddress & " equ./LEVEL" & lvl & " " & LevelAddress & ")"
End Function