PDA

View Full Version : Switch between Word open documents hide/show userform



ShielFever
09-12-2012, 10:53 PM
I have a Word Template that on open displays a userform where the user inputs a bunch of data that is then written to DocVariables throughout the document.

However, when the userform is open, some of the information that is required to be input may be present in another Word document.

When Document1 opens from the template, I cannot switch between this and other open Word documents whilst the userform is displayed.

I have a similar situation with an Excel workbook and the following works for switching between different workbooks, can this be translated to Word somehow?

This is my Excel code in ThisWorkbook

Private Sub Workbook_Activate()
frmUserForm1.Show vbModeless
End Sub

Private Sub Workbook_Deactivate()
frmUserform1.Hide
End Sub

I've tried this in ThisDocument in my Word document but have had no success.

Private Sub Document_Activate()
frmUserForm1.Show vbModeless
End Sub

Private Sub Document_Deactivate()
frmUserForm1.Hide
End Sub

The interesting thing is that I am not getting a degug error dialogue box and the userform works as it should (aside from allowing me to switch between active Word documents).

Any help would be greatly appreciated.

Thanks.

fumei
09-13-2012, 03:39 PM
It is not very clear what you are doing, but in principle, there should be no need to do ANY shifting in active document. A userform can both action, as well as get information, from any open document. they do not have to be active.

If you have them set as document objects, you can do pretty much whatever you want to do.

"However, when the userform is open, some of the information that is required to be input may be present in another Word document."

The fact they are present in another document is not a problem. If you give some details it should not be difficult to get that information.

ShielFever
09-17-2012, 04:24 PM
Thanks for the reply. I have attached what the user form & letter with DocVariables looks like.

The user form writes the info to the DocVariables in the letter after the user clicks OK on the user form.

The reason I need to be able to switch between open documents is so that I can obtain details from a previous letter to the same person. Address, DOB etc and once the userform is open in the template, I can't switch to the old letter.

I hope this explains my purpose somewhat.

Frosty
09-17-2012, 04:43 PM
Two problems to this design, that I can see.
1. When you launch your userform. If it launches when you open a document based on the template the code is in, then you are, by definition, associating this form with that document. You can get around this design by changing the ShowModal property of the userform to False (not at runtime, but at design time -- i.e., double-click the form in the VBA Editor, and look through the Properties window). That will allow you to interact with the Word application without dismissing the form (so you can switch to a different document and check the docvariables there).

2. When you populate the data of the UserForm1. I'm going to guess it's during your Initialize event. You need to move that code to a "GetDataFromActiveDocument" subroutine. And then call that subroutine from your Initialize for the UserForm, but also add a new command button called "Get Data" to your userform, which will run that subroutine as well (this allows you to switch to a different document, and capture the data from that newly activated document).

From there, I'd probably change your "OK" button to be called "Write Data", remove your Me.Hide or Unload UserForm1 statement from your OK button routine, and add a third command button called "Close", where you would unload that button.

Also, you'll probably want to add a macro which displays the user form on something other than just the Document Open event... and is called from the userinterface (ribbon button? QAT? Command bar button if you're using an earlier version of Word than 2007/2010).

Hope this helps.

ShielFever
09-17-2012, 05:14 PM
Hi Frosty, thanks for the reply.

If possible I'd like to keep it as simple as possible, as in terms of what the user has to do.

I have around 300 letters for all different things but the user form is basically the same across all letters. There are 3 variations of the userform.

My main problem is that 98% of people using them know how to open/save a word document and that's about it.

Hence the reason for the form initializing on open and having only an OK button.

My code whilst it works is fairly simple. Here it is, maybe you can point me in the right direction.

