Excel: require Power Query add-in load from VBA macro - excel

The scenario is a Windows Server 2012 R2, 64 bit; Excel 2010, 32 bit. Many users, just a couple of them have administrative privileges. I installed Power Query from the built-in administrator. Without asking anything, the add-in got installed for all users; I mean that its settings may be found in a registry key under HKLM, not HKCU.
The key is
HKEY_LOCAL_MACHINE -> SOFTWARE -> Wow6432Node -> Microsoft -> Office -> Excel -> AddIns -> Microsoft.Mashup.Client.Excel
and the relevant value is
LoadBehavior (REG_DWORD)
Now just a few users really need Power Query. I don't want it to load for everybody, everytime Excel is launched. I tried some different settings for the LoadBehavior value (see this link). I found the following:
If LoadBehavior = 2, the add-in is not loaded for any user, no way.
If LoadBehavior = 3, the add-in is loaded for all users. However, if I create a specific key for a specific user (in the registry), the user can disable the add-in from Excel. E.g., in HKEY_CURRENT_USER, the path for the key is:
Software -> Microsoft -> Office -> Excel -> Addins -> -Microsoft.Mashup.Client.Excel
More specifically, it is sufficient to put in the user's key the LoadBehavior value, and this allows the user to decide whether he wants the add-in loaded or not. A value of 3 means "Load", a value of 2 means "No load".
I need exactly the opposite: add-in normally not loaded, and some users allowed to load it. I found that it is possible to set the LoadBehavior in the HKLM to 9. This means "Load on demand". I.e., the add-in is only loaded when the user requires an action depending on the add-in itself. Quite fine for me.
At this point I may leave out the key for specific users (in HKCU, e.g.). However, I found out that if I create it, it takes precedence over the HKLM (when the latter has LoadBehavior = 9). So it is possible to decide, for specific users, to have the add-in on "Always Load" mode. Just set LoadBehavior = 3 in the key under HKCU.
All this seems fine. Now the problem is that I need to call some Power Query actions from a VBA procedure. If Power Query is already loaded, all is fine. But if it is not loaded, even with the "Load on demand" setting, the action fails. In order to get Power Query loaded, one has to press some button on the Excel GUI which calls a Power Query action.
I found that there is a property of the add-in object available in VBA which indicates whether the add-in is loaded, and may be set to load or unload it from VBA. It is:
Application.COMAddIns.Item("Microsoft.Mashup.Client.Excel").Connect
If it is True, the add-in is loaded, and if it is False, the add-in is unloaded.
Now it should be possible to load the add-in just by setting this property to True. However, this is not the case in my scenario: the result is an error (80004005). This seems a problem related to the user not having administrative privileges. See this page - this behavior is considered a bug.
My last idea, which I will try later, is to completely remove the LoadBehavior in the key under HKLM. I already checked out that this prevents users from seeing the add-in, unless the user-specific key is created, in which case the user can set the add-in load behavior autonomally. I will see what happens in this case when the load is requested from VBA.
Meanwhile, I'd appreciate any idea to solve the thing: having Power Query not loaded normally, possibly available on demand for all users, loaded automatically from VBA (at least for some users), and all this without having to manually add the user-specific key for all users. It is acceptable to add this key for a few users, those who actually need Power Query.
EDIT
Removing, or renaming, the LoadBehavior value in the key under HKLM works. Power Query is then only seen by users who have a specific key under HKCU. If, in this key, the value of LoadBehavior is set to 3 (or 2), then the add-in is loaded by default (respectively, not loaded). The VBA instruction to change the .Connect property works fine; it switches the LoadBehavior between 3 (True) and 2 (False). Luckily, I can also set LoadBehavior = 9 in the registry (under HKCU), and the .Connect property is still writable. In this situation, when this property is assigned a True value the add-in is loaded, but the LoadBehavior value stands still at 9, so that upon closing and re-opening Excel the add-in is unloaded, is set as "Load on demand", and may be loaded from VBA.
This is exactly the behavior I was looking for; the only caveat is that the key needs to be created for all users who need Power Query. Since in my situation they may be counted on one hand's fingers, this solution is acceptable.
I'm still curious to see whether anyone comes out with any better solution.

