1. Trang chủ
  2. » Công Nghệ Thông Tin

LẬP TRÌNH VBA FOR WORD

221 751 1

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

LẬP TRÌNH VBA FOR WORD (Tiếng Anh) Nguồn tư liệu : http://word.mvps.org/FAQs/MacrosVBA/index.htm Người sưu tầm : Phan Tự Hướng Nơi phát hành: : www.giaiphapexcel.com Lập trình VBA for Word CHAPTER 1: Beginners' tips 10 How to modify a recorded macro 10 1.1 What's wrong with the recorder, anyway? 10 1.2 Cleaning out unneeded dialog arguments 10 1.3 Making a macro more general 11 Making toggle macros 13 2.1 Fixing broken Replace macros 13 2.2 Naming and storing macros 14 2.3 More fun to come 15 Creating a macro with no programming experience using the recorder 15 Getting to grips with VBA basics in 15 minutes 17 Making the transition from WordBasic to VBA 22 Organizing your macros 23 6.1 Getting yourself organized 23 6.2 Editing Macros 24 6.3 Organizing your Global Templates 24 When to use parentheses to enclose subroutine and function arguments 26 The art of defensive programming 27 Recommended further reading 30 How to cut out repetition and write much less code, by using subroutines and functions that take arguments 31 10 How to use a single VBA procedure to read or write both custom and built-in Document Properties 34 10.1 Writing Document Properties 34 10.2 Reading Document Properties 36 11 How to get the username of the current user 37 12 How can I get a list of the available printer names? 38 13 How to find out, using VBA, how many replacements Word made during a Find & Replace All 40 14 Finding and replacing symbols 43 14.1 Basic Latin symbols listed under “(normal text)” 44 14.2 Upper Unicode characters and symbols which use decorative fonts 44 14.3 How to write your own macro to the job 45 15 Distributing macros to other users 48 CHAPTER 2: Returning information 50 How to check whether Word is open 50 Control Word from Excel 50 Determine whether the insertion point is located at the end of a document 52 Nơi phát hành: www.giaiphapexcel.com Lập trình VBA for Word 3.1 Start Property 52 3.2 End Property 52 3.3 Are We There Yet? 53 Detect whether a table cell is empty 54 4.1 Method 54 4.2 Method 54 4.3 Method 55 Determine the page number at the current cursor position 55 Determine the number of pages in a document 55 How to get the column number of the selection (in a document containing snaking, or newspaper-style, columns) 56 Getting help with calling Word's built-in dialogs using VBA (and why doing so can be much more useful than you'd think) 56 8.1 Where to find Help on them 56 8.2 Why use built-in dialogs? 56 Determine the position of the cursor on the page in points 58 9.1 Important caveat 58 10 Determine whether the selection or range is at the start of a paragraph 59 11 Detect whether the first character in a selection is alphanumeric 59 12 How to find out whether the current document is running in another application (such as Internet Explorer, Outlook, etc.) 59 CHAPTER 3: Working with Bookmarks in VBA 61 Working with Bookmarks in VBA 61 1.1 Types of Bookmarks 61 (1) Placeholder Bookmarks 61 (2) Enclosing Bookmarks 61 1.2 Inserting and retrieving text from a Bookmark 61 Inserting text at a bookmark without deleting the bookmark 62 2.1 The problem 62 2.2 The solution 63 How to create a menu to navigate to the non-hidden bookmarks in a document 63 CHAPTER 4: Working with built-in dialogs 66 Calling FileOpen dialog in VBA does not allow opening of multiple files 66 How to change the directory of the Save As dialog 67 How to set the default suggested filename to be displayed by the Save As dialog the first time a user saves a new document 68 Passwords not saved when calling FileSaveAs dialog from VBA 69 Force the user to save documents into a particular folder or a subfolder of that folder 70 Nơi phát hành: www.giaiphapexcel.com Lập trình VBA for Word How to get the full path from the SaveAs dialog 71 Force the File New dialog to display in List view 71 CHAPTER 5: Working with events 72 Running a macro automatically when Word starts or quits 72 1.1 Global templates 72 Running a macro automatically when a document is created, opened or closed 72 2.1 Using Document events 72 2.2 Using Auto macros 73 2.3 Using Application Events 73 Writing application event procedures 73 3.1 How to set up code that will respond to application events 73 3.2 Summary of set-up procedure 76 3.3 oApp_Quit 77 3.4 oApp_DocumentChange 77 3.5 oApp_DocumentBeforeClose, oApp_DocumentOpen, oApp_NewDocument, oApp_ WindowActivate, oApp_WindowDeactivate 78 3.6 oApp_DocumentBeforePrint, oApp_DocumentBeforeSave 78 3.7 oApp_WindowBeforeDoubleClick, oApp_WindowBeforeRightClick, oApp_WindowSelectionChange 78 How to create global event procedures similar to AutoOpen, AutoNew and AutoClose, without using Normal.dot 78 78 Using Word 97 78 81 Using Word 2000 and later versions 81 Intercepting events like Save and Print 82 5.1 Intercepting commands 82 5.2 Intercepting events (Word 2000 or later) 83 A Pseudo DocumentBeforeClose Event 84 How can I prevent Word from running macros automatically when I create a new instance of Word, open a Word document or create a new one? 85 Assigning a macro to the tab key 86 Change the behavior of the TAB key inside a table cell 86 10 Prevent a file from showing up on the recently used files list 89 11 How can I prevent users from editing the header of a document in Word 2000 or higher?90 CHAPTER 6: Working with properties 91 Using VBA, how can I get access to the Document Properties of a Word file without opening the document? 91 Nơi phát hành: www.giaiphapexcel.com Lập trình VBA for Word How to use a single VBA procedure to read or write both custom and built-in Document Properties 91 2.1 Writing Document Properties 92 2.2 Reading Document Properties 93 Using VBA, how can I get access to the Document Properties of a Word file without opening the document? 95 How to use a single VBA procedure to read or write both custom and built-in Document Properties 95 4.1 Writing Document Properties 95 4.2 Reading Document Properties 97 Highlight any misspelled words, so that unrecognized words stand out prominently on a printout 98 Clear all highlighting from a document 99 Turning “Allow spacing between cells” off with VBA in a Word 2000 table 99 7.1 Workaround 99 7.2 Workaround 100 CHAPTER 7: Working with ranges and selections (not including Tables) 101 How to select – or set a Range object – to the page that the cursor is on 101 Determine the index number of the current paragraph, table, section 101 102 In order to operate on the currently selected paragraph, table, section, etc 102 102 Get the index number, by setting a range to the start of the document 102 How to move a range variable to the end of an inserted file after using [range].InsertFile 103 3.1 Workaround 103 3.2 Workaround 103 Delete any paragraph that is an exact duplicate of the preceding paragraph, using a Range object 103 Delete any paragraph that is an exact duplicate of the preceding paragraph, using a Selection object 104 How to find out whether a range is off-screen 105 How to get the column number of the selection (in a document containing snaking, or newspaper-style, columns) 105 CHAPTER 8: Working with Tables 106 Maximising the performance of Word tables 106 As a user 106 In code 108 How can I resize a table to fit the page's width? 114 Nơi phát hành: www.giaiphapexcel.com Lập trình VBA for Word 2.1 Word 2000 114 2.2 Word 97 114 Deleting duplicate rows in a table 116 3.1 Method 116 3.2 Method 118 Detect whether a table cell is empty 118 4.1 Method 118 4.2 Method 119 4.3 Method 119 Delete all rows of a table that contain a particular text string in the first column 120 Determine the index number of the current paragraph, table, section 120 120 In order to operate on the currently selected paragraph, table, section, etc 120 121 Get the index number, by setting a range to the start of the document 121 Apply changes to all cells in a table 122 Apply changes to an individual cell in a table 122 Select all but the first two cells in a table column 122 10 Display in a message box the contents of each cell in a table column 123 11 Select a range of cells within a table 123 12 Select all rows of a table except the first row 123 13 How to centre a left-justified table (or left or right-justify a centred one) 124 14 How to get the Rowspan and Colspan of a table cell using VBA 124 14.1 Rowspan 124 14.2 Colspan 125 15 Change the behavior of the TAB key inside a table cell 125 16 Turning “Allow spacing between cells” off with VBA in a Word 2000 table 128 16.1 Workaround 128 16.2 Workaround 128 CHAPTER 9: Working with strings, dates and Find & Replace 129 How I return the date of the previous month using VBA? 129 Using a macro to replace text where ever it appears in a document 130 2.1 Step 130 2.2 Step 131 2.3 Step 132 How to Find & ReplaceAll on a batch of documents in the same folder 133 Clear settings from Find and Replace dialog to prevent unexpected results from future Find or Replace operations 136 Nơi phát hành: www.giaiphapexcel.com Lập trình VBA for Word Flush bad karma from Word's find facility after an unsuccessful wildcard search 137 How to prevent the built-in BrowseNext and RepeatFind commands from creating bad karma for wildcard searches 138 6.1 Workaround 1: Intercepting the RepeatFind, BrowseNext and BrowsePrev commands 138 6.2 Workaround 2: Executing the Find & Replace dialog to clear the bug 139 6.3.1 Notes regarding Workaround 141 How to find out, using VBA, how many replacements Word made during a Find & Replace All 142 Finding out how many times some text appears in a document 145 How to use Edit Find to select everything from where the cursor is to the first found item145 9.1 Doing it programmatically 146 10 How to replace text in quotation marks with italic or highlighted text minus the quotes 147 10.1 To it manually 147 10.2 To it with a macro 148 11 Replace each instance of the text string “Document One” with the contents of a file called c:\test\Doc1.doc 150 12 Replace one character with another wherever it appears in a string 151 13 Remove the underline attribute from characters with descenders 152 14 Remove all empty paragraphs from a document 152 CHAPTER 10: Working with files and directories 156 How to allow the user to browse to and select a folder 156 How to Find & ReplaceAll on a batch of documents in the same folder 157 Skipping Password-Protected Documents in a Batch Process 160 How to check if a file has already been opened by another user 162 How to copy an open file using VBA 162 How to create a copy of an open document 163 How to save a document using a filename that gets incremented by each time if the filename already exists 164 Insert into a document the names of all files in a selected folder 164 How to retrieve Word's default Documents path or Pictures path setting 165 10 How to delete files using VBA, including files which may be readonly 166 11 How to read the filenames of all the files in a directory into an array 167 12 How to get the names of all the folders in the folder tree, starting from a specified folder 168 Notes 172 13 How to ensure (using VBA) that all your Word add-ins are installed in the correct path 172 Nơi phát hành: www.giaiphapexcel.com Lập trình VBA for Word CHAPTER 11: Miscellaneous 175 How can I get the mousewheel working in the VBA editing window? 175 How to a mail merge to the printer using VBA, without displaying the Print dialog 176 How to a screen capture using VBA 177 3.1 Using SendKeys 177 3.2 Using API calls 177 How to get the username of the current user 178 Useful WordBasic commands that have no VBA equivalent 180 5.1 SortArray 180 5.2 FileNameInfo$() 181 5.3 DisableAutoMacros 182 5.4 ToolsBulletsNumbers 182 5.5 FileCopy/FileCopyA 183 5.6 FileProperties 184 5.7 SendKeys 184 How to send an email from Word using VBA 184 6.1 Using the Routing Slip method 184 6.2 Automating Outlook 185 How to get the most recently used document to be opened automatically when you open Word 187 187 Using a command line switch to open the most recently used document 187 188 Using a macro to open the most recently used document whenever Word opens 188 189 Using a macro to open the most recently used document whenever Word is opened from its icon, but not when you open Word by launching a file 189 190 The Application.GoBack bug and how to get round it 190 Creating upside down or rotated text in Word 190 8.1 Using two table cells 190 8.2 Word 2002 only: Rotating a picture of your text 191 8.3 Pasting from PowerPoint into Word as a picture 191 8.4 Pasting from other vector graphics applications 192 8.5 Using Word Art 192 8.6 And just for the sake of completeness 193 How can I tile documents vertically in Word 2000? 194 10 “Invalid Page Fault” message when running a macro 196 10.1 Obtaining the Word Code Cleaner 197 11 Creating sequentially numbered documents (such as invoices) 198 12 Sequentially numbering multiple copies of single document using a macro 199 Nơi phát hành: www.giaiphapexcel.com Lập trình VBA for Word 13 How to remove manually typed numbering from a document 200 14 I want the numbers in my footnotes not to be superscripted, and I want the numbers to be followed by a dot and a tab 201 15 How to speed up Word Automation by hiding the application 203 Chapter 12: Working with other objects and collections 206 How to convert the hyperlinks in a document to plain text 206 Preserving hyperlinks within your Table of Contents 207 Size the text in a textbox to fill the textbox 208 When I position a floating object (such as a text box or graphic) “Relative to Page” in Word 2000, it doesn’t end up where it should – why doesn’t it? 209 Move shape anchors away from heading paragraphs 210 The simplest way, using VBA, to reset part of a style definition (e.g the font name), so it inherits the definition of the style it is based on 211 Cycle a paragraph through all available paragraph styles, eventually returning to the style the paragraph started with 213 How to safely update a document's styles from its template without using the Organizer (and how to make the Tools + Templates and Add-ins dialog safe) 215 7.1 Overview of updating styles and template strategy 215 7.2 When should styles be updated? 215 7.3 “Gotchas” to be aware of, and their workarounds 216 If you want to be able to update the styles of Word 97 documents that are attached to Normal.dot 219 Scroll all open documents the same percentage as the active document 220 Nơi phát hành: www.giaiphapexcel.com Lập trình VBA for Word CHAPTER 1: Beginners' tips How to modify a recorded macro Article contributed by Jay Freedman Lots of articles advise you to use the macro recorder to get started with Word macros An example is our own Creating a macro with no programming experience using the recorder Although it's good advice, the macros you record often need tweaking—and sometimes they don't work at all 1.1 What's wrong with the recorder, anyway? The macro recorder's job is to translate your actions into programming code, using a language called Visual Basic for Applications (VBA) That's easy to when you simply type some words into a document, or when you give a simple command such as Edit > Copy It's harder for the recorder to make good code for more complicated commands such as File > Open or Edit > Replace Sometimes the recorded code doesn't exactly what you want it to do, and in a few situations the code is incorrect 1.2 Cleaning out unneeded dialog arguments You can record a macro while you make a change in the document by using a dialog, such as Format > Font or Format > Paragraph You might think the macro recorder should capture only the settings that you changed, but it doesn't—instead, it throws into the macro every setting in the whole dialog! Look at what you might get if you just change the font size to 10 pt: Sub Macro1() With Selection.Font Name = "Times New Roman" Size = 10 Bold = False Italic = False Underline = wdUnderlineNone UnderlineColor = wdColorAutomatic StrikeThrough = False DoubleStrikeThrough = False Outline = False Emboss = False Shadow = False Hidden = False SmallCaps = False AllCaps = False Color = wdColorAutomatic Engrave = False Superscript = False Subscript = False Spacing = Scaling = 100 Position = Kerning = Animation = wdAnimationNone End With End Sub Nơi phát hành: www.giaiphapexcel.com 10 Lập trình VBA for Word End Sub On the other hand, if you want to remove the hyperlink fields but still have the text of the URLs formatted with the Hyperlink character style, you could use the following variation on the same theme: Sub GetRidOfHlinksButPreserveCharacterStyle() Dim oHlink As Hyperlink, i As Long, MyRange As Range For i = ActiveDocument.Hyperlinks.Count To Step -1 With ActiveDocument.Hyperlinks(i) Set MyRange = Range Delete MyRange.Style = wdStyleHyperlink End With Next i End Sub Preserving hyperlinks within your Table of Contents In Word 2000 and above, if your table of contents contains the /h switch (in other words, if the text in the Table of Contents – not only the page numbers – hyperlinks to your headings), the above code will remove those text hyperlinks as well (although they will be automatically regenerated when you next update the table of contents) That is, it won't unlink the Table of Contents, and the page numbers will still hyperlink to the headings, but the text in the TOC won't hyperlink to the Headings after running the above code To prevent that from happening, you could use the following code instead: Sub GetRidOfHlinksExceptInToc() Dim oHlink As Hyperlink, i As Long, MyRange As Range, _ oToc As TableOfContents, LinkIsInToc As Boolean For i = ActiveDocument.Hyperlinks.Count To Step -1 With ActiveDocument.Hyperlinks(i) Set MyRange = Range LinkIsInToc = False For Each oToc In ActiveDocument.TablesOfContents If MyRange.InRange(oToc.Range) Then LinkIsInToc = True Exit For End If Next oToc If Not LinkIsInToc Then Delete Nơi phát hành: www.giaiphapexcel.com 207 Lập trình VBA for Word MyRange.Font.Reset 'or use MyRange.Style = wdStyleHyperlink if you prefer End If End With Next i End Sub As an aside, if you have no other fields in the document, you can convert all the hyperlinks to plain text manually by Selecting All and pressing Ctrl+Shift+F9 (unlink fields) That's a big “if”, though, and it's a risk I'd rather not take The above macros run very fast Size the text in a textbox to fill the textbox Article contributed by Bill Coan Sub ResizeTextToFitTextBox() If Selection.StoryType wdTextFrameStory Then Exit Sub Dim myTextRange As Range Dim myShape As Shape Set myShape = Selection.ShapeRange(1) Set myTextRange = myShape.TextFrame.TextRange myTextRange.Font.Size = If myShape.TextFrame.Overflowing = True Then ActiveDocument.Undo MsgBox "Even when set to a size of points, the text overflows the textbox." Exit Sub End If Do Until myShape.TextFrame.Overflowing = True myTextRange.Font.Size = _ myTextRange.Font.Size + 0.5 Loop myTextRange.Font.Size = _ myTextRange.Font.Size - 0.5 End Sub Nơi phát hành: www.giaiphapexcel.com 208 Lập trình VBA for Word When I position a floating object (such as a text box or graphic) “Relative to Page” in Word 2000, it doesn’t end up where it should – why doesn’t it? Article contributed by Dave Rado Word 2000 can be a nightmare when it comes to positioning shapes – Word 97 was much more predictable The problem in Word 2000 is that: • • • Anchors can be within a table If the anchor is within a table you can't position the shape relative to the page (if you select that option, it gets positioned relative to the table instead!) Anchors in Word 2000 have a way of jumping into tables when you're looking the other way, and then laughing at you while you try to figure out what happened! So if you're positioning shapes manually, lock the anchor to a paragraph that is not in a table before you start If you're doing it in code, anchor the shape to a paragraph that is not in a table, and lock the anchor If you want a shape (such as a line, text box or graphic) to appear on every page, you should put it in the Header and set it to be “behind text” The final paragraph in the Header cannot be in a table, so it makes sense to anchor it to that paragraph Here's an example of how to it with code (you could use the same principle for watermarks) This code inserts two lines in the primary Header of the first section of the document: Sub AddLinesToHeader() Dim oHeader As HeaderFooter, MyRange As Range, oLine As Shape System.Cursor = wdCursorWait Set oHeader = ActiveDocument.Sections(1).Headers(wdHeaderFooterPrimary) 'Make sure the shape anchored to the final paragraph in the Header Set MyRange = oHeader.Range.Paragraphs.Last.Range Set oLine = oHeader.Shapes.AddLine(0, 0, 0, 0, Anchor:=MyRange) With oLine RelativeHorizontalPosition = wdRelativeHorizontalPositionPage RelativeVerticalPosition = wdRelativeVerticalPositionPage Width = CentimetersToPoints(1) Left = CentimetersToPoints(0.5) Top = CentimetersToPoints(21.76) LockAnchor = True WrapFormat.Type = wdWrapNone 'It's a good idea to name shapes you add, so that if you want to hide them, 'or whatever later, you can refer to them by name Nơi phát hành: www.giaiphapexcel.com 209 Lập trình VBA for Word Name = "First Line" 'Add any other parameters you need, eg Line.Weight = etc End With Set oLine = oHeader.Shapes.AddLine(0, 0, 0, 0, Anchor:=MyRange) With oLine RelativeHorizontalPosition = wdRelativeHorizontalPositionPage RelativeVerticalPosition = wdRelativeVerticalPositionPage Width = CentimetersToPoints(1) Left = CentimetersToPoints(0.5) Top = CentimetersToPoints(22.08) LockAnchor = True WrapFormat.Type = wdWrapNone Name = "Second Line" 'add other parameters you need, eg Line.Weight = etc End With System.Cursor = wdCursorNormal End Sub Move shape anchors away from heading paragraphs Article contributed by Bill Coan Problem When shape anchors are located in heading paragraphs, the table of contents is unable to display heading numbers This routine works even on shapes whose anchors are locked It preserves the location of a shape even if the shape is positioned relative to paragraph! Solution Cut offending shapes out of the document and paste them back into the document with their anchors at a new location, immediately below the heading paragraph Do this without affecting the location of the shape on the page Sub MoveAnchorsOutOfHeadings() Dim oShape As Shape For Each oShape In ActiveDocument.Shapes If Left$(oShape.Anchor.Style, 7) = "Heading" Then oShape.Select Selection.Cut Selection.MoveDown unit:=wdParagraph, Count:=1 Selection.Paste End If Next oShape End Sub Nơi phát hành: www.giaiphapexcel.com 210 Lập trình VBA for Word The simplest way, using VBA, to reset part of a style definition (e.g the font name), so it inherits the definition of the style it is based on Article contributed by Henk van Boeijen In Word, styles can be (and usually are) based on other styles If you create a new style, Word bases it on the style of the paragraph that is currently selected, unless you explicitly change this in the “Modify Style” dialog The style it is based on is called its “base style” (or sometimes, the “parent style”) If it's a paragraph style, the new style will inherit (in an object-oriented fashion) all of its font and paragraph properties from its base style, and will be defined by Word only as “the definition of the base style plus anything you have defined to be different from the base style” So in the Format + Style dialog, you will see definitions like: “Normal + Indent: Hanging 0.25", Space After point” In this example, only the Indent and the Space After setting are held in the style definition So if you change the Font in the Normal style, the font in the child style will automatically change, too But if you change the “Space After” property of the Normal style, the “Space After” property of the child style will not change, because that property is stored in the child style's definition and so is not inherited Similarly, if you see a definition like: “Normal + Font Arial” in the Format + Style dialog, then nothing but the font name is stored in the style definition So if you change the Font of your Normal style, the font in the child style will not change; but if you change the Space After property of the Normal style, the Space After property of the child style will change Character styles behave similarly except that only font properties are defined or inherited So you will see character style definitions in the Format + Style dialog like “Default Paragraph Font + Font color: Dark Blue” In this example, nothing is stored in the character style definition except the font colour Everything else is inherited from the underlying paragraph style of whichever paragraph you happen to have applied the character style to So a style can be based on another style which in turn is based on another style, and so on In this way you can form an hierarchy tree of styles Each member in that tree inherits the formatting options of its parent and adds its own specific options to it Used sensibly, this mechanism is absolutely essential to your ability to maintain complex documents and templates Another example Style "Normal": - Font.Name = "Times New Roman" - Font.Size = 11 - Font.Bold = False Nơi phát hành: www.giaiphapexcel.com 211 Lập trình VBA for Word Style "Special": - this style is based on "Normal" - Font.Size = Style "MoreSpecial" - this style is based on "Special" - Font.Bold = True All three styles share the same font name The font name is defined in “Normal” and is inherited by “Special” and “MoreSpecial” When the font name in “Normal” is changed to “Arial”, this change also applies to “Special” and “MoreSpecial” The font size is only shared by “Special” and “MoreSpecial”: points is defined in “Special” It overrides the font size setting of “Normal” which is 11 points “MoreSpecial” inherits points from “Special” If the font size of “Normal” is changed to 12 points, this setting will not be inherited by “Special” or “MoreSpecial” In some cases you may want to delete formatting properties in a style's definition, in order that it should inherit those properties from its parent (or base) style To this in VBA, use the following logic: Dim oStyle As Style Set oStyle = ActiveDocument.Styles("Special") oStyle.Font.Name = oStyle.BaseStyle.Font.Name After running this code, the font name will no longer be stored in the style definition of the “Special” style, but will now be inherited from the Normal style If you need to this more than once, you could make your life easier by calling a subroutine like the following, which clears the font name of a given style It accepts a style name (of type String) or a WdBuiltinStyle constant, or a style object, as its argument So you could call it like this: ClearStyle "List Number" or like this: ClearStyle wdStyleListNumber or like this: ClearStyle ActiveDocument.Styles("List number") If the style is not based on another style, the routine exits without generating an error Public Sub ClearStyleFont(oStyle As Variant) Nơi phát hành: www.giaiphapexcel.com 212 Lập trình VBA for Word Dim oBaseFont As Font With ActiveDocument.Styles(oStyle) If BaseStyle = "" Then 'There is no base style, nothing to clear Else Set oBaseFont = BaseStyle.Font With Font Name = oBaseFont.Name 'Add other font properties here if needed End With Set oBaseFont = Nothing End If End With End Sub You could use exactly the same logic to clear paragraph properties from a style definition, so that they are inherited from the base style If you wanted to clear all font and paragraph properties from a style definition, (including any list numbering, language and borders definitions, although unfortunately, not including Frames definitions), in order that you can start defining your own properties for the style knowing that you are starting with a clean slate, you could use the following subroutine Public Sub ClearStyle(oStyle As Variant) With ActiveDocument.Styles(oStyle) If BaseStyle "" Then Font = BaseStyle.Font ParagraphFormat = BaseStyle.ParagraphFormat End If End With End Sub Cycle a paragraph through all available paragraph styles, eventually returning to the style the paragraph started with Article contributed by Bill Coan The following macro includes a line that prevents execution when text is selected (The cursor must be flashing for the macro to run.) I played with this a bit because someone else thought it would be a nice feature I assigned the macro to a button, then to a keystroke I found the keystroke much easier to use But Word has so many built-in styles that it can be tedious to keep cycling through the styles until the original style comes back around Nơi phát hành: www.giaiphapexcel.com 213 Lập trình VBA for Word Sub CycleThroughStyles() Dim NeedToRollOver As Boolean Dim i As Long, j As Long, k As Long NeedToRollOver = True 'quit if cursor isn't flashing 'This limits action to one paragraph If Selection.Type wdSelectionIP Then GoTo EndGracefully 'find the current paragraph style, then 'find the next available paragraph style For i = To ActiveDocument.Styles.Count If Selection.Paragraphs(1).Style = ActiveDocument.Styles(i) Then For j = i + To ActiveDocument.Styles.Count If ActiveDocument.Styles(j).Type = wdStyleTypeParagraph Then Selection.Paragraphs(1).Style = ActiveDocument.Styles(j) NeedToRollOver = False Exit For End If Next j End If If NeedToRollOver = False Then Exit For End If Next i 'if we reached the last paragraph style, then 'roll over to first available paragraph style If NeedToRollOver = False Then GoTo EndGracefully For k = To ActiveDocument.Styles.Count If ActiveDocument.Styles(k).Type = wdStyleTypeParagraph Then Selection.Paragraphs(1).Style = ActiveDocument.Styles(k) Exit For End If Next k 'tell user what current style is 'clear the undo buffer to prevent error message 'about document formatting being too complex EndGracefully: Application.StatusBar = Selection.Paragraphs(1).Style ActiveDocument.UndoClear Nơi phát hành: www.giaiphapexcel.com 214 Lập trình VBA for Word End Sub How to safely update a document's styles from its template without using the Organizer (and how to make the Tools + Templates and Add-ins dialog safe) Article contributed by Dave Rado, Margaret Aldis, Ian Sharpe and Beth Melton 7.1 Overview of updating styles and template strategy If you want to update the style definitions of a document with the style definitions in its attached template, you can manually select Tools + Templates and Add-ins, check the box which says “Automatically update document styles”, click OK; and then, because that setting is sticky (and most of the time, undesirable), immediately select Tools + Templates and Add-ins again, deselect the “Automatically update document styles” box, and click OK If the attached template is Normal.dot, this doesn't work in Word 97; but it works for all other attached templates in Word 97; and it works for all templates, including Normal.dot, in later versions of Word (It can be made to work in Word 97, even if the attached template is Normal.dot, with a little programming – this is covered below) It is important to realise that the only styles that are updated when you update a document's styles from its template are the ones listed in the template itself under “Styles in use” (in the Style dialog, where it says “List”) So if a user modifies the definition of a built-in style in their document, but that style was not listed under “Styles in use” in the template, then updating their styles from the template will have no affect on that particular style definition Because of this, if you are a template designer, you must ensure that any built-in styles which you want control over are listed under “Style in use” The best way to add a built-in style to the “In use” list is to insert it in the template (first redefining it if required) You could use a dummy paragraph for the purpose, and delete it again once you have finished applying your styles The styles, having been applied once, will remain in the “In use” list for ever more 7.2 When should styles be updated? The “Automatically update document styles” setting is document-specific, and if left switched on when a particular document is saved, will update that document's styles whenever it is opened by anyone (until the document is saved again with the setting switched off) This is usually undesirable, because, whereas one would want a document's styles to be updated whenever a style in its template is redefined while a document is being revised, once the document is “live”, one would definitely not Also if emailing to an external reviewer who does not have access to the template, the setting should emphatically not be switched on Nơi phát hành: www.giaiphapexcel.com 215 Lập trình VBA for Word So in a corporate context, it's best never to save a document with its “Automatically update document styles” setting switched on Instead, assuming you have a version control strategy, store the draft/live status of a document in a document variable (or document property); and by using an AutoOpen macro to read the variable or property, update the styles if it's in Draft mode, but not if it's Live In addition, your users may want to update a document's styles using the dialog, if their style definitions have been mangled Updating a document's styles from its template is a lot faster than using the Organizer (and subject to the qualifications below, seems to be more reliable, as well) 7.3 “Gotchas” to be aware of, and their workarounds As has already been mentioned, updating styles from the template doesn't work in Word 97 if the attached template is Normal.dot More seriously, in all versions of Word, updating styles can sometimes mangle your style definitions, especially in the case of numbering styles, where it can sometimes destroy the link between the styles and their List Templates But the good news is that updating styles can be made reliable, as follows For it to be reliable, your numbering styles must use named List Templates See the links at How to cure Word's List Numbering with a dose of VBA for more details All the styles in the “Styles in Use” list need to have been physically applied to text in the template once (but they not need to have been applied in documents based on the template) What the difference is, in terms of the flags stored inside a template file, between a style that is listed in the “In use” list but has never been applied to text, and one that has been applied, is a mystery; but it seems there is a difference Unfortunately, it is all too easy to add a style to the “Styles in Use” list without ever applying the style to any text In the case of built-in styles, you can this manually by selecting Format + Style, where it says “List”, select “All styles”, and click Modify + OK + Close Or programmatically, you can add it to the “In use” list by running code that defines the style In the case of custom styles, you can add them to the “In use” list without applying them to text by selecting Format + Style + New + OK + Close; or programmatically, by defining a new style without applying it Styles (especially numbering styles) that are listed in the “In use” list of a template, but have never physically been applied to text, will not be stable if you update your styles from the template So if in doubt, it is a good idea to insert a dummy paragraph in each of your templates, cycle it through all the styles in the template's “In use” list, delete the dummy paragraph, and save the template And if you subsequently need to redefine any of the styles in the template, it is again a good idea to apply the redefined style to a dummy paragraph Sometimes, you have to the update twice or occasionally even three times in order preserve your List Template names and their links to your numbering styles: Dim oLT As ListTemplate Nơi phát hành: www.giaiphapexcel.com 216 Lập trình VBA for Word ActiveDocument.UpdateStyles ActiveDocument.UpdateStyles On Error Resume Next For Each oLT In ActiveDocument.AttachedTemplate.ListTemplates If Not oLT.Name = "" Then If Not ActiveDocument.ListTemplates(oLT.Name).ListLevels(1) _ LinkedStyle = oLT.ListLevels(1).LinkedStyle Then ActiveDocument.UpdateStyles Exit For End If End If Next oLT No theories as to why this might be; it's a bug; but at least there is a workaround You can make the Tools + Templates and Add-ins dialog safe for users to use by intercepting the Word command as follows: Sub FileTemplates() With Dialogs(wdDialogToolsTemplates) Show If LinkStyles = Then ActiveDocument.UpdateStyles Dim oLT As ListTemplate On Error Resume Next For Each oLT In ActiveDocument.AttachedTemplate.ListTemplates If Not oLT.Name = "" Then If Not ActiveDocument.ListTemplates(oLT.Name).ListLevels(1) _ LinkedStyle = oLT.ListLevels(1).LinkedStyle Then ActiveDocument.UpdateStyles Exit For End If End If Next oLT ActiveDocument.UpdateStylesOnOpen = False End If End With End Sub [The ActiveDocument.UpdateStylesOnOpen = False line in the above code sample prevents the user from being able to save the document with the “Automatically update document styles” setting switched on; and means they don't have to immediately go back to the dialog every time they update their styles, simply in order to deselect that setting If that's not what you want, though, you can remove that line But if you remove that line, then you will also need to have an AutoOpen macro that checks whether the setting is switched on, and if it is, that updates the styles again if need be; otherwise the numbering styles will sometimes be broken when the Nơi phát hành: www.giaiphapexcel.com 217 Lập trình VBA for Word document is reopened.] But unfortunately, the Dialogs(wdDialogToolsTemplates) object is buggy – the dialog it displays doesn't show the list of add-ins, and half the buttons on it are greyed out This is well worth emailing mswish@microsoft.com about You can get round this as follows: a) Instead of intercepting the FileTemplates command, create the following macro: Sub ReplacementToolsTemplatesAndAddins() 'Execute the built-in button CommandBars.FindControl(ID:=751).Execute If Dialogs(wdDialogToolsTemplates).LinkStyles = Then Dim oDoc As Document, oLT As ListTemplate Set oDoc = ActiveDocument oDoc.UpdateStyles On Error Resume Next For Each oLT In oDoc.AttachedTemplate.ListTemplates If Not oLT.Name = "" Then If Not oDoc.ListTemplates(oLT.Name).ListLevels(1) _ LinkedStyle = oLT.ListLevels(1).LinkedStyle Then oDoc.UpdateStyles Exit For End If End If Next oLT oDoc.UpdateStylesOnOpen = False End If End Sub (Again, remove the ActiveDocument.UpdateStylesOnOpen = False line if you don't want it.) b) Create a new toolbar, name it “Hidden”, and move the built-in “Templates and Add-ins” button to the new toolbar This is in order that the above macro can execute the built-in button (doing so avoids the bugs that you get if you use Dialogs(wdDialogToolsTemplates)), without the built-in button being visible to the user c) Go to Tools + Customize, select the “Commands” tab; in the left pane, select “All macros”, in the right pane select the ReplacementToolsTemplatesAndAddins macro, and drag it onto the Tools menu, to where the “Templates and Add-ins” button used to be Right-click the new button and rename it: Templates and Add-&Ins d) Disable the new toolbar (which makes it invisible to the user), as follows: CommandBars("Hidden").Enabled = False e) If you've made the above customisations in an add-in, create an AutoExec macro as follows: Sub AutoExec() Nơi phát hành: www.giaiphapexcel.com 218 Lập trình VBA for Word CommandBars("Hidden").Enabled = False End Sub Or if you've customized a template rather than an add-in, create an AutoNew and AutoOpen macro in the template, containing the same code If you have already disabled the Web toolbar, of course, one could use that for this purpose, rather than creating a new Toolbar called “Hidden” See also: How to stop the web toolbar from jumping up at you whenever you click on a page number in the table of contents With one qualification, your users should now be able to update their styles from their template(s) safely That one qualification is this: the above macro will safely update styles if their definitions have been changed in the attached template, and will safely revert them to the attached template's definitions if they have been redefined in the document It will also safely update styles that are defined in the attached template but not in the document But if there are broken list numbering styles in the document, it will sometimes, but not always, fix those In other words, it is not a complete substitute for a “Fix numbering” macro (although it should greatly reduce the frequency with which you'll need to run the latter) For details of the latter, see the links at How to cure Word's List Numbering with a dose of VBA If you want to be able to update the styles of Word 97 documents that are attached to Normal.dot If instead of using the UpdateStyles method, you use CopyStylesFromTemplate, then you can update your document's styles even in Word 97, when the attached template is Normal.dot However, using CopyStylesFromTemplate is significantly slower than using UpdateStyles; so the following variation on the above macro only uses the slower method when necessary, and uses UpdateStyles when possible: Sub ReplacementToolsTemplatesAndAddins() Dim Word97Normal As Boolean, oDoc As Document, oLT As ListTemplate 'Execute the built-in button CommandBars.FindControl(ID:=751).Execute If Dialogs(wdDialogToolsTemplates).LinkStyles = Then Set oDoc = ActiveDocument If Left$(Application.Version, 1) = "8" And _ oDoc.AttachedTemplate = NormalTemplate Then Word97Normal = True End If If Word97Normal Then oDoc.CopyStylesFromTemplate NormalTemplate oDoc.CopyStylesFromTemplate NormalTemplate Else Nơi phát hành: www.giaiphapexcel.com 219 Lập trình VBA for Word oDoc.UpdateStyles End If On Error Resume Next For Each oLT In oDoc.AttachedTemplate.ListTemplates If Not oLT.Name = "" Then If Not oDoc.ListTemplates(oLT.Name).ListLevels(1) _ LinkedStyle = oLT.ListLevels(1).LinkedStyle Then If Word97Normal Then oDoc.CopyStylesFromTemplate NormalTemplate Else oDoc.UpdateStyles End If Exit For End If End If Next oLT oDoc.UpdateStylesOnOpen = False End If End Sub Scroll all open documents the same percentage as the active document Article contributed by Bill Coan Scroll the active document to the desired point, then run a macro that scrolls all other open documents to the same percentage The following code is written for Word 97 It looks at how far you've scrolled the active window, then scrolls all other document windows the same percentage Of course, if one document is 10 pages long and another is 100 pages long, then a 50% vertical scroll would put you on page in one document and page 50 in the other Sub ScrollAllWindowsALike() Dim myWindow As Window Set myWindow = ActiveWindow ScrollPercent = myWindow.VerticalPercentScrolled For Each oWindow In Application.Windows oWindow.Activate oWindow.VerticalPercentScrolled = ScrollPercent Next oWindow myWindow.Activate End Sub Nơi phát hành: www.giaiphapexcel.com 220 Lập trình VBA for Word Nơi phát hành: www.giaiphapexcel.com 221 ... PasswordDocument:= "" , PasswordTemplate:= "" , _ Revert:= False , WritePasswordDocument:= "" , _ WritePasswordTemplate:= "" , _ Format:=wdOpenFormatAuto, XMLTransform:= "" ' more code, for example... Selection.Find.ClearFormatting Selection.Find.Replacement.ClearFormatting Nơi phát hành: www.giaiphapexcel.com 13 Lập trình VBA for Word With Selection.Find Text = "" Replacement.Text = "" Forward = True... the page's width? 114 Nơi phát hành: www.giaiphapexcel.com Lập trình VBA for Word 2.1 Word 2000 114 2.2 Word 97 114 Deleting duplicate rows in a table

Ngày đăng: 12/03/2017, 09:28

Xem thêm: LẬP TRÌNH VBA FOR WORD

TỪ KHÓA LIÊN QUAN

w