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

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

How to automatically hide columns in other sheets

问题

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

  1. Private Sub Worksheet_Change(ByVal Target As Range)
  2. Dim i As Integer, ws As Worksheet
  3. If IsEntireColumn(Target) = True Then
  4. If Target.Hidden = True Then
  5. For i = 1 To Target.Columns.Count
  6. For Each ws In ThisWorkbook.Worksheets
  7. If ws.Name = "Master" Or ws.Name = "Affiliate Codes" Then
  8. Else
  9. ws.Cells(1, ColumnIndexReturn(ws.Name, Target.Cells(1, i), 3)).EntireColumn.Hidden = True
  10. End If
  11. Next ws
  12. Next i
  13. End If
  14. End If
  15. 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:

  1. Private Sub Worksheet_Change(ByVal Target As Range)
  2. Dim i As Integer, ws As Worksheet
  3. If IsEntireColumn(Target) = True Then
  4. If Target.Hidden = True Then
  5. For i = 1 To Target.Columns.Count
  6. For Each ws In ThisWorkbook.Worksheets
  7. If ws.Name = "Master" Or ws.Name = "Affiliate Codes" Then
  8. Else
  9. ws.Cells(1, ColumnIndexReturn(ws.Name, Target.Cells(1, i), 3)).EntireColumn.Hidden = True
  10. End If
  11. Next ws
  12. Next i
  13. End If
  14. End If
  15. 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 事件。

我想到了以下代码片段:

  1. Option Explicit
  2. Dim lastSelectedColumn As Range
  3. Private Sub Worksheet_SelectionChange(ByVal Target As Range)
  4. If Not lastSelectedColumn Is Nothing Then
  5. ShowHideColumns lastSelectedColumn
  6. End If
  7. If IsEntireColumn(Target) Then
  8. Set lastSelectedColumn = Target
  9. Else
  10. Set lastSelectedColumn = Nothing
  11. End If
  12. End Sub
  13. Private Sub Worksheet_Deactivate()
  14. If Not lastSelectedColumn Is Nothing Then
  15. ShowHideColumns lastSelectedColumn
  16. Set lastSelectedColumn = Nothing
  17. End If
  18. End Sub
  19. Sub ShowHideColumns(Target As Range)
  20. Dim col As Long, ws As Worksheet
  21. For col = 1 To Target.Columns.Count
  22. For Each ws In ThisWorkbook.Worksheets
  23. If ws.Name <> "Master" And ws.Name <> "Affiliate Codes" And ws.Name <> Target.Parent.Name Then
  24. Dim cell As Range
  25. Set cell = Target.Cells(1, col)
  26. ws.Cells(1, cell.Column).EntireColumn.Hidden = cell.EntireColumn.Hidden
  27. End If
  28. Next ws
  29. Next col
  30. End Sub
  31. Function IsEntireColumn(Target As Range) As Boolean
  32. IsEntireColumn = (Target.Rows.Count = Target.Parent.Rows.Count)
  33. 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:

  1. Option Explicit
  2. Dim lastSelectedColumn As Range
  3. Private Sub Worksheet_SelectionChange(ByVal Target As Range)
  4. If Not lastSelectedColumn Is Nothing Then
  5. ShowHideColumns lastSelectedColumn
  6. End If
  7. If IsEntireColumn(Target) Then
  8. Set lastSelectedColumn = Target
  9. Else
  10. Set lastSelectedColumn = Nothing
  11. End If
  12. End Sub
  13. Private Sub Worksheet_Deactivate()
  14. If Not lastSelectedColumn Is Nothing Then
  15. ShowHideColumns lastSelectedColumn
  16. Set lastSelectedColumn = Nothing
  17. End If
  18. End Sub
  19. Sub ShowHideColumns(Target As Range)
  20. Dim col As Long, ws As Worksheet
  21. For col = 1 To Target.Columns.Count
  22. For Each ws In ThisWorkbook.Worksheets
  23. 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
  24. Dim cell As Range
  25. Set cell = Target.Cells(1, col)
  26. ws.Cells(1, cell.Column).EntireColumn.Hidden = cell.EntireColumn.Hidden
  27. End If
  28. Next ws
  29. Next col
  30. End Sub
  31. Function IsEntireColumn(Target As Range) As Boolean
  32. IsEntireColumn = (Target.Rows.Count = Target.Parent.Rows.Count)
  33. End Function

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