Have you considered using a powershell script to update the registry entries for each user accordingly? The following example is a bit complex, line 111 has the loop you need to set it for many users.
https://daniel.streefkerkonline.com/2014/04/09/re-enable-microsoft-office-add-ins-with-powershell/
My other recommendation is you should not use VBA in Excel 2010 to call anything PowerQuery related. Given how it is an add-in I don't think it's included in the service agreements for Excel 2010. VBA interaction with PowerQuery was not fully supported in Excel 2010 or debugged. I noticed in several patches broke the GUI in PowerQuery altogether. Upgrading to Excel 2013 or 2016 was the fix.
When using Excel 2016 VBA editor to interact with PowerQuery, the macro code is challenging to debug and get working, and its references are poorly documented. It's more stable to show you an error and not just crash but it's very challenging to troubleshoot the errors the compilers find.

Related

Excel changes loadbehaviour of add-in

I created an Excel VSTO add-in, which users can install. However, after using the add-in, the next time Excel is started, the add-in is no longer loaded automatically.
The user can resolve this by enabling the add-in, but it happens every time, and I would like to stop that.
What happens is that in te registry, the key:
HKEY_CURRENT_USER\Software\Microsoft\Office\Excel\Addins\TiaGenerator\LoadBehavior is set to 2, which means inactive by default. I can change it back to 3 (load on startup), but after running Excel, it is changed back to 2.
Edit:
As #Cindy Meister said: Excel should change load behavior to 3 after startup, so there must be a problem. After some searching, it turned out the problem lies within the constructor of a self made class called ErrorWriter. The problem seems to be within this call:
Public Class Errorwriter
Inherits IO.StreamWriter
Sub New()
MyBase.New("C:\tmp\newLog.txt")
End Sub
End Class
Does anyone know why this causes Excel to change the load behavior?
Thanks to the comment of #Cindy Meister, I was able to dig a little bit deeper and here is what I found:
Apperantly, Excel changes the load behaviour of an Add-in if it encounters an unhandled exception during startup.
In the startup routine, I create a new instance of an 'ErrorWriter' object, which inherits from 'StreamWriter', and uses a reference to this file.
What happens is that Excel is loaded, an locks this file. Upon using some functions of this add-in, a second Excel instance is started in the background, which tries to use this file as well. This results in an unhandled exception, but because this second instance is not visible, this error is never shown to the user (nor the programmer).
Because the ErrorWriter is not needed in the second instance of Excel, it never becomes clear that the error occeured in any way.
This causes Excel to change its load behavior.
It is fixed by moving the offending code into a seperate function, which is only called upon invoking add-in functions.
I have thoroughly investigated the problem and found a solution. Changing the "LoadBehavior" is the right way of doing it, but you have to be careful about one thing. Both Outlook or Excel restore the previous settings for each add-in. BUT not at the start of the add-in but AFTER the add-in's start up.
In other words if you attempt to change the LoadBehavior in Windows Registry as part of the startup it will never work. You have to do it afterwards.
I hope this will help.
Thank you, VJ

How do I enable an Excel Automation Add-in through the registry?

