MyVBA加载宏——添加自定义菜单04——功能实现

2020-07-28 14:30:23 浏览数 (1)

有了前面的功能分析基础,使用VBA代码实现这个功能就不是很难了,逐行读取CommandBarDir.txt里面的信息,然后创建弹出式菜单或者按钮,最终实现的效果如下:

功能实现

01

类模块功能

类模块CCommandBar就是为了响应单击按钮的功能:

  • 根据单击的按钮的名称,读取对应名称的txt文件
  • 将读取到的文本插入到VBE中

所以,分别先实现2个函数,读取txt文件的内容在前面有过介绍:

  • VBA调用外部对象02:FileSystemObject——操作文本文件
  • 文件操作——读取

在这里使用FSO来读取。

代码语言:javascript复制
Private Function FsoReadTxt(file_name As String) As String
    Dim fso As Object, sr As Object
    
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set sr = fso.OpenTextFile(file_name, 1) 'ForReading=1

    FsoReadTxt = sr.ReadAll()
    
    Set fso = Nothing
    Set sr = Nothing
End Function

在VBE中插入代码,就是操作VBE对象相关的属性和方法

代码语言:javascript复制
Private Function InsertCode(str_code As String)
    Dim i_row As Long
    '获取鼠标定位所在的行号
    Application.VBE.ActiveCodePane.GetSelection i_row, 0, 0, 0
    '从获取的行号开始处插入代码
    Application.VBE.SelectedVBComponent.CodeModule.InsertLines i_row, str_code
End Function

这2个函数都放在类模块CCommandBar中。

然后是实现类模块响应按钮的单击事件:

代码语言:javascript复制
Public WithEvents cmdbe As VBIDE.CommandBarEvents

Private Sub cmdbe_Click(ByVal CommandBarControl As Object, handled As Boolean, CancelDefault As Boolean)
    On Error GoTo ErrHandle
    
    Dim str_code As String
    Const VBE_DIR As String = "vbaCodes"
    
    str_code = FsoReadTxt(ThisWorkbook.Path & VBE_DIR & CommandBarControl.Caption & ".txt")
    InsertCode str_code
    Exit Sub
    
ErrHandle:
    MsgBox Err.Description
End Sub

VBE_DIR的路径名称可以自己设置,但建议放在MyVBA.xlam同一路径下。

02

添加菜单的功能

添加菜单和按钮的代码:

代码语言:javascript复制

'记录所有需要执行单击事件的菜单按钮
Private cbars As Collection

Private Type CommandBarInfo
    mso As Long     '菜单类型
    Caption As String  '名称
    FaceId As Long  '图标
    Flag As Long    '记录是否是弹出式菜单
End Type

Sub AddCommanBar()
    If Not CheckVbproject Then
        Exit Sub
    End If
    
    Set cbars = New Collection
    add_bar
End Sub

Function add_bar() As Long
    Dim bar_btn As CommandBarControl
    Dim bar_info As CommandBarInfo
    Dim num_file As Integer
    Dim tmp_bar As CommandBarPopup
    Dim my_bar As CommandBarPopup
    Dim cbar As CCommandBar
    
    Const sBAR_NAME As String = "插入代码(&C)"
    Const VBACodes As String = "vbaCodesCommandBarDir.txt"
        
    On Error Resume Next
    Application.VBE.CommandBars(1).Controls(sBAR_NAME).Delete
    On Error GoTo 0
    
    '添加菜单
    Set my_bar = Application.VBE.CommandBars(1).Controls.Add(msoControlPopup)
    my_bar.Caption = sBAR_NAME
    Set tmp_bar = my_bar
    
    '打开目录
    num_file = VBA.FreeFile
    Open ThisWorkbook.Path & VBACodes For Input As #num_file
     '跳过标题行
    Line Input #num_file, bar_info.Caption
    Do Until VBA.EOF(num_file)
        Input #num_file, bar_info.mso, bar_info.Caption, bar_info.FaceId, bar_info.Flag
        If bar_info.Caption <> "" Then
            If bar_info.mso = msoControlPopup Then
                '弹出式菜单
                Set tmp_bar = my_bar.Controls.Add(msoControlPopup)
                tmp_bar.Caption = bar_info.Caption
            Else
                Set bar_btn = tmp_bar.Controls.Add(bar_info.mso)
                bar_btn.Caption = bar_info.Caption
                bar_btn.FaceId = bar_info.FaceId
                bar_btn.BeginGroup = True
                
                Set cbar = New CCommandBar
                Set cbar.cmdbe = Application.VBE.Events.CommandBarEvents(bar_btn)
                '添加到集合中
                cbars.Add cbar
                
                'flag=1 表示1个popup的结束
                If bar_info.Flag = 1 Then Set tmp_bar = my_bar
            End If

        End If
    Loop
    
    Close #num_file

    Set bar_btn = Nothing
End Function

Function CheckVbproject() As Boolean
    Dim obj As Object
    
    On Error Resume Next
    Set obj = Application.VBE.ActiveVBProject
    If Err.Number <> 0 Then
        MsgBox "请勾选 信任对VBA工程对象模型的访问"
        CheckVbproject = False
    Else
        CheckVbproject = True
    End If
End Function

因为要操作VBE,所以先使用CheckVbproject检查是否勾选了信任对VBA工程对象模型的访问,如何设置请参考VBA操作VBA——VBA工程对象

03

自动更新

使用过程中增加了代码后,只要重新打开加载宏就会自动进行更新,在ThisWorkbook模块添加代码:

代码语言:javascript复制
Private Sub Workbook_Open()
    Call AddCommanBar
End Sub

后面需要做的就是维护好CommandBarDir.txt即可。

vba

0 人点赞