Can I use an Outlook Add-In from macro code? - vba

Is it possible to execute an Outlook Add-In or access it's properties from within Outlook's own VBA code? Or are Add-Ins completely isolated from macro development?
I am trying to extend the use of the Skype for Business Add-In (UCAddin.dll).

No they are no isolated.
Just add a new COM Object (maybe a singleton) that is supported by your addin, with the interface you need. Use CreateObject inside the macro code and you have access to your special interface and the internals of your addin...

If it is your own addin, then yes - your code can access the Application.COMAddins collection, find the addin, and use COMAddin.Object property. Your addin in turn has to expose an object in that COMAddin.Object property - to do that, it needs to set the property on the COMAddin object passed as a parameter when processing the IDTExtensbility2.OnConnection callback.
That being said, I don't think Skype addin exposes anything through the COMAddin.Object property.

See Walkthrough: Calling Code in a VSTO Add-in from VBA.
You must know public APIs available in add-ins. Or follow the contract/interface which is available publicly.

Related

Limitations of Creating Application Objects in VBA

I am curious as to what applications can be manipulated using VBA. I was under the impression that any application can be accessed with VBA by creating an object instance of the application, but I am sure there certain applications that can't.
I have the following questions:
Can any application be instantiated as object?
What would prevent an application from being able to be instantiated as an object?
An application is only controllable in VBA (via automation) if it has an appropriate Component Object Model (COM) interface.
All the Microsoft Office programs have COM interfaces, but it's not a necessary requirement for applications that run on Windows.
For further reading, see What is COM?

Calling Private Macros / UDFs From Another Workbook (Add-In)

