如何自动隐藏其他工作表中的列。

huangapple go评论47阅读模式
英文:

How to automatically hide columns in other sheets

问题

我想编写一个VBA函数,使得当“主”工作表中的一列被隐藏时,所有其他工作表中具有相同名称的列也会被隐藏。以下是我在“主”工作表中的代码:

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim i As Integer, ws As Worksheet

    If IsEntireColumn(Target) = True Then
        If Target.Hidden = True Then

            For i = 1 To Target.Columns.Count
                For Each ws In ThisWorkbook.Worksheets
                    If ws.Name = "Master" Or ws.Name = "Affiliate Codes" Then
                    Else
                        ws.Cells(1, ColumnIndexReturn(ws.Name, Target.Cells(1, i), 3)).EntireColumn.Hidden = True
                    End If
                Next ws
            Next i

        End If
    End If

End Sub

为了背景信息,IsEntireColumn是一个布尔函数,如果选择的范围确实是整个列,则返回True,而ColumnIndexReturn是另一个函数,根据其名称返回列的索引。

由于这是一个Worksheet_Change子过程,我期望每次隐藏一列时,其他工作表中的相应列也会自动隐藏。然而,到目前为止,这并没有发生,其他工作表中的列没有自动隐藏。

请问可能的问题是什么?如果需要更多信息,请随时告诉我。非常感谢您的帮助!提前致谢!

英文:

I would like to write a VBA function such that when a column in a "Master" sheet is hidden, the same column (of the same name) in all other sheets is also hidden. Below is what I have in my "Master" sheet code:

Private Sub Worksheet_Change(ByVal Target As Range)    
    Dim i As Integer, ws As Worksheet

    If IsEntireColumn(Target) = True Then    
        If Target.Hidden = True Then

            For i = 1 To Target.Columns.Count
                For Each ws In ThisWorkbook.Worksheets
                    If ws.Name = "Master" Or ws.Name = "Affiliate Codes" Then
                    Else
                        ws.Cells(1, ColumnIndexReturn(ws.Name, Target.Cells(1, i), 3)).EntireColumn.Hidden = True
                    End If
                Next ws
            Next i 

        End If    
    End If    

End Sub

For context, IsEntireColumn is a boolean function that returns True if the selected range is indeed entire columns, while ColumnIndexReturn is another function that returns the column index of a column by its name.

Since this is a Worksheet_Change sub, I would expect that each time I hide a column, the corresponding columns in other sheets will also be hidden automatically. However, so far this has not been happening, the columns in the other worksheets are not hiding themselves automatically.

May I know what may be the issue here? Feel free to let me know if any further information is required. Any help would be greatly appreciated! Thank you in advance!

答案1

得分: 5

你的请求有点棘手。

主要原因是你的代码没有做任何事情:Change 事件只有在单元格内容发生更改时才会触发。显示/隐藏单元格(或任何其他格式)不会触发更改事件。

一个更好的事件可能是 Selection_Change 事件,它会在选择单元格时触发。然而,这也不起作用:当你选择一个列时,它会触发一次,当你右键单击(选择“隐藏”命令)时,它会再次触发,但在隐藏列之后会触发。

我想到的最好的方法是在 Selection_Change 事件中“记住”所选列。当下一次调用 Selection_Change 时,执行先前记住的列的显示/隐藏逻辑 - 迟早用户会选择另一个单元格。但有一个例外:当用户在隐藏列之后立即选择另一个工作表。为了解决这个问题,我们可以使用 Worksheet_Deactivate 事件。

我想到了以下代码片段:

Option Explicit
Dim lastSelectedColumn As Range

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Not lastSelectedColumn Is Nothing Then
        ShowHideColumns lastSelectedColumn
    End If
    
    If IsEntireColumn(Target) Then
        Set lastSelectedColumn = Target
    Else
        Set lastSelectedColumn = Nothing
    End If
End Sub

Private Sub Worksheet_Deactivate()
    If Not lastSelectedColumn Is Nothing Then
        ShowHideColumns lastSelectedColumn
        Set lastSelectedColumn = Nothing
    End If
End Sub

Sub ShowHideColumns(Target As Range)
    Dim col As Long, ws As Worksheet
    For col = 1 To Target.Columns.Count
        For Each ws In ThisWorkbook.Worksheets
            If ws.Name <> "Master" And ws.Name <> "Affiliate Codes" And ws.Name <> Target.Parent.Name Then
                Dim cell As Range
                Set cell = Target.Cells(1, col)
                ws.Cells(1, cell.Column).EntireColumn.Hidden = cell.EntireColumn.Hidden
            End If
        Next ws
    Next col
End Sub

Function IsEntireColumn(Target As Range) As Boolean
    IsEntireColumn = (Target.Rows.Count = Target.Parent.Rows.Count)
