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.
Related
I built a series of macros, all of which have worked with the custom ribbon I built using the Custom UI Editor.
I added one more macro and updated my Ribbon with a new button. I test the macro first and it works when run from the developer tab or just running directly from VBA and the sub heading is as follows: "Sub GetDES()".
Once I make it so it works with the button on the ribbon by changing to:
Sub GetDES(control as IRibboncontrol)
I get the "Cannot run macro..." error
Sub GetDES(control as IRibboncontrol)
'PURPOSE: Get description page and insert into each confirm page
Dim Fpath As String
Fpath = ActiveSheet.Range("I6").Value
With Application.FileDialog(msoFileDialogFilePicker)
.ButtonName = "Add this DES!"
.AllowMultiSelect = False
.InitialFileName = Fpath
.Filters.Add "All Pictures", "*.*"
.Show
If .Show = -1 Then
Dim img As Object
Set img = ActiveSheet.Pictures.Insert(.SelectedItems(1))
img.Left = 75
img.Top = shOutput.Range("B40").Top
img.Width = 450
Else
MsgBox ("Cancelled.")
End If
End With
End Sub
The only thing I can think of is I still have something weird happening when I run it without the Control. When I run it the dialouge picker opens twice. I'm wondering if that is my problem with running it from the button on the ribbon.
When I step through the code, the line
set img=Activesheet.Picture.Insert(.SelectedItems(1))
is what causes the file dialogue picker to open again.
Ideas? Thank you
To make sure the callback is invoked by the Office you may try to assign a sample sub to a button, for example, with a simple MsgBox statement to make sure it works correctly.
Sub GetDES(control as IRibbonControl)
MsgBox "test"
End Sub
If that works correctly you can try putting your original code. But you may try to avoid shorthand properties like ActiveSheet or With operator. Hope it helps.
I believe I stumbled across my issue. I built a new module that I wrote this code in, I named the module with the same name as the sub. When Testing, I never went to run it from the macro list, I just ran it from the VBA window. When I looked at the Macro's List window, I saw that the new macro I wrote in this workbook was not displaying like the other macros. As you see in the photo, "Confirm Tool-Master_V5.xlsm'!GetDES.GetDES"
I removed that module and took the copy, listed as GetDES3 and renamed it
GetDES(control as IRibboncontrol)
and it runs from my ribbon. I'm not sure why it looked different or if there was something to do with the module name and the sub being named the same that caused it to be like that. so I tested it. I wrote a test sub and named the module test and it did the same thing.
So, Lesson is, don't name your sub and the module with the same name
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
Scenario
I am using a macro whereby I use Application.Visible = False to hide the workbooks. Also I use Application.Visible = True to unhide the workbook. At certain situation, I use Windows(ThisWorkbook.Name).Visible = False and Windows(ThisWorkbook.Name).Visible = True to hide and unhide only the workbook which contains macro.
Problem
I noticed during these operations, some additional excel windows(without any workbook) appear other than the workbook. Please see the picture below. You can see a grey window behind with a name Excel. That is the window I am talking about
If I closed that window, the whole excel will close. Does anyone know why this extra window appearing and how to prevent it from appearing?
I am not sure if this will meet the needs of your specific situation. But, what if you kept Application.Visible = False at the beginning of your code and changed Application.Visible = True to
Application.Windows(ThisWorkbook.Name).Visible = True at the end. This worked for me.
Hiding Excel
With the following code
Sub AppVisibleTrue
Application.Visible = True
End Sub
Sub AppVisibleFalse
Application.Visible = False
End Sub
you are showing or 'hiding' the 'whole' excel application, so you have to 'unhide' it in the same code, otherwise you won't be able to use the open files after you hide it, e.g. open a new workbook, in VBE add a new module and paste the above code into the module. Now, stay in VBE!!! Run the 'False' Sub. You will notice Excel has 'vanished', but you can still find it in the Task Manager's processes. Now run the 'True' Sub. Excel has 'reappeared'.
The following process will make Excel 'vanish'. The only way to close it will be via the Task Manager. If you not too familiar with doing this, just take my word for it.
Close the VBE. Now run the 'False' Sub. Excel has 'vanished'.
To conclude, this is obviously an error in your code, so I would suggest if you want to show a window (worksheet) that isn't 'ThisWorkbook' and you're dancing from one to the other, you should declare a variable
Const strSheet as String = "Sheet2"
Dim oSheet as Worksheet
'...
Set oSheet = ActiveWorkbook.Worksheets(strSheet)
Now you do with oSheet whatever you want.
Try to lose Active, Select and similar methods in the code.
If you would provide the actual scenario with the codes, a better assessment of the problem could be done.
The additional Excel window(s) could be related to your Windows Explorer. If you are previewing a document (in this case an Excel document) then the application to view that document is running in the background.
In this case, forcing the application to be visible will also make the background "preview" windows visible.
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 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...