Excel 动态 'Data Validation' 列表
Excel dynamic 'Data Validation' list
我正在使用 excel sheet 来帮助配置大型 xml 文件。
我有以下
在 24 个不同的 Type
选项中,它们共享大量要配置的公共字段(黄色单元格,其中有 15 列,然后是另外 36 列,主要适用于所有 24类型。)
最后我有 21 列标记为 Option1
、Option2
... 因为它们的单元格根据 Type
:
有不同的翻译
那张图片是钥匙的地方,仅供参考。
在实际配置项目时,我使用数据验证(如图 1 所示)对 select Type
然后在 OptionX
单元格中显示引用的变量类型来自 Options 键(此处有一个具体说明:作为对用户的提醒,我希望在仍然应用数据验证列表的同时适当地填充每个单元格的值)
以下是我遇到的问题
我希望每个选项在需要时有条件地应用数据验证列表。所以本质上,用户 selects Type
然后填充 OptionX
并根据该 Option
单元格中的值,将显示适当的数据验证列表(如果一个是适用,因为某些选项基于 ID 号等...在这种情况下,我不会有列表或最多是一个空列表)
(另一个旁注:我从中学起就没有使用过excel-所以如果我的一些方法形式不佳,我深表歉意。因为我是在问这个问题之前进行研究,我注意到许多 INDIRECT
调用是错误的,我目前有很多。每个 Option
都包含一个类似于
的公式
=VLOOKUP( OFFSET(INDIRECT(ADDRESS(ROW(),COLUMN())),0,-54),Sheet2!A16:B39,2,FALSE)
为了引用 Type
的值,这样我就可以 copy/paste 公式向下 ~500 行(每个项目要配置的平均项目数)虽然我怀疑 Excel 能够以更优雅的方式处理此问题。)
我改进了单元格公式,将第一个替换为:
=VLOOKUP( D3,'smart MDR710 config.xlsx'!options,2,FALSE)
copy/pasting 接下来的 499 个单元格
您需要按照这些教程进行操作,因为您没有提供足够的问题信息来详细说明此处的确切解决方案。
简而言之,您将需要一个 table,其中最左边的列是类型选择,其余 headers 是第一列中的 24 个类型选择及其相关子选择。本质上是一个交叉表。
然后您需要创建一个名为 MainList 的命名范围,其公式如下...
=INDEX(Table1[[Choose…]],1):INDEX(Table1[[Choose…]],COUNTA(Table1[[Choose…]]))
您可以在其中将 choose 替换为您希望单元格提示用户的任何内容,将 Table1 替换为您命名为 table 并带有相关选择信息的任何内容。
然后您需要创建一个名为 SubList 的命名范围,其公式如下...
=IF(OR(Sheet1!B8="Choose…",Sheet1!B8=""),"",INDEX(Table1,1,MATCH(Sheet1!B8,Table1[#Headers],0)):INDEX(Table1,COUNTA(INDEX(Table1,,MATCH(Sheet1!B8,Table1[#Headers],0))),MATCH(Sheet1!B8,Table1[#Headers],0)))
然后,您需要将这些命名范围作为数据验证标准应用于给定的单元格(您的类型列 = MainList,后续列等于您的子列表)。
现在,您需要确保您的 MainList 列直接位于动态单元格的左侧,并且您是否希望您的组合框级联(即一列允许在另一列中选择某些值等)您将需要直接在左侧的子列表数据验证单元格。
如果是我,我会完全按照附加链接中的评论进行操作,并将数据输入单元格放在 table 中。这将使您能够使用下面的工作表事件,如果您从子列表选择中更改某些内容"upstream",该事件将更新单元格。
Option Explicit
Const CHOOSE = "Choose…"
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo ErrorHandler
Dim targetCell As Range
Dim nextCell As Range
Dim oldCalc As Excel.XlCalculation
If Not Intersect(Target, [DataEntryTable]) Is Nothing Then
If [Radio_Choice] = 1 Then
With Application
.EnableEvents = False
.ScreenUpdating = False
oldCalc = .Calculation
.Calculation = xlCalculationManual
End With
For Each targetCell In Target
'Clear any cells that use 'SubList' to the right of targetCell in the current table.
If targetCell.Column < (targetCell.ListObject.ListColumns.Count + targetCell.ListObject.Range.Column - 1) Then 'there are table cells to the right
For Each nextCell In targetCell.Offset(, 1).Resize(, targetCell.ListObject.ListColumns.Count + targetCell.ListObject.Range.Column - targetCell.Column - 1)
If HasValidationFormula(nextCell) Then
If nextCell.Validation.Formula1 = "=SubList" Then nextCell.Value = ""
End If
Next nextCell
End If
'Perform different action depeding on whether we're dealing with a 'MainList' dropdown
' or a 'SubList' dropdown
If HasValidationFormula(targetCell) Then
Select Case targetCell.Validation.Formula1
Case "=MainList"
If targetCell.Value = "" Then
targetCell.Value = CHOOSE
ElseIf targetCell.Value = CHOOSE Then
'Do nothing.
Else
targetCell.Offset(, 1).Value = CHOOSE
End If
Case "=SubList"
If targetCell.Value = "" Then
targetCell.Value = CHOOSE
ElseIf targetCell.Offset(, -1).Value = CHOOSE Then
targetCell.Value = ""
ElseIf targetCell.Value = CHOOSE Then
'Do nothing
Else
Set nextCell = targetCell.Offset(, 1)
If HasValidationFormula(nextCell) Then
If nextCell.Validation.Formula1 = "=SubList" Then nextCell.Value = CHOOSE
End If
End If
End Select
End If
Next targetCell
With Application
.EnableEvents = True
.ScreenUpdating = True
.Calculation = oldCalc
End With
End If
End If
Exit Sub
ErrorHandler:
With Application
.EnableEvents = True
.ScreenUpdating = True
If oldCalc <> 0 Then .Calculation = oldCalc
End With
MsgBox Err.Description, vbCritical, Name & ".Worksheet_Change()"
End Sub
Private Function HasValidationFormula(cell As Range) As Boolean
On Error GoTo ValidationNotExistsError
If cell.Validation.Formula1 <> "" Then
HasValidationFormula = True
Else
HasValidationFormula = False
End If
Exit Function
ValidationNotExistsError:
HasValidationFormula = False
End Function
功劳归
http://chandoo.org/wp/2014/02/13/dynamic-cascading-dropdowns-that-reset/
和
我正在使用 excel sheet 来帮助配置大型 xml 文件。
我有以下
在 24 个不同的 Type
选项中,它们共享大量要配置的公共字段(黄色单元格,其中有 15 列,然后是另外 36 列,主要适用于所有 24类型。)
最后我有 21 列标记为 Option1
、Option2
... 因为它们的单元格根据 Type
:
那张图片是钥匙的地方,仅供参考。
在实际配置项目时,我使用数据验证(如图 1 所示)对 select Type
然后在 OptionX
单元格中显示引用的变量类型来自 Options 键(此处有一个具体说明:作为对用户的提醒,我希望在仍然应用数据验证列表的同时适当地填充每个单元格的值)
以下是我遇到的问题
我希望每个选项在需要时有条件地应用数据验证列表。所以本质上,用户 selects Type
然后填充 OptionX
并根据该 Option
单元格中的值,将显示适当的数据验证列表(如果一个是适用,因为某些选项基于 ID 号等...在这种情况下,我不会有列表或最多是一个空列表)
(另一个旁注:我从中学起就没有使用过excel-所以如果我的一些方法形式不佳,我深表歉意。因为我是在问这个问题之前进行研究,我注意到许多 INDIRECT
调用是错误的,我目前有很多。每个 Option
都包含一个类似于
=VLOOKUP( OFFSET(INDIRECT(ADDRESS(ROW(),COLUMN())),0,-54),Sheet2!A16:B39,2,FALSE)
为了引用 Type
的值,这样我就可以 copy/paste 公式向下 ~500 行(每个项目要配置的平均项目数)虽然我怀疑 Excel 能够以更优雅的方式处理此问题。)
我改进了单元格公式,将第一个替换为:
=VLOOKUP( D3,'smart MDR710 config.xlsx'!options,2,FALSE)
copy/pasting 接下来的 499 个单元格
您需要按照这些教程进行操作,因为您没有提供足够的问题信息来详细说明此处的确切解决方案。
简而言之,您将需要一个 table,其中最左边的列是类型选择,其余 headers 是第一列中的 24 个类型选择及其相关子选择。本质上是一个交叉表。
然后您需要创建一个名为 MainList 的命名范围,其公式如下...
=INDEX(Table1[[Choose…]],1):INDEX(Table1[[Choose…]],COUNTA(Table1[[Choose…]]))
您可以在其中将 choose 替换为您希望单元格提示用户的任何内容,将 Table1 替换为您命名为 table 并带有相关选择信息的任何内容。
然后您需要创建一个名为 SubList 的命名范围,其公式如下...
=IF(OR(Sheet1!B8="Choose…",Sheet1!B8=""),"",INDEX(Table1,1,MATCH(Sheet1!B8,Table1[#Headers],0)):INDEX(Table1,COUNTA(INDEX(Table1,,MATCH(Sheet1!B8,Table1[#Headers],0))),MATCH(Sheet1!B8,Table1[#Headers],0)))
然后,您需要将这些命名范围作为数据验证标准应用于给定的单元格(您的类型列 = MainList,后续列等于您的子列表)。
现在,您需要确保您的 MainList 列直接位于动态单元格的左侧,并且您是否希望您的组合框级联(即一列允许在另一列中选择某些值等)您将需要直接在左侧的子列表数据验证单元格。
如果是我,我会完全按照附加链接中的评论进行操作,并将数据输入单元格放在 table 中。这将使您能够使用下面的工作表事件,如果您从子列表选择中更改某些内容"upstream",该事件将更新单元格。
Option Explicit
Const CHOOSE = "Choose…"
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo ErrorHandler
Dim targetCell As Range
Dim nextCell As Range
Dim oldCalc As Excel.XlCalculation
If Not Intersect(Target, [DataEntryTable]) Is Nothing Then
If [Radio_Choice] = 1 Then
With Application
.EnableEvents = False
.ScreenUpdating = False
oldCalc = .Calculation
.Calculation = xlCalculationManual
End With
For Each targetCell In Target
'Clear any cells that use 'SubList' to the right of targetCell in the current table.
If targetCell.Column < (targetCell.ListObject.ListColumns.Count + targetCell.ListObject.Range.Column - 1) Then 'there are table cells to the right
For Each nextCell In targetCell.Offset(, 1).Resize(, targetCell.ListObject.ListColumns.Count + targetCell.ListObject.Range.Column - targetCell.Column - 1)
If HasValidationFormula(nextCell) Then
If nextCell.Validation.Formula1 = "=SubList" Then nextCell.Value = ""
End If
Next nextCell
End If
'Perform different action depeding on whether we're dealing with a 'MainList' dropdown
' or a 'SubList' dropdown
If HasValidationFormula(targetCell) Then
Select Case targetCell.Validation.Formula1
Case "=MainList"
If targetCell.Value = "" Then
targetCell.Value = CHOOSE
ElseIf targetCell.Value = CHOOSE Then
'Do nothing.
Else
targetCell.Offset(, 1).Value = CHOOSE
End If
Case "=SubList"
If targetCell.Value = "" Then
targetCell.Value = CHOOSE
ElseIf targetCell.Offset(, -1).Value = CHOOSE Then
targetCell.Value = ""
ElseIf targetCell.Value = CHOOSE Then
'Do nothing
Else
Set nextCell = targetCell.Offset(, 1)
If HasValidationFormula(nextCell) Then
If nextCell.Validation.Formula1 = "=SubList" Then nextCell.Value = CHOOSE
End If
End If
End Select
End If
Next targetCell
With Application
.EnableEvents = True
.ScreenUpdating = True
.Calculation = oldCalc
End With
End If
End If
Exit Sub
ErrorHandler:
With Application
.EnableEvents = True
.ScreenUpdating = True
If oldCalc <> 0 Then .Calculation = oldCalc
End With
MsgBox Err.Description, vbCritical, Name & ".Worksheet_Change()"
End Sub
Private Function HasValidationFormula(cell As Range) As Boolean
On Error GoTo ValidationNotExistsError
If cell.Validation.Formula1 <> "" Then
HasValidationFormula = True
Else
HasValidationFormula = False
End If
Exit Function
ValidationNotExistsError:
HasValidationFormula = False
End Function
功劳归
http://chandoo.org/wp/2014/02/13/dynamic-cascading-dropdowns-that-reset/
和