End Function

请注意,这段代码不仅隐藏列,还会显示它们。

英文:

Your request is a little bit tricky.

The main reason your code is not doing anything: The Change-event is only triggered if content of cells are changed. Showing/hiding a cell (or any other formatting) will not trigger the change-event.

A better event would the the Selection_Change-event that is triggered, whenever a cell is selected. However, this is also not working: This event is triggered when you select a column, it is triggered another time when you right click (to select the "Hide"-command), but it is not triggered after the column was hidden.

Best idea I came up is to "remember" a selected column in the Selection_Change event. When the Selection_Change is called the next time, do the show/hide logic for the previous remembered columns - sooner or later the user will select another cell. With one exception: When a user selects a different sheet immediately after hiding a column. To address this, we can use the Worksheet_Deactivate-event.

I came up with the following piece of code:

Option Explicit
Dim lastSelectedColumn As Range

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Not lastSelectedColumn Is Nothing Then
        ShowHideColumns lastSelectedColumn
    End If
    
    If IsEntireColumn(Target) Then
        Set lastSelectedColumn = Target
    Else
        Set lastSelectedColumn = Nothing
    End If
End Sub

Private Sub Worksheet_Deactivate()
    If Not lastSelectedColumn Is Nothing Then
        ShowHideColumns lastSelectedColumn
        Set lastSelectedColumn = Nothing
    End If
End Sub

Sub ShowHideColumns(Target As Range)
    Dim col As Long, ws As Worksheet
    For col = 1 To Target.Columns.Count
        For Each ws In ThisWorkbook.Worksheets
            If ws.Name &lt;&gt; &quot;Master&quot; And ws.Name &lt;&gt; &quot;Affiliate Codes&quot; And ws.Name &lt;&gt; Target.Parent.Name Then
                Dim cell As Range
                Set cell = Target.Cells(1, col)
                ws.Cells(1, cell.Column).EntireColumn.Hidden = cell.EntireColumn.Hidden
            End If
        Next ws
    Next col
End Sub

Function IsEntireColumn(Target As Range) As Boolean
    IsEntireColumn = (Target.Rows.Count = Target.Parent.Rows.Count)
End Function

Note that the code not only hides the column(s), but it will also show them again.

答案2

得分: 3

@FunThomas,你快了24分钟

将此代码放入模块“ThisWorkbook”中

Option Explicit

Private Sub Workbook_SheetActivate(ByVal Sh As Object)
    Dim i As Integer, c As Integer, ws As Worksheet
    For i = 1 To Worksheets("Master").UsedRange.Columns.Count
        For Each ws In ThisWorkbook.Worksheets
            If ws.Name <> "Master" And ws.Name <> "Affiliate Codes" Then
               c = ColumnIndexReturn(ws.Name, Worksheets("Master").Cells(1, i))
               If c <> 0 Then
                  ws.Cells(1, c).EntireColumn.Hidden = Worksheets("Master").Columns(i).EntireColumn.Hidden
               End If
            End If
        Next
    Next
End Sub

Private Function ColumnIndexReturn(sSheetName As String, sColumnName As String) As Integer
    Dim i As Integer
    For i = 1 To Worksheets(sSheetName).UsedRange.Columns.Count
        If Worksheets(sSheetName).Cells(1, i).Value = sColumnName Then
           ColumnIndexReturn = i
           Exit Function
        End If
    Next
End Function

此代码仅在用户更改工作表时运行,而不是在每个单元格更改时运行,当在“Master”中更改为可见时,它还会将列重新显示。

英文:

@FunThomas, you were 24 minutes quicker

Place this code in module "ThisWorkbook"

Option Explicit

Private Sub Workbook_SheetActivate(ByVal Sh As Object)
    Dim i As Integer, c As Integer, ws As Worksheet
    For i = 1 To Worksheets(&quot;Master&quot;).UsedRange.Columns.Count
        For Each ws In ThisWorkbook.Worksheets
            If ws.Name &lt;&gt; &quot;Master&quot; And ws.Name &lt;&gt; &quot;Affiliate Codes&quot; Then
               c = ColumnIndexReturn(ws.Name, Worksheets(&quot;Master&quot;).Cells(1, i))
               If c &lt;&gt; 0 Then
                  ws.Cells(1, c).EntireColumn.Hidden = Worksheets(&quot;Master&quot;).Columns(i).EntireColumn.Hidden
               End If
            End If
        Next
    Next
End Sub
Private Function ColumnIndexReturn(sSheetName As String, sColumnName As String) As Integer
    Dim i As Integer
    For i = 1 To Worksheets(sSheetName).UsedRange.Columns.Count
        If Worksheets(sSheetName).Cells(1, i).Value = sColumnName Then
           ColumnIndexReturn = i
           Exit Function
        End If
    Next
