Programatically Install Microsoft Access Add-In Using VBA - vba

Finding information on Add-In development for Microsoft Access is like getting all of your teeth pulled! Yes I've found the couple Managed Add-In Articles written... but could find next to nothing for Un-Managed Add-Ins. I did find one great article which is very old in creating basically an unmanaged .mda project... which I've followed and created a add-in. Now I would like an automated way to deploy this add-in.
I've seen it done from VBA with such tools as Rick Fisher's Find and Replace add-in tool... but can not find a way to do this programatically in Access. I have found lot's and lot's of articles on Excel Add-In's and even Excel Add-In Installation. One such method uses VBA like so:
Sub InstallAddIn()
Dim AI As Excel.AddIn
Set AI = Application.AddIns.Add(Filename:="C:\MyAddIn.xla")
AI.Installed = True
End Sub
Unfortunately Access does not use the same method. If anyone could point me in the right direction I would greatly appreciate it. AND if anyone knows of any books or references that goes more in-depth to developing Add-Ins for Microsoft Access that would be greatly appreciated as well as most of the picking seem slim.

This is just a bad idea. To be honest, I'm not sure where it's even located in the current version of Windows/Office. I have found Word and Excel at the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office, but I have Access installed and I don't see an Access folder there. At one point, Access add-ins were accessible through this registry key:
HKEY_CURRENT_USER\Software\Classes\VirtualStore\MACHINE\SOFTWARE\Microsoft\Office\11.0\Access\Menu Add-Ins
This worked for Office 2003 on Win Vista. But it changes every time Microsoft updates Office/Windows, so trying to do it programmatically would be moot because you would have to update and roll out a database change every time you updated Office or Windows.

If you target the main registry hive there is logic that will put the key in the correct location for you. For example, you never hard code Wow6432Node because that location is automatically managed by 64-bit windows when a 32-bit application tries to use the registry. Likewise, in modern C2R versions of office the registry location is in a really strange place. You don't have to worry about it. If you target the main key from Access, the key will end up in the correct location magically.
If you want to install per user I recommend using the following locations.
Put the file here:
Private Function GetAddinFileName() As String
GetAddinFileName = Environ$("AppData") & "\Microsoft\AddIns\" & CodeProject.Name
End Function
Use this registry location:
Private Function GetAddinRegPath() As String
GetAddinRegPath = "HKCU\SOFTWARE\Microsoft\Office\" & _
Application.Version & "\Access\Menu Add-Ins\"
End Function

Related

How to get full path for Word VBA references

I am attempting to migrate my entire Word VBA project to a back up laptop.
Years ago I had great difficulty finding a number active X dlls that are used for various objects that my my project currently uses. They are all installed and working correctly after performing a lot of research.
When browsing the currently checked references (Tools--References) I see that some of the checked references (that I need and use) show only the top part of the path. I know that many of these checked references will not exist anywhere on my back up laptop (Both Win7, Office 2003)
If I can see the full path, I can go to it, copy it and install it on the back up laptop.
Is there anyway to get the full path??
I really dont want to do what I originally did on my original laptop, run the project, note the complaint that a dll is missing, try to figure out what reference that this dll belongs to, ad nauseum.
Not any help out there on Google for Word, lots of info for Access and excell that dont apply to Word.
Maybe these references are stored in the registry??
Thanks
Note, this project is very extensive, more than 3000 lines of code, integration with AutoIt, SQLite, Home Inspection software. Saves me tons of work.
From: https://www.tek-tips.com/viewthread.cfm?qid=1563159
After referencing 'Microsoft Visual Basic for Applications Extensibility 5.3' you can:
Function ListAllRefs()
Dim my_ref As VBIDE.Reference
For Each my_ref In ThisWorkbook.VBProject.References
With my_ref
Debug.Print .Name, .Description, .FullPath, .IsBroken
Debug.Print
End With
Next
End Function

Best way for Excel workbooks to share VBA functions

