Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Word Macro to edit each page

Status
Not open for further replies.

Groves22

Technical User
Jan 29, 2009
102
0
0
US
Hey all..

I have never written a macro in Word before (mostly because I didn't know you could)

I am trying to edit a recipe book that I have for better and consistent viewing. Each page has 1 recipe on it. The recipes look something like this:

BAKED CUSTARD
2 cups Milk, scalded
3 Eggs, slightly beaten
1/3 cup Sugar
1 teaspoon Vanilla
1/8 teaspoon Salt
Nutmeg or coconut
Scald milk, let cool slightly. Combine eggs, sugar, vanilla, and salt.
Slowly stir in slightly cooled milk. Pour into buttered 1-qt baking dish. Sprinkle with nutmeg or coconut. Cover with foil.
Set baking dish on a trivet or meat rack in Crock Pot.
Pour hot water around baking dish, 1-inch deep. Cover pot and cook on high for 2 to 2 1/2 hours or until knife inserted in custard comes out clean. Serve warm or chilled.
Makes 5 to 6 servings.

OR

BARBECUED MEATBALLS I
* 1 to 2 lbs. ground beef
* 2 tsp. Worcestershire sauce
* 2/3 c. evaporated milk
* 1 envelope dry onion soup mix
Sauce:
* 2 c. ketchup
* 1 c. brown sugar, packed
* 1 tbsp. Worcestershire sauce
Mix beef, 2 teaspoons Worcestershire sauce, evaporated milk and soup mix. Shape into balls the size of walnuts. Broil 4 inches from broiler for 12 minutes or until done. Turn if necessary to keep from burning. Mix sauce ingredients and boil 10 minutes. Pour over meatballs in slow
cooker/Crock Pot turned on low.
2 pounds of ground beef makes about 50 meatballs.

What I want it to look like is:
(space between title and ingredients. space between ingredients and directions. no * for ingredients)

BAKED CUSTARD

2 cups Milk, scalded
3 Eggs, slightly beaten
1/3 cup Sugar
1 teaspoon Vanilla
1/8 teaspoon Salt
Nutmeg or coconut

Scald milk, let cool slightly. Combine eggs, sugar, vanilla, and salt.
Slowly stir in slightly cooled milk. Pour into buttered 1-qt baking dish. Sprinkle with nutmeg or coconut. Cover with foil.
Set baking dish on a trivet or meat rack in Crock Pot.
Pour hot water around baking dish, 1-inch deep. Cover pot and cook on high for 2 to 2 1/2 hours or until knife inserted in custard comes out clean. Serve warm or chilled.
Makes 5 to 6 servings.

How would I go about doing something like that?
Thanks

 



Styles. Forum68.

I do not believe that this is a VBA question.

Skip,
[sup][glasses]Don't let the Diatribe...
talk you to death![tongue][/sup][sub]
[glasses]Just traded in my old subtlety...
for a NUANCE![tongue][/sub]
 
Well... it's a 478 page cookbook in word. And each recipe is formatted in the one of two ways above.

I was just wondering if I could write a VBA to format each page for me, rather than going through and doing it page by page.
 



Have you tried your macro recorder?

Skip,
[sup][glasses]Don't let the Diatribe...
talk you to death![tongue][/sup][sub]
[glasses]Just traded in my old subtlety...
for a NUANCE![tongue][/sub]
 
Yeah... didn't quite do what I wanted it to do.

Oh well... I will just do it by hand over the next couple days. No biggie.

Thanks
 
Of course, it's possible to do just about anything, whether it makes sense or not. The question I have is how you recognize where you want to insert a blank line, and where you want to insert a page break.

From the looks of your examples, I surmise that
1. The title is ALL CAPS and nothing else ever is
2. The directions are distinguishable from the ingredients (programmatically, of course it's obvious to a reader) only by the use of a "period".

If these are the rules, then a routine would be something like:
- find a line in all caps
- insert a page break before that line
- insert a page break after that line
- remove any "*" at the start of a line
- find an occurrence of "."
- insert a page break before the line where the "." occurs [note: this presupposes that the first sentence in the directions will never be more than one line]

Does this sound like what you want?

_________________
Bob Rashkin
 
Hey Bong...

That sounds like something I am looking for. However, I have already formatted 200 pages. Not too bad, just tedious. So don't worry about working on my code... unless you're bored!

Thanks
 
Bob, could you explain:

If these are the rules, then a routine would be something like:
- find a line in all caps
- insert a page break before that line
insert a page break after that line

Why the page break after the ALL CAPS line? Surely the OP does not want:

BAKED CUSTARD
Page Break
2 cups Milk, scalded
etc.

Why would anyone want a page break after the title of the recipe?

Groves22, as Bong mentions, just about anything is possible. I can certainly understand not wanting to manually go through a 478 page document.

However, you have to understand that Word does not really use pages. "Pages" are derived constructions, not actual..ummm..."things" to Word. This is a common misunderstanding.

So....

First off, are there page breaks between each recipe? This is very important to know. If there are, then we can basically ignore the page breaking structure.

Do any recipes cover more than one page?

Are ALL recipe title in all caps?

Are you sure all recipes follow one of the two looks - i.e. the ingredients have the * (or not)? The main problem is that if the ingredients do NOT have the *, it makes it much much harder. After all, look at this:

Nutmeg or coconut
Scald milk, let cool slightly. Combine eggs, sugar, vanilla, and salt.

WHAT distinquishes the ingredient line (paragraph) from the instruction paragraph? Basically...nothing. HOW would you tell Word the first one is an ingredient, and the second is not? Now if the ingredient line start with *, then it is easy logic.

IF a paragraph case is all caps, it is a title paragraph.
IF a paragraph starts with *, it is an ingredient paragraph.
IF a paragraph is NOT all caps, does NOT start with *, then it is an instruction paragraph.

But as I mentioned:

Nutmeg or coconut
Scald milk, let cool slightly. Combine eggs, sugar, vanilla, and salt.

What can you use, as logic, to tell which is an ingredient, and which is an instruction? Other than possibly having logic that if a paragraph is longer than X characters, then it is an instruction. But that seems very dangerous to me.

So, to automate this so you could just fire it up, and it processes through the entire document, would be tricky. Very tricky.

I will offer an alternative suggestion. You would still have to go through, manually, page by page, but you could certainly speed things up.

As Skip mentioned, the proper way to have this is using Styles. Word is designed around styles.

So, make some styles.

RecipeTitle: all caps, space after = 12 pt (or whatever size of space after you want)

RecipeIngredient: whatever font you want, space after = 5 pt - this makes the ingredient list a little tighter.

RecipeIngredientLast: like RecipeIngerdient, but with extra SpaceAfter to make the space before instructions.

RecipeInstruction: whatever font you want.

Make keyboard hotkeys for them. Then start running through the document.

You could automate the Titles - again assuming all of them are indeed full caps.
Code:
Dim oPara As Paragraph
For Each oPara In ActiveDocument.Paragraphs
   If oPara.Range.Case = 1 = True Then
      oPara.Range.Style = "RecipeTitle"
   End If
Next
That could change:

BAKED CUSTARD
2 cups Milk, scalded
3 Eggs, slightly beaten
1/3 cup Sugar

to:

BAKED CUSTARD

2 cups Milk, scalded
3 Eggs, slightly beaten

Note that by using a style, that space between Baked Custard and the first ingredient is NOT, repeat NOT, one of those "extra" paragraphs people put in to make space. The space is in the style. This is how Word is designed to be used, although few actually do.

All in all though, unless you can find a way to really tighten up the logic (the determination of WHAT to do), trying to work out a full VBA solution would not be worth the effort.

However, you could possibly use a partial VBA solution to do some of the tedious work.

Oh, and back to Bob. I am willing to bet you $100 (OK, maybe not a $100) that doing a search for AllCaps will turn up.....nothing. Searching for lines with font as all caps will return....nothing. That is if you did it as afont characteristic:
Code:
If
.Range.Font.AllCaps = True

I am willing to bet that BAKED CUSTARD was typed in with CapsLock on. In which case, the font in NOT AllCaps, but the Range.Case is.

Gerry
 
Too little sleep.

Obviously (to me) I meant:
[tt]- find a line in all caps
- insert a page break before that line
- insert a page breakline feed after that line
- remove any "*" at the start of a line
- find an occurrence of "."
- insert a page breakline feed before the line where the "." occurs [note: this presupposes that the first sentence in the directions will never be more than one line][/tt]

_________________
Bob Rashkin
 
Gerry,
I missed the second part. Tedious though it may be, one could loop through each character of a line ensuring that Asc() returns 65 - 90 .or. 32.

_________________
Bob Rashkin
 
Here's a suggestion that could help pre-format the document making it a little easier to identify sections and then to apply styles:

Steps:
1. I think it will be quite difficult identifying the directions' section other than by it containing full stops.

2. Alas, you also use abbreviations (tsp, tbsp etc.) i.e. also full stops in your ingredients' list.

I would suggest to
a) first replace all abbreviations with their full terms
b) do some nifty wildcard search/replace to pre-format your document.

