Creating objects with late binding causes ActiveX runtime error 429 depending on file folder location - excel

I have come across a strange behavior in Excel VBA when creating objects using late binding.
System information:
Windows 10 Enterprise Version: 1803
Office 365 MSO (16.0.11126.20192)32 bit
Problem description:
I have an empty Excel sheet with a macro:
Option Explicit
Sub test()
Dim ob As Object
Set ob = CreateObject("Scripting.Dictionary")
End Sub
Running this macro gives me
Run time error '429': ActiveX component can't create object
Depending on the folder where I store the macro enabled Excel file.
Folders where I can run the macro without errors
my one drive folder: C:\Users\myusername\OneDrive - MY Company Name\
all the subfolders inside this one.
Folders where errors occurs
C:\Users\myusername\
C:\Users\myusername\Desktop\
Shared network location ex: \xpto\xpto1\
C:\Temp\
C:\Q\ folder I created where I tried to mimic the same access rights as in the OneDrive folder where the macro works.
If I use early binding with the correct references the problem is not there anymore!
I tried following some steps in: https://support.microsoft.com/en-ca/help/828550/you-receive-run-time-error-429-when-you-automate-office-applications.

Related

How to work around Excel 2016 halting without message when trying to assign variable to VBProject?

System Details.
Windows 10
Excel 365 64-bit V16.0 (Apps for Enterprise)
Issue.
I have a macro that opens a file, checks if the user has allowed programmatic access to the VBA Project in the trust center and raises an alert if they have not. This works fine on windows 7 machines with both 32bit and 64bit Excel from 2013 onwards.
The specific problem I am having on the Windows 10 machine is that when workbooks.open(path) is executed the file opens but in the VBA Project explorer window the VBAProject object for that file does not appear. I also get a popup saying that code cannot be run in break mode when I try this while stepping through the code. When run on Win 7 with this version of Excel and others both 32 and 64-bit the VBAProject object appears and no popup is generated.
This lack of the VBA Project causes an issue later when I run set vbproj = ActiveWorkbook.VBProject. At this point when stepping through the code execution halts with no messages at all. The Project pops up in the Project explorer window and it takes me to a module in the opened workbook. This gets opened with Design Mode turned on and when you click to turn it off I get an error message saying 'Macros have been disabled'
Notes
set vbproj = ActiveWorkbook.VBProject works fine if the file is open and the VBAProject is visible in the Project explorer window.
If the file being opened does not contain a macro then it works correctly.
I have made sure that the files are in a Trusted Location.
I have set Enable all macros in the Macro Settings of the Trust Center.
When opening the files manually I do not get any alerts that macros have been disabled by an administrator and I do not get any message asking if I want to enable macros.
I have looked at W10 group policies to see if there is one that would block VBAProjects / Macros from files opened via VBA and there does not appear to be one as far as I can see.
The Trust Center setting for programmatic access to the VBA Project does not matter to this test case. It will return True if it is allowed and False if it is not allowed.
This has been tested on another Windows 10 laptop with the same version of Excel 64-bit and it has the same result so is not an issue with a specific users laptop.
I removed the folder from the Trusted Location on the Windows 7 machine and the code still executes correctly and returns True/False.
In the actual macro this check is done for each opened file in a loop and the variant vbproj is used to remove data from the modules within that project. I have considered working around the issue by using Application.onTime and that may be a solution but have not spent much time on that and with how it halts it may not be viable.
Attempted Solutions
I have tried set wb = workbooks.open(path) to open the workbook and then using set vbproj = wb.VBProject but it has the same behavior as above.
I have tried doing ActiveWorkbook.Activate and similar actions to see if that will make the VBA project appear, it does not.
I have tried setting Application.FileValidation = msoFileValidationSkip before opening the file, this does not change the behavior.
I have tried setting Application.EnableEvents=False before opening the file, this does not change the behavior.
I have tried making vbproj a variant, an object and a VBProject, this does not change the behavior.
Steps to Recreate
Create a new workbook.
Put the below code into Module 1.
Function projectAccess()
Dim vbproj As Variant
On Error GoTo noaccess
Set vbproj = ActiveWorkbook.VBProject 'If access is denied an error is raised.
projectAccess = True
Exit Function
noaccess:
projectAccess = False
End Function
Sub openfile()
Dim filepath As String
filepath = Application.ThisWorkbook.Path
Workbooks.Open (filepath & "\openfile.xlsm")
Debug.Print projectAccess
End Sub
Save the workbook
Create a 2nd workbook, in my case it was called openfile.xlsm and put some code into Module 1.
put both workbooks in the same location and make sure it is a Trusted Location in Excel.
run openfile().
If successful the immediate window will display True / False depending on the Trust Center setting.
I am out of ideas. Any suggestions for some setting that I may have overlooked to make the Win 10 machines behave the same as the Win 7 machines or suggestions for a possible work around?
Even if it is a group policy setting that would be something I can raise with IT as long as I know what to ask for.
Many Thanks
Andrew
EDIT: Thanks to Rory in the comments the issue was making sure that the automation security was set like so Application.AutomationSecurity = msoAutomationSecurityLow as the way the new Win 10 + Office 64 systems have been set up by my IT dept is to have it default to msoAutomationForceDisable

