Duplicate paragraph deleting

S

Steve Wylie

I got this small subroutine off a VBA website. It's supposed to delete
duplicate paragraphs in a document. It looks like it should work, but it
doesn't. It doesn't manage to delete any paragraphs, unless I'm doing
something wrong. Why does it not work? Something simple?

Public Sub Main()
Application.ScreenUpdating = False
For Each Paragraph In ActiveDocument.Paragraphs
ParaCount = ParaCount + 1
If Paragraph = MyOldPara Then
Paragraph.Range.Select
Selection.Delete
DeleteCount = DeleteCount + 1
Else
MyOldPara = Paragraph
End If
Application.StatusBar = " . . . . . . . . . . . . . . . . . . " & _
Int(100 * (ParaCount / ActiveDocument.Paragraphs.Count)) & _
"% of document scanned and" & Str(DeleteCount) & " paragraphs deleted."
Next
Application.ScreenUpdating = True
End Sub



Steve Wylie
 
J

Jezebel

The two main problems are these:
If Paragraph = MyOldPara then

This won't work. Paragraphs are objects, so you can directly test equality.
It's actually the TEXT of the paragraphs you want to compare, so you need
something like
If Paragraph.Range = MyOldPara.Range then

Second, since you're dealing with objects, you can assign them directly,
either. So this line doesn't work
MyOldPara = Paragraph

You need to use the Set keyword:

Set MyOldPara = Paragraph


Third, using the word 'Paragraph' is troubling, since that's a defined type
in Word VBA. Add an 'Option Explicit' statement to your code module, then
declare your variables. This would have picked up some of your problems for
you, since VBA can recognize -- and alert you to -- some kinds of data type
mistakes.


But simpler still, you can delete duplicate paragraphs using Find and
Replace. With 'Use wildcards' checked, search for: (*^13)\1 and replace
with: \1
 
J

Jezebel

They should be ashamed of themselves. I just looked at some of the other
code snippets on that site. Dreadful! Amateurish, incompetent, and as you
have just demonstrated the hard way, obviously untested.
 
S

Steve Wylie

Hmm... and there was me thinking I'd found myself a little treasure
trove of VBA routines to use.

Can you suggest any decent websites containing VBA snippets that are
well written and work?

Steve
 
J

Jezebel

word.mvps.org

Also, bear in mind that -- apart from form handling -- VB and VBA are pretty
much the same, so the VB sites are worth looking at too.
 
S

Steve Wylie

I've tried your amended macro and that doesn't work either. I get an
"Object required" error on

If Paragraph.Range = MyOldPara.Range then

BTW, the advantage, apparently of this macro over using Find & Replace
is that the paragraphs don't need to be sorted for it to work. When
it works.

Steve
 
M

Malcolm Smith

Steve

The code which you were given is enough to give someone a heap of
problems. As Jezebel states Paragraph is a built-in class so using this
is all wrong.

So, let's look at their code:

Application.ScreenUpdating = False
For Each Paragraph In ActiveDocument.Paragraphs
ParaCount = ParaCount + 1
If Paragraph = MyOldPara Then

and then changed it to something like:

Dim oParagraph as Paragraph
Dim ParaCount as Long

Application.ScreenUpdating = False
For Each oParagraph In ActiveDocument.Paragraphs
ParaCount = ParaCount + 1
If oParagraph = MyOldPara Then

That may help this problem.

Here I have called the OBJECT oParagraph and it is of type CLASS
Paragraph. The major difference between objects and classes is that a
class is the blueprint of the thing whilst the object is the actual thing
which is built.

As a example, a draughtsman may design plans for a small boat. This is
the class. Then the builder will take the blueprint and knock up one or
more boats. These are the objects.

In Word VBA Paragraph is a class; so the statement I updated:

For Each oParagraph in ActiveDocument.Paragraphs

creates an object called oParagraph, which is based on the Paragraph
blueprint (class) and it goes through the collection of the Paragraphs
within the document pointing to each one in turn.

I haven't been to that site before and I can't see my rushing there now.

- Malc
 
J

Jezebel

There's still a problem. The comparison doesn't work on the first iteration,
because OldPar hasn't been set at that point. You could do it this way --


Dim pIndex as long

With ActiveDocument
pIndex = 2
Do while pIndex <= .Paragraphs.Count
if .Paragraphs(pIndex).Range = .Paragraphs(pIndex - 1).Range then
.Paragraphs(pIndex).Range.Delete
else
pIndex = pIndex + 1
next
Loop
End with
 
S

Steve Wylie

That smaller routine doesn't work either. It doesn't like the Next
statement. Is it supposed to work standalone or as part of a larger
subroutine?

And would it still work if the duplicate paras were not next to each other?

Steve Wylie
 
H

Helmut Weber

Hi Steve,
how about this one:
Sub Makro6()
Dim prg1 As Paragraph
Dim prg2 As Paragraph
For Each prg1 In ActiveDocument.Range.Paragraphs
For Each prg2 In ActiveDocument.Range.Paragraphs
If prg1.Range.text = prg2.Range.text Then
If prg1.Range.start <> prg2.Range.start Then
prg2.Range.Delete
End If
End If
Next
Next
End Sub
I think it works, but it cost me some time to find out,
where paragraphs differed, which seemed to hold the same text.
And shapes, inlineshapes and other objects may cause trouble.
---
Greetings from Bavaria, Germany
Helmut Weber, MVP
"red.sys" & chr(64) & "t-online.de"
Word XP, Win 98
http://word.mvps.org/
 
S

Steve Wylie

Yes, that seems to work okay. Thanks very much.

And thank you to Jezebel and Malcolm too for their input into this thread.

Steve
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top