PDA

View Full Version : Solved: Error message: Didn't provide a valid object qualifier



hkeiner
10-13-2010, 12:04 PM
I am trying to add a VBA command on a macro attached to the normal document that would close an open VBA form (fPointLinks) that is attached to an open document. The name of the opon document containing the VBA form is random and often varies.

When running the macro, I keep getting an error message that says that I didn't provide a valid object qualifier. That is likely as I don't know what I am doing. I attached a screen shot of the VBA project window as an example for naming purposes.

This is an example of what I have tried:



Public Sub ClosePointLinkForm()
fPointLinks.hide
End Sub



Any suggestions?

fumei
10-14-2010, 11:08 AM
Please let people know when you cross-post.

I hope 516bb1eee3bc424aaa1b3e98bae5fb5b is not the real name!

As I stated in the other thread. Read up on Scope.

If the document shows the userform, how are you going to get any procedure in Normal to execute? The userform has focus.

hkeiner
10-14-2010, 11:48 AM
1) Yes, an example document name is 516bb1eee3bc424aaa1b3e98bae5fb5b. The vendor's application stores/manages these workpapers on an SQL server and assigns a unique random file name to them when saved to the server. When the Word document is later retrieved/opened for further use of the form "features", the file name is as shown in the VBA project window example that was attached above.

2) The userform is not fully modal. The Word document can be active with the user form still floating/visible on the corner of the screen. It does disappear (closes/hides) if the OK or cancel buttons on the form are clicked. I presume clicking on the open userform makes it active while the Word document is also open but not active.

3) My reading up on Scope has not helped me figure this out. If anything, my reading seems to indicate to me that what I want to do is not possible. If that is the case, a definitive answer from a knowlegeable programer would save me me lots of fruitless effort trying. If it is possible, there must be a trick/techniqe that I can not gleen from what I have read so far. I do try to figure things out on my own when I can, almost to a fault.

4) Sorry for any cross posting. I am new at this...

5)
If the document shows the userform, how are you going to get any procedure in Normal to execute? The userform has focus. The procedure/macro in Normal would be executed using an icon added to the Quick Access Toolbar

hkeiner
10-14-2010, 11:55 AM
Crosspost:

http://www.tek-tips.com/viewthread.cfm?qid=1623827&page=1

fumei
10-14-2010, 12:47 PM
It can be done by having an unloading procedure in the document with the userform and then calling it.

So, in 516bb1eee3bc424aaa1b3e98bae5fb5b you have a procedure:
Sub KillTheForm()
Unload frmPointLinks
End Sub


and in Normal, you have:
Dim Doc As Document
Set Doc = Documents("516bb1eee3bc424aaa1b3e98bae5fb5b.doc")
Application.Run Macroname:="doc!ThisDocument.KillTheForm"
What this does is make a Call to a procedure that IS in Scope - it is in the VBProject that contains the userform.

Now, probably, your 516bb1eee3bc424aaa1b3e98bae5fb5b does not have the procedure, so you can either:

1. have another procedure that writes the procedure, OR
2. export it, and then import it when you open 516bb1eee3bc424aaa1b3e98bae5fb5b.

fumei
10-14-2010, 02:29 PM
I am not going to bounce back and forth between these threads. You have added a hugely different situation at the TEk-Tips thread.

When you have determined EXACTLY what you are trying to do, and can express it clearly, post.

I suspect with the new information you posted at TT, this may be a lot more difficult.

hkeiner
10-14-2010, 03:21 PM
OK, I'll stop posting on this thread.

I meant to use a simple example (e.g. hide/close a userform on a "custom" Word document using a macro from the normal template) as a way to get started in learning how to control various code associate with the userform. I was not sure if this was even possible based upon the the constraints of my situation. I was thinking that the first answer would be either "no, you can't do that" or yes, this is the code you use...".

Sorry to take up your time.

Contraints:
- We have hundreds of copies of the custom word document containg the same code and userform
- Each copy of the custom Word document has its own unique file name
- I can not add/change VBA code on any of the existing copies or future copies of the custom Word document.
- I can not add/change the userform on any of the existing copies or future copies of the custom Word document.
- Adding an icon to the QAT to run multiple subs on the custom Word document at one time is not possbile.
- I can only add/change code on the normal template.

fumei
10-15-2010, 09:07 AM
From that I STILL do not get what you are trying to do. I understand the constraints, but what ARE you trying to do?

"I meant to use a simple example (e.g. hide/close a userform on a "custom" Word document using a macro from the normal template) as a way to get started in learning how to control various code associate with the userform."

As posted above, this can be done.

hkeiner
10-15-2010, 11:38 AM
FIRST SUGGESTION:
So, in 516bb1eee3bc424aaa1b3e98bae5fb5b you have a procedure:

