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

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

Related

UserInterfaceOnly = True is discarded when opening a file

I have an Excel+VBA file named "Myfile.xlsm" which needs that UserInterfaceOnly = True property so the VBA code can perform many operations without the user being aware.
I did place the following code to set UserInterfaceOnly = True property in the Workbook_Open event (also tried in the Workbook_Activate event) of "Myfile.xlsm".
Private Sub Workbook_Open()
Dim WSh As Worksheet
For Each WSh In ThisWorkbook.Worksheets
WSh.Protect Password:="myPWD", UserInterfaceOnly:=True
DoEvents
If WSh.ProtectionMode = False Then MsgBox "UIFOnly Init Failed on " & WSh.Name & " !!"
End If
Next WSh
End Sub
In some cases the UserInterfaceOnly is not set as expected and I get the "UIFOnly Init Failed on " message at opening "Myfile.xlsm" and as a consequence many other problems later.
EVEN BETTER: I created a new very simple "UnlockUIFOnly.xlsm" file which has the same code in Private Sub Workbook_Open().
If I open "UnlockUIFOnly.xlsm" first, protection works as expected. If I then open "Myfile.xlsm" (keeping "UnlockUIFOnly.xlsm" open) it works as expected.
If I close both files and open ONLY "Myfile.xlsm" it fails again.
I'm running Office 365 (version 2203 Build 16.0.150028.20512) 32 bits with Windows 10.
FURTHER OBSERVATION #1: I copied this not working "MyFile.xlsm" from its original directory to a new one.
When I opened it from its new directory, I got a banner to enable contents, and I answered yes. Then everything went smooth (No UIFOnly Init Failed on " message, no error 1004 ...). I checked some functionalities, so Excel asked whether I wanted to save changes, answered yes, then later if I wanted that document to be a trusted document, answered Yes as well.
At second open, I did not get any banner to enable contents (normal) but the problems were back.
FURTHER OBSERVATION #2: I again copied this not working "MyFile.xlsm" from its original directory to a new one.
When I opened it from its new directory, I got a banner to enable contents, and I answered yes. Then everything went smooth (No UIFOnly Init Failed on " message, no error 1004 ...). I checked some functionalities, so Excel asked whether I wanted to save changes, answered YES, then later if I wanted that document to be a trusted document, answered no. All further open tentatives asked to enable contents (answer yes) but were smooth.
It looks like declaring a document as trusted bypasses something or changes in which order events are generated, and has a huge impact on my problem

Good VBA script fails to run on other computer

I have a very complex excel macro workbook. The VBA code seems to run pretty well on PC's at my location. As soon as I send it to a German colleague it fails to run in unexpected locations of the code.
The last problem I came across is a Runtime error 5 when the code try to modify the Caption of a UserForm (and some text boxes and cmd buttons as well).
Previously we faced with the same issue with SlicerCache(x).ClearManualFilter but somehow I healed itself...
My first thought was to break up the nest With and see which row causes the fail, but it's immediately the first row. I assume it'll do the same for all rows.
I have checked the windows and office settings:
I'm running Win10, English language settings and Hungarian formatting settings. -> Code running well.
My local colleagues run the same system with Hungarian language and formatting. -> Code running well.
The problematic colleague runs Win10 with German language and formatting settings. -> Code fails to run.
We both have the same Reference libraries in VBA editor, none missing. (I assume it's carried by the excel file itself.)
I have Microsoft 365 MSO (16.0.13801.21050) 32-bit, he running 16.013801.21004 32-bit. (I suppose the update scheduled by the IT department.) This portion of code months before my latest office update, so I don't think it's a cause.
The sub called by a CommandButton_Click event, and calls the user form zurueckExport. The form is deisgned so that can called for differnet purposes, so the captions have to be modified according to the needs.
I have ran out of ideas, don't see what and why cause it. Does anybody could give me some help to deal with this issue? I would be very glad.
Public Sub verExport()
With zurueckExport
.Caption = "Version Exportieren zum Creo"
.Label1.Caption = "Welche Version möchten Sie zum Creo exportieren?"
.CommandButtonExportieren.Visible = True
.CommandButtonZurueckladen.Visible = False
.CommandButtonKennlinie.Visible = False
.KennlinieFormat.Visible = False
.Show
End With
End Sub
The captions were too long, that generated the error message on the other computer.
Resolution:
I have added several different labels to the UserForm and modify their visibility instead of overwrite the caption.
Many thanks for #J0eBl4ck for the idea.

Why isn't my script able to locate my excel file when given correct filepath?

I have a .vbs script that opens two excel files and copies the contents of a sheet from the first file into the second file. It's supposed to run daily via task scheduler.
The script ran normally until the excel files in question were recently modified and slightly renamed - I went through the script and edited the filenames accordingly after the changes were made, triple checking that the names and filepaths matched up.
Everything ran fine for a few weeks after the changes but now the script fails immediately after starting, giving me an error claiming that the file can't be located even though the file is located at the given path. The error code is 800A03EC.
This is the first chunk of code in the script, including line 7 which seems to be throwing the error:
Dim objApp ' as excel object
Dim x, y ' as workbook
Set objApp = CreateObject("Excel.Application")
objApp.DisplayAlerts = False
objApp.Visible = False
Set x = objApp.Workbooks.Open("S:\Work (Public)\PORT MGMT & TRADING\PORT MGMT FORMS\ORION_FPFOCUS.xlsm")
Set y = objApp.Workbooks.Open("S:\Work (Public)\PORT MGMT & TRADING\PORT MGMT FORMS\FPFocusPasteSpecialValues.xlsb")
Dim WSx, WSy ' as excel worksheet
Set WSx = x.Worksheets("FPSUP")
Set WSy = y.Worksheets("FPFOCUS-COPY")
WSy.Range("B1").value = FormatDateTime(Now)
objApp.Application.Run "ORION_FPFOCUS.xlsm!Auto_Open"
The excel files in question are both located in the same directory:
S:\Work (Public)\PORT MGMT & TRADING\PORT MGMT FORMS\ORION_FPFOCUS.xlsm
S:\Work (Public)\PORT MGMT & TRADING\PORT MGMT FORMS\FPFocusPasteSpecialValues.xlsb
And the script is located here:
C:\Users\bserv\Documents\CopyFPFocus.vbs
The S drive isn't a physical drive, it's a virtual drive hosted by a service called Workplace. I can navigate through it and open the excel files manually just fine.
I initially thought it was a user privilege issue with task scheduler, but I've selected the 'run with highest privileges' option and the script is still failing. I also went through the privacy/trust settings in Excel to make sure the script wasn't being denied access, but I don't see any settings that would disable the script from working, and I also know that all these settings haven't changed since the script was working, so I don't see how they could be potential causes.
When I try running the code manually via cscript in the command line, it returns this error:
C:\Users\bserv\Documents\CopyFPFocus.vbs(25, 4) (null): The remote procedure call failed.
This is line 25 of the script for reference:
objApp.Run "RefreshAllStaticData"
When I try again by running command prompt as an admin, I get the same error I got initially. Sorry, is it possible the file was moved renamed or deleted.
The part that really confuses me is that the script ran fine for some time after the changes - so I'm really unsure about what actually changed to cause this issue to randomly pop up.
One other thing I've noticed is that upon opening the excel files I get a popup saying they're in use and locked for editing by me. I can't remember if this popup was showing up before the issue started. The other users on the network have been accessing these files regularly long before the script started failing, so I don't see how that could be the issue. The error code/message also doesn't seem to correspond with this being the problem.
I'd appreciate any help or insight into this issue. Thank you!

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.

Outlook 2010 - strange item.Attachments error

I have the following code, that should save a specific Excel file attached to an email. The code is combined with a rule, that trigger this script when an emai lwith a specific subject is received.
The code is triggered, but here comes the strangest error I saw lately: itm.Attachments.Count appear to be zero and obviously the file is not saved! But... if I put a breakpoint on "For each..." line and add itm.Attachments.Count to watch window, it is shown as zero. If I add itm only, then browse to Attachments property, then to Count property it shows 1 for Count (as it should) and the code is executed fine. I spent half a day trying to understand what's going on, but I can't figure it out.
The behaviour is the same both on a Outlook 2010 x64 on a Windows 7 x64 and on a Outlook 2010 x86 on a Windows 7 x86. Macros are enabled in Trust Center. I have attached some screenshot with the code and rule settings and also a movie showing the watch windows strangeness.
The script was built some time ago and it worked well on a couple of PCs and it was based on the steps from here: iterrors.com/outlook-automatically-save-an-outlook-attachment-to-disk/.
Any ideas?
Rule screen here
1 min. movie here
Public Sub Kona(itm As Outlook.MailItem)
Dim objAtt As Outlook.Attachment
Dim saveFolder As String
saveFolder = "C:\test"
For Each objAtt In itm.Attachments
If InStr(objAtt.DisplayName, "Kona Preferred Fixed Price Matrix (ALL)") Then
objAtt.SaveAsFile saveFolder & "\" & objAtt.DisplayName
End If
Set objAtt = Nothing
Next
End Sub
In case if you have an IMAP account configured in Outlook: your Offline Settings might be set to only store up to 1 month, 3 months, 12 month worth of emails on your local disk.
If you’ve got enough space on your disk and want to cache more emails locally, you can set the sync slider in the following way:
File-> Account Settings-> Account Settings…-> double click on your IMAP account.
Try to increase the offline storage in Outlook. See Empty Inbox and other IMAP synching issues in Outlook 2013 for more information.
My best understanding of this behavior is that Microsoft Outlook (at least the versions of 2010 that I tested) has a bug. There may be other factors that I'm not aware of contributing to this, but I was able to reproduce the error using different service pack levels / builds of Outlook 2010 on Windows Vista. Office 2013 does not appear to be affected.
I managed to create a workaround.
I found that by displaying the message while stepping through the code in debug mode using
objMailItem.GetInspector.Activate
the number of attachments was subsequently correctly detected (without having to do strange things like setting up a watch for the object variable and then clicking on it in the IDE).
However, this only worked while stepping through the code, not during normal execution.
For this reason, I suspected the message might not be displaying long enough during normal code execution for Outlook to get the twist out of its knickers. I reasoned that it might be possible to insert a delay to allow sufficient time for this.
I tried out several methods of inserting a delay. Here is the one that worked for me. I created a form called
frmTimer
and added the freeware RSTimer OCX control (http://www.softpedia.com/get/Programming/Components-Libraries/RS-Timer.shtml) to it.
I set the
Interval
property of the OCX to 1000 ms.
The form is loaded right after displaying the message like this:
objMailItem.GetInspector.Activate
frmTimer.Show ' <-- form is loaded and displayed (it is not sufficient to just 'load' it)
objMailItem.Close OlInspectorClose.olDiscard
The form has one single event handler:
Private Sub RSTimer1_Timer()
Unload frmTimer
End Sub
When the event fires, the form is unloaded and code execution continues with
objMailItem.GetInspector.Activate
frmTimer.Show
objMailItem.Close OlInspectorClose.olDiscard ' <-- code execution continues here
Here is a complete function that allows the attachment to be detected correctly.
Function EmailHasAttachments(ByVal objMailItem As Outlook.MailItem) As Boolean
On Error GoTo ErrHandler
objMailItem.GetInspector.Activate
frmTimer.Show
objMailItem.Close OlInspectorClose.olDiscard
If objMailItem.Attachments.Count > 0 Then
EmailHasAttachments = True
Else
EmailHasAttachments = False
End If
ExitHere:
Exit Function
ErrHandler:
Debug.Print Err.Number, Err.Description
Select Case Err.Number
Case 12345
' handle the error
Case Else
MsgBox "An unknown error has occurred."
Exit Function
End Select
End Function

Resources