AutoItX and VBA

Recommended Posts

dao 0

dao 0

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?

Share this post

Link to post

Share on other sites

zfisherdrums 5

zfisherdrums 5

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).

Share this post

Link to post

Share on other sites

dao 0

dao 0

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.

Share this post

Link to post

Share on other sites

zfisherdrums 5

zfisherdrums 5

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.

Share this post

Link to post

Share on other sites

dao 0

dao 0

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!!

Share this post

Link to post

Share on other sites

zfisherdrums 5

zfisherdrums 5

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.