I have an Excel Automation Add-in that is registered with COM by my installer. By registering with COM, my add-in appears in the (for Excel 2007) Excel Options > Add-Ins > Manage Excel Add-Ins Go... > Automation list. The users must still navigate to the dialog above and select my add-in to enable it.
Is it possible (via a registry key perhaps) to enable my automaton add-in programmatically in my installer class (or in VBA) after the types are registered with COM?
Thanks in advance - Frank
Ive not done ths specifically, but a reference that I use has this to say regarding your question:
Automation Add-Ins are loaded in the same way as normal .xla Add-Ins , but using the ProgID instead of the file name, as in the following code:
Sub installAutomationAddIn()
AddIns.Add Filename:="Excel2007ProgRef.Simple"
AddIns("Excel2007ProgRef.Simple").Installed = True
End Sub
If you are creating an installation routinefor your Add-In, you may want to write directly to the registry in order to set the Automation Add-In as installed. To do so, you need to create the following registry entry (Which will already exist if you've used the above code).
(In the Registry Key:)
HKEY_CURRENT_USER\SOftware\Microsoft\Office\12.0\Excel\Options
(Create the string value:)
Name = the first unused item in the series: Open, Open1, Open2, etc.
Value = /A "Excel2007ProgRef.Simple"

ssis excel source cannot acquire connection manager at DESIGN time

I have an SSIS (super)package that consists of several (about) 40 packages, each of which has several data flow tasks, most of them loading some excel data to a sqlserver database. So I have several excel source connection managers, one per excel file.
This has always worked fine until recently : I have to change an excel source in one of my packages (a column was added in the excel which has to be loaded in the destination sqlserver table) but I cannot edit the excel source in SSIS : when I click on "columns" I get an error box "DTS_E_CANNOTACQUIRECONNECTIONFROMCONNECTIONMANAGER". So this is a design time issue, not a run time problem. I've seen a question like this one on stackoverflow but no answer. Anyone has an idea ?
I' ve already removed office 2007 and reinstalled office 2003 on my machine, but this didn't help
it has nothing to do with 64bit mode, which I've read about here
Is there some limit on the number of connection managers in ssis ?
Most of my connection managers were created with copy/paste and hence they have the same Id, although they point to different excel files. Could this be a problem ?
I should also mention that the package runs without any problems, so it's only "editing/changing" the package that doesn't work. For the moment I circumvent this problem by disabling the data flow that should change and by replacing it with a sql statement that hardcoded inserts the data from the excel into the destination table.
Maybe another intersting thing to mention : I can create a new package and add and change excel sources without problems, but then again, when I try to copy this excel source in my package, I cannot edit it.
Did you try to check the advanced options on the Source Connection?
Right click on the component and select "Show Advanced Editor..."
Select the column mappings tab and press the Refresh button.
This should point out that the XLS connection has some additional columns or that the file that you are pointing at, cannot be pre-validated at runtime.
M.
I'm not sure if this will work but try the Work Offline option in the SSIS menu in BIDS/VS. What this should do is not validate the connection before you edit the component. It might be able to get you into the component.

must capture document properties for word, excel and powerpoint documents

I am new to VBA and this area. I would like to capture the document proporties like (document title, subject, author, team, manager,company etc...) while create or saving the document. This properties capture is must and i would like to implement to all the Word, Excel, Powerpoint users in my company.
How this can be possible. If I wrote a macro, is it possible to deploy all the MS-Office users. or a VB program will do?.
All i need is to make mandatory to input document properties for all the documents. these properties can also be fetched from a template file from the user machine.
Is this possible in VBA or any other easy ways to do it.
To force users to fill in all the properties before saving the document, you can create add-ins (one for each of Excel, Word and PowerPoint) that intercept the "before save" event and check the document properties. If the add-in detects some properties that have not been filled in, it can prompt the user and cancel the save.
The means by which you can create an add-in is similar (but not identical) across the 3 applications. You would of course also have to ensure that the add-ins were installed on all your users machines.
If you just want to be able to read (or modify) the properties, you can use the Office Document Property Reader to read and write properties of Office documents, without even needing Office installed. That works across all Office applications.

ms office file extensions

I made a discovery some time back. Just follow these steps:
Create a .doc/.xls/.ppt file in office 2003. Keep some test data in there and close the file. Now rename the file to change it's file extension to a random string, taking care that it is unassociated, like test.asdfghjkl etc.
Double click the file and it opens seamlessly in the parent application.
Now AFAIK, windows checks the file extension of the file and uses it to do an action, viz open an application and pass the file to it to open. Then how does the office suite manage to do this?
EDIT: How about the case when the extension is changed to one that is associated with another application. Is there a priority algorithm in place for handling that ?
Do you have the "View extensions for known types" option on?
EDIT: #Comments....
Yes, its a stupid/insulting question, but when troubleshooting a problem I have learned to assume nothing, and trust the users 0%.
BUT, I tried it, and you're right. Its stupid that MS has this kind of behavior, and it can only lead to security vulnerabilities, which led me on a search for your answer.
From the posts at http://seclists.org/fulldisclosure/2007/Jan/0444.html
"You have stumbled on an age-old
quirky behavior of Windows. Office
document formats are based on a
standard Windows container format, OLE
structured storage files, also known
as "docfiles". A docfile's name and
extension are irrelevant - the file
is, conceptually, a serialization of
an OLE object, and like all
serialization formats it contains the
identifier of the application that
produced it, in the form of an OLE
class id (in GUID format) in this
case. You can easily verify that it
doesn't work with the newer Office XML
formats"
Indeed it doesnt work for the 2007 *X file types, but 2K3 is still a problem. To solve this problem... Upgrade! =)
And here at security focus under TOC point 2.
So, there you go.
I can't seem to make this happen now, but I know I saw Windows reading XML processing instructions a few years back. Maybe that is what's going on?

Resources