Changing the location of a referenced library

I have a C# Library which I use in an Excel VBA project. I wish now wish to restructure my project and want to move the library to a different folder. However after removing the reference to the library and deleting all instances of the library from my computer, the References Available box for the project still shows the reference to the old library location even though it no longer exists on the computer and nothing I do seems to be able to remove that reference.
I don't know if this makes any difference, but the project is an Excel AddIn.
I had this problem back in 2019, and received a response to a question with the same title in April 2019. On that occasion the the issue was resolved by following the advise given. However this time the system stubbornly refuses to play ball.
The procedure that I was advised to follow in 2019 was:
Remove the reference
Save the File and close it
Delete the dll (in my case the .tbl) file from your computer. Do not save it anywhere.
ReOpen the file
Check if there is any reference still there. If not copy the dll to a new folder and then set a reference again. Save and close the file.
ReOpen to check if everything is OK
I was going to try code to remove the reference, but the following code did not find the reference
Sub delRef()
deleteReference ("FiskDLLlib")
End Sub
Sub deleteReference(s As String)
Dim oFs As Object, oReferences As Object, oReference As Object
Dim sFileName As String, sRefName As String, sRefFileName As String
Dim toBeDeletedRef As String
Set oReferences = Application.Workbooks("fiskAIWkBook.xlam").VBProject.References
For Each oReference In oReferences
sRefFileName = oReference.FullPath
sRefName = oReference.name
If sRefName = s Then
toBeDeletedRef = s
Exit For
End If
Next
If toBeDeletedRef <> "" Then
Debug.Print oReference.FullPath
Else
Debug.Print "No Reference found for " & s
End If
End Sub
Similarly the Watches panel didn't show the library.
I have subsequently discovered a registry key
\HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TypeLib{B22F6C9D-53E0-4D1B-9596-56AA1EA4BDBA}\1.0\0\win32
the value of which was set to the location of the reference I am trying to remove. I changed this to a reference to the new location in which I want to store my dll (.tlb) file. This at least looked like it would allow me to create a new reference in the References box but on clicking OK I got a message saying "Error in loading DLL"
I resolved my problem in the end by removing all references to the library in the Registry with a registry Cleanup tool (ReImage) before copying the library to its new directory and then reregistering it with regASM

Constantly getting Err 1004 when trying to using Application.AddIns.Add

I'm trying to implement a bootstrap installer for my add-ins workbook, such that I can easily install the add-in for new users and send out updates. It works fine on my machine, but when having others test it, I get a runtime error when I try to call Set AI = Application.AddIns.Add(fileName:=fullPath, copyfile:=True). Specifically, the error is "1004: Unable to get the Add property of the AddIns class". I thought this was because the user needed to have "Trust access to the VBA project object model" enabled, but the error seems to occur even after they've toggled that box.
Other things I've checked:
The fullPath to the add-in is valid and the user can access the directory and the file
The user has the folder located at Application.UserLibraryPath
Any ideas?
Figured it out. It appears that the issue isn't one of permissions, but rather of whether a workbook is already open. Opening any workbook before running the Addins.Add prevented the error from occurring so I've simply added that into the program:
If Application.Workbooks.Count = 0 then Set wb = Application.Workbooks.Add()
Set AI = Application.AddIns.Add(fileName:=fullPath, copyfile:=True)
If not wb is nothing then wb.Close
Duke, perhaps it's the Trust Center settings on the recipients' machines. I have found this and may be helpful.
Best,
Danny
Check out VBA videos on ExcelVBADude on YouTube.

Compatibility Between MS-Access 2003 and MS-Excel 2013

