Word 2013中的VBA编码

时间:2017-10-11 15:48:49

标签: vba ms-word word-vba

我在Word 2013中遇到了有关VBA的问题。我对编码的经验有限,而宏对我来说是一个新的领域。

我有一个成功的VBA代码来自一个不再在我的办公室工作的工人,这个代码允许在办公室表格中的下拉菜单,允许用户选择他们的位置,页脚更改文本地址办公室在一个字符串。

我一直在尝试做的是调整此代码,以便在选择位置时,不会在页面底部显示文本,而是会更改标题模板。我已成功录制了宏,因此它可以在我的计算机上执行我想要的操作,但是当我尝试与其他人共享时,会发生一些事情。下拉菜单没有出现,然后我必须放入开发人员选项卡。在那之后我每次要运行宏时都要解锁文件(即使旧文件也被锁定,旧文件也不需要这个),然后我得到错误代码,说明所请求的成员不存在,指向我录制的宏。

我确定我做错了什么,但我不确定那是什么。一些帮助将不胜感激。

Option Explicit
Sub AutoNew()
Dim Mybar As CommandBar
Dim myControl As CommandBarComboBox
Dim cmd As CommandBar
Dim cmdyes As Integer
cmdyes = 0

For Each cmd In CommandBars
If cmd.Name = "Select Location" Then
cmdyes = 1
Exit For
Else
End If
Next

If cmdyes = 1 Then
CommandBars("Select Location").Visible = True
Else
Set Mybar = CommandBars _
.Add(Name:="Select Location", Position:=msoBarFloating, _
Temporary:=False)
Set myControl = CommandBars("Select Location").Controls _
.Add(Type:=msoControlDropdown, Before:=1)
With myControl
.AddItem " South Portland"
.AddItem " Bangor"
.AddItem " Presque Isle"
.ListIndex = 1
.Caption = "Select Office Location"
.Style = msoComboLabel
.BeginGroup = True
.OnAction = "processSelection"
.Tag = "AddresSelect"
    End With
End If

CommandBars("Select Location").Visible = True

If ActiveDocument.ProtectionType = wdAllowOnlyFormFields = False Then
ActiveDocument.Protect Type:=wdAllowOnlyFormFields, NoReset:=True, 
Password:="password"
' ActiveDocument.Protect Type:=wdAllowOnlyFormFields, NoReset:=True, 
Password:=""
End If
End Sub
Sub AutoOpen()
Dim Mybar As CommandBar
Dim myControl As CommandBarComboBox
Dim cmd As CommandBar
Dim cmdyes As Integer
cmdyes = 0

For Each cmd In CommandBars
If cmd.Name = "Select Location" Then
cmdyes = 1
Exit For
Else
End If
Next

If cmdyes = 1 Then
CommandBars("Select Location").Visible = True
Else
Set Mybar = CommandBars _
.Add(Name:="Select Location", Position:=msoBarFloating, _
Temporary:=False)
Set myControl = CommandBars("Select Location").Controls _
.Add(Type:=msoControlDropdown, Before:=1)
With myControl
.AddItem " South Portland"
.AddItem " Bangor"
.AddItem " Presque Isle"
.ListIndex = 1
.Caption = "Select Office Location"
.Style = msoComboLabel
.BeginGroup = True
.OnAction = "processSelection"
.Tag = "AddresSelect"
    End With

End If

CommandBars("Select Location").Visible = True

If ActiveDocument.ProtectionType = wdAllowOnlyFormFields = False Then
ActiveDocument.Protect Type:=wdAllowOnlyFormFields, NoReset:=True, 
Password:="password"
' ActiveDocument.Protect Type:=wdAllowOnlyFormFields, NoReset:=True, 
Password:=""
End If
End Sub
Sub processSelection()
Dim userChoice As Long
userChoice = CommandBars("Select Location").Controls(1).ListIndex
Select Case userChoice
    Case 1
        Call SoPortlandAddress
    Case 2
        Call BangorAddress
    Case Else
        Call PresqueIsleAddress
