PDA

View Full Version : Macro works in word 2003 and 2007 but fails in 2010



Redbarn
03-03-2012, 09:28 AM
Perhaps the title should be "Don't we all love microsoft"

Frustrations apart, the macro below works ok in 2003 and 2007 but throws a wobbly in 2010 saying library or project not found.

The macro is intended to take a document containing multiple choices which are highlighted and when the user has selected their choice the command button copies the document, closes the original, creates a new document, strips out all highlighting and saves to a new folder.

Any pointers as to where I am going wrong?

Private Sub CommandButton1_Click()
ActiveDocument.Range.Copy
Documents.Add
Set Doc1 = Documents(1)
Doc1.Range.Paste
For Each aShape In Doc1.InlineShapes
aShape.Delete
Next aShape
Doc1.Activate
Dim Wrd As Range
For Each Wrd In ActiveDocument.Words
If Wrd.Font.Color <> wdColorBlack And Wrd.Font.Color <> wdColorAutomatic Then
Wrd.Font.Color = wdColorAutomatic
End If
Next Wrd
Dim i As Long
For i = 1 To 100
Call highlight
Next i

Dim fso
Dim fol As String
fol = "C:\Program Files\French\MyLetters"
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FolderExists(fol) Then
fso.CreateFolder (fol)
End If
With ActiveDocument.Range.Font
.Name = "Times New Roman"
.Size = 12
End With
ActiveDocument.SaveAs "C:\Program Files\French\MyLetters\ChangeMYname.doc"
Me.Close (Word.WdSaveOptions.wdDoNotSaveChanges)
End Sub

:doh: :think:

Frosty
03-03-2012, 11:05 AM
Put Option Explicit at the top of your code modules. Use the VBA tag to make your code more readable for the forum.

See if Option Explicit helps you know what's falling.

My guess is you need to type variables correctly, and that some new functionality in 2010 means that the assumptions you've made in prior versions by not having option explicit are falling over now.

You should always use Option Explicit.

Let us know what confuses you after you get that in at the top of all your code modules, and you compile your project (go 1 module/form at a time, and compile, or it will become overwhelming).

Frosty
03-05-2012, 10:17 AM
Thanks for the VBA tag, that does make it a lot easier to read.

Two spots that jump out at me (apart from no typed variables)

1. Why are you running the "Highlight" subroutine an arbitrary number of times?

2. Me.Close ... is that a public subroutine on the calling form?

Need a bit more info to be able to give you a good guess as to why the macro is failing in one version-- but you could step through the code and see why it fails (do you know about Break Points and using F8 to step through code?).

And as an FYI-- this macro is doing a good bit more than simply getting rid of any highlighting. It's also attempting to delete all inline shapes. And there are some pretty big assumptions in the code (I'm guessing you don't run it when you have multiple documents open?), which could cause issues.

