ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 168|回复: 8

[求助] 如何实现二级菜单根据一级菜单内容自动显示

[复制链接]

TA的精华主题

TA的得分主题

发表于 2025-1-11 02:55 | 显示全部楼层 |阅读模式
B2:C5000是内容,B列是班级名称,C列是学生姓名,如何在单元格下拉框 选择了班级名称后, 自动只显示该班级对应的学生(不显示其它班级的学生)
1736535279926.png

二级菜单.zip

7.67 KB, 下载次数: 8

TA的精华主题

TA的得分主题

发表于 2025-1-11 07:43 | 显示全部楼层
Private Sub Worksheet_SelectionChange(ByVal T As Range)
If T.Row = 1 And T.Column = 6 Then
    Set d = CreateObject("scripting.dictionary")
    r = Cells(Rows.Count, 2).End(xlUp).Row
    arr = Range("b1:c" & r)
    For i = 2 To UBound(arr)
        d(arr(i, 1)) = ""
    Next i
    T.Select
    With Selection.Validation
        .Delete
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=Join(d.keys, ",")
    End With
    d.RemoveAll
End If

End Sub
Private Sub Worksheet_Change(ByVal T As Range)
If T.Row = 1 And T.Column = 6 Then
    If T.Count > 1 Then End
    Set d = CreateObject("scripting.dictionary")
    r = Cells(Rows.Count, 2).End(xlUp).Row
    arr = Range("b1:c" & r)
    For i = 2 To UBound(arr)
        If arr(i, 1) = T.Value Then
            d(arr(i, 2)) = ""
        End If
    Next i
    T.Offset(1).Select
    With Selection.Validation
        .Delete
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=Join(d.keys, ",")
    End With
   d.RemoveAll
End If
End Sub


TA的精华主题

TA的得分主题

发表于 2025-1-11 07:44 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
二级菜单.rar (14.78 KB, 下载次数: 14)

TA的精华主题

TA的得分主题

发表于 2025-1-11 08:37 | 显示全部楼层
参与一下,仅供参考。。。
单元格f1/f2这两个单元格写的selectionchange事件,请留意
image.png
image.png

二级菜单.zip

15.06 KB, 下载次数: 6

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2025-1-11 08:38 | 显示全部楼层
代码如下。。。
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Target.Address = "$F$2" Or Target.Address = "$F$1" Then
        arr = Range([b1], Cells(Rows.Count, 3).End(3))
        Set d = CreateObject("scripting.dictionary")
        For i = 2 To UBound(arr)
            s = arr(i, 1)
            If s <> Empty And arr(i, 2) <> Empty Then
                If Not d.exists(s) Then
                    d(s) = arr(i, 2)
                Else
                    d(s) = d(s) & "," & arr(i, 2)
                End If
            End If
        Next
        If Target.Address = "$F$1" Then
            With Target.Validation
                .Delete
                kk = d.keys
                .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=Join(d.keys, ",")
            End With
        ElseIf Target.Address = "$F$2" And d.exists([f1].Value) Then
            With Target.Validation
                .Delete
                .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=d([f1].Value)
            End With
        End If
        Set d = Nothing
'        Beep
    End If
End Sub

评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2025-1-11 09:11 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
精简一下,用字典嵌套
二级菜单.rar (14.29 KB, 下载次数: 12)

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2025-1-11 09:12 | 显示全部楼层
Dim d As Object
Private Sub Worksheet_SelectionChange(ByVal T As Range)
If T.Row = 1 And T.Column = 6 Then
    Set d = CreateObject("scripting.dictionary")
    r = Cells(Rows.Count, 2).End(xlUp).Row
    arr = Range("b1:c" & r)
    For i = 2 To UBound(arr)
        If arr(i, 1) <> "" Then
            If Not d.exists(arr(i, 1)) Then Set d(arr(i, 1)) = CreateObject("scripting.dictionary")
            d(arr(i, 1))(arr(i, 2)) = ""
        End If
    Next i
    T.Select
    With Selection.Validation
        .Delete
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=Join(d.keys, ",")
    End With