Option Explicit
Private Sub cmdOK_Click()
'Declare variables
Dim oBMs As Bookmarks
Dim oVar As Variable
Dim oCC As ContentControl
Dim oRng As Word.Range
Dim strAddress As String
Set oBMs = ActiveDocument.Bookmarks
'Create the "Title" variable
ActiveDocument.Variables("Title").Value = Me.cbTitle.Text
'Create the "First Name" variable
ActiveDocument.Variables("FirstName").Value = Me.txtFirstName.Text
'Create the "Surname" variable
ActiveDocument.Variables("Surname").Value = Me.txtSurname.Text
'Build the multi-line address string
If Len(Me.txtAddress1.Text) > 0 Then
strAddress = Me.txtAddress1.Text & vbCr
End If
If Len(Me.txtAddress2.Text) > 0 Then
strAddress = strAddress & Me.txtAddress2.Text & vbCr
End If
If Len(Me.txtAddress3.Text) > 0 Then
strAddress = strAddress & Me.txtAddress3.Text & vbCr
End If
If Len(Me.txtSuburb.Text) > 0 Then
Me.txtSuburb.Text = Me.txtSuburb.Text & vbCr
End If
strAddress = strAddress & Me.txtSuburb.Text & " " & Me.cbState.Value & " " & Me.txtPostCode.Text
'Write the address to the CC titled "Client Address"
ActiveDocument.SelectContentControlsByTitle("Client Address").Item(1).Range.Text = strAddress
'Create the "Extension" variable
ActiveDocument.Variables("Extension").Value = Me.txtExtension.Text
'Create the "Policy Owner" variable
ActiveDocument.Variables("PolicyOwner").Value = Me.txtPolicyOwner.Text
'Create the "Date of Birth" variable
ActiveDocument.Variables("DOB").Value = Me.txtDOB.Text
'Create the "Policy Number" variable
ActiveDocument.Variables("PolicyNumber").Value = Me.txtPolicyNumber.Text
'Create the "Claim Number" variable
ActiveDocument.Variables("ClaimNumber").Value = Me.txtClaimNumber.Text
'Create the "Sender" variable
ActiveDocument.Variables("Sender").Value = Me.cbSender.Text
With ActiveDocument.Fields
.ToggleShowCodes
.Update
End With
Unload Me
lbl_Exit:
Exit Sub
End Sub
Private Sub UserForm_Initialize()
Dim arrStateList() As String
Dim arrTitleList() As String
'Define combobox list members in an array.
arrTitleList = Split("Mr Mrs Ms Miss Dr")
'Populate combobox list.
Me.cbTitle.List = arrTitleList
'Define combobox list members in an array.
arrStateList = Split("ACT QLD NSW NT SA TAS VIC WA")
'Populate combobox list.
Me.cbState.List = arrStateList
'Define combobox list members in an array.
cbSender.Clear
Call cbSender.AddItem("removed")
Call cbSender.AddItem("removed")
Call cbSender.AddItem("removed")
Call cbSender.AddItem("removed")
Call cbSender.AddItem("removed")
Call cbSender.AddItem("removed")
Call cbSender.AddItem("removed")
Call cbSender.AddItem("removed")
Call cbSender.AddItem("removed")
Call cbSender.AddItem("removed")
Call cbSender.AddItem("removed")
Call cbSender.AddItem("removed")
Call cbSender.AddItem("removed")
Call cbSender.AddItem("removed")
Call cbSender.AddItem("removed")
Call cbSender.AddItem("removed")
Call cbSender.AddItem("removed")
Call cbSender.AddItem("removed")
lbl_Exit:
Exit Sub
End Sub

Also, do you know why this works in excel but not word? It does exactly as I want and hides the userform when switching between workbooks and unhides when I switch back.

Private Sub Workbook_Activate()
frmUserForm1.Show vbModeless
End Sub

Private Sub Workbook_Deactivate()
frmUserform1.Hide
End Sub

Thanks

ShielFever
09-17-2012, 05:17 PM
Sorry, forgot to mention. I'm using Word 2007.

Frosty
09-17-2012, 07:27 PM
Well, not to be snarky, but the reason it works in excel and not in word is because is because it works in excel, but not in word.

Also, you're using different events. You're using the activate/deactivate events which are built in to excel, but the analogous events in word are not built in.

So, bottom line, you have to handle it differently in Word.

I'll double check the .Show method in word 2007, as I would think there is a way of showing a form modeless at runtime, but it may also need to be different.

However, there is still going to be a design issue here, as you simply don't have the same activate/deactivate events available in a built in fashion.

If you don't want to add additional buttons, and you don't want to provide an available documents list on your userform (i.e., you want the exact same UI in word as you have in excel), you're going to have to create your own event handler and start working with the document_change event.

I think it would be easier to avoid that, but it's all possible.

Your code actually isn't necessary, as what you're doing is very obvious. These are design decisions, rather than coding errors.

How familiar are you with VBA and event/class module coding? How familiar are you with the concept of global addins and deployment issues? Some of that will have bearing on what the best route forward is.

ShielFever
09-17-2012, 07:43 PM
Thanks again Frosty,

I would say that I have an intermediate knowledge of VBA. I understand why things are done as a result of the code that is written. The code I posted earlier is my code so I don't know if that's any type of guage on what I know.

As for my problem here, everything works as it should (except being able to switch to other open docs).

I find that using VBA in excel is much more tangible in what you can ask it to do whereas word seems somewhat limited or requires a lot more code to do something simple.