I seek advice on how to manage userdefined VBA-functions that are used in several workbooks:
Background:
Over time i have created several Excel workbooks (wbs), each with a slightly different purpose, that are ultimately based on a library of my userdefined functions and class modules (From now on: library). The "master"-versions of the wbs are revision-controlled. The wbs are used by several people.
However, I do not use an addin for the library, and hence the modules and class modules are actually locally present in each wb's specific VBA project. This makes it a nightmare when doing either expansions or corrections, as I have to revisit and implement said alterations in each wb.
Furthermore, in each wb there are unique functions, understood such that those are not intended to be shared. Those functions, however, might utilize the library-functions.
Main-Question: How should one manage vba functions across several workbooks shared by several users?
My considerations/Sub questions:
Should I convert the library to a true addin and discard the local copies in each wb?
How do I tell the users that the add-in is required upon getting a copy of the maser-version?
How does one cope with legacy/local versions/branches that are spread among the users? Both current legacy copys and future legacy copies that might be used for reccuring tasks?
Where should such an addin-in be stored (in a shared folder or something)?
Would it be considered "bad practice" to force load the add-in using the workbook_opensub?
Any advice or guidance in best practice is appreciated.
Edit: I have tried to highlight the main question, please consider the sub questions as my own thoughts on the subject.
Until recently, I had several add-ins that lived on a shared drive. I had the users install the add-in using File - Options - Addins and wrote up the instructions to do it. The copy on the shared drive was read-only. For changes, I would code and test on the dev copy on my machine, then deploy it to the shared drive. The next time the user started Excel, the changes would be there.
Then we wanted more people to have the addins and not all of them had access to this shared drive. Also, people complained when they were off the network that it still tried to connect to the addins. So we went a different route.
We used a program called PDQ Deploy to put the addins in everyone's addins directory, so they had a local copy. We also deployed a script that copied the files from a company-wide shared drive to their addins directory. If they weren't connected to the nextwork, the script would fail silently. Finally, we used group policy to 1) create the registry entries to install the addins and 2) create a scheduled task that kicked off the script every night. Updating every day is overkill, but the files are only a few kbs, so we went with it.
Now I can deploy new versions to the company-wide shared drive and everyone will have the changes the next day (or the day after they're back on the network).
I put my vba stuff on the "personal" workbook (Windows menu : Unhide...) and whatever workbook I am using I can use them from there.
You do have to make sure about knowing which one is acrtive though...

Cannot register an ActiveX control on only one computer

I have run into an odd problem while attempting to register a vendor-supplied ActiveX control on two different computers. On one computer, I can register the part using regsvr32, and then use it in an Access 2007 form with no problems. On the other computer, after I register the same DLL, it is simply not recognized as a valid ActiveX part by Access 2007, or any other Office 2007 program.
The ActiveX part is contained in a single DLL. I am not missing an additional file on one of the computers.
I cross-checked the exact version of the DLL on both computers using md5sum. Both DLL files are exactly identical.
I cross-checked all of the registry entries generated when the part is registered, using the Nirsoft ActiveX Helper utility. The entries are identical.
I checked Access to make sure that the part had a reference entry which pointed to the DLL.
I checked that the location of the DLL was specified as a Trusted Location in Access.
Unfortunately, I am not enough of a COM expert to know whether or not I am overlooking something odvious. Any additional ideas would be appreciated.
OK, total shot in the dark, but we have some computers in our organization the the IT has locked down pretty tight. When we run setup's they run OK and register our ActiveX components, but the first time we run the program it has to be as an administrator. After that the normal user is able to run the program.
You could try a simple VBS script to verify that the control can be created.
Using Notepad (or similar) save the following as test.vbs, and then double click it to run it.
set oTest = CreateObject("<YOUR PROGID HERE>")
MsgBox ("All Done Successfully")
You should get an reasonably descriptive error or "All Done Successfully".
This would at least point to whether its a system wide or Office specific problem.
And if you get an error it may well point to the actual problem.
OTH, if you don't get an error then you probably have an Office installation issue - which could be resolved by a re-install.

VSTO Excel add-in not loading on terminal server

My configuration is windows server 2003 (i'm logged in with admin privileges), office 2003, vtso runtime 2005 se. After installing my addin, all registry keys are in the correct locations and I have given fulltrust to my assembly using caspol.exe. My addin is a application level addin.
When I run excel with regmon and filemon running I can see that excel reads the registry keys of my addin, but I do not see the AddinLoader.dll being loaded in filemon. I get no errors from vsto since it doesn't appear the runtime is even starting up. I've read almost all of the vsto doco on msdn particularly the application addin architecture and vsto runtime overview as well as various other articles and discussions on the topic. I still can't figure out why the runtime won't load on the terminal server.
When installing this on an XP machine it all works fine and my addin gets loaded every time.
Anyone have any idea what might be preventing the vsto runtime from loading?
I had a similar problem with Outlook 2007 on a 64 bit Windows.
I added this reg key and then it worked:
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Office\12.0\Common\General]
"EnableLocalMachineVSTO"=dword:00000001
Keep in mind to update Office 2007 to the latest service pack ( 3 as of now )
Never Mind I found that I was missing some registry keys after all. Got it working now.
For anyone that is looking for an answer to a similar problem then the registry keys you need to make a 2003 VSTO addin load for all users should look something like this:
[HKEY_CLASSES_ROOT\CLSID\{MY-EXCEL-ADDIN-GUID}]
#="MyExcelAddin -- an addin created with VSTO technology"
[HKEY_CLASSES_ROOT\CLSID\{MY-EXCEL-ADDIN-GUID}\InprocServer32]
#="Is vsdrvtEnvironmentString value type with "%CommonProgramFiles%\Microsoft Shared\VSTO\8.0\AddinLoader.dll" as its value"
"ManifestLocation"="C:\\Path\\To\\MyExcelAddin\\"
"ManifestName"="MyExcelAddin.dll.manifest"
"ThreadingModel"="Both"
[HKEY_CLASSES_ROOT\CLSID\{MY-EXCEL-ADDIN-GUID}\ProgID]
#="MyExcelAddin"
[HKEY_CLASSES_ROOT\CLSID\{MY-EXCEL-ADDIN-GUID}\Programmable]
[HKEY_CLASSES_ROOT\CLSID\{MY-EXCEL-ADDIN-GUID}\VersionIndependentProgID]
#="MyExcelAddin"
[HKEY_CLASSES_ROOT\MyExcelAddin]
#=""
[HKEY_CLASSES_ROOT\MyExcelAddin\CLSID]
#="{MY-EXCEL-ADDIN-GUID}"
[HKEY_CURRENT_USER\Software\Classes\MyExcelAddin]
#=""
[HKEY_CURRENT_USER\Software\Classes\MyExcelAddin\CLSID]
#="{MY-EXCEL-ADDIN-GUID}"
[HKEY_CURRENT_USER\Software\Classes\CLSID\{MY-EXCEL-ADDIN-GUID}]
#="MyExcelAddin -- an addin created with VSTO technology"
[HKEY_CURRENT_USER\Software\Classes\CLSID\{MY-EXCEL-ADDIN-GUID}\InprocServer32]
"ThreadingModel"="Both"
#="Is vsdrvtEnvironmentString value type with "%CommonProgramFiles%\Microsoft Shared\VSTO\8.0\AddinLoader.dll" as its value"
"ManifestLocation"="C:\\Path\\To\\MyExcelAddin\\"
"ManifestName"="MyExcelAddin.dll.manifest"
[HKEY_CURRENT_USER\Software\Classes\CLSID\{MY-EXCEL-ADDIN-GUID}\ProgID]
#="MyExcelAddin"
[HKEY_CURRENT_USER\Software\Classes\CLSID\{MY-EXCEL-ADDIN-GUID}\Programmable]
[HKEY_CURRENT_USER\Software\Classes\CLSID\{MY-EXCEL-ADDIN-GUID}\VersionIndependentProgID]
#="MyExcelAddin"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\Excel\Addins\MyExcelAddin]
"Description"="MyExcelAddin -- an addin created with VSTO technology"
"LoadBehavior"=dword:00000003
"FriendlyName"="MyExcelAddin"
"CommandLineSafe"=dword:00000001
Of course you will need to change GUIDs and paths to appropriate values. By Putting the addin keys under local machine instead of current user the addin will work for all users without having to repair the install after running excel for the first time. Also this only lets the office application know the addin is there and that it needs to attempt to load it, this does not give the assembly trust in the system, you need to use Caspol.exe to do that. Read the msdn article about SetSecurty to do this http://msdn.microsoft.com/en-us/library/bb332052.aspx.

Excel 2007 automation on top of a Windows Server 2008 x64

I’m well aware of the Microsoft support base article stating that it’s not supported to automate office products UI less. It seems that Windows Server 2008 x64 and Excel 2007 enforce the given statement.
I’m running the following code in a NT Service (Local System account) OnStart method. All it does is Excel automation the way it’s working when you run the same code in a Console Application.
The provided code has two parts. The first part launches Excel, creates a new work book and saves it to the given filename. The second part launches a new instance of Excel and opens the given file. The open operation ends in this exception:
Service cannot be started. System.Runtime.InteropServices.COMException (0x800A03EC): Microsoft Office Excel cannot access the file 'c:\temp\test.xls'. There are several possible reasons:
• The file name or path does not exist.
• The file is being used by another program.
• The workbook you are trying to save has the same name as a currently open workbook.
Why was the automated excel able to launch and write files to disk but fails when it’s asked “just “ to open an existing file?
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
// launch excel and create/save a new work book
Microsoft.Office.Interop.Excel.ApplicationClass excel = new Microsoft.Office.Interop.Excel.ApplicationClass();
excel.UserLibraryPath, excel.Interactive));
//
string filename = "c:\\temp\\test.xls";
if(System.IO.File.Exists(filename)) System.IO.File.Delete(filename);
//
excel.Workbooks.Add(System.Reflection.Missing.Value);
excel.Save(filename);
excel.Quit();
excel = null;
// lauch new instance of excel and open saved file
excel = new Microsoft.Office.Interop.Excel.ApplicationClass();
try
{
Microsoft.Office.Interop.Excel.Workbook book = excel.Workbooks.Open(filename,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value,
true,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value,
false,
false,
System.Reflection.Missing.Value,
false,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value);
book.Close(false, System.Reflection.Missing.Value, System.Reflection.Missing.Value);
book = null;
}
finally
{
excel.Quit();
excel = null;
}
//
GC.Collect();
The solution is really simple. The msdn forum thread can be found here
To make a long story short I'm posting the solution here, credit goes to H Ogawa
This solution is ...
・Windows 2008 Server x64
Please make this folder.
C:\Windows\SysWOW64\config\systemprofile\Desktop
・Windows 2008 Server x86
Please make this folder.
C:\Windows\System32\config\systemprofile\Desktop
...instead of dcomcnfg.exe.
This operation took away office automation problems in my system.
A Desktop folder seems to be necessary in the systemprofile folder to open file by Excel.
It disappears from Windows2008, Windows2003 had the folder,
and I think it cause this error.
Also like stated in the source, you need to set the correct rights for the Desktop folder.
This worked for me on Windows 2008-64bits and Office 2010 32bits.
Create directory "C:\Windows\SysWOW64\config\systemprofile\Desktop " (for 64 bit Windows) or "C:\Windows\System32\config\systemprofile\Desktop " (for 32 bit Windows)
Assign user "Network Services (Service Réseau)" the following rights for the created folder:
Read & Execute, List folder contents, Read
John.
I've quite often found that calling Quit() isn't enough to release the resources. Try adding: -
System.Runtime.InteropServices.Marshal.ReleaseComObject(excel);
between the Quit() statement and setting it to null.
There are many more errors than the one mentioned that you'll need to work through in order to get Excel working on Windows Server 2007 64-bit. See the steps I worked out after working on this for two full days!
If you are using Apache, you might also need to follow these steps to get MS Word working properly (along with everything outlined in other answers):
Below is a screenshot showing the two dialogs you'll need to bring up:
For Apache:
Services->Apache->Right Click (Properties)->Log On Tab
MS Word:
Launch dcomcnfg.exe->Console Root->Component Services->Computers->My Computer->DCOM Config->Find Microsoft Application->Right Click(Properties)->Identity Tab
**if you can't find the MS Word, make sure you are launching the correct DCOM Config (64 bit vs 32 bit) depending on what version of Office you have installed.
There are two options here, you can set Apache to use Local System Account and check the checkbox to ALLOW desktop interaction. If you do this then you need to set the Identity for MS Word to Interactive User.
Otherwise, you need to set both to the same user (Ideally the user that is logged in) like shown in the picture.