rvfowler2
asked on
How to Pause a Word Macro
Received the tip to type "stop" in my Word macro code if I wanted to pause and perform some final editing before continuing to insert pictures, etc., and then saving to a pdf document. Only problem is that it brings up the macro editor which would throw off my users. Tried a MssBox, but that does not let me edit the Word doc until you click OK, which then unpauses the Macro. Any ideas?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Actually, an addendum. On another question, I did receive a solution to losing the content of the variables when the first macro ends. The answer suggested storing the content of the variables in the Custom Document Properties of the Word doc before the first macro finished so they can be reused for the seconde macro. See below.
Here's the deal with custom document properties, as used in the code sample earlier in this thread. We want to create a place in the document to keep information that will remain there even after the macros have been run. I like to use custom document properties (CDPs) for this purpose because they don't appear in the document text anywhere (unless you want them to) and so are not prone to accidental erasure.
Creating a CDP is easy, with a simple Add to the CustomDocumentProperties collection:
ActiveDocument.CustomDocum entPropert ies.Add _
Name:=sMyCDP, LinkToContent:=False, Value:="upc_setup_r" & MyValue & PropValue & "test.doc", _
Type:=msoPropertyTypeStrin g
Parameters:
* The Name parameter can be anything (no reason not to hardcode it, if you're only going to be working with the one CDP).
* LinkToContent ties it to a value in the document, which I never do. I set it to False based on a choice I made in the late 90s, but you can probably just ignore it. (I don't remember anymore why I did that.)
* Value is what it says it is.
* Type is where you declare it as a string (you can also choose dates, numbers, etc.).
So, that much is easy. I've run into problems, though, trying to Add a CDP that already exists, so I've gotten into the habit of always checking whether it exists, first. I do this by cycling through all the CDPs in the collection and comparing each name to the one I want to Add (or Update):
Dim xx As DocumentProperty
For Each xx In ActiveDocument.CustomDocum entPropert ies
If LCase(xx.Name) = LCase(sMyCDP) Then
bCDPFound = True
End If ' xx.Name <> CdpName
Next xx
As before, you can hardcode the name if you prefer (I'm using the string variable sMyCDP in the example). There's also no particular reason to use a boolean to track whether the CDP was found; that's another bit of legacy code that follows me around. To ditch it, you can replace the "bCDPFound = True" statement with the code that sets the value of an existing CDP:
ActiveDocument.CustomDocum entPropert ies(sMyCDP ) = "upc_setup_r" & MyValue & PropValue & "test.doc"
In that case (skipping the boolean), you'd want to put the CDP creation code in the Else side of the If..Then..Else..End If section. Here's the whole thing in that format:
Dim xx As DocumentProperty
For Each xx In ActiveDocument.CustomDocum entPropert ies
If LCase(xx.Name) = LCase(sMyCDP) Then
' Populate the CDP with the current name:
ActiveDocument.CustomDocum entPropert ies(sMyCDP ) = "upc_setup_r" & MyValue & PropValue & "test.doc"
Else
' Didn't find one, so Add it and populate it
ActiveDocument.CustomDocum entPropert ies.Add _
Name:=sMyCDP, LinkToContent:=False, Value:="upc_setup_r" & MyValue & PropValue & "test.doc", _
Type:=msoPropertyTypeStrin g
End If
Next xx
Of course, you can use a variable for the Value parameter, such as sFileName...but you know all that.
The code snippet I've attached is a routine I use to create/add a CDP and give it a value. You'll pass in the CDP name and the value, and it does the rest. Since it refers to yet another routine (CdpExists), I've included that, too. Finally, I'm throwing in the one I use to create a CDP with a numerical value instead of a string (I didn't even remember I had this, so I can't say why I chose Currency).
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32: '--------------
Public Sub CreateAndPopulateOneCDP(By Val psCdpName As String, ByVal psCdpValue As String)
If CdpExists(psCdpName) Then
ActiveDocument.CustomDocum entPropert ies(psCdpN ame) = psCdpValue
Else ' CdpExists(psCdpName) = False
ActiveDocument.CustomDocum entPropert ies.Add _
Name:=psCdpName, LinkToContent:=False, Value:=psCdpValue, _
Type:=msoPropertyTypeStrin g
End If ' CdpExists(psCdpName)
End Sub ' CreateAndPopulateOneCDP(By Val psCdpName As String, ByVal psCdpValue As String)
'--------------
Public Function CdpExists(ByVal CdpName As String) As Boolean
Dim xx As DocumentProperty
For Each xx In ActiveDocument.CustomDocum entPropert ies
If LCase(xx.Name) = LCase(CdpName) Then
CdpExists = True
Exit Function
End If ' xx.Name <> CdpName
Next xx
CdpExists = False
End Function
'--------------
Public Sub CreateAndPopulateOneCDP_Nu mber(ByVal psCdpName As String, ByVal pcurCdpValue As Currency)
If mxcCdpExists(psCdpName) Then
ActiveDocument.CustomDocum entPropert ies(psCdpN ame) = psCdpValue
Else ' CdpExists(psCdpName) = False
ActiveDocument.CustomDocum entPropert ies.Add _
Name:=psCdpName, LinkToContent:=False, Value:=pcurCdpValue, _
Type:=msoPropertyTypeNumbe r
End If ' CdpExists(psCdpName)
End Sub ' CreateAndPopulateOneCDP_Nu mber(ByVal psCdpName As String, ByVal pcurCdpValue As Currency)
'--------------_
Here's the deal with custom document properties, as used in the code sample earlier in this thread. We want to create a place in the document to keep information that will remain there even after the macros have been run. I like to use custom document properties (CDPs) for this purpose because they don't appear in the document text anywhere (unless you want them to) and so are not prone to accidental erasure.
Creating a CDP is easy, with a simple Add to the CustomDocumentProperties collection:
ActiveDocument.CustomDocum
Name:=sMyCDP, LinkToContent:=False, Value:="upc_setup_r" & MyValue & PropValue & "test.doc", _
Type:=msoPropertyTypeStrin
Parameters:
* The Name parameter can be anything (no reason not to hardcode it, if you're only going to be working with the one CDP).
* LinkToContent ties it to a value in the document, which I never do. I set it to False based on a choice I made in the late 90s, but you can probably just ignore it. (I don't remember anymore why I did that.)
* Value is what it says it is.
* Type is where you declare it as a string (you can also choose dates, numbers, etc.).
So, that much is easy. I've run into problems, though, trying to Add a CDP that already exists, so I've gotten into the habit of always checking whether it exists, first. I do this by cycling through all the CDPs in the collection and comparing each name to the one I want to Add (or Update):
Dim xx As DocumentProperty
For Each xx In ActiveDocument.CustomDocum
If LCase(xx.Name) = LCase(sMyCDP) Then
bCDPFound = True
End If ' xx.Name <> CdpName
Next xx
As before, you can hardcode the name if you prefer (I'm using the string variable sMyCDP in the example). There's also no particular reason to use a boolean to track whether the CDP was found; that's another bit of legacy code that follows me around. To ditch it, you can replace the "bCDPFound = True" statement with the code that sets the value of an existing CDP:
ActiveDocument.CustomDocum
In that case (skipping the boolean), you'd want to put the CDP creation code in the Else side of the If..Then..Else..End If section. Here's the whole thing in that format:
Dim xx As DocumentProperty
For Each xx In ActiveDocument.CustomDocum
If LCase(xx.Name) = LCase(sMyCDP) Then
' Populate the CDP with the current name:
ActiveDocument.CustomDocum
Else
' Didn't find one, so Add it and populate it
ActiveDocument.CustomDocum
Name:=sMyCDP, LinkToContent:=False, Value:="upc_setup_r" & MyValue & PropValue & "test.doc", _
Type:=msoPropertyTypeStrin
End If
Next xx
Of course, you can use a variable for the Value parameter, such as sFileName...but you know all that.
The code snippet I've attached is a routine I use to create/add a CDP and give it a value. You'll pass in the CDP name and the value, and it does the rest. Since it refers to yet another routine (CdpExists), I've included that, too. Finally, I'm throwing in the one I use to create a CDP with a numerical value instead of a string (I didn't even remember I had this, so I can't say why I chose Currency).
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32: '--------------
Public Sub CreateAndPopulateOneCDP(By
If CdpExists(psCdpName) Then
ActiveDocument.CustomDocum
Else ' CdpExists(psCdpName) = False
ActiveDocument.CustomDocum
Name:=psCdpName, LinkToContent:=False, Value:=psCdpValue, _
Type:=msoPropertyTypeStrin
End If ' CdpExists(psCdpName)
End Sub ' CreateAndPopulateOneCDP(By
'--------------
Public Function CdpExists(ByVal CdpName As String) As Boolean
Dim xx As DocumentProperty
For Each xx In ActiveDocument.CustomDocum
If LCase(xx.Name) = LCase(CdpName) Then
CdpExists = True
Exit Function
End If ' xx.Name <> CdpName
Next xx
CdpExists = False
End Function
'--------------
Public Sub CreateAndPopulateOneCDP_Nu
If mxcCdpExists(psCdpName) Then
ActiveDocument.CustomDocum
Else ' CdpExists(psCdpName) = False
ActiveDocument.CustomDocum
Name:=psCdpName, LinkToContent:=False, Value:=pcurCdpValue, _
Type:=msoPropertyTypeNumbe
End If ' CdpExists(psCdpName)
End Sub ' CreateAndPopulateOneCDP_Nu
'--------------_
ASKER
If you are still linked to this. Having problems with the CDP code. Received a "catastrophic failure.
Ouch. That doesn't sound good. I hope no one was injured. Can you tell at what point the code errored out?
ASKER