here's an example

Code:
Sub FormatRecipes()

Dim Abbreviations, FullText
Dim i As Integer

Abbreviations = Array("lbs.", "tsp.", "tbsp.", "c.")
FullText = Array("pounds", "teaspoon", "tablespoon", "cup")

With ActiveDocument.Content.Find
    .ClearFormatting
    .Replacement.ClearFormatting
    .MatchWildcards = False
    
[green]'First: replace all abbreviations with full text to 
' make directions identifiable via the contained periods.[/green]
    For i = 0 To UBound(Abbreviations)
        .Text = Abbreviations(i)
        .Replacement.Text = FullText(i)
        .Execute Replace:=wdReplaceAll
    Next i
        
[green]'next: remove bulleting asterisks *[/green]
    .Text = "^p* "
    .Replacement.Text = "^p"
    .Execute Replace:=wdReplaceAll
    
[green]'delimit each new recipe by adding three asterisks 
'(or whatever else as a "new recipe" identifier) 
' and an empty line after the title[/green]
    .Text = "([A-Z ]{2;})(^13)"
    .MatchWildcards = True
    .Replacement.Text = "***^13\1^13^13"
    .Execute Replace:=wdReplaceAll
    
End With

End Sub

I tried to find some regexp to add a line before the entire descriptive paragraph. Alas, the directives' "paragraph" consists of more than just one paragraph.