This is a follow-up question for my previous question: How Can I Prevent The Suggestion of Custom VBA Functions When Writing Formulas in Excel?
I have implemented the suggestions made in the answer given in order to make my macros and UDFs private, in a way which allows them to be called within other modules in the same workbook but prevents them from being suggested when writing formulas.
I'm trying to produce an Add-In which contains reusable macros and UDFs, and in other VBA projects I am adding this Add-In as a reference (tools > references) so that I can call the functions directly rather than using Application.Run()
By doing this, projects using these reusable functions will be easier to write as the required / optional parameters can be seen at the point of writing the line, and will generally keep the code looking tidier.
By implementing the solution to my first question to make these functions private, the functions are accessible from within the same workbook, however are not accessible to other workbooks.
Does anyone know a solution to achieve this?
If it needs to be accessible beyond the project it's defined in, then it must be Public.
Make macros and UDFs public in a standard code module.
Implement the "utility" code in class modules, and make these classes PublicNotCreatable. Now export these classes and open the .cls file in Notepad.
Locate the VB_PredeclaredId attribute and switch it to True, save and reimport it back in - given class Utilities, a VBA project that references that addin can call the code without creating an instance of the class (it can't New it up anyway), but you can access its public members as you would a default instance of any UserForm class, by qualifying the method with the class name:
foo = Utilities.DoSomething(42)
This is because the PredeclaredId makes a global-scope instance of the class named after the class itself: now you can use that class as if it were a standard module (or a Shared class in VB.NET), and its members won't be available as macros or UDF's.

VBA CreateObject

I am stranded on this code line since 10th of January where i got it in an email and i found out i had to learn class modules so i did and returned to ask on a new basis now. The code line is (Critical Warning: you have to go to Tools--> References in VBE and activate the Microsoft WinHTTP Services, version 5.1 with Early Binding):
Dim WinHttpReq As Object
Set WinHttpReq = CreateObject("WinHttp.WinHttpRequest.5.1")
For CreateObject I go to MS Help and says: Creates and returns a reference of an ActiveX object
Now for all i know, when we create a reference it is for an object only and done like this (please correct me if i am wrong):
Dim ThatIKnow as Workbook
then we instantiate it like this
Set ThatIKnow = Workbooks.Add
Why we need CreateObject?
Help continues by saying "...of an ActiveX object"
And if I go to click ActiveX on the help it points out the glossary that says:
An object that is exposed to other applications or programming tools through Automation interfaces
And this line absolutely tells me nothing. All I knew about ActiveX is this
...which i think are the ActiveX controls... (I must admit though ActiveX was always a foggy term for me)
Now inside the CreateObject("WinHttp.WinHttpRequest.5.1") i have scoured the Web and i cannot find some decent MS help for the WinHttp object and what it does. Anyway the Object Browser has it as library but the F1 help button shows up nothing. So the Object Browser says it's a Library, i have found it in the Web called as WinHttp Reference and also as a WinHttp Object. What is it from all these?
And for the love of God why it is called "5.1"? i didn't found anywhere a WinHttpRequest.5.1 term
i am not asking for chewed up food but any effort to crack the ainigma really tightens the whole situation more. Please any pinch that could help me crack this line of code will be tones of help
thanks for watching my question
I will not cover the difference between Early Binding and Late Binding. You can read about them in this KB Article
What I will do however is answer all your little questions that you have in your question such as
What is CreateObject?
What is an ActiveX Control?
Creates and returning a reference of an ActiveX object - Meaning
And for the love of God why it is called "5.1"?
What is CreateObject?
As I mentioned in the comment above CreateObject is a function which is used in Visual Basic (vb6 and vb.net), Visual Basic for Applications (VBA) and VBScript to dynamically create an instance of an ActiveX control or COM object.
What is an ActiveX Control?
An ActiveX control is a component program object which can be re-used by numerous application programs. The main technology for creating ActiveX controls based on Component Object Model (COM). In general, ActiveX controls replace the earlier OCX (Object Linking and Embedding custom controls).
An ActiveX control can be created in any programming language that recognizes Microsoft's Component Object Model for example Visual Basic and C++
These ActiveX control runs in what is known as a container, for example MS Excel, which uses the Component Object Model program interfaces. In fact this actually helps us all. Imagine writing the code for these controls from scratch every time!
Creates and returning a reference of an ActiveX object - Meaning
Let me explain it in reference to what you quoted.
Dim ThatIKnow as Workbook
Set ThatIKnow = Workbooks.Add
What we are doing by Dim ThatIKnow as Workbook is telling the runtime environment that we will create an object of type "Workbook" and reference it as "ThatIKnow" in our code. However this actually doesnt create the object neither does it allocate any memory. The memory is allocated only when the object is created using the New keyword or any other way such as Createobject and assiged to this variable ThatIKnow
So when we say Set ThatIKnow = Workbooks.Add or Set oXLApp = CreateObject("Excel.Application"), we are actually creating the object in memory.
And for the love of God why it is called "5.1"?
It is because of "God's Love" we evolved from primates which diverged from other mammals. So consider us a Version X of those mammals :D
Yes, Pankaj Jaju is right when he mentioned that it is the version number. Now what is version number and why is it important?
Version control a.k.a source control a.k.a Revision control in simple terms is nothing but management of changes to documents, applications, collection of information etc. Any new change is usually identified by a number or letter code or a mix of it.
This is helpful as it let's us know the current version of that document or application.
For further reading on version control see THIS LINK
Hope I have covered all your questions? If not, then feel free to ask.
Dim WinHttpReq As Object
Set WinHttpReq = CreateObject("WinHttp.WinHttpRequest.5.1")
is almost same as
Dim WinHttpReq As WinHttpRequest
Set WinHttpReq = New WinHttpRequest
The difference is that with first approach you do not have to include the library in the "References" list, but as a price to pay you will not have intllisense hints in the IDE because your reference is generic Object.
Second form is preferable. It allows VB to check object types for compatibility as you assing them or pass them as parameters. It also give you hints which methods and properties the object has as you type its name.

Can I monitor COM calls to my VisualBasic 6 ActiveX control?

I wrote a little ActiveX control in VisualBasic 6 which is going to be used as a plugin for some 3rd party framework. The framework expects that my control exposes a few properties and methods. It all seems to work well except that one of my properties seems to be ignored.
In C++, I could put debug statement into the reimplementations of IDispatch::GetIDsOfNames and IDispatch::Invoke to see which members the framework attempts to access - maybe the documentation is wrong, and it's expecting a different property name or something.
Is it possible to monitor the accesses to COM properties/methods in Visual Basic 6, too?
The easiest way is to add logging of some form in the methods/properties in question. I don't think you can hook the lower level COM calls though.
For the logging, you can use OutputDebugString().
There's a rather old 'Hardcore Visual Basic' book around that teaches you exactly how to implement IUnknown, IDispatch etc. in VB5/6.

intercepting the GetCustomUI callback in a VSTO3 addin

I've got a VSTO3 Word addin that makes use of custom ribbons and taskbars, etc.
Now, Office 2010 comes along and there's this nifty new BACKSTAGE concept, which I'd like to hook into. However, from what I can tell, doing it with VSTO requires Vsto 4, which requires VS2010, which isn't an option.
Soooo. I started looking online and have found all sorts of examples of, essentially, piggybacking the backstage XML onto whatever Ribbon xml I define and returning that as the value of GetCustomUI. All good, except if you're using VSTO3, there doesn't appear to be any way to "hook" into the call chain for GetCustomUI. It's all "automagically" handled for you by the OfficeRibbon and RibbonManage classes.
I know I +COULD+ convert the addin to a shared addin and just implement the IDTExtensibility interfaces directly. I'd lose all the vsto goodness (yeah, that's debatable) but I'd gain access to the GetCustomUI call.
Anyone every tried to get access to GetCustomUI +WHILE+ using VSTO though? Is it even possible?
I thought I could create a wrapper class for RibbonManager, but lo, MS has gone and done what looks to be some supreme violation of encapsulation. The RibbonManager implements the nice and easy IRibbonExtensibility interface, and yet, where that interface is passed around, they actually check the passed object to be sure it's of the actual type RibbonManager! Ugh, so much for any kind of wrapper.
Turns out it's possible, just not easy. You have to override the CreateRibbonExtensibilityObject method on connect, as well as the CreateRibbonObjects, and the RequestService methods.
Then, you have to create an object that wraps the built in VSTO RibbonManager object, and implements iReflect to intercept reflection INVOKE calls and forward them on to the underlying RibbonManager.
Finally, on the interceptor object, you have to also implement IRibbonExtensibility, then code up the GetCustomUI method of that interface.
once you do all that, your GetCustomUI will be called and passed in the full XML of the ribbons you've defined via VSTO, which you can then alter directly (in my case I needed to add backstage support), and then return that xml from the function.
definitely not straightforward, but it works.
If you want to edit XML ribbon at runtime in a VSTO app, I have created a simple solution here: Outlook 2007 ribbon customization in .NET using VS2010; insertBeforeMso dynamic function