我正在尝试在一个worksheet_change中实现多个功能。我之前可以集成3个功能(所有功能都与隐藏/取消隐藏行有关),但是在添加一个允许在下拉列表中进行多项选择的功能时遇到了麻烦。
我试图将新的多重选择代码添加到以前存在的代码中,它不会给我错误,但是不会运行。在理想情况下,它将保留隐藏/取消隐藏功能,并允许在已标识的行中进行多个选择。
Private Sub Worksheet_Change(ByVal Target As Range)
ActiveSheet.Activate
If Not Application.Intersect(Range("C10:AA10"), Range(Target.Address))
Is Nothing Then
Select Case Target.Value
Case Is = "Select One": Rows("14:58").EntireRow.Hidden = True
Rows("10").EntireRow.Hidden = False
Case Is = "1": Rows("17:58").EntireRow.Hidden = True
Rows("14:16").EntireRow.Hidden = False
Case Is = "2": Rows("20:58").EntireRow.Hidden = True
Rows("14:19").EntireRow.Hidden = False
Case Is = "3": Rows("23:58").EntireRow.Hidden = True
Rows("14:22").EntireRow.Hidden = False
Case Is = "4": Rows("26:58").EntireRow.Hidden = True
Rows("14:25").EntireRow.Hidden = False
Case Is = "5": Rows("29:58").EntireRow.Hidden = True
Rows("14:28").EntireRow.Hidden = False
Case Is = "6": Rows("32:58").EntireRow.Hidden = True
Rows("14:31").EntireRow.Hidden = False
Case Is = "7": Rows("35:58").EntireRow.Hidden = True
Rows("14:34").EntireRow.Hidden = False
Case Is = "8": Rows("38:58").EntireRow.Hidden = True
Rows("14:37").EntireRow.Hidden = False
Case Is = "9": Rows("41:58").EntireRow.Hidden = True
Rows("14:40").EntireRow.Hidden = False
Case Is = "10": Rows("44:58").EntireRow.Hidden = True
Rows("14:43").EntireRow.Hidden = False
Case Is = "11": Rows("47:58").EntireRow.Hidden = True
Rows("14:46").EntireRow.Hidden = False
Case Is = "12": Rows("50:58").EntireRow.Hidden = True
Rows("14:49").EntireRow.Hidden = False
Case Is = "13": Rows("30:58").EntireRow.Hidden = True
Rows("14:52").EntireRow.Hidden = False
Case Is = "14": Rows("56:58").EntireRow.Hidden = True
Rows("14:55").EntireRow.Hidden = False
Case Is = "15": Rows("14:58").EntireRow.Hidden = False
End Select
End If
If Not Intersect(Range("C66:AA66"), Target) Is Nothing Then
Select Case Target.Value
Case "GBP", "USD", "Yuan", "EUR", "LRD", "Select One"
Rows("67").Hidden = True
Case "Other"
Rows("67").Hidden = False
End Select
End If
If Not Intersect(Range("C11:AA11"), Target) Is Nothing Then
Select Case Target.Value
Case "$"
Rows("13").Hidden = True
Rows("12").Hidden = False
Case "%"
Rows("13").Hidden = False
Rows("12").Hidden = True
Case "Select One"
Rows("13").Hidden = True
Rows("12").Hidden = True
End Select
End If
Dim Oldvalue As String
Dim Newvalue As String
Application.EnableEvents = True
On Error GoTo Exitsub
If Target.Row = "15",”18”,”21” Then
If Target.SpecialCells(xlCellTypeAllValidation) Is Nothing Then
GoTo Exitsub
Else: If Target.Value = "" Then GoTo Exitsub Else
Application.EnableEvents = False
Newvalue = Target.Value
Application.Undo
Oldvalue = Target.Value
If Oldvalue = "" Then
Target.Value = Newvalue
Else
If InStr(1, Oldvalue, Newvalue) = 0 Then
Target.Value = Oldvalue & ", " & Newvalue
Else:
Target.Value = Oldvalue
End If
End If
End If
End If
Application.EnableEvents = True
Exitsub:
Application.EnableEvents = True
End Sub
我希望它能够根据选择继续隐藏/取消隐藏给定的行,并允许从代码中概述的行的下拉列表中进行多次选择。代码没有给我错误,但是多选功能无法运行
答案 0 :(得分:1)
我想我明白您正在尝试做的事情,希望这些评论对您的代码有所帮助。有一些评论...
Option Explicit
。无论您在Webz上找到什么示例代码,使用此习惯都将对您将来有很大帮助。对于您的Worksheet_Change
事件代码,我可以将逻辑简化为更易于理解的流程:
Option Explicit
Private Sub Worksheet_Change(ByVal target As Range)
Dim groupsRange As Range
Dim currencyRange As Range
Dim valuesRange As Range
Set groupsRange = ActiveSheet.Range("C10:AA10")
Set currencyRange = ActiveSheet.Range("C66:AA66")
Set valuesRange = ActiveSheet.Range("C11:AA11")
If Not Intersect(groupsRange, target) Is Nothing Then
ShowActiveGroups target
ElseIf Not Intersect(currencyRange, target) Is Nothing Then
ShowCurrency target
ElseIf Not Intersect(valuesRange, target) Is Nothing Then
ShowValues target
End If
If target.Count > 1 Then Exit Sub
If (target.Row = 15) Or (target.Row = 18) Or (target.Row = 21) Then
CheckMultiSelect target
End If
End Sub
很显然,我可能没有得到您范围的“点”(使用“组”,“货币”,“值”),但是您应该使用描述性名称,以便于理解什么以及为什么逻辑在某些部分上起作用。
在Subs
事件中调用的Worksheet_Change
的代码被放置在一个单独的模块中,所有代码都标记为Public
。他们每个人都有相似的逻辑,这里有一些工作。
Sub
代码中),您应该经历建立确切地被引用的工作表的步骤。始终fully qualify your range references (see #5)至关重要。最简单的方法(没有很长的复合语句)是使用中间变量。 因此,在上面调用的每个“显示”例程中,我都建立了对目标单元格(引起Worksheet
事件的单元格)的Worksheet_Change
的引用。
Dim targetWS As Worksheet
Set targetWS = target.Parent
在您的情况下,您要引用许多不同的行并将其隐藏/取消隐藏。我不知道为什么。但是,如果您可以“命名”代码中的行,则可能更有意义。这是我使用的一些示例:
Const RED_GROUP_1 As String = "14:58"
Const RED_GROUP_2 As String = "10"
Const GREEN_GROUP_1 As String = "17:58"
Const GREEN_GROUP_2 As String = "14:16"
所以前三个“显示”例程可能看起来像这样:
Public Sub ShowActiveGroups(ByRef target As Range)
Dim targetWS As Worksheet
Set targetWS = target.Parent
Const RED_GROUP_1 As String = "14:58"
Const RED_GROUP_2 As String = "10"
Const GREEN_GROUP_1 As String = "17:58"
Const GREEN_GROUP_2 As String = "14:16"
With targetWS
Select Case target.Value
Case "Select One"
.Rows(RED_GROUP_1).EntireRow.Hidden = True
.Rows(RED_GROUP_2).EntireRow.Hidden = False
Case 1
.Rows(GREEN_GROUP_1).EntireRow.Hidden = True
.Rows(GREEN_GROUP_2).EntireRow.Hidden = False
Case 2
.Rows("20:58").EntireRow.Hidden = True
.Rows("14:19").EntireRow.Hidden = False
' ...
Case Else
'--- what should we do if it's not a valid value?
End Select
End With
End Sub
Public Sub ShowCurrency(ByRef target As Range)
Dim targetWS As Worksheet
Set targetWS = target.Parent
Const CURRENCY_LINE As String = "67"
With targetWS
Select Case target.Value
Case "GBP", "USD", "Yuan", "EUR", "LRD", "Select One"
.Rows(CURRENCY_LINE).EntireRow.Hidden = True
Case "Other"
.Rows(CURRENCY_LINE).EntireRow.Hidden = False
Case Else
'--- what should we do if it's not a valid value?
End Select
End With
End Sub
Public Sub ShowValues(ByRef target As Range)
Dim targetWS As Worksheet
Set targetWS = target.Parent
Const MONEY_LINE As String = "13"
Const PERCENT_LINE As String = "12"
With targetWS
Select Case target.Value
Case "$"
.Rows(MONEY_LINE).EntireRow.Hidden = True
.Rows(PERCENT_LINE).EntireRow.Hidden = False
Case "%"
.Rows(MONEY_LINE).EntireRow.Hidden = False
.Rows(PERCENT_LINE).EntireRow.Hidden = True
Case "Select One"
.Rows(MONEY_LINE).EntireRow.Hidden = True
.Rows(PERCENT_LINE).EntireRow.Hidden = True
Case Else
'--- what should we do if it's not a valid value?
End Select
End With
End Sub
最后,我总是遇到您在webz上找到的数据验证/多选代码的麻烦。因此,我将使用一个有一些轻微修改的工具。该代码也包含在常规代码模块中。
Public Sub CheckMultiSelect(ByRef target As Range)
Dim targetWS As Worksheet
Set targetWS = target.Parent
On Error Resume Next
Dim dvCheck As Range
Set dvCheck = targetWS.Cells.SpecialCells(xlCellTypeAllValidation)
If dvCheck Is Nothing Then Exit Sub
Application.EnableEvents = False
'--- only allow multi-select if the cell has defined data validation
If Not Intersect(dvCheck, target) Is Nothing Then
Dim currentValue As String
Dim oldValue As String
currentValue = target.Value
Application.Undo
oldValue = target.Value
If oldValue = vbNullString Then
target.Value = currentValue
Else
If InStr(1, oldValue, currentValue) = 0 Then
target.Value = oldValue & "," & currentValue
Else
If currentValue = vbNullString Then
target.Value = vbNullString
Else
target.Value = oldValue
End If
End If
End If
End If
Application.EnableEvents = True
End Sub
使用上面的代码在工作表模块和常规代码模块中,我都能够成功执行您原始问题中的某些操作。