Not sure how to achieve this.
[ponder]

Would have been a lot better to think this over BEFORE writing 478 pages of that stuff! [rednose]

[navy]"We had to turn off that service to comply with the CDA Bill."[/navy]
- The Bastard Operator From Hell
 
I bet the OP did not write the 478 pages. I bet they got the document, and it was/is an amalgamation of various people's input.

"this presupposes that the first sentence in the directions will never be more than one line"

Whoa, that may be unlikely. Even the meatballs example seems to be more than one line.

Gerry
 
@Gerry: Yes, you're probably right.

This gives me an idea:

@Groves22: Do you happen to have the set of singular recipes somewhere? They might be easier to process!

(Unless you have already done it all manually in ~24 hours straight work or so...)

[navy]"We had to turn off that service to comply with the CDA Bill."[/navy]
- The Bastard Operator From Hell
 
Grove22,

How about a semi-automated procedure? It would seem this might be the easiest to write, and it would eliminate all of the programatic "guesswork". For instance:

1) Open document manually, start code
2) Code displays Messagebox1 with directions such as "Place cursor on the first character of the first ingredient and press (key of your choice)"
3) Code inserts a blank line in front of chosen character
4) Code displays Messagebox2 with directions such as "Now, place cursor on the last character of the last ingredient and press (key of your choice)"
5) Code inserts a blank line in behind chosen character
6) Code checks for EOF
7) If not EOF goes to next page and repeats the above.

This leaves you with minimal work to do, assures you get consistent results, and eliminates code failure if one recipe doesn't follow the normal pattern.

Skip, Gerry: Feel free to poke holes in this idea. I used something similar for a project a few years back and it worked just fine.

----------------------------------------------------------------------------------
[small][ponder]"How many liberal, forward thinking Kansans does it take to change a light bulb?"[/small]
"Both of them!" [lol]
 
No need to poke holes, it is a good suggestion. It is similar to my suggestion to have proper styles and keyboard shortcuts. Although using shortcuts avoids having those messageboxes.

Gerry
 

Gerry,

I thought the messageboxes might be better for a newbie (which I gather Grove22 might be) than styles and keyboard shortcuts. The messages can be easier than trying to remember and/or annotate the shortcuts for the various styles. My only thought was to prime Grove to learn a little coding and make the end product more accessible to all potential end-users.

However, I'm perfectly willing to admit that your method is superior in that it involves no coding at all, and illustrates why everyone should learn to use styles.

----------------------------------------------------------------------------------
[small][ponder]"How many liberal, forward thinking Kansans does it take to change a light bulb?"[/small]
"Both of them!" [lol]
 
Well, yes. Using styles properly would eliminate (IMO) a large majority of issues people have with Word.

Gerry
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top