End Function

This code only runs when the user changes the sheet, not on every cell change, also it shows a column again when it is changed to visible in in Master

答案3

得分: 2

这是一个更加多功能的hennep代码版本。

Sub SyncMasterColumnVisibility(Optional TargetWorksheet As Worksheet)
    Application.ScreenUpdating = False
    Const MasterSheetName As String = "Master"
    Dim Excludes As Variant
    Excludes = Array("Master", "Affiliate Codes")
    
    Dim TargetWorksheets As New Collection
    Dim ws As Worksheet

    If Not TargetWorksheet Is Nothing Then
        TargetWorksheets.Add TargetWorksheet
    Else
        For Each ws In ThisWorkbook.Worksheets
            On Error Resume Next ' In case Match function does not find a match
            If IsError(Application.WorksheetFunction.Match(ws.Name, Excludes, 0)) Then
                TargetWorksheets.Add ws
            End If
            On Error GoTo 0 ' Reset error handling
        Next ws
    End If
    
    Dim MasterSheetColumnVisibility As New Collection
    Dim Cell As Range
    
    For Each Cell In ThisWorkbook.Worksheets(MasterSheetName).UsedRange.Rows(1).Cells
        If Len(Cell.Value) > 0 Then
            On Error Resume Next
            MasterSheetColumnVisibility.Add Cell.EntireColumn.Hidden, CStr(Cell.Value)
            On Error GoTo 0
        End If
    Next
    
    Dim Hidden As Boolean
    Dim tWs As Variant ' Use variant type because the collection may contain different object types
    For Each tWs In TargetWorksheets
        For Each Cell In tWs.UsedRange.Rows(1).Cells
            On Error Resume Next ' In case Match function does not find a match
            Hidden = MasterSheetColumnVisibility(CStr(Cell.Value))
            If Err.Number = 0 Then Cell.EntireColumn.Hidden = Hidden
            On Error GoTo 0 ' Reset error handling
        Next
    Next tWs
End Sub

使用`Workbook_SheetActivate`事件

Private Sub Workbook_SheetActivate(ByVal Sh As Object)
    SyncMasterColumnVisibility Sh
End Sub

使用`Workbook_SheetDeactivate`事件

Private Sub Workbook_SheetDeactivate(ByVal Sh As Object)
    Const MasterSheetName As String = "Master"
    If Sh.Name = MasterSheetName Then SyncMasterColumnVisibility
End Sub
英文:

Here is a more versatile version of hennep code.

Sub SyncMasterColumnVisibility(Optional TargetWorksheet As Worksheet)
Application.ScreenUpdating = False
Const MasterSheetName As String = &quot;Master&quot;
Dim Excludes As Variant
Excludes = Array(&quot;Master&quot;, &quot;Affiliate Codes&quot;)
Dim TargetWorksheets As New Collection
Dim ws As Worksheet
If Not TargetWorksheet Is Nothing Then
TargetWorksheets.Add TargetWorksheet
Else
For Each ws In ThisWorkbook.Worksheets
On Error Resume Next &#39; In case Match function does not find a match
If IsError(Application.WorksheetFunction.Match(ws.Name, Excludes, 0)) Then
TargetWorksheets.Add ws
End If
On Error GoTo 0 &#39; Reset error handling
Next ws
End If
Dim MasterSheetColumnVisibility As New Collection
Dim Cell As Range
For Each Cell In ThisWorkbook.Worksheets(MasterSheetName).UsedRange.Rows(1).Cells
If Len(Cell.Value) &gt; 0 Then
On Error Resume Next
MasterSheetColumnVisibility.Add Cell.EntireColumn.Hidden, CStr(Cell.Value)
On Error GoTo 0
End If
Next
Dim Hidden As Boolean
Dim tWs As Variant &#39; Use variant type because the collection may contain different object types
For Each tWs In TargetWorksheets
For Each Cell In tWs.UsedRange.Rows(1).Cells
On Error Resume Next &#39; In case Match function does not find a match
Hidden = MasterSheetColumnVisibility(CStr(Cell.Value))
If Err.Number = 0 Then Cell.EntireColumn.Hidden = Hidden
On Error GoTo 0 &#39; Reset error handling
Next
Next tWs
End Sub

Using the Workbook_SheetActivate event:

Private Sub Workbook_SheetActivate(ByVal Sh As Object)
SyncMasterColumnVisibility Sh
End Sub

Using the Workbook_SheetDeactivate event:

Private Sub Workbook_SheetDeactivate(ByVal Sh As Object)
Const MasterSheetName As String = &quot;Master&quot;
If Sh.Name = MasterSheetName Then SyncMasterColumnVisibility
End Sub

huangapple
  • 本文由 发表于 2023年6月19日 17:35:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76505365.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定