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
控件。但是,使用与ColumnsHide
或ColumnsUnhide
相同的方式不会归档所需的结果。
有什么想法吗?
答案 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