VBA多级联动菜单
- 格式:xls
- 大小:253.00 KB
- 文档页数:2


玩转excel下拉菜单,自动更新、剔除重复项、空值,全搞定在单元格中设置下拉菜单能有效提高表格录入和查找效率,还能规范数据,避免输入错误,是很受欢迎的实用功能。
网上很多文章在讲解设置方法时,用的案例数据都很简单规范,实现起来比较容易。
但在实际工作中,数据不一定规范,这样生成的菜单往往会存在一些瑕疵、甚至错误。
本文针对实际工作数据生成菜单中遇到的问题,分享处理解决方法,和大家一起玩转excel下拉菜单。
一级菜单1、设置方法选中需要设置下拉菜单的单元格,点击“数据”菜单下的“数据有效性”,将“允许”项设置为“序列”,单击一下“来源”输入框后,在表格里选取单元格区域作为菜单选项,或者手动在来源框输入单元格区域作为菜单选项,点击确定,菜单设置完成。
其中来源框输入公式为:=$A$1:$E$1,即将A1至E1单元格数据作为菜单的下拉选项。
可一次性选中I2至I5单元格,一步设置多个单元格的下拉菜单。
2、菜单自动更新、消除空值实际工作中,上面的案例可能会需要中途增加菜单选项的要求,比如要求增加F1单元格为菜单选项。
这时我们就需要重新设置一次菜单,选择单元格修改来源看的输入公式为:=$A$1:$F$1。
为避免每次增加选项都要重新进行菜单设置,可以在设置来源公式时,直接将预计可能会增加的菜单项单元格输入到公式里,比如上面的案例,虽然F1没有数据,但我们在设置来源公式时可以直接输入:=$A$1:$F$1。
这样在后期F1单元格补充输入数据时,数据就会自动出现在菜单选项中,得到达到自动更新菜单的效果。
但是,这样生成的菜单有个小瑕疵,即当F1还未填入数据时,菜单选项对应F1的位置会出现空白,不太合适。
我们需要实现当F1有数据就显示在菜单选项中,当F1没数据时,空白区域不显示在菜单中。
方法如下:修改来源位置的公式为:=OFFSET($A$1,,,1,MATCH(CHAR(1),$A$1:$F$1,-1)),公式里的$A$1:$F$1为预设菜单的区域。
vb在excel中设二级右键菜单在Excel中设置二级右键菜单,可以使用VBA编程来实现。
下面是一个简单的示例代码:```vb' 在模块中添加以下代码Option Explicit' 声明全局变量Dim cBar As CommandBar' 定义右键菜单点击事件Sub ClickMe()MsgBox "你点击了菜单选项"End Sub' 在Workbook_Open事件中创建右键菜单Private Sub Workbook_Open()' 删除已存在的右键菜单On Error Resume NextCommandBars("MyMenu").DeleteOn Error GoTo 0' 创建菜单Set cBar = CommandBars.Add(Name:="MyMenu", Position:=msoBarPopup, MenuBar:=False)With cBar.Controls.Add Type:=msoControlPopup, Before:=1 ' 添加主菜单项.Controls(1).Caption = "菜单项1"With .Controls.Add(Type:=msoControlPopup, Before:=2) ' 添加子菜单项.Caption = "菜单项2".Controls.Add Type:=msoControlButton ' 添加子菜单项的点击事件.Controls(1).Caption = "点击我".Controls(1).OnAction = "'" & & "'!ClickMe"End WithEnd WithSet cBar = NothingEnd Sub```将以上代码复制粘贴到Excel的VBA编辑器中(按下Alt+F11进入),在 "ThisWorkbook" 的代码窗口中添加 `Workbook_Open` 事件。
vba二级菜单数据索引indirect
VBA二级菜单数据索引indirect形式指的是使用indirect函数来引用数据的方法。
在VBA中,indirect函数可以用于将字符串作为引用,用于动态地获取特定单元格范围的值。
在实际应用中,可以将二级菜单中的选项名称存储在一列或一行的单元格中,然后使用indirect函数将选项名称作为字符串引用,从而获取对应选项的值。
这样就可以实现在二级菜单选项变化时,相应值的自动更新。
例如,假设选项名称存储在Sheet1中的A列单元格中,而选项对应的值存储在B 列单元格中。
使用indirect函数可以通过以下代码在VBA中获取选项对应的值:vbaDim optionName As StringDim optionValue As VariantoptionName = Sheet1.Range("A1").Value '假设选项名称存储在A1单元格中optionValue = Application.WorksheetFunction.VLookup(optionName,
Sheet1.Range("A:B"), 2, False)MsgBox "选项" & optionName & "对应的值是:" & optionValue以上代码将获取A列中与A1单元格相同的选项名称所对应的B列的值,并将其存储在optionValue中。
然后使用MsgBox函数将选项名称和对应的值显示在一个消息框中。
这种indirect形式的数据索引在处理动态菜单及其对应值时非常有用,可以根据菜单的选择自动更新相关的数值。
VBA应⽤实例:开发餐饮点菜单系统VBA使⽤VBA开发餐饮点菜单系统基本要求1、选择桌位号;2、查看菜单;3、选菜;删菜;4、提交、⽣成菜单⽐如,请先欣赏下⾯这张菜单点击【点菜】后,出现下⾯这张丑陋的弹窗:可以看到,功能有:【选择桌位】【查看菜单】【加⼊菜单】【从菜单删除】【已选菜单】【提交菜单】然后噼⾥啪啦如下⼀顿操作:提交菜单后,我们看到了4号桌的菜单功能简陋⽆⽐,下⾯将贴出代码,先贴图,这样看起来⽐较清晰下⾯是窗体中的代码,图⽚看上去⽐较模糊(后⾯会贴出⽂字版),主要是看整体的样式窗体中的代码如下:Private Sub UserForm_Initialize()'菜单.RowSource = '菜单!C2:E29''引⽤表单内单元格的格式'caidan =Sheet2.Range('C2:D29')'For cai_i = LBound(caidan, 1) To UBound(caidan, 1)'菜单.AddItem'菜单.List(菜单.ListCount - 1, 0) = caidan(cai_i, 1)'菜单.List(菜单.ListCount - 1, 1) = caidan(cai_i, 2)'Next菜单.ColumnCount = 3 '列表框显⽰的列数已选菜单.ColumnCount = 4选择桌位号.RowSource = '菜单!F2:F51''或:选择桌位号.RowSource = '菜单!' & Range('F2:F51').AddressEnd SubPrivate Sub 查看菜单_Click()caidan = Sheet2.Range('C2:D29')For cai_i = LBound(caidan, 1) To UBound(caidan, 1)菜单.AddItem菜单.List(菜单.ListCount - 1, 0) = caidan(cai_i, 1)菜单.List(菜单.ListCount - 1, 1) = caidan(cai_i, 2)菜单.List(菜单.ListCount - 1, 2) = ''NextEnd SubPrivate Sub 从菜单删除_Click()For n = 0 To 已选菜单.ListCount - 1If 已选菜单.Selected(n) = True Then'遍历菜单,把即将从已选菜单中删除的菜的'√'去掉For n_caidan = 0 To 菜单.ListCount - 1If 菜单.List(n_caidan, 0) = 已选菜单.List(n, 0) Then菜单.List(n_caidan, 2) = ''Exit ForEnd IfNext'从已选菜单中删除已选菜单.RemoveItem (n)'ListBox.RemoveItem ⽅法,从列表中删除⼀⾏'格式:ListBox.RemoveItem(pvargIndex),如果⽅法成功,则返回trueExit ForEnd IfNextEnd SubPrivate Sub 加⼊菜单_Click()'遍历菜单,如果被选中,则For i = 0 To 菜单.ListCount - 1If 菜单.Selected(i) = True Then'ListBox.Selected 属性,返回⼀个布尔值,指⽰listbox中项⽬的选择状态If 菜单.List(i, 2) <> '√' Then已选菜单.AddItem'先添加⼀个空⾏'⼀维数组或者单个元素,通过additem添加'ListBox.AddItem⽅法,向列表中添加项⽬已选菜单.List(已选菜单.ListCount - 1, 0) = 菜单.List(i, 0)已选菜单.List(已选菜单.ListCount - 1, 1) = 菜单.List(i, 1) '单价已选菜单.List(已选菜单.ListCount - 1, 2) = '1'已选菜单.List(已选菜单.ListCount - 1, 3) = 菜单.List(i, 1) '⾦额'⼆维数组,通过list添加菜单.List(i, 2) = '√''选过了的菜品,在原菜单中打钩ElseIf 菜单.List(i, 2) = '√' ThenFor i_already = 0 To 已选菜单.ListCount - 1If 菜单.List(i) = 已选菜单.List(i_already) Then已选菜单.List(i_already, 2) = 已选菜单.List(i_already, 2) + 1已选菜单.List(i_already, 3) = 已选菜单.List(i_already, 1) * 已选菜单.List(i_already, 2)ExitForEnd IfNextEnd IfEnd IfNextEnd SubPrivate Sub 提交菜单_Click()Set new_sheet =ThisWorkbook.Worksheets.Add'Set new_sheet = Worksheets.Addnew_ = 选择桌位号.Value & '号桌'new_sheet.Range('A1') = '菜名'new_sheet.Range('B1') = '单价'new_sheet.Range('C1') = '数量'new_sheet.Range('D1') = '⾦额'menu_num = 0menu_mon = 0'遍历已选菜单,在新表单中记录菜名、单价和数量For m = 0 To 已选菜单.ListCount - 1new_sheet.Range('A' & m + 2) = 已选菜单.List(m, 0) '菜名new_sheet.Range('B' & m + 2) = 已选菜单.List(m, 1) '单价new_sheet.Range('C' & m + 2) = 已选菜单.List(m, 2) '数量menu_num = menu_num + 已选菜单.List(m, 2)new_sheet.Range('D' & m + 2) = 已选菜单.List(m, 3) '⾦额menu_mon = menu_mon + 已选菜单.List(m, 3)Nexthuizong_row =new_edRange.Rows.Countnew_sheet.Range('A' & huizong_row + 1) = '汇总'new_sheet.Range('C' & huizong_row + 1) = menu_numnew_sheet.Range('D' & huizong_row + 1) = menu_monEnd Sub功能相当简陋同志仍需努⼒好书推荐最近中午在看的是《商君书》,篇幅很短,总共200页,也就100张。