Excel 2010:隐藏列组的宏

Posted

技术标签:

【中文标题】Excel 2010:隐藏列组的宏【英文标题】:Excel 2010: Macro for hidden column groups 【发布时间】:2013-06-25 10:48:43 【问题描述】:

VBA 不是我的专长,但我们开始吧:

我想在一组列被隐藏或显示后触发一个宏。我该如何存档?


我之前的研究结果

我能找到的唯一好的提示是 this MSDN 上的讨论。这里,一个解决方案是用下面的方式起草的:

从 xlsx 文件的根目录创建一个文件 customUI\customUI.xml,内容为

<customUI  xmlns="http://schemas.microsoft.com/office/2006/01/customui" >
    <commands >
        <command 
            idMso="ColumnsHide"
            onAction="ColumnHide_onAction"/>
        <command 
            idMso="ColumnsUnhide"
            onAction="ColumnUnhide_onAction"/>
    </commands >
</customUI >

并添加

<Relationship Id="edTAB" Type="http://schemas.microsoft.com/office/2006/relationships/ui/extensibility" Target="customUI/customUI.xml" />

_rels\_rels.xml。 (这一切使用 Visual Studio 可能要容易得多,但我无法使用微软世界中如此复杂的工具......)现在,可以通过以下方式使用宏:

Public Sub ColumnHide_onAction(control As IRibbonControl, ByRef cancelDefault)
'
' Code for onAction callback. Ribbon control command
'
    MsgBox "Ribbon Column Hide"
    cancelDefault = False

End Sub
Public Sub ColumnUnhide_onAction(control As IRibbonControl, ByRef cancelDefault)
'
' Code for onAction callback. Ribbon control command
'
    MsgBox "Ribbon Column Unhide"
    cancelDefault = False
End Sub

这种方法完美地捕捉了列的隐藏和取消隐藏,但不能隐藏和取消组的隐藏。所以,接近,但不完全在那里。

从here 下载可能的idMso 值,我注意到GroupViewShowHide 控件。但是,以与 ColumnsHideColumnsUnhide 相同的方式使用它不会存档所需的结果。

有什么想法吗?

【问题讨论】:

if(cell.outlinelevel > 0) 然后 cell.entirerow.showdetail = true/false 【参考方案1】:

对于隐藏 列组,我注意到您没有在代码示例中使用.Hidden 属性。它可能非常有用,尤其是当您在数组中定义一组列时。例如:For byti = 0 To UBound(cols()) If Hide Then ActiveSheet.columns(cols(byti)).EntireColumn.Hidden = True ...等等。


检查一组列是否已经隐藏,您也可以使用数组。通过将列分配给数组来对列进行分组,然后将工作表的当前状态(隐藏哪些列,隐藏哪些列)与该数组进行比较。

下面的代码是一个开始的建议,你可以适应你的项目。它不需要您在问题中提到的 customUI.xml 文件。

关键部分是用于检查列是否隐藏的 MyColumnCheck 变体和.Match 方法。这是Match 电子表格函数的VBA 等效项。

处理这段代码教会了我很多关于如何在数组中搜索的知识,以及使用Match 与其他方法(例如Find 并只是循环遍历数组)的优劣!这已经在几篇文章中讨论过,请参阅this one 以获得一个很好的例子。我选择使用Match 而不是For...Next 循环,尽管包含一个For..Next 循环来检查隐藏列是否在您分配的组中会很容易。

如果您想知道 IfError 声明:Application.IfError(Application.Match(MyColumnCheck.Column, MyColumnArray, 0),... ...这是因为在 VBA 代码中使用 Match 通常有点棘手,正如 here 所提到的。此外,正如@Lori_m 写的here,“使用不带 .WorksheetFunction 的应用程序会返回一个变体,它允许在参数和结果中使用数组。”

此外,我选择在检查组数组时将它们的值更改为 -1,因此当该过程完成时,简单的数学运算将显示数组引用的所有列是否都被隐藏。负数更适合此检查,因为我假设您会引用只有正数的实际列。


因此,总而言之,.Match 可以有效地用于检查工作表上的隐藏列是否与数组定义的一组列匹配。

'the column group you're looking for, dim as a dynamic array of column numbers
Dim MyColumnArray(1) As Long
'MyColumnArray(0) is column 2 or "B", MyColumnArray(1) is column 3 or "C", etc
MyColumnArray(0) = 2
MyColumnArray(1) = 3
Dim MyColumnCheck As Variant 'column check

For Each MyColumnCheck In Worksheets("Sheet1").columns
  'if the column is hidden and exists in MyColumnArray array...
  If columns(MyColumnCheck.Column).EntireColumn.Hidden = True And _
  Application.IfError(Application.Match(MyColumnCheck.Column, MyColumnArray, 0), 0) > 0 _
  Then
    MyColumnArray(Application.Match(MyColumnCheck.Column, MyColumnArray, 0) - 1) = -1
    '... set that element of the MyColumnArray array to -1.
  End If
Next

If WorksheetFunction.Sum(MyColumnArray) = 0 - (UBound(MyColumnArray) + 1) Then
  Debug.Print "group MyColumnArray is hidden"
  'execute code here for when the group is hidden
Else
  Debug.Print "group MyColumnArray is visible"
  'execute code here for when the group is visible
End If

【讨论】:

以上是关于Excel 2010:隐藏列组的宏的主要内容,如果未能解决你的问题,请参考以下文章

隐藏SSRS矩阵中的多个列

在excel中显示/隐藏状态栏的宏

如何根据列组前缀替换列组的空白?

用于显示/隐藏行组的数据表按钮

具有动态列组的 LINQ GroupBy

EXCEL中如何显示隐藏项