Excel 2010:隐藏列组的宏

时间:2013-06-27 19:23:19

标签: excel excel-vba excel-2010 vba

VBA不是我特别的力量,但我们走了:

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


我以前的研究结果

我能找到的关于这一点的唯一好消息是MSDN上的this讨论。这里,一个解决方案正在使用以下方式起草:

从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相同的方式不会归档所需的结果。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

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


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

以下代码是启动的建议,您可以适应您的项目。它不需要您在问题中提到的customUI.xml文件。

关键部分是MyColumnCheck变体,用于检查列是否隐藏,以及.Match方法。这是VBA等效于Match电子表格功能。

使用这段代码教会了我很多关于如何在数组中搜索,以及使用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