In short, there is a lot I'd address, but just this snippet isn't enough to tell you what would fail in 2010. If I have option explicit off, the only two lines that fail to compile are "Call Highlight" (obviously, because I don't have a subroutine for that) and "Me.Close" which I assume is a subroutine in your calling form.

Redbarn
03-05-2012, 11:18 AM
Option Explicit
Private Sub CommandButton1_Click()
Dim Doc1
Dim aShape
ActiveDocument.Range.Copy
Documents.Add
Set Doc1 = Documents(1)
Doc1.Range.Paste
For Each aShape In Doc1.InlineShapes
aShape.Delete
Next aShape
Doc1.Activate
Dim Wrd As Range
For Each Wrd In ActiveDocument.Words
If Wrd.Font.Color <> wdColorBlack And Wrd.Font.Color <> wdColorAutomatic Then
Wrd.Font.Color = wdColorAutomatic
End If
Next Wrd
Dim i As Long
For i = 1 To 100
Call highlight
Next i

Dim fso
Dim fol As String
Dim CreateFolder
fol = "C:\Program Files\French\MyLetters"
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FolderExists(fol) Then
fso.CreateFolder (fol)
End If
With ActiveDocument.Range.Font
.Name = "Times New Roman"
.Size = 12
End With
ActiveDocument.SaveAs "C:\Program Files\French\MyLetters\ChangeMYname.doc"
Me.Close (Word.WdSaveOptions.wdDoNotSaveChanges)
End Sub

This code works but I am aware that it is badly written and awkward.

I entered option explicit and then delared each item the code snagged on and finally it ran.

The "Highlight" routine x 100 was a bit of code I came across when I couldn't get the code below to loop - it just cleared the first highligted text and ignored the rest. Suggestions on improving it welcomed.

If Wrd.Font.Color <> wdColorBlack And Wrd.Font.Color <> wdColorAutomatic Then
Wrd.Font.Color = wdColorAutomatic
End If

The MeClose line loses the original document as unsaved to enable reuse.

The project is intended to have a series of letters with various options highlighted in matching colours for the letter options in English and then in French. The user will simply delete the options not required on both letters and should result in an itelligibe letter in French by someone who could never write it normally.

I am very much a beginner with vb and welcome constructive critisism.

Frosty
03-05-2012, 11:38 AM
Remember to use the VBA tags... it's a button in the reply field, or you can manually enclose your code with a "[" VBA "]" (and "[" /VBA "]" (without quotes and spaces-- separated out to demonstrate).

The code now works?

You should get used to using DIM as well as "typing" your variables... so...
Dim Doc1 As Document
Dim aShape As InlineShape
Dim fso As Object
Dim CreateFolder As Object

When you do this, you can then compile your project (Debug > Compile Project) before running, and that will be an additional step that MS can say "did you really mean to use an InlineShape?" etc... otherwise, the only time you'll know your code fails is when you're running it.

If all you do is...
Dim Doc1
That's essentially the same as not using Option Explicit... you force MS to guess what kind of "peg" to use, and sometimes MS is going to choose "round peg" in "square hole" situations.

Me.Close is strange to me-- is this code run from a macrobutton in a document? Or is it run from a userform? How do you trigger this code? In general, "Me" refers to the calling "Class" (typically a userform for a beginning programmer, but it can also refer to a custom class object).

What I'm unclear on in the above, is which document is which... and why you can't just, essentally, make the entire document wdColorAutomatic?

Incidentally, while re-writing this, it seems that .Color might have disappeared and been replaced with .ColorIndex in 2010 (although .Color isn't causing a compile issue).

Here is a little bit of a rewrite... but two main questions:
1. Do you need to delete the inline shapes?
2. Can you simply use ActiveDocument.Range.Font.ColorIndex = wdAuto instead of the for loops?

Private Sub CommandButton1_Click()
Dim docNew As Document
Dim docOrig As Document
Dim aShape As InlineShape
Dim fso As Object
Dim fol As String
Dim CreateFolder As Object
Dim Wrd As Range
Dim i As Long

'initial setup
Set docOrig = ActiveDocument
docOrig.Range.Copy
Set docNew = Documents.Add
docNew.Range.Paste

'why are you deleting all these shapes?
For Each aShape In docNew.InlineShapes
aShape.Delete
Next aShape

'now you're going through all the words in the body of the document?
'is there some reason you can't simply use
docNew.Range.Font.ColorIndex = wdAuto

'if it's neither Black nor Automatic, make it automatic?
For Each Wrd In docNew.Words
If Wrd.Font.Color <> wdColorBlack And Wrd.Font.Color <> wdColorAutomatic Then
Wrd.Font.Color = wdColorAutomatic
End If
Next Wrd

'what's going on here?
For i = 1 To 100
Call HighlightSomething
Next i

'now do the saving as stuff, creating a folder as needed?
fol = "C:\Program Files\French\MyLetters"
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FolderExists(fol) Then
fso.CreateFolder (fol)
End If

With docNew.Range.Font
.Name = "Times New Roman"
.Size = 12
End With
docNew.SaveAs "C:\Program Files\French\MyLetters\ChangeMYname.doc"
'which doc to close here? docNew? Original doc?
docNew.Close (Word.WdSaveOptions.wdDoNotSaveChanges)
docOrig.Close (Word.WdSaveOptions.wdDoNotSaveChanges)
End Sub
Sub HighlightSomething()
'do what here?
End Sub

Redbarn
03-05-2012, 12:25 PM
Private Sub CommandButton1_Click()
Dim docNew As Document
Dim docOrig As Document
Dim aShape As InlineShape
Dim fso As Object
Dim fol As String
Dim CreateFolder As Object
Dim Wrd As Range
'Dim i As Long
Dim oRng As Word.Range
Dim wdNoColor

'initial setup
Set docOrig = ActiveDocument
docOrig.Range.Copy
Set docNew = Documents.Add
docNew.Range.Paste

'why are you deleting all these shapes? So that they don't show or print on the final document
For Each aShape In docNew.InlineShapes
aShape.Delete
Next aShape
------------------------
Set oRng = ActiveDocument.Range
With oRng.Find
.highlight = True
While .Execute
oRng.HighlightColorIndex = wdNoColor
Wend
End With
---------------------------------------

'what's going on here? The 7 lines above were originally in a separate macro "highlight"
'For i = 1 To 100 which I couldn't get to repeat so I found a workround.
' Call highlight
'Next i

'now do the saving as stuff, creating a folder as needed?
fol = "C:\Program Files\French\MyLetters"
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FolderExists(fol) Then
fso.CreateFolder (fol)
End If
With docNew.Range.Font
.Name = "Times New Roman"
.Size = 12
End With
docNew.SaveAs "C:\Program Files\French\MyLetters\ChangeMYname.doc"
'which doc to close here? Original doc?
'docNew.Close (Word.WdSaveOptions.wdDoNotSaveChanges)
docOrig.Close (Word.WdSaveOptions.wdDoNotSaveChanges)
End Sub



'Sub Highlight()
'Set oRng = ActiveDocument.Range
'With oRng.Find
' .highlight = True
' While .Execute
' oRng.HighlightColorIndex = wdNoColor
' Wend
'End With

'End Sub

I have removed the text color changes as they are now not required.

The sub "Highlight" is shown for info and I would dearly like to incorporate it as above between the rows of dashes but I cannot get it to repeat.

The above works but will only remove a single instance of highlight. There may be up to 30 in a document.

Frosty
03-05-2012, 12:29 PM
Skip those lines, and simply do...
docNew.Range.HighlightColorIndex = wdNoColor

If all you're doing is "turning off" a highlight anywhere it is found in the document, then you can do the code equivalent of "Select All" and click "No Highlight"

No need for find loops.... unless you are looking for a specific highlight color and only turning that off?

VBA tags please...

Redbarn
03-05-2012, 01:11 PM
Frosty you are a wonderfully generous and talented man. Thank you so much for your help. Having seen just how powerful VB is in office I am set to find a training course to take me on. As I retire at 70 in 3 weeks time I will have time (When I have finished renovating a house wreck in France!)

Thank you again.



Skip those lines, and simply do...
docNew.Range.HighlightColorIndex = wdNoColor

If all you're doing is "turning off" a highlight anywhere it is found in the document, then you can do the code equivalent of "Select All" and click "No Highlight"

No need for find loops.... unless you are looking for a specific highlight color and only turning that off?

VBA tags please...

Frosty
03-05-2012, 01:17 PM
My pleasure! Enjoy the home renovation and your retirement! There is a lot to be said for the engaged mind.

All the best to you.

- Jason aka Frosty