答案2

得分: 3

@FunThomas,你快了24分钟

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

  1. Option Explicit
  2. Private Sub Workbook_SheetActivate(ByVal Sh As Object)
  3. Dim i As Integer, c As Integer, ws As Worksheet
  4. For i = 1 To Worksheets("Master").UsedRange.Columns.Count
  5. For Each ws In ThisWorkbook.Worksheets
  6. If ws.Name <> "Master" And ws.Name <> "Affiliate Codes" Then
  7. c = ColumnIndexReturn(ws.Name, Worksheets("Master").Cells(1, i))
  8. If c <> 0 Then
  9. ws.Cells(1, c).EntireColumn.Hidden = Worksheets("Master").Columns(i).EntireColumn.Hidden
  10. End If
  11. End If
  12. Next
  13. Next
  14. End Sub
  15. Private Function ColumnIndexReturn(sSheetName As String, sColumnName As String) As Integer
  16. Dim i As Integer
  17. For i = 1 To Worksheets(sSheetName).UsedRange.Columns.Count
  18. If Worksheets(sSheetName).Cells(1, i).Value = sColumnName Then
  19. ColumnIndexReturn = i
  20. Exit Function
  21. End If
  22. Next
  23. End Function

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

英文:

@FunThomas, you were 24 minutes quicker

Place this code in module "ThisWorkbook"

  1. Option Explicit
  2. Private Sub Workbook_SheetActivate(ByVal Sh As Object)
  3. Dim i As Integer, c As Integer, ws As Worksheet
  4. For i = 1 To Worksheets(&quot;Master&quot;).UsedRange.Columns.Count
  5. For Each ws In ThisWorkbook.Worksheets
  6. If ws.Name &lt;&gt; &quot;Master&quot; And ws.Name &lt;&gt; &quot;Affiliate Codes&quot; Then
  7. c = ColumnIndexReturn(ws.Name, Worksheets(&quot;Master&quot;).Cells(1, i))
  8. If c &lt;&gt; 0 Then
  9. ws.Cells(1, c).EntireColumn.Hidden = Worksheets(&quot;Master&quot;).Columns(i).EntireColumn.Hidden
  10. End If
  11. End If
  12. Next
  13. Next
  14. End Sub
  15. Private Function ColumnIndexReturn(sSheetName As String, sColumnName As String) As Integer
  16. Dim i As Integer
  17. For i = 1 To Worksheets(sSheetName).UsedRange.Columns.Count
  18. If Worksheets(sSheetName).Cells(1, i).Value = sColumnName Then
  19. ColumnIndexReturn = i
  20. Exit Function
  21. End If
  22. Next
  23. 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代码版本。

  1. Sub SyncMasterColumnVisibility(Optional TargetWorksheet As Worksheet)
  2. Application.ScreenUpdating = False
  3. Const MasterSheetName As String = "Master"
  4. Dim Excludes As Variant
  5. Excludes = Array("Master", "Affiliate Codes")
  6. Dim TargetWorksheets As New Collection
  7. Dim ws As Worksheet
  8. If Not TargetWorksheet Is Nothing Then
  9. TargetWorksheets.Add TargetWorksheet
  10. Else
  11. For Each ws In ThisWorkbook.Worksheets
  12. On Error Resume Next ' In case Match function does not find a match
  13. If IsError(Application.WorksheetFunction.Match(ws.Name, Excludes, 0)) Then
  14. TargetWorksheets.Add ws
  15. End If
  16. On Error GoTo 0 ' Reset error handling
  17. Next ws
  18. End If
  19. Dim MasterSheetColumnVisibility As New Collection
  20. Dim Cell As Range
  21. For Each Cell In ThisWorkbook.Worksheets(MasterSheetName).UsedRange.Rows(1).Cells
  22. If Len(Cell.Value) > 0 Then
  23. On Error Resume Next
  24. MasterSheetColumnVisibility.Add Cell.EntireColumn.Hidden, CStr(Cell.Value)
  25. On Error GoTo 0
  26. End If
  27. Next
  28. Dim Hidden As Boolean
  29. Dim tWs As Variant ' Use variant type because the collection may contain different object types
  30. For Each tWs In TargetWorksheets
  31. For Each Cell In tWs.UsedRange.Rows(1).Cells
  32. On Error Resume Next ' In case Match function does not find a match
  33. Hidden = MasterSheetColumnVisibility(CStr(Cell.Value))
  34. If Err.Number = 0 Then Cell.EntireColumn.Hidden = Hidden
  35. On Error GoTo 0 ' Reset error handling
  36. Next
  37. Next tWs
  38. End Sub
  39. 使用`Workbook_SheetActivate`事件
  40. Private Sub Workbook_SheetActivate(ByVal Sh As Object)
  41. SyncMasterColumnVisibility Sh
  42. End Sub
  43. 使用`Workbook_SheetDeactivate`事件
  44. Private Sub Workbook_SheetDeactivate(ByVal Sh As Object)
  45. Const MasterSheetName As String = "Master"
  46. If Sh.Name = MasterSheetName Then SyncMasterColumnVisibility
  47. End Sub
