ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[原创] VBA之Listbox控件基础教程

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2021-12-18 12:04 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
强强强,实在太有用了

TA的精华主题

TA的得分主题

发表于 2022-1-19 13:06 | 显示全部楼层
老师,按照你的代码,照葫芦画瓢用了起来,现在有五百多条记录,今后还会更多,每次在模糊查询时在查询输入框点撤销按钮时,都卡的很。所以我用了一个清空按钮来代替撤销按钮。这种卡顿是通病还是我的代码有问题呢。这段代码还能优化提高查询速度吗?怎么优化呢? 捕获.PNG 捕获2.PNG




能不能帮我实现这个功能,在这个查询窗口增加一个输入框和一个修改按钮,当点击某条数据后,我可以点击修改把我需要的车牌号,重新赋予覆盖到这条数据里。
捕获3.PNG

捕获4.PNG

TA的精华主题

TA的得分主题

发表于 2022-1-26 01:22 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2022-2-6 00:01 | 显示全部楼层
花了一晚上,从头到尾看回复,下载看编写,终于学以致用。谢谢老师

TA的精华主题

TA的得分主题

发表于 2022-3-9 10:42 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
学习中,强大

TA的精华主题

TA的得分主题

发表于 2022-4-14 12:35 | 显示全部楼层
学习了,非常有用。
因为Listbox的兼容性很强,所以经常用。

TA的精华主题

TA的得分主题

