Populate fields in VB6 executable from MS office VBA - vba

I'm developing a VB6 standalone application that I'd like to be able to call from VBA modules running in Excel, Outlook, etc. Ideally, I'd like the VBA module to check whether the VB6 application is already running, if not, open it, then populate certain controls (textbox, listbox, etc) in the VB6 application with information from the VBA module. Is this even possible? Can I just create a reference somehow to the VB6 application, then treat it like any other object? Thanks for your help!

Make the Vb6 app into an ActiveX Exe project. Here's the VB6 manual tutorial on creating an ActiveX exe. Add a reference to the vb6 from the VBA code. You will be able to call into objects in the Vb6 from your VBA.
Use GetObject to instantiate a Vb6 object from the VBA. That will connect to any existing instance of the vb6 app, or start a new instance if necessary.

You cannot do as you describe and treat the VB6 app like and object but you could do it in the following way:
Use the FindWindow API call to determine if the VB6 application is running
Use the Shell command to start it
Use AppActivate to make VB6 window active and SendKeys to send the data to it
That would be the simplest "out of the box" solution. However, this will be quite brittle. For example, if you removed controls from the VB6 form or changed the tab order of the controls, your app will malfunction!
Another option is DDE but I think the DDE link is intended to go from the VB6 app to Word or Excel, not the other way around.

Related

Cannot create VB6 ActiveX dll

I am trying to create a simple VB6 ActiveX exe and call it from Excel.
In VB6 I create an ActiveX DLL project called BigTrev, using all the default settings.
I create a MultiUse class called Trev with a single method containing no code
Public Sub HelloWorld()
End Sub
I make a DLL and register it from the command line (VB6 also registers it for me but I did it using cmd as well anyway).
Then it Excel I create a reference to my DLL in a new workbook. It clearly has been registered because the Intellisense knows about Trev and HelloWorld.
Sub cats()
Dim derek As BigTrev.Trev
Set derek = New BigTrev.Trev
derek.HelloWorld
End Sub
It compiles in Excel, when I step through it it fails in the second line, the Set one. Error message is "ActiveX component can't create object".
Why? I have done this or similar loads of times many years ago when VB6 was used widely, I am using Windows 7 now and I am an admin on my box.
I would suggest registering the DLL (or EXE if that's the direction you've chosen) with the relevant regsvr32.exe. In this case, where you're registering a 32bit DLL for use in 64bit environment, use the one hiding out in c:\windows\syswow64.
Sadly, I don't have Excel (shock, horror) and the spreadsheet I do have (LibreOffice) is 32bit.

Excel Interop in .Net - Catch VBA errors?

Similar to Errors when calling certain Excel VBA macros from C#, I want to implement an error handler that will catch VBA errors and return gracefully.
Basically, I'm opening up an arbitrary macro workbook in Excel, and if the macro fails (i.e. you get a VBA error dialog with "end" and "debug" buttons), I want my application to handle it internally instead of using the VBA's dialogs. This is primarily so that a buggy book won't freeze processing (I'm using a queue of sorts to process multiple workbooks).
I already know about the DisplayAlerts=False property, and On Error Resume Next inserted into each routine, but I don't want to need to inject this into everything (especially since some of these workbooks may already modify the mentioned settings and reset them mid-routine!)
My best idea so far is to write up some sort of process watcher that looks for windows titled "Microsoft Visual Basic" and sendkey an "E" (to click the end button).
I've read in a few places that there's a property called Application.BreakOnVBAError that can be set to False, but it doesn't seem to exist in the interop assembly.
With the help of pinvoke.net and MWinAPI, I've been able to enumerate all of the windows created under Excel's process ID, which I can then drill down into to discover the elements of the dialog (if it's a dialog such as the Microsoft Visual Basic dialog).
Since it's an automated instance, the main window is hidden so the only thing that should show up are message boxes and the VBA error box, which I can then send keyboard input messages to to End the script when necessary.
Of course, this method never hits the "Debug" button so I should never see the VBE windows, but just in case I handle that too.
Source code available upon request?

Deploy Outlook UserForm

I made a userform to give out to colleagues.
The installation procedure goes approximately like this:
allow unsigned macros
open VB Editor
add 2 references by manually navigating to the .ocx / .tlb files (needed for Treeview control)
import form
create a new module
copy a procedure into that module (hook for button, contains essentially MyForm.Show)
run another proc to create toolbar button
save, restart
My plan was to make an install script; but I found Outlook's VBProject is sealed tight against any automated access.
How can I make that installation procedure simpler?
As microsoft wrote here:
https://support.microsoft.com/en-us/help/290779/managing-and-distributing-outlook-visual-basic-for-vba
If you are developing a solution that you intend to distribute to more than a few people, you should convert your VBA code into an Outlook COM or VSTO add-in or an Office add-in for Outlook.
Outlook macros are not made to be deployed so you will always have troubles deploying them to users as they will need to make too much actions as you described.
To avoid that, I recommend you to look at VSTO add-ins and ClickOnce. Here are the links:
VSTO
https://learn.microsoft.com/en-us/visualstudio/vsto/getting-started-programming-vsto-add-ins?view=vs-2019
ClickOnce deployment
https://learn.microsoft.com/en-us/visualstudio/vsto/deploying-an-office-solution-by-using-clickonce?view=vs-2019

Calling VB.NET code from Excel

I open an Excel workbook from VB.Net and then want an event in the workbook (such as pressing a button) to activate code in VB.Net. How do I accomplish this type of callback?
Make the .Net assembly act as a COM object which is quite easy to use from VBA.
See this page for a comprehensive example:
http://richnewman.wordpress.com/2007/04/15/a-beginner%E2%80%99s-guide-to-calling-a-net-library-from-excel/

Loading a Vb.net control inside a VB 6 form

I have a user control in vb.net application.
and i have a form in vb 6.
so in my vb.net applciation to this user control i need to mention the vb 6 form as its parent.
Means when i run a vb6 application i should see this user control as a part of that form.
Ahy help appreciated.
Take a look at the COM interop Toolkit.
It allows you to easily create com-visible .NET usercontrols, which can be used in VB6 for instance.
You can try saving it as a dom object in .net
After this, you can open it in vb6 in the menu components.
I've done it with guid class of .net but i donĀ“t know what you and to do, but i think you should try it.
It is actually fairly easy to add some plumbing to a VB.NET User control to expose it via COM as an ActiveX control that can be used by VB6 and other COM clients.
Here is an article describing how to do that:
"Writing an ActiveX Control in VB.NET"