英文:

Here is a more versatile version of hennep code.

  1. Sub SyncMasterColumnVisibility(Optional TargetWorksheet As Worksheet)
  2. Application.ScreenUpdating = False
  3. Const MasterSheetName As String = &quot;Master&quot;
  4. Dim Excludes As Variant
  5. Excludes = Array(&quot;Master&quot;, &quot;Affiliate Codes&quot;)
  6. Dim TargetWorksheets As New Collection
  7. Dim ws As Worksheet
  8. If Not TargetWorksheet Is Nothing Then
  9. TargetWorksheets.Add TargetWorksheet
  10. Else
  11. For Each ws In ThisWorkbook.Worksheets
  12. On Error Resume Next &#39; In case Match function does not find a match
  13. If IsError(Application.WorksheetFunction.Match(ws.Name, Excludes, 0)) Then
  14. TargetWorksheets.Add ws
  15. End If
  16. On Error GoTo 0 &#39; Reset error handling
  17. Next ws
  18. End If
  19. Dim MasterSheetColumnVisibility As New Collection
  20. Dim Cell As Range
  21. For Each Cell In ThisWorkbook.Worksheets(MasterSheetName).UsedRange.Rows(1).Cells
  22. If Len(Cell.Value) &gt; 0 Then
  23. On Error Resume Next
  24. MasterSheetColumnVisibility.Add Cell.EntireColumn.Hidden, CStr(Cell.Value)
  25. On Error GoTo 0
  26. End If
  27. Next
  28. Dim Hidden As Boolean
  29. Dim tWs As Variant &#39; Use variant type because the collection may contain different object types
  30. For Each tWs In TargetWorksheets
  31. For Each Cell In tWs.UsedRange.Rows(1).Cells
  32. On Error Resume Next &#39; In case Match function does not find a match
  33. Hidden = MasterSheetColumnVisibility(CStr(Cell.Value))
  34. If Err.Number = 0 Then Cell.EntireColumn.Hidden = Hidden
  35. On Error GoTo 0 &#39; Reset error handling
  36. Next
  37. Next tWs
  38. End Sub

Using the Workbook_SheetActivate event:

  1. Private Sub Workbook_SheetActivate(ByVal Sh As Object)
  2. SyncMasterColumnVisibility Sh
  3. End Sub

Using the Workbook_SheetDeactivate event:

  1. Private Sub Workbook_SheetDeactivate(ByVal Sh As Object)
  2. Const MasterSheetName As String = &quot;Master&quot;
  3. If Sh.Name = MasterSheetName Then SyncMasterColumnVisibility
  4. 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:

确定