如果我从VBA编辑器中启动脚本,我遇到了运行正常的脚本问题,但是当我直接从Word启动它时却没有。作为解释,脚本定义Word文档中的首字母缩写词。在Word文件出现之前,它会进行第一级编辑,编辑器会在其中突出显示他/她已验证的术语。因为我的脚本也使用突出显示,所以我用彩色文本替换现有的突出显示。
'Turn track changes off, replace yellow highlighting from FLEs with colored text to avoid confusion between
'FLE highlighting and acronym defininer highlighting
ActiveDocument.TrackRevisions = False
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Highlight = True
With .Replacement
.Highlight = False
.Font.Color = RGB(155, 187, 89)
End With
.Execute Replace:=wdReplaceAll, Wrap:=wdFindStop
End With
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
当我直接从Word运行脚本时,它会跳过整个代码块。其他所有工作都应该如此,但第一级编辑的重点仍然存在。当我直接从VBA编辑器运行时,一切都按预期工作。当我进行其他更改时(例如,我刚刚更新了宏调用的一个表单以添加绿色文本的解释),无论我从哪里开始编写脚本,它们都会通过。任何想法为什么这部分代码可能会被跳过?以下是整个脚本。
Option Explicit
Public Definitions(5) As String
Sub Acronym_Definer()
'Defines Workbook and Worksheet, Opens Excel
Dim xlApp As Excel.Application
Dim xlWbk As Workbook
Dim FN As String: FN = "C:\Users\" & Environ$("Username") & "\AppData\Roaming\Gartner\AcronymDefiner\AcronymDefiner.xlsx"
Dim Current_Row As Long: Current_Row = 2
Set xlApp = New Excel.Application
xlApp.Visible = False
Set xlWbk = xlApp.Workbooks.Open(FN)
'Determines whether Track Changes is on or off so it can be returned to original state at end of macro
Dim Track_Changes As Boolean
If ActiveDocument.TrackRevisions = False Then
Track_Changes = False
End If
'Changes to Simple View in Track Changes to keep deleted text from coming up in searches throughout the macro
With ActiveWindow.View.RevisionsFilter
.Markup = wdRevisionsMarkupSimple
.View = wdRevisionsViewFinal
End With
'Turn track changes off, replace yellow highlighting from FLEs with colored text to avoid confusion between
'FLE highlighting and acronym defininer highlighting
ActiveDocument.TrackRevisions = False
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Highlight = True
With .Replacement
.Highlight = False
.Font.Color = RGB(155, 187, 89)
End With
.Execute Replace:=wdReplaceAll, Wrap:=wdFindStop
End With
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
'Begins acronym definition loop
Do While Current_Row <= xlWbk.ActiveSheet.UsedRange.Rows.Count
'Use to decide which column to check for NNTD status
Dim NNTD_Column As Integer
Dim NNTD As Boolean: NNTD = False
Dim Chosen_Definition As String
Dim Current_Acronym As String: Current_Acronym = xlWbk.ActiveSheet.Cells(Current_Row, 1)
Dim User_Skip As Boolean
Selection.HomeKey unit:=wdStory
With Selection.Find
.ClearFormatting
'.Font.Color = wdColorAutomatic
.Text = Current_Acronym
.MatchCase = True
.MatchWholeWord = True
.Wrap = wdFindStop
End With
'Check for presence of acronym
If Selection.Find.Execute Then
'How many definitions does this acronym have?
Dim Number_Definitions As Integer: Number_Definitions = xlWbk.ActiveSheet.Cells(Current_Row, 2)
'There's only one definition; the definition is in column 3 and the NNTD status is in column 4
If Number_Definitions = 1 Then
Chosen_Definition = xlWbk.ActiveSheet.Cells(Current_Row, 3)
NNTD_Column = 4
NNTD = xlWbk.ActiveSheet.Cells(Current_Row, NNTD_Column)
User_Skip = False
'There's more than one definition; put definitions into array and get definition from user form
Else
'Ensures Array is empty at start of each loop
Erase Definitions
'Adds the definitions to Definitions array
Dim i As Integer
Dim Current_Column As Integer: Current_Column = 3
For i = 1 To Number_Definitions
Definitions(i - 1) = xlWbk.ActiveSheet.Cells(Current_Row, Current_Column)
Current_Column = Current_Column + 2
Next i
'Opens userform to allow user to choose from the available definitions
Load DefinitionList
DefinitionList.lstAvailableDefinitions.List = Definitions
DefinitionList.Show
'Did the user select an option?
If IsNull(DefinitionList.lstAvailableDefinitions.Value) Then
User_Skip = True
Else
'Assigns user selection to Chosen_Definition variable
Chosen_Definition = DefinitionList.lstAvailableDefinitions.Value
User_Skip = False
'Determines NNTD column
Dim j As Integer
For j = LBound(Definitions) To UBound(Definitions)
If Definitions(j) = Chosen_Definition Then
NNTD_Column = (2 * j) + 4
Exit For
End If
Next j
Unload DefinitionList
NNTD = xlWbk.ActiveSheet.Cells(Current_Row, NNTD_Column)
End If
End If
'Acronym is NNTD
If NNTD = True Then
'Highlights NNTD acronyms in yellow.
Options.DefaultHighlightColorIndex = wdYellow
Selection.HomeKey unit:=wdStory
With Selection.Find
'.Font.Color = wdColorAutomatic
.Text = Current_Acronym
.MatchCase = True
.MatchWholeWord = True
With .Replacement
.Highlight = True
.Text = ""
End With
.Execute Replace:=wdReplaceAll, Wrap:=wdFindStop
End With
'User chose to skip or clicked OK without selecting an option; highlight all instances of acronym in red
ElseIf User_Skip = True Then
Unload DefinitionList
Options.DefaultHighlightColorIndex = wdRed
Selection.HomeKey unit:=wdStory
With Selection.Find
'.Font.Color = wdColorAutomatic
.Text = Current_Acronym
.MatchCase = True
.MatchWholeWord = True
With .Replacement
.Highlight = True
.Text = ""
End With
.Execute Replace:=wdReplaceAll, Wrap:=wdFindStop
End With
'Acronym needs to be defined
Else
'Selects first instance of acronym. Get start position of first instance of acronym.
Selection.HomeKey unit:=wdStory
Selection.Find.Execute Current_Acronym
Dim AcronymStart As Long: AcronymStart = Selection.Start
'Determines whether definition occurs in document
Selection.HomeKey unit:=wdStory
With Selection.Find
'.Font.Color = wdColorAutomatic
.Text = Chosen_Definition
.MatchCase = False
.Execute Wrap:=wdFindStop
End With
'Definition doesn't occur; insert definition before first definition of acronym and add
'parentheses around acronym
If Selection.Find.Found = False Then
Selection.HomeKey unit:=wdStory
With Selection.Find
'.Font.Color = wdColorAutomatic
.Text = Current_Acronym
.MatchCase = True
.Execute
End With
With Selection
.InsertBefore Chosen_Definition & " ("
.InsertAfter ")"
End With
'Definition occurs in document; get end position of definition and compare to start position of acronym
'(should be two lower than acronym)
Else
Selection.HomeKey unit:=wdStory
Selection.Find.Execute Chosen_Definition
Dim DefinitionEnd As Long: DefinitionEnd = Selection.End
'Acronym is correctly defined; no further action is needed to define the acronym
If DefinitionEnd = AcronymStart - 2 Then
'Definition occurs after acronym; insert definition before first instance of acronym
ElseIf DefinitionEnd > AcronymStart Then
'Moves to first instance of acronym
Selection.HomeKey unit:=wdStory
'Adds definition and places parentheses around acronym
With Selection.Find
'.Font.Color = wdColorAutomatic
.Text = Current_Acronym
.MatchCase = True
.Execute
End With
With Selection
.InsertBefore Chosen_Definition & " ("
.InsertAfter ")"
End With
'Definition occurs before (but not immediately prior to) acronym
Else
Selection.HomeKey unit:=wdStory
Selection.Find.Execute Chosen_Definition
'Inserts acronym (surrounded by parentheses) after definition
With Selection
.InsertAfter " (" & Current_Acronym & ")"
End With
End If
End If
'Replace subsequent instances of acronym *and* definition with just acronym
Dim Defined_Acronym As String: Defined_Acronym = Chosen_Definition & " (" & Current_Acronym & ")"
'Moves cursor to follow first instance of Defined_Acronym
Selection.HomeKey unit:=wdStory
With Selection.Find
'.Font.Color = wdColorAutomatic
.Text = Defined_Acronym
.MatchCase = False
.Execute
End With
'Performs actual replacement of all but first instance of Defined_Acronym with acronym.
Selection.HomeKey unit:=wdStory
With Selection.Find
'.Font.Color = wdColorAutomatic
.Text = Defined_Acronym
.MatchCase = False
.Execute
End With
Selection.EndOf unit:=wdWord, Extend:=wdMove
With Selection.Find
'.Font.Color = wdColorAutomatic
.Text = Defined_Acronym
.MatchCase = False
With .Replacement
.Highlight = False
.Text = Current_Acronym
End With
.Execute Wrap:=wdFindStop, Replace:=wdReplaceAll
End With
'Replace subsequent instances of definition (by itself) with acronym
'Moves cursor to follow first instance of Defined_Acronym
Selection.HomeKey unit:=wdStory
With Selection.Find
'.Font.Color = wdColorAutomatic
.Text = Defined_Acronym
.MatchCase = False
.Execute
End With
Selection.EndOf unit:=wdWord, Extend:=wdMove
With Selection.Find
'.Font.Color = wdColorAutomatic
.Text = Chosen_Definition
.MatchCase = False
With .Replacement
.ClearFormatting
.Text = Current_Acronym
End With
.Execute Replace:=wdReplaceAll, Wrap:=wdFindStop
End With
'Set highlight color to teal for non-NNTD acronyms, highlight all instances of Current_Acronym
Options.DefaultHighlightColorIndex = wdTeal
Selection.HomeKey unit:=wdStory
With Selection.Find
.ClearFormatting
'.Font.Color = wdColorAutomatic
.Text = Current_Acronym
.MatchCase = True
.MatchWholeWord = True
With .Replacement
.Highlight = True
.Text = ""
End With
.Execute Replace:=wdReplaceAll, Wrap:=wdFindStop
End With
End If
End If
'Ends acronym definition loop
Current_Row = Current_Row + 1
Loop
'Returns track changes to same status it was in when script began
If Track_Changes = False Then
ActiveDocument.TrackRevisions = False
End If
'Returns view to show all track changes
With ActiveWindow.View.RevisionsFilter
.Markup = wdRevisionsMarkupAll
.View = wdRevisionsViewFinal
End With
Load Instructions
Instructions.Show
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
'Closes Excel
xlWbk.Close SaveChanges:=False
xlApp.Quit
End Sub
Function Define_Acronym()
End Function
答案 0 :(得分:1)
根据您调用宏的方式,一开始可能不存在选择。请记住Selection.Find
本质上意味着&#34;在当前选择&#34;指定的范围内找到[无论如何]。看到您使用Selection.Homekey Unit:=WdStory
将所选内容折叠为空,我试图弄清楚为什么代码可以正常工作并失败。出于某种原因,单独使用Word似乎同意在选择为0(或1)时搜索整个文档。但零和Nothing一样。
更好的方法是指定要搜索的范围或选择。无论哪种方式,如果您希望搜索文档的整个正文,它应该是ActiveDocument.Content
。虽然您的代码基于使用Selection对象,但您必须进行此类选择,例如ActiveDocument.Content.Select
。
@Slai我建议不要使用Selection对象。请改用Range对象。阅读差异at MSDN