End Select
End Sub
Sub SoPortlandAddress()
'
' SoPortlandAddress Macro
'
'
If ActiveWindow.View.SplitSpecial <> wdPaneNone Then
    ActiveWindow.Panes(2).Close
End If
If ActiveWindow.ActivePane.View.Type = wdNormalView Or ActiveWindow. _
    ActivePane.View.Type = wdOutlineView Then
    ActiveWindow.ActivePane.View.Type = wdPrintView
End If
ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
Templates.LoadBuildingBlocks
Application.Templates( _
    "C:\Users\bex172\AppData\Roaming\Microsoft\Document Building 
Blocks\1033\15\Building Blocks.dotx" _
    ).BuildingBlockEntries("South Portland Header").Insert Where:=Selection. 
_
    Range, RichText:=True
ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument

  If ActiveDocument.ProtectionType = wdAllowOnlyFormFields Then
ActiveDocument.Unprotect Password:="password"
End If
If ActiveDocument.ProtectionType = wdNoProtection Then
  FormLock
End If
End Sub

Sub BangorAddress()
'
' BangorAddress Macro
'
'
If ActiveWindow.View.SplitSpecial <> wdPaneNone Then
    ActiveWindow.Panes(2).Close
End If
If ActiveWindow.ActivePane.View.Type = wdNormalView Or ActiveWindow. _
    ActivePane.View.Type = wdOutlineView Then
    ActiveWindow.ActivePane.View.Type = wdPrintView
End If
ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
Templates.LoadBuildingBlocks
Application.Templates( _
    "C:\Users\bex172\AppData\Roaming\Microsoft\Document Building 
Blocks\1033\15\Building Blocks.dotx" _
    ).BuildingBlockEntries("Bangor Header").Insert Where:=Selection.Range, _
    RichText:=True
ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument

If ActiveDocument.ProtectionType = wdAllowOnlyFormFields Then
ActiveDocument.Unprotect Password:="password"
End If
If ActiveDocument.ProtectionType = wdNoProtection Then
  FormLock
End If
End Sub

Sub PresqueIsleAddress()
'
' PresqueIsleAddress Macro
'
'
If ActiveWindow.View.SplitSpecial <> wdPaneNone Then
    ActiveWindow.Panes(2).Close
End If
If ActiveWindow.ActivePane.View.Type = wdNormalView Or ActiveWindow. _
    ActivePane.View.Type = wdOutlineView Then
    ActiveWindow.ActivePane.View.Type = wdPrintView
End If
ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
Templates.LoadBuildingBlocks
Application.Templates( _
    "C:\Users\bex172\AppData\Roaming\Microsoft\Document Building 
Blocks\1033\15\Building Blocks.dotx" _
    ).BuildingBlockEntries("Presque Isle Header").Insert Where:=Selection. _
    Range, RichText:=True
ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument

If ActiveDocument.ProtectionType = wdAllowOnlyFormFields Then
ActiveDocument.Unprotect Password:="password"
End If
If ActiveDocument.ProtectionType = wdNoProtection Then
  FormLock
End If
End Sub
Sub FormLock()
'
' ToggleFormLock Macro
' Macro created 1/27/2004 by name removed
'
If ActiveDocument.ProtectionType = wdAllowOnlyFormFields = False Then
ActiveDocument.Protect Type:=wdAllowOnlyFormFields, NoReset:=True, 
Password:="password"
 'if a password is used, add the line below after a space above
 'Password:="myPassword"
Else


 'if a password is used, add a comma after
 'the last line and include the line below
 'Password:="myPassword"
End If
End Sub

1 个答案:

答案 0 :(得分:0)

