I have a sheet with a Workbook_Open code loading a userform.
After closing the form and the workbook Excel prompts me for the VBA Project password.
I've found some info on this issue on this pages:
http://support.microsoft.com/kb/280454
http://social.msdn.microsoft.com/Forums/office/en-US/8cb79e54-26ae-487c-8945-69b84b2e4eeb/com-addins-and-vba-password-prompt-bug
But it seems to be a problems with COM add-ins, which I have some.
The problem is that the add-ins are not mine and I can't change or disable them.
Is there any other solution?
For me, the problem was not some add-ins or unreleased references. It was the Dropbox Badge. As soon as I removed it, the password was not solicited anymore when I closed Excel. To disable Dropbox Badge, open the Dropbox app, go to Settings, then Preferences and in the General Tab select "Never show" under Dropbox Badge.
I found this solution on the following forum:
https://www.excelforum.com/excel-programming-vba-macros/1100960-ever-annoying-vba-password-prompt-at-close-of-excel-2.html
This happens when you have hanging pointers to objects.
For every 'Set xyz=' you do in VBA, make sure that you have a corresponding 'Set xyz=Nothing'.
Similarly for anything pointing to or obtained from COM objects.
Make sure you close any ADO connections etc.
Be especially careful to handle all errors so that ALL object variables are set to Nothing before the workbook can close, something along these lines:
Option Explicit
Option Compare Text
Public Sub Refresh()
On Error GoTo FAIL
Set wb = ThisWorkbook
wb.Activate
' do something useful
DONE:
On Error GoTo 0
Set wb = Nothing
Exit Sub
FAIL:
MsgBox Err.Description
GoTo DONE
End Sub
I have a number of workbooks that were experiencing the same problem with some users. We went through the process of checking for COM add-ins and various combinations of Windows and Office.
In the end we included the following code as part of the workbook_beforeclose event and the problem was resolved for our users.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim intResponse as Integer
'If the workbook needs to be saved then ask the user if they want to save the workbook, if not then exit without saving
'Need a global boolean to ensure the request to save the workbook is not shown twice
If Not ThisWorkbook.Saved And Not blnStartedClose Then
blnStartedClose = True
intResponse = MsgBox("Do you want to Save the this Workbook" & vbNewLine & vbNewLine & _
"Select 'Yes' to save the workbook" & vbNewLine & _
"Select 'No' to close without saving", vbYesNo, "Confirm - Workbook Save?")
If intResponse = vbYes Then ThisWorkbook.Save
End If
'If the user has clicked on 'No' to save the workbook then reset the "Saved" property to TRUE so that when we exit this routine no attempt to save the workbook is made
ThisWorkbook.Saved = True
End Sub
I've had some clients have this issue and I finally started getting it after installing BlueBeam Extreme. I unchecked the BluebeamOfficeAddIn in the COM Add-Ins and the password box stopped popping up when closing my .xlsm file. I'm going to do more digging to see if it's my code but I haven't had this issue until now and disabling that addin seemed to help...
Related
I am setting-up an excel spreadsheet and I want to force the user to either accept the terms of service with OK within a message Box or have the program close with Cancel. I am working within visual basic. I also placed the "terms" Macro within the workbook.
Well, I did it the wrong way and locked myself of of my own program. I keep reworking the code but I can't get it to pull together.
Sub terms()
MsgBox Prompt:="By using this program, the user agrees to all Terms and Conditions as set forth herein. Click OK to accept and continue, or cancel to exit program.", Buttons:=vbOKCancel + vbExclamation, Title:="User Agreement:"
Dim Answer As VbMsgBoxResult
If Answer = vbCancel Then Workbooks.Close
If vbOK Then Workbooks.Open
End Sub
In the workbook I put the following code:
Private Sub Workbook_Open()
terms
End Sub
I was expecting the program to close if the user clicked "Cancel" and the program to open if they clicked OK. I tried various different approaches and the latest error noted a compiler error saying argument not optional.
Workbooks is an collection of all Open workbooks. So the statement Workbooks.Open makes no sense, since all members are already open. The open method adds a specific workbook to the collection in the form Workbooks("c:\Test\myspreadsheet.xls").Open (and logically should have been Add not Open but I see where they were coming from) Similarly Workbooks.Close will close all open workbooks, whereas you would probably only want to close the file just opened.
Also to get a reply from a messagebox you must assign a variable to capture that reply - so
answer = msgbox("You sure?",vbyesno)
So what you actually want is
Sub terms()
Dim msg as string
Dim Answer As VbMsgBoxResult
msg = "By using this program, the user agrees to all Terms and Conditions as set forth herein. Click OK to accept and continue, or cancel to exit program."
Answer = MsgBox(Prompt:=msg, Buttons:=vbOKCancel + vbExclamation, Title:="User Agreement:")
If Answer = vbCancel Then ThisWorkbook.Close
End Sub
I could not find a simple answer to this question, which I thought was odd. I was making changes to an Add-in I wrote and I was pressing the save button ever so often in the excel VBA editor. When I came back to make some more changes I found that all my changes over the last few days are gone. Is there any hope of recovering my work? More importantly, if I am making changes what is a better way of saving the project. I usually work out of my add on and only save a new copy when I need to send it out to a teammate.
I remember having this bad surprise at some point, but then I started to look closely at the save button before clicking and I noticed that VBA is telling you which workbook will be saved if you click on the floppy disk.
The reason why it is important to have a look at this is because the file that will be saved depends on what is currently selected in the Project Explorer and not what is currently visible in the VBA Code Editor Window.
You can also make sure that your add-in is properly saved by selecting one of its elements and running the following command in the Immediate Window (which should replicate exactly what the VBE save button does):
Thisworkbook.Save
Finally, unlike for other types of workbooks, Excel won't tell you when you close the application without saving changes to an add-in. For that reason, you can take extra precautions by adding the following code to the object Thisworkbook of your add-in:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
If ThisWorkbook.Saved = False Then
Dim strMsg As String
' Specify the message to display.
strMsg = "Want to save your changes to '" & ThisWorkbook.Name & "'?"
Dim Decision As Boolean, ireply As Variant
ireply = MsgBox(prompt:=strMsg, Buttons:=vbYesNoCancel)
If ireply = vbYes Then
Decision = True
ElseIf ireply = vbNo Then
Decision = False
Else 'They cancelled (VbCancel)
Cancel = True
Exit Sub
End If
If Decision = True Then
ThisWorkbook.Save
End If
End If
End Sub
Which will prompt you with a message allowing you to save your add-in if it has an unsaved status when the Excel application is closing.
I keep running into an issue where the worksheet in question gets updated, and then doesn't reflect the changes until I close and re-open the book. It's not really a big deal, I just want to simplify it a bit into a single button click.
I was told that this is impossible to do because closing a workbook will immediately stop execution of code, so you can't reopen the book. But since, I have learned about the PERSONAL.xlsb, and figured since it's a persistent workbook, it could handle the code execution to save, close, and reopen the workbook.
Basically, here's what I've got in the main worksheet:
Public Sub Refresh()
ActiveWorkbook.Save
Application.Run "PERSONAL.xlsb!Module1.RefreshCurrentSheet",ThisWorkbook.Name,_
ThisWorkbook.FullName
End Sub
Which then calls the personal.xlsb macro "Refreshcurrentsheet":
Private Sub RefreshCurrentSheet(ByVal sheetname, Optional ByVal sheetfullname = 0)
Workbooks(sheetname).Close
MsgBox "So far so good!" 'I never see this box
Workbooks(sheetfullname).Open
MsgBox "No errors here..." 'I never see this box
End Sub
This successfully closes the workbook in question, but code execution stops and it doesn't reopen. Is there a way around this? Some way to run the second macro in the persistent sheet without code execution stopping?
We can reopen the workbook using this code inside it (there is no need to use other workbook):
Sub test()
Application.DisplayAlerts = False
Workbooks.Open ThisWorkbook.FullName
Application.DisplayAlerts = True
End Sub
The following code, which is part of an Excel Add-In that I created, will create a file name of the current data extract that we have open.
Sub ExtractSave()
'
If InStr(LCase$(ActiveWorkbook.name), "extract") > 0 Then
Exit Sub
Else
Dim MyDir As String, fn As String
MyDir = CreateObject("WScript.Shell").SpecialFolders("MyDocuments") & "\Extract Files" ' change this to valid path
If Len(Dir(MyDir, vbDirectory)) = 0 Then MkDir MyDir
fn = MyDir & "\Extract - " & Format(Now, "mm-dd-yyyy hh_mm")
ActiveWorkbook.SaveAs Filename:=fn, FileFormat:=xlOpenXMLWorkbook
End If
End Sub
When I close the workbook, it does require a save to occur as changes will be made to the workbook. All of this works just fine. The issue is that the company has a .COM Add-In that is required to run on all documents. It labels the document footer with a specific security level identifier. While I do not need to bypass this, I would like to know if it is possible to write code that will replicate hitting enter when this box appears? There are two buttons, Yes and Cancel. The default button is Yes on the popup. I did try adding
Application.DisplayAlerts = False
If Me.Saved = False Then Me.Save
Application.DisplayAlerts = True
into the Workbook_BeforeClose private Sub, but the op still appeared. Also, if I am correct, this bit of code will not work for the Saved workbook because this is running from within the Add-In.
I have not been able to find any equivalent information for this particular issue, so any help would be appreciated. Also, I do not know what other information would be useful in your assistance to finding a solution, so please ask and do not down vote because I missed something.
Order of events:
Import data into new workbook
Run ExtractSave routine
See the .COM addin popup (need to have YES button pressed, YES is
the default button)
User performs duties on the workbook
Click on close
prompted to Save the changes to the workbook (again, default is YES,
need this "clicked")
See the .COM addin popup again(need to have YES button pressed, YES
is the default button)
What VBA code is available to automatically click on the YES buttons for the .COM add-in while saving the workbook?
From comments:
Adding Application.SendKeys ("~") before this line ActiveWorkbook.SaveAs Filename:=fn, FileFormat:=xlOpenXMLWorkbook worked when the first save event (#2 from the list in the OP) occurred.
And For #7 .COM addin popup, adding Application.SendKeys ("~") in Workbook_BeforeSave event didn't help (I hope someone can help us to fix it):
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
SendKeys "~"
End Sub
I have a VBA macro which is called from a spreadsheet function (user defined function, UDF). When the spreadsheet is downloaded from the internet and the user has set "Trust Center" settings accordingly, the spreadsheet will open in so the called "Protected View". The function will not be called. A button "Enable Editing" is shown.
If the button is pressed, the spreadsheet is "trusted" and reopened normally, starting calculation, and hence calling the user defined function.
However, in that VBA function the value of Application.ActiveWorkbook is Nothing. This can be verified in the debugger.
Since I just need to read some properties (like path name) of the spreadsheet, I could alternatively inspect the availability of Application.ActiveProtectedViewWindow which should reference to the protected version of the workbook. In the debugger, this object can be inspected. However, running in release (without debug) the value of Application.ActiveProtectedViewWindow is also Nothing.
Both behaviors - especially the first one - appears to be a bug present in Excel 2010 and 2013 (see also a post at the MSDN forum ).
Question: Is there a way to get hold of properties of the active workbook after it has been enabled for editing?
PS: As a follow up to the nice observation of Siddharth Rout, that "ThisWorkbook" might work: In my case, the macro is not part of the Workbook being openend. The UDF is defined in an XLA. Hence, ThisWorkbook would reference the XLA. I do need to get the ActiveWorkbook (= the workbook calling the UDF) instead of ThisWorkbook (= the workbook running the UDF).
IMPORTANT REQUIREMENT:
My function is called as a user defined function, i.e., execution order is determined by Excel updating the cell.
The function is not part of the workbook being opened. It is part of an XLA.
I cannot add any code to the workbook which is opened.
Summary: The problem can be replicated and there are some possible workarounds. The most promising one - resulting from a chat - is to use ActiveWindow.Parent instead of ActiveWorkbook.
I was able to replicate the problem.
I tried
Private Sub Workbook_Open()
MsgBox "Application.ActiveWorkbook Is Nothing = " & _
CStr(Application.ActiveWorkbook Is Nothing)
End Sub
And I got True
However, then I tried this and it gave me False
Private Sub Workbook_Open()
MsgBox "Application.ActiveWorkbook Is Nothing = " & _
CStr(Application.ThisWorkbook Is Nothing)
End Sub
Now answering your question...
Question: Is there a way to get hold of properties of the workbook after it has been enabled for editing?
Yes. Use ThisWorkbook instead of ActiveWorkbook
Followup From Comments
Once the workbook completely loads after you exit the Protected Mode, you would be able to access the ActiveWorkbook object. To test this, put this code in the protected file.
Private Sub Workbook_Activate()
MsgBox "Application.ActiveWorkbook Is Nothing = " & _
CStr(Application.ActiveWorkbook Is Nothing)
End Sub
You will notice that you get a False
So once your workbook loads, your add-in can use ActiveWorkbook to interact with the opened file.
Here is another test
Private Sub Workbook_Activate()
MsgBox ActiveWorkbook.Path
End Sub
This is what I got the moment, I exit the Protected Mode
FOLLOWUP FROM CHAT
Using ActiveWindow.Parent.Path instead of ActiveWorkbook.Path would solve the problem.
I had this same issue today, and neither the accepted answer nor any other answer that I could find on this page or through searching the Google-verse worked for me. I'm using the version of Excel within Office 365, and I figured that was at the root of the problem.
I eventually came to a solution after finding a Microsoft Excel 2010 resource and hitting the old try-fail cycle for a few hours. Here's what I got:
Option Explicit
Public WithEvents oApp As Application
Private bDeferredOpen As Boolean
Private Sub Workbook_Open()
Set oApp = Application
End Sub
Private Sub oApp_WorkbookActivate(ByVal Wb As Workbook)
If bDeferredOpen Then
bDeferredOpen = False
Call WorkbookOpenHandler(Wb)
End If
End Sub
Private Sub oApp_WorkbookOpen(ByVal Wb As Workbook)
Dim oProtectedViewWindow As ProtectedViewWindow
On Error Resume Next
'The below line will throw an error (Subscript out of range) if the workbook is not opened in protected view.
Set oProtectedViewWindow = oApp.ProtectedViewWindows.Item(Wb.Name)
On Error GoTo 0
'Reset error handling
If oProtectedViewWindow Is Nothing Then
bDeferredOpen = False
Call WorkbookOpenHandler(Wb)
Else
'Delay open actions till the workbook gets activated.
bDeferredOpen = True
End If
End Sub
Private Sub WorkbookOpenHandler(ByVal Wb As Workbook)
'The actual workbook open event handler code goes here...
End Sub
The difference between the 2010 solution and mine is that I had to call Workbook_Open and explicitly set the oApp variable there, because without that assignment neither the oApp_WorkbookActivate nor oApp_WorkbookOpen functions would fire when I opened the file.
Figured that someone else might be able to benefit from this, so I posted it, despite the fact that the most recent update to this thread is better than 2 years old.
Best.
Try using Application.Caller.Parent.Parent instead of Application.Activeworkbook
This is not a complete answer to the original question, but a (dirty) workaround for a problem related to this.
I needed ActiveWorkbook to infer the workbooks path, that is ActiveWorkbook.Path.
An alternative to using ActiveWorkbook.Path is to check for Application.RecentFiles(1).Path which is the path of the most recently opened file. In many cases this will be the workbook for which the user just has "Enabled Editing". However, of course, this method may fail: In the case the used opened another sheet, then enabling the previously opened sheet.
(Note: ActiveWorkbook.Path give the path of the folder, while Application.RecentFiles(1).Path gives the complete path of the file, so there has to be some post-processing).
I know it's old thread, but i came across the same issue and i found solution ;)
The only way to go around it, is to use variable type Workbook
Dim wbk as Workbook
Set wbk = Application.ProtectedViewWindows(index).Workbook
Warning:
ActiveSheet returns Nothing when active window is protected too.
Dim wsh As Worksheet
Set wsh = wbk.Worksheets(index)
Try this code it works.
If (UCase(ActiveWorkbook.Name) = ucase("<YOUR XLA NAME WITH EXTENSION>")) Then
End
End If
Set wbObj = ActiveWorkbook
First time when you run the macro, it just ends without doing anything. Second time it picks up the proper file.