This is similar to a question that I've asked yesterday, but I've managed to find a fair bit more information: enough to warrant a new question, I feel.
My office has recently moved to Windows 7 along with Office 2013 - with the except of Access which has stayed as 2003.
Access works absolutely fine except when I try to automate Excel. This is a feature of nearly all my applications.
When I load an old project, the reference is automatically updated to "Microsoft Excel 15.0 Object Library" - it is held as an EXE file in Program Files (x86). Note: it does not say the reference is missing.
When I try to run any code which uses early binding, it fails with the following error message: "Error in loading DLL"
I've since tried late binding by doing the following:
Dim app As Object
Dim wb As Object
Set app = CreateObject("Excel.Application")
app.Visible = True
Set wb = app.Workbooks.Add
This creates the Application, it becomes visible, a Workbook is added, but then I get the following error: "Run-time error '1004':
Application-definted or object-defined error"
If I try to access VBA in the new Workbook I get the following error: "An error occurred initializing the VBA libraries (1004)" The Workbook is loaded in "Compatibility Mode"
The above leads me to believe that the 2 applications may not be compatable, but the following is worth considering:
If I try to use early binding I don't get the Intellisense drop-downs but words like Workbook and Worksheet do auto-capitalise themselves as you would normally expect them to. The code won't compile at all if I don't have the reference set, but it does compile - and throw and error - when it is. I've since tried Word 2013 - who's Object Reference is an OLB file rather than EXE - and I get the full Intellisense features I would except, but it still throws the same error when trying to run.
In a nut shell, does anyone know if I stand any chance of having the 2 work together?
Thanks

How to auto check the 'Microsoft ActiveX Data Objects x.x Library' from the Tools --> References?

We share our Excel Macro - MS Access project with our client.
They don't know to select the 'Microsoft ActiveX Data Objects x.x Library' from the Tools --> References.
Any code to automatically update MS ADO library settings?
Note: In Office we are using MS 2010. I think the client's office is using Micorsoft XP.
I suggest above to use late binding, but you could do something like this (my code exactly as used in PPT 2010, should be easy enough to adapt to Access but I do not ever use access).
You may need to change the ADODBReference constant for use in XP. Or you could add another constant and a logic check to see what Application.Version and load from the appropriate destination path.
Public Const ADODBReference As String = "C:\Program Files (x86)\Common Files\System\ado\msado15.dll"
Sub PPT_AddRefToADODBLibrary()
'Adds a programmatic reference to ADODB library if one doesn't already exist
'ADODBReference is a public const refers to Microsoft ActiveX Data Objects 6.0 Library
If Not PPT_RefExists(ADODBReference, "Microsoft ActiveX Data Objects 6.0 Library") Then
Application.VBE.ActiveVBProject.References.AddFromFile _
ADODBReference
Else:
'Already installed
End If
End Sub
The sub above calls on this custom function, which first iterates the active References
Function PPT_RefExists(refPath As String, refDescrip As String) As Boolean
'Returns true/false if a specified reference exists, based on LIKE comparison
' to reference.description.
Dim ref As Variant
Dim bExists As Boolean
'Assume the reference doesn't exist
bExists = False
For Each ref In Application.VBE.ActiveVBProject.References
If ref.Description Like refDescrip Then
PPT_RefExists = True
Exit Function
End If
Next
PPT_RefExists = bExists
End Function
Trying to simply turn it on with a code like this:
Application.VBE.ActiveVBProject.References.AddFromFile "C:\Program Files (x86)\Common Files\System\ado\msado15.dll"
you may come across three problems: it is already installed, earlier version is installed, the file path is invalid. So my logic is as follows:
Code loops through all refs and checks if ref to Microsoft ActiveX Data Objects 6.0 Library is installed.
If not installed, then it tries to install it with error handling.
If failure will occur, it means that either earlier version i.e. Microsoft ActiveX Data Objects 2.8 is installed (could be checked while looping) or the file path is invalid.
Code:
Sub AddReferenceMicrosoftActiveXDataObjectsLibrary()
Const MyRefPath As String = "C:\Program Files (x86)\Common Files\System\ado\msado15.dll"
Dim ref As Variant
Dim IsInstalled As Boolean: IsInstalled = False
For Each ref In Application.VBE.ActiveVBProject.References
Debug.Print ref.FullPath
If ref.FullPath = MyRefPath Then IsInstalled = True
Next
If IsInstalled = False Then
On Error GoTo err:
Application.VBE.ActiveVBProject.References.AddFromFile MyRefPath
On Error GoTo 0
Debug.Print "Just installed"
Exit Sub
Else
Debug.Print "Already installed"
End If
Exit Sub
err:
MsgBox "Probably earlier version of Microsoft ActiveX Data Objects is already installed or other error occurred"
End Sub
I think late binding is the only way.
I made an Excel-based application for my office, and every time i prepare new version there is about 10% of users I have to visit to add references.
I found out, that since these computers have different Windows versions, for some dll's there is no version which would exist on each computer.
This makes adding references from code more difficult and I do not want to use late binding.
Thats a pity - most of the dll's functionality I use is compatible among all versions.

Resources