Jump to content

AutoItX and VBA


dao
 Share

Recommended Posts

I'm using an AutoItX object within VBA to send keystrokes to the parent application. When entered through the keyboard, the keystrokes immediately open another window (from which I want to extract information). After sending the keystrokes through AutoItX, the window is not created until the VBA script has completed. I've tried incorporating a WinWaitActive command to pause execution of the script until the desired window is open but then the code just hangs indefinitely. Is there some way of instructing the parent application to execute any commands in the stack without terminating the VBA macro?

Link to comment
Share on other sites

dao,

I've used AutoITX in Excel VBA before and seem to recall having a similar experience.

I feel at a disadvantage to help because I don't know what Office product you're using.

Can you provide anymore details, code snippets, screenshots, etc?

Link to comment
Share on other sites

Thanks for your response! I'm not quite sure how to include screen shots on this board. I can't seem to compress them enough to fit the 64KB requirement. Anyway, I hope this helps...

I'm working within SolidWorks (CAD software)

The following code opens a "Summary" window (although it doesn't actually extract any information - I've just done this for the sake of explanation):

AutoIt.WinActivate "SolidWorks Office Professional"

AutoIt.WinWaitActive "SolidWorks Office Professional"

AutoIt.Send "!opss{ENTER}" 'Open Summary Window

End Function

The following code causes SolidWorks to hang (because the Summary window doesn't appear until the VBA script exits):

AutoIt.WinActivate "SolidWorks Office Professional"

AutoIt.WinWaitActive "SolidWorks Office Professional"

AutoIt.Send "!opss{ENTER}" 'Open Summary Window

'DoEvents

AutoIt.WinWaitActive "Summary"

As you can see from the code above, I've also tried (as a "Hail Mary") to issue a DoEvents command but it was no help. Any suggestions you may have would be appreciated.

Link to comment
Share on other sites

dao,

I'm afraid I don't have any experience with Solidworks Office Professional. But I used your example code to do a little prototyping in Excel VBA. In doing so, I was reminded of a peculiarity that might be happening in your case.

It occured whenever a function that performed window-related acivities (focus, kill, wait, waitActive, etc) was run from the VBA editor. It appeared that the VBA editor would steal focus after interpreting each line. So a command would execute, then VBA Editor would steal focus, and any command(s) I was sending to what I "thought" was the active window ended up being sent to the editor.

I'm attaching an Excel Spreadsheet to demonstrate. When it opens:

  • Click the button in Sheet1.
  • You should get a Style dialog box, provided your "ALT-O-S" sequence navigates to that menu item.
  • Now open up the VBA editor by pressing Alt-F11.
  • If you open the code-behind for Sheet1, you'll see that the click event calls the Test subroutine directly.
  • Now, open Module1.
  • Click inside the Test subroutine and press F5 to run (or just type 'Test' into the Immediate Window).
  • Chances are a menu will appear inside the VBA editor.
The same code ran with 2 different results. The only difference was running the code from the editor.

(note: you may need to enable macros to use it. The workbook also references the AutoItX3.dll via Tools>References).

Let me know if this helps you at all!

Zach...

VBA_with_AutoItX.zip

Edited by zfisherdrums
Link to comment
Share on other sites

Very interesting. The slight difference with what I'm seeing is that the command is actually issued to SolidWorks rather than the VBA editor. I can tell because when I kill the hanging VBA (AutoIt) process, the desired window finally opens up in SolidWorks. Its like the command exists in SolidWorks' message queue (?) but the application doesn't actually process the call until VB releases control. That's why I tried to use the DoEvents() command in the hope of processing the call in SolidWorks. To work around the VBA environment, I even tried to call an external AutoIt script using a synchronous shell within VB to do the AutoIt functionality. Unfortunately, still no luck.

So... the question of the day. Can you think of some workaround for this? Can I use any of the process control features in AutoIt to correct the problem? Otherwise, I think I'm out of luck automating the task that I was hoping to simplify. :)

Thanks for looking into this for me. I really appreciate your feedback.

Link to comment
Share on other sites

dao,

After looking at it again, I was able to replicate your bug. I'll be looking into it some more.

Right now, I'd have to agree with your observations. The VBA environment appears to assume control of the process and any functionality native to the main application seems to wait until the VBA environment is done with its processing. By using a timeout parameter of 5 seconds in the WinWaitActive function, I was able to observe that the desired window did not appear until after 5 seconds. I then tried to check for the existence of the window using WinExists, but that was blocked as well. This would explain why the synchronous shell call did not work either.

It looks like the only viable ways to effectively automate the tasks at hand are either:

A.) Step outside the application/VBA environment paradigm.

If AutoIt is your choice for automation, you may have better luck scripting the activity from outside the process by writing stand-alone scripts. However, I think a better solution may be...

B.) Script application-specific functionality using VBA.

The VBA environment should be setup to integrate seamlessly into the SolidWorks application. Is there any documented object model for SolidWorks? A quick search on Google Web yielded this. Google Groups yielded even more specific hits on using the API with VBA. This came from the Solidworks website.

Finally, when I was starting out I used Excel's macro recording functionality to reverse-engineer the object model and learn how to script the calls to the needed functionality. Perhaps a combination of this and the links above could yield a potential solution.

You seem to be a bright individual, dao, and I pray that these suggestions did not come off as condescending. Let me know if there's any more I can help with.

Zach...

Edited by zfisherdrums
Link to comment
Share on other sites

Actually, the macro I'm calling from SolidWorks already makes extensive use of the SolidWorks API. Unfortunately, I'm trying to automate the functionality of a third-party add-in for SolidWorks that, you guessed it, has no API.

Having said that, I think you've nailed the solution in part A)! My SolidWorks macro also references an Excel spreadsheet. Therefore, rather than calling Excel from within SolidWorks, I could just as easily connect to SolidWorks from within Excel VBA. That way, if the VBA for Excel environment is "busy", it should be no problem when processing SolidWorks commands. Brilliant! Thanks for the advice!!

Take care,

Dave

Link to comment
Share on other sites

Dave,

Glad I could help.

Just one word of advice when using Excel VBA with AutoItX to automate external apps: Make liberal useage of time-outs and fault detection.

I had so many nightmares where I would code a new feature and test it only to have a synchronous call get "stuck" with no way out but to kill the process. Obviously, these are beginner's mistakes and I wouldn't mean to imply that you'd make them. But whenever I automated external apps from within Excel VBA - this scenario got me more than once.

Take care and great luck!

Zach...

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...