我有一张工作表用于设置多个数据验证列表的数据源。换句话说,我使用此工作表为多个其他工作表提供下拉列表。
我需要根据数据源工作表上的一个或多个更改动态更新所有工作表。我可能明白这应该与整个工作簿上的事件宏一起出现。
我的问题是如何实现在整个工作簿中保持“OFFSET”公式?
谢谢
为了支持我的问题,我放上了一段试图让它工作的代码:
提供以下信息:
- 我正在使用这样一个公式对下拉列表进行伪动态更新,例如:
=OFFSET(MyDataSourceSheet!$O$2;0;0;COUNTA(MyDataSourceSheet!O:O)-1)
与数据源工作表相关的宏:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
' Macro to update all worksheets with drop down list referenced upon
' this data source worksheet, base on ref names
Dim cell As Range
Dim isect As Range
Dim vOldValue As Variant, vNewValue As Variant
Dim dvLists(1 To 6) As String 'data validation area
Dim OneValidationListName As Variant
dvLists(1) = "mylist1"
dvLists(2) = "mylist2"
dvLists(3) = "mylist3"
dvLists(4) = "mylist4"
dvLists(5) = "mylist5"
dvLists(6) = "mylist6"
On Error GoTo errorHandler
For Each OneValidationListName In dvLists
'Set isect = Application.Intersect(Target, ThisWorkbook.Names("STEP").RefersToRange)
Set isect = Application.Intersect(Target, ThisWorkbook.Names(OneValidationListName).RefersToRange)
' If a change occured in the source data sheet
If Not isect Is Nothing Then
' Prevent infinite loops
Application.EnableEvents = False
' Get previous value of this cell
With Target
vNewValue = .Value
Application.Undo
vOldValue = .Value
.Value = vNewValue
End With
' LOCAL dropdown lists : For every cell with validation
For Each cell In Me.UsedRange.SpecialCells(xlCellTypeAllValidation)
With cell
' If it has list validation AND the validation formula matches AND the value is the old value
If .Validation.Type = 3 And .Validation.Formula1 = "=" & OneValidationListName And .Value = vOldValue Then
' Debug
' MsgBox "Address: " & Target.Address
' Change the cell value
cell.Value = vNewValue
End If
End With
Next cell
' Call to other worksheets update macros
Call Sheets(5).UpdateDropDownList(vOldValue, vNewValue)
' GoTo NowGetOut
Application.EnableEvents = True
End If
Next OneValidationListName
NowGetOut:
Application.EnableEvents = True
Exit Sub
errorHandler:
MsgBox "Err " & Err.Number & " : " & Err.Description
Resume NowGetOut
End Sub
与目标工作表相关的宏 UpdateDropDownList:
Sub UpdateDropDownList(Optional vOldValue As Variant, Optional vNewValue As Variant)
' Debug
MsgBox "Received info for update : " & vNewValue
' For every cell with validation
For Each cell In Me.UsedRange.SpecialCells(xlCellTypeAllValidation)
With cell
' If it has list validation AND the validation formula matches AND the value is the old value
' If .Validation.Type = 3 And .Value = vOldValue Then
If .Validation.Type = 3 And .Value = vOldValue Then
' Change the cell value
cell.Value = vNewValue
End If
End With
Next cell
End Sub
答案1
基于以下设置,我现在可以工作了:
一个数据源工作表,工作表更改事件设置如下。此宏调用目标工作表宏更新下拉列表带有 2 个参数(旧值和新值),这是下拉列表的动态更新所必需的。
数据源工作表宏(改变事件):
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
' Macro to update all worksheets with drop down list referenced upon
' this data source worksheet, base on ref names
Dim cell As Range
Dim isect As Range
Dim vOldValue As Variant, vNewValue As Variant
Dim dvLists(1 To 6) As String 'data validation area
Dim OneValidationListName As Variant
dvLists(1) = "myListName1"
dvLists(2) = "myListName2"
dvLists(3) = "myListName3"
dvLists(4) = "myListName4"
dvLists(5) = "myListName5"
dvLists(6) = "myListName6"
On Error GoTo errorHandler
For Each OneValidationListName In dvLists
Set isect = Application.Intersect(Target, ThisWorkbook.Names(OneValidationListName).RefersToRange)
' If a change occured in the datasource worksheet
If Not isect Is Nothing Then
' Prevent infinite loops
Application.EnableEvents = False
' Get previous value of this cell
With Target
vNewValue = .Value
Application.Undo
vOldValue = .Value
.Value = vNewValue
End With
' Call to other worksheets update macros
Call Sheets(5).UpdateDropDownList(vOldValue, vNewValue)
' GoTo NowGetOut
Application.EnableEvents = True
End If
Next OneValidationListName
NowGetOut:
Application.EnableEvents = True
Exit Sub
errorHandler:
MsgBox "Format Err " & Err.Number & " : " & Err.Description
Resume NowGetOut
End Sub
目标工作表宏:
Sub UpdateDropDownList(Optional vOldValue As Variant, Optional vNewValue As Variant)
On Error GoTo errorHandler
' Debug
' MsgBox "Received info for update : " & vNewValue
' For every cell with validation
For Each cell In Me.UsedRange.SpecialCells(xlCellTypeAllValidation)
With cell
' If it has list validation AND the validation formula matches AND the value is the old value
If .Validation.Type = 3 And .Value = vOldValue Then
' Change the cell value
cell.Value = vNewValue
End If
End With
Next cell
Exit Sub
errorHandler:
MsgBox "Saisie Err : " & Err.Number & " : " & Err.Description
End Sub