End If
End Sub
Private Sub Worksheet_Change(ByVal T As Range)
If T.Row = 1 And T.Column = 6 Then
    If T.Count > 1 Then End
    T.Offset(1).Select
    With Selection.Validation
        .Delete
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=Join(d(T.Value).keys, ",")
    End With
   d.RemoveAll
End If
End Sub

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2025-1-11 15:26 | 显示全部楼层
3190496160 发表于 2025-1-11 09:12
Dim d As Object
Private Sub Worksheet_SelectionChange(ByVal T As Range)
If T.Row = 1 And T.Column  ...

1736579297644.jpg

不好意思,我以为用类似上面函数就能处理了。用VBA代码的话不知道实时判断单元格变化是否消耗资源。参照你的代码,我修改的VBA代码如下:
一个是字典的,一个只用字符的。不知道哪个效率最高,有请高手点评一下。
  1. Private Sub Worksheet_Change(ByVal T As Range)
  2. If Not Intersect(T, Me.Range("F1")) Is Nothing Then
  3.     Dim d As Object, d2 As Object, bj As String
  4.     bj = T.Value2
  5.     If Len(bj) > 0 Then '防止一级菜单值为空
  6.         Cells(2, 6).Value2 = ""  '清空二级菜单原有的值
  7.         Set d = CreateObject("scripting.dictionary")
  8.         Set d2 = CreateObject("scripting.dictionary")
  9.         d(bj) = 1  '使用字典来判断
  10.         r = Cells(Rows.Count, 2).End(xlUp).Row
  11.         arr = Range("b1:c" & r)
  12.         For i = 2 To UBound(arr)
  13.             If d.exists(arr(i, 1)) Then d2(arr(i, 2)) = i  'If arr(i, 1) = bj Then  不知道哪个效率更快
  14.         Next i

  15.         Cells(2, 6).Select
  16.         With Selection.Validation
  17.             .Delete
  18.             '防止找不到对应的二级菜单值
  19.             If d2.Count > 0 Then .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=Join(d2.keys, ",")
  20.         End With
  21.         Set d = Nothing
  22.         Set d2 = Nothing
  23.    End If
  24. End If
  25. End Sub


  26. Private Sub Worksheet_Change(ByVal T As Range)
  27. If Not Intersect(T, Me.Range("F1")) Is Nothing Then
  28.     Dim bj As String, cd2 As String
  29.     bj = T.Value2
  30.     If Len(bj) > 0 Then '防止一级菜单值为空
  31.         Cells(2, 6).Value2 = ""  '清空二级菜单原有的值
  32.         r = Cells(Rows.Count, 2).End(xlUp).Row
  33.         arr = Range("b1:c" & r)
  34.         For i = 2 To UBound(arr)
  35.             If arr(i, 1) = bj Then
  36.                 If cd2 <> "" Then
  37.                     cd2 = cd2 & "," & arr(i, 2)
  38.                 Else
  39.                     cd2 = arr(i, 2)
  40.                 End If
  41.             End If
  42.         Next i
  43.         
  44.         Cells(2, 6).Select
  45.         With Selection.Validation
  46.             .Delete
  47.             '防止找不到对应的二级菜单值
  48.             If cd2 <> "" Then .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=cd2
  49.         End With
  50.         Set d = Nothing
  51.         Set d2 = Nothing
  52.    End If
  53. End If
  54. End Sub
复制代码


TA的精华主题

TA的得分主题

发表于 2025-1-12 12:25 | 显示全部楼层
chengsijing 发表于 2025-1-11 15:26
不好意思,我以为用类似上面函数就能处理了。用VBA代码的话不知道实时判断单元格变化是否消耗资源。 ...

想多了吧??呵呵
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2025-1-16 16:47 , Processed in 0.031376 second(s), 12 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表