-1

I'm trying to control Word using a Python3 script using win32com. I've imported a VBA UserForm, and am trying to show it but receiving an error. Some code:

from win32com.client.dynamic import Dispatch
from win32com.client.dynamic import ERRORS_BAD_CONTEXT
import win32com.client as win32

app = win32.gencache.EnsureDispatch('Word.Application')

app.Visible = True        
app.Documents.Open('.../'+current_doc+'.docx')                

try:
    app.VBE.VBProjects(1).VBComponents \
        .Import('.../UserForm1.frm')
    app.Run('UserForm_Initialize()')

The script succesfully imports the UserForm, but upon attempting to initialize, it is throwing this error:

com_error: (-2147352567, 'Exception occurred.', (0, 'Forms.Form.1', "Can't move focus to the control because it is invisible, not enabled, or of a type that does not accept the focus.", 'fm20.hlp', 0, -2147352573), None)

Does anyone know a way to initialize the UserForm successfully? I can't use an alternative to using a VBA UserForm unfortunately, as that part is already written entirely.

Thanks!!!

Note: I've verified the app.Run() command is correct by also separately importing a module to call the UserForm, and running it. Same error. However, if I then open the VBA console and run the same module, it successfully opens the UserForm.

5
  • I'm feeling a bit out of depth here but it seems to me that you are calling an initialize event without qualifying which form you wish to initialise. Commented Oct 9, 2018 at 22:48
  • My apologies, I should clarify that while the UserForm_Initialize() sub I'm trying to call is uniquely named, you're right that I'm not using full context when I call it. From some Excel examples, I've tried things like: UserForm1.UserForm.Initialize() ..without any success. Commented Oct 11, 2018 at 12:58
  • I found a comment on another ask stating that the 'can't move focus' error is actually more like an 'out of range' error, so I think you're probably right that I'm not calling the script in the right way. Commented Oct 11, 2018 at 13:04
  • Try UserForms(Name).Userform_Initialize. I found this snippet here stackoverflow.com/questions/13964780/… Commented Oct 12, 2018 at 8:22
  • That's a good reference. I've updated my question with an answer based on it and some other options I was able to rule out. Thanks! Commented Oct 15, 2018 at 0:19

1 Answer 1

0

I have a working solution now. After importing the UserForm as before, I import an initialization module:

Sub init()
    UserForm1.UserForm_Initialize
End Sub

After that, I use the app.Run() to call this script, which in turn calls the UserForm:

app.VBE.VBProjects(1).VBComponents.Import('.../UserForm1.frm')
app.VBE.VBProjects(1).VBComponents.Import('.../init.bas')
app.Run('init')

The important difference to what I was trying before is leaving '()' off the .Run reference to the init() Module. Thanks to Steven Laycock above for the reference and reminder.

As an alternative, I also attempted to call the UserForm directly from the program using the reference above, something like:

app.VBE.VBProjects(1).VBComponents.UserForms('UserForm1').UserForm_Initialize

but had no luck. Since I have a working solution, I won't be researching the direct call any further.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.