发表于 2022-4-25 16:05 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2022-5-9 20:07 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册

  1. Private Original$ '存储目标单元格原始值
  2. Private ListIdx& '存储列表框按下方向键而尚未弹起时的行索引值
  3. Private Const RangeAddr = "E4" '设置作用区域

  4. Private Sub HideCtrl()
  5.     '隐藏控件,到处需要使用,做出公共过程
  6.     ListBox1.Clear '清空列表
  7.     TextBox1 = "" '文本框为空
  8.     ListBox1.Visible = False '隐藏列表框
  9.     TextBox1.Visible = False '隐藏文本框
  10. End Sub

  11. Private Sub ListBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
  12.     '为什么要记录ListIdx?是因为在ListBox1按住上、下箭头无需弹起也能滚动列表(持续触发KeyDown)
  13.     '不在按下方向键时标记ListIdx,KeyUp按键弹起事件中就会多走一定数量的行。
  14.     ListIdx = ListBox1.ListIndex
  15. End Sub

  16. Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
  17.     ListIdx = ListBox1.ListIndex
  18. End Sub

  19. Private Sub Ctrl_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
  20.     '因为Listbox和TEXTBOX控件都要用到这个事件,故定义一个公共子过程
  21.     'Shift值:0代表没有按3键中的任何一个,1代表按了Shift键,2代表按了Ctrl键,4代表按了ALT
  22.     Dim lRow&, lCol&, i&
  23.     With ListBox1
  24.         Select Case KeyCode
  25.             Case vbKeyReturn '按回车键,完成输入动作
  26.                 WriteInto
  27.                
  28.             Case vbKeyTab '按ESC键无法响应,改为Tab键,取消输入,恢复原值
  29.                 ActiveCell = Original
  30.                 HideCtrl
  31.                
  32.             Case vbKeyUp, vbKeyDown '上、下方向键
  33.                 If Shift = 2 Then 'Ctrl+上、下方向键,跳到当前活动单元格的上、下方单元格
  34.                     With ActiveCell
  35.                         Do
  36.                             i = i + KeyCode - 39 '↑、↓键码为38、40,KeyCode - 39 = ±1
  37.                             lRow = .Row + i
  38.                             If lRow < 1 Or lRow > Rows.Count Then Exit Do '超出工作表行数范围
  39.                             If Rows(lRow).Height Then .Offset(i).Activate: Exit Do '隐藏行高为0
  40.                         Loop
  41.                     End With
  42.                 ElseIf .ListCount > 2 Then 'Listbox中有数据行时
  43.                     ListIdx = ListIdx + KeyCode - 39
  44.                     If ListIdx <= 0 Then ListIdx = .ListCount - 1 '选中第一行标题时变成选最后一行
  45.                     If ListIdx >= .ListCount Then ListIdx = 1 '超过最后一行后返回到第二行(第一行为标题)
  46.                     .ListIndex = ListIdx
  47.                 End If
  48.                
  49.             Case vbKeyLeft, vbKeyRight '左、右方向键
  50.                 If Shift = 2 Then 'ActiveCell.Offset(, KeyCode - 38).Activate
  51.                     With ActiveCell
  52.                         Do
  53.                             i = i + KeyCode - 38 '←、→键码为37、39,KeyCode - 38 = ±1
  54.                             lCol = .Column + i
  55.                             If lCol < 1 Or lCol > Columns.Count Then Exit Do '超出工作表列数范围
  56.                             If Columns(lCol).Width Then .Offset(, i).Activate: Exit Do '隐藏列宽为0
  57.                         Loop
  58.                     End With
  59.                 End If
  60.             Case Else
  61.         End Select
  62.     End With
  63. End Sub

  64. Private Sub ListBox1_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
  65.     Ctrl_KeyUp KeyCode, Shift
  66. End Sub

  67. Private Sub TextBox1_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
  68.     Ctrl_KeyUp KeyCode, Shift
  69. End Sub

  70. Private Sub Worksheet_SelectionChange(ByVal Target As Range)
  71.     '判断是否符合条件

  72.     'If InputSwitchFlag = False Then Exit Sub '不能用HideCtrl,事件中运行任何代码修改值或属性都会影响复制后的粘贴功能,
  73.     '这句代码这样设置,InputSwitchFlag = False时不影响粘贴。如果用Application.EnableEvents = False会影响其他事件使用。
  74.     '使用Application.CutCopyMode<>False也有问题,单元格编辑状态(双击)下复制无法探测。检测剪贴板上是否有内容也不完美。
  75.     If Intersect(Target, Range(RangeAddr)) Is Nothing Then HideCtrl: Exit Sub
  76.     If Target.Count > 1 Then HideCtrl: Exit Sub
  77.     If IsEmpty(arr) Then Call GetData
  78.     If IsEmpty(arr) Then HideCtrl: Exit Sub
  79.    
  80.     '初始化准备工作
  81.     '设定控件的尺寸、位置、字体等 属性
  82.     ListBox1.Visible = False
  83.     TextBox1.Visible = False
  84.     With TextBox1
  85.         .Top = Target.Top
  86.         .Left = Target.Left
  87.         .Width = Target.Width
  88.         .Height = Target.Height
  89.         .Font.Size = Target.Font.Size - 1
  90.         .BorderStyle = fmBorderStyleSingle
  91.         .BorderColor = &H80000006
  92.         .Text = ActiveCell.Value
  93.         Original = .Text
  94.         .Activate
  95.         .Visible = True
  96.     End With
  97.     With ListBox1
  98.         .Top = Target.Top + Target.Height + 2
  99.         .Left = Target.Left + Target.Width
  100.         .Height = 200 '高度
  101.         .Width = 600 '宽度
  102.         .Font.Size = 10
  103.         .ForeColor = vbBlue
  104.         .BackColor = 15849925
  105.         .ColumnCount = UBound(arr, 2) ' '列表框的列数=数组的列数
  106.         .ColumnWidths = "80;80;80;50;50;50;50;50;50;50;50;50"
  107.         .Visible = True
  108.     End With
  109.     TextBox1_Change
  110. End Sub


  111. Private Sub WriteInto() '填入内容到哦工作表
  112.     Dim brr
  113.     With ListBox1
  114.         If .ListCount < 2 Then '没有查询到数据,直接输入TextBox1内容
  115.             ActiveCell = TextBox1.Text
  116.         Else
  117.             If .ListIndex = 0 Then Exit Sub
  118.             ReDim brr(1 To .ColumnCount)
  119.             For i = 2 To UBound(brr)
  120.                 brr(i) = .List(.ListIndex, i - 1)
  121.             Next
  122.             ActiveCell.Resize(1, UBound(brr)) = brr
  123.         End If
  124.         TextBox1.Text = ""
  125.         'ActiveCell.Offset(1).Activate
  126.         
  127.         'SmallScroll可有四个参数:
  128.         'Down 将内容向下滚动的行数。
  129.         'Up 将内容向上滚动的行数。
  130.         'ToRight 将内容向右滚动的列数。
  131.         'ToLeft 将内容向左滚动的列数。
  132.         'ActiveWindow.SmallScroll Down:=1
  133.     End With
  134. End Sub



  135. Private Sub TextBox1_Change()
  136.     Dim s$, t$, i&, j&, u&, brr
  137.     If IsEmpty(arr) Then Exit Sub
  138.     t = UCase(TextBox1)
  139.     With ListBox1
  140.         If Len(t) = 0 Then
  141.             .List = arr
  142.             .ListIndex = 1
  143.             Exit Sub
  144.         End If
  145.    
  146.         ReDim brr(1 To UBound(arr, 2), 1 To 1) '定义二维数组brr,1到数组的列数
  147.         For i = 2 To UBound(arr, 2) '标题 ''UBound(brr, 2)数组的列数表达
  148.             brr(i, 1) = arr(2, i)
  149.         Next
  150.         .Clear
  151.         For i = 2 To UBound(arr) '数组的行数的表达,
  152.             s = arr(i, 1) & "|" & arr(i, 2) & "|" & arr(i, 3) & "|" & arr(i, 4) & "|" & arr(i, 5) '多条件模糊查询,只需把各列串联起来即可。
  153.             If InStr(s, t) Then
  154.                 ReDim Preserve brr(1 To UBound(arr, 2), 1 To UBound(brr, 2) + 1) 'UBound(brr, 2)数组的列数表达
  155.                 u = UBound(brr, 2) 'UBound(brr, 2)数组的列数表达
  156.                 For j = 1 To UBound(arr, 2) '想显示几列就赋值几列
  157.                     brr(j, u) = arr(i, j)
  158.                 Next
  159.             End If
  160.         Next
  161.        .Column = brr '用Column属性赋值无需转置数组
  162.         If UBound(brr, 2) > 1 Then .ListIndex = 1
  163.     End With
  164. End Sub

  165. Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
  166.     WriteInto
  167. End Sub

复制代码


@ivccav 请问向图片中的双标题行如果修改呢?有一个是数据源表的总标题,第4行才是数据源的标题行。。
001.png

TA的精华主题

TA的得分主题

发表于 2022-8-10 14:48 | 显示全部楼层
请教两个问题:1 listbox如何设置水平滚动条?当一行文字过多显示不全问题如何解决;2 类似控件的详细文档,在微软官网上哪里可以查到? 谢谢

TA的精华主题

TA的得分主题

发表于 2022-8-19 14:08 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
强!学习了
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-12-23 11:50 , Processed in 0.042849 second(s), 8 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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