By event/class module coding, I assume you are referring to a Macro based on an event - I could be wrong. But say, the OK button, when pressed runs a macro to do whatever as opposed to having the code within the user form initialize? Or if a field is changed, then run a macro for somewthing else.

Am I on the right track?

ShielFever
09-17-2012, 07:53 PM
My design was based on a previous standard letter we were using.

On open it would display a form to select the type of product the letter related to, then a form would display to select the signatory of the letter, then a form where all the contact details and so forth for the person the letter was being sent to.

I've tried to streamline this somewhat by removing the first 2 forms and having only the 1 form where all the info can be input and then written to the document.

I've just tried to use the old template to see if it allows me to switch between open docs and it does with no problem.

I've looked through the code and it is 28 pages long and I can't find anything that looks like it may be of use to my problem.

Do you think there is any relation to the fact that my template is .docm and the old template is .dot? It would seem silly if this is the case but I'm just trying to figure out any reasons why I can't do it with mine.

Thanks

Frosty
09-18-2012, 09:28 AM
Couple of questions to address:
1. Events.
You're on the right track, especially when you talk about the OK button. That's an event-- it is the "Click" event of that button. In fact, if you put your cursor in that cmdOK_Click procedure, you could click on the right combo box (the one that says "Click"), you would see that you have a host of other events available just for that control type (DblClick, Enter, Exit, KeyDown, etc etc). Those are all the available events related specifically to that button.

There are also application events. Some are built-in (if you go to ThisDocument module in Word, click on the drop down that says "(General)" and choose "Document"... you will see a host of options on the right (New, Open, Close, and a bunch of others). This is very analogous to Excel/ThisWorkbook ... however, while there are some of the same events available (Open), there are also a lot of differences.

However, you can set up your own application event handler to get additional available events. The one probably most analogous to the Excel stuff would be DocumentChange. We can discuss that more later if you think you need to use something like the Document_Change event to create a system like the available Excel events of Activate/Deactivate-- just trying to get broad stroke concepts here.

2. .Dot vs. .Docm.
Word 2007 changed a lot of things, not the least of which is the available document formats. As someone with more experience in Excel, this is a big deal, because you are, apparently, trying to upgrade your templates?
First off-- the old templates (the .dots) should still work-- why not use them?

Word 2003 and previous:
.doc = regular document, can store macros, default windows action (double-click the document in windows explorer) is to open the file.
.dot = document template, can store macros, default windows action is to create a new file based on that file.

Word 2007 and later:
.docx = regular document, cannot store macros, default action is "open"
.docm = regulard document, can store macros, default action is "open"
.dotx = regular template, cannot store macros, default action is "new"
.dotm = regular template, can store macros, default action is "new"

Basically, microsoft identified what document types can have macros and what can't. But they didn't change the essential structure of how things work (documents are documents, templates are templates).

So it seems strange to me that you are changing from a .dot to a .docm. You are changing from a template which stores macros to a document which stores macros. This is different essential structure and behavior.

Practically speaking-- in 2003, when someone created a new document based on the old .dot... that new document didn't have any macros in it. It simply had a reference (the "attached template") to the .dot, which allowed those macros to be run. This paradigm continues in 2007 with templates that have macros in them (.dotm).

But you're setting up a scenario where every document created would have macros in it. This is bad-- you're going to have versions of your code everywhere. If you need to translate an old .dot into the newer version, then you should move to a .dotm. I don't believe you need to translate though, if the old stuff is working. Just create new documents based on the .dot, and then save as a .docx.

3. Old code vs. New code.
If you've looked through the 28 pages of code and don't see anything that jumps out at you, then you should look at the actual individual userforms. Not everything is in code. There are properties of userforms and userform controls which are the initial settings. Look for ShowModal and see if any of those have a value of False. Most likely, you either missed something in your review of the code, or that ShowModal must be false on the form that is displayed while allowing you to switch between documents.

4. I know you say everything is currently working except for the switching, but even if you just change the .ShowModal property of the userform to False, I don't know how you can grab values from a document you switch to... unless you've got some code running during that event, or you're simply relying on your user to manually type stuff in from what is displayed on that other document.

All for now.. take a look at the .ShowModal property for the UserForm, and then see what that gets you.

I really think you need to re-examine the .docm choice, however... unless that was a typo.

huangwei0716
10-11-2012, 01:10 AM
I have written many COM addins, but I am struggling to see how you would do this. If I get some time I will do some work on it, see if it does look possible.






________________________________________________________
Lectores Codigos De Barras (http://www.reliabletop.es/-launch-esc??ner-de-c?3digo_c47)
Llaves de Coche (http://www.reliabletop.es/-llaves-de-coche_c29)
Tablet PC China (http://http://www.reliabletop.es)