I found your code a little unwieldy and understand that it poses a problem for you. The abbreviated version below should be easier to understand and therefore easier for you to manage once you acquaint yourself with its own peculiarities. Note that I tested everything except the actual extraction and insertion of the building block, since you said it is working.

Option Explicit

    ' declare the name (so as to eliminate typos)
    Const CmdName As String = "Select Location"

Sub AutoNew()
    ' 12 Oct 2017
    SetCommandBar
End Sub

Sub AutoOpen()
    ' 12 Oct 2017
    SetCommandBar
End Sub

Sub SetCommandBar()
    ' 12 Oct 2017

    Dim MyBar As CommandBar
    Dim MyCtl As CommandBarControl
    Dim MyList() As String
    Dim Cmd As CommandBar
    Dim i As Integer

    ' delete the existing (so that you can modify it)
    For Each Cmd In CommandBars
        If Cmd.Name = CmdName Then
            Cmd.Delete
            Exit For
        End If
    Next Cmd

    ' in Word >= 2007 the commandbar will be displayed
    ' in the ribbon's Add-ins tab
    Set MyBar = CommandBars.Add(Name:=CmdName, _
                                Position:=msoBarFloating, _
                                MenuBar:=True, _
                                Temporary:=True)
    Set MyCtl = CommandBars(CmdName).Controls.Add( _
                                Type:=msoControlDropdown, _
                                Before:=1)

    ' Names must match Building Block names (without " Header")
    MyList = Split(" South Portland, Bangor, Presque Isle", ",")
    With MyCtl
        .Caption = "Select Office Location"
        .Style = msoComboLabel
        For i = 0 To UBound(MyList)
            .AddItem MyList(i)
        Next i
        .ListIndex = 1
        .OnAction = "SetHeader"
    End With
    CommandBars(CmdName).Visible = True
End Sub

Sub SetHeader()
    ' 12 Oct 2017

    Const BlockFile As String = "C:\Users\bex172\AppData\Roaming\Microsoft\" & _
                                "Document Building Blocks\1033\15\" & _
                                "Building Blocks.dotx"
    Dim BlockID As String

    SetFormLock False               ' not needed if the document isn't locked
    With ActiveWindow
        If .View.SplitSpecial <> wdPaneNone Then .Panes(2).Close
        With .ActivePane.View
            If .Type = wdNormalView Or .Type = wdOutlineView Then
                .Type = wdPrintView
            End If
            .SeekView = wdSeekCurrentPageHeader
        End With
    End With

    BlockID = Trim(CommandBars(CmdName).Controls(1).Text) & " Header"
    Templates.LoadBuildingBlocks
    Application.Templates(BlockFile).BuildingBlockEntries(BlockID).Insert _
                Where:=Selection.Range, _
                RichText:=True
    SetFormLock True                ' not needed if the document isn't to be locked
End Sub

Sub SetFormLock(ByVal FormLock As Boolean)
    ' 12 Oct 2017
    ' call this procedure with either "True" or "False" as argument
    ' to either lock or unlock the form.

    ' The same password is used for unlocking and locking.
    ' MAKE SURE THE DOCUMENT IS UNLOCKED before changing the password!
    Const Password As String = ""

    Dim Doc As Document

    Set Doc = ActiveDocument
    With Doc
        If .ProtectionType = wdNoProtection Then
            If FormLock Then
                 ' you can't set the protection while any other part of the document is active
                ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument

               ' you may wish to specify another type of protection:
                ' this code protects all except FormFields
                .Protect Type:=WdProtectionType.wdAllowOnlyFormFields, _
                         NoReset:=True, _
                         Password:=Password, _
                         UseIRM:=False, _
                         EnforceStyleLock:=False
            End If
        Else
            If Not FormLock Then .Unprotect Password
        End If
    End With
End Sub

Your question didn't allow full understanding of your problem. It might have to do with the location of the code itself or with the protection. By making the code more transparent I hope that you will either be able to eliminate the problem or find the right question to ask.