VBA:
Sub KillTheForm()
Unload frmPointLinks
End Sub

SECOND SUGGESTION:
and in Normal, you have:

VBA:
Dim Doc As Document
Set Doc = Documents("516bb1eee3bc424aaa1b3e98bae5fb5b.doc")
Application.Run Macroname:="doc!ThisDocument.KillTheForm"

- The first suggestion does not work for me because one of my constraints is that I can not add/edit any procedures to the individual Word documents. The Word documents are created by a document management system that is outside my control and there are hundreds of them being actively used and shared between many different users.

- The second suggestion does not work for me because one of my contraints is that each Word document has it's own unique file name (project name). Using a document name (such as "516bb1eee3bc424aaa1b3e98bae5fb5b.doc") in my Normal template code would only work for that particular document and none of the others.

I think that my above conclusions are correct. Unless there are other methods to close/hide/kill the form, perhaps there is no way to do what I want to do because of my constraints.

I do appreciate very much your trying to help me out.

fumei
10-15-2010, 12:54 PM
First of all, those are two separate suggestions. The first procedure is required to use the second.

"Using a document name (such as "516bb1eee3bc424aaa1b3e98bae5fb5b.doc") in my Normal template code would only work for that particular document and none of the others. "

Yes, but you can GET the name of any given document. or use ActiveDocument (the current one).

Dim Doc As Document
Set Doc = Documents("516bb1eee3bc424aaa1b3e98bae5fb5b.doc")
Application.Run Macroname:="doc!ThisDocument.KillTheForm"


change it to:

Dim Doc As Document
Set Doc = ActiveDocument
Application.Run Macroname:="doc!ThisDocument.KillTheForm"


However, you STILL have to have the procedure in that document.

"The first suggestion does not work for me because one of my constraints is that I can not add/edit any procedures to the individual Word documents. The Word documents are created by a document management system that is outside my control and there are hundreds of them being actively used and shared between many different users."

What is stopping you? You can do this once for a document, and the module stays put. Say you have 516bb1eee3bc424aaa1b3e98bae5fb5b.doc, and it is Active. It is thus ActiveDocument.

Previously (and again you only need to do this once), you write a standard module with its content being:

Option Explicit

Sub KillTheForm()
Unload frmPointLinks
End Sub


You Export it as a .bas file. Right click it, and Export. You can save it anywhere, and name it anything. I saved it as c:\KillTheDamnForm.bas

Now, in Normal, you have the closing procedure ImportThenExecute:
Sub ImportThenExecute()
Dim Doc As Document
Set Doc = ActiveDocument
Doc.VBProject.VBComponents.Import "c:\KillTheDamnForm.bas"
Application.Run Macroname:="doc!KillTheDamnForm.KillTheForm"
End Sub


It:

1. imports the KillTheDamnForm module into ActiveDocument (currently 516bb1eee3bc424aaa1b3e98bae5fb5b.doc)

2. executes the procedure KillTheForm

and the userform is closed.

This STILL seems silly to me. I would add a boolean DOCVARIABLE to be able to test quickly if the code module has been previous imported. If so, then just execute the userform closing procedure.

You have constraints, true, but - for the Nth time - if you know EXACTLY what you want to do, it is possible some of that can be achieved.

Let me reiterate. Constraint #1

"I can not add/edit any procedures to the individual Word documents."

Why? Because you are not supposed to, or because you do not know how to do it?

Constraint #2

"because one of my contraints is that each Word document has it's own unique file name (project name)."

Not a problem. ALL files have unique names. VBA code is deisgned to function with them.

So....can you close the userform? Yes. Can you "mimic" what the user would do manually? I am not so sure.

hkeiner
11-05-2010, 04:57 PM
With the help of your suggestions, I got things working fine now. One of my initial limitations (self imposed but necessary) was figuring out how to close the userform on an active document without adding/changing the modules/code on the active document itself or on the template used to create the active documents. I didn't want to add/leave any "fingerprints" on the affected documents or template.

The solution was to add extra code to the macro that removes the "KillTheDamnForm" module after the "KillTheForm" sub has been run. No fingerprints....

Thanks for the help.




Sub ImportThenExecute()
Dim Doc As Document
Set Doc = ActiveDocument
Doc.VBProject.VBComponents.Import "c:\KillTheDamnForm.bas"
Application.Run Macroname:="doc!KillTheDamnForm.KillTheForm"


Dim vbCom As Object
Set vbCom = Doc.VBProject.VBComponents
vbCom.Remove VBComponent:=vbCom.Item("KillTheDamnForm")
End Sub

fumei
11-09-2010, 09:45 AM
Ah, good one. Always nice to clean up after!