How to read destination path after the SaveAs UI is used - excel

I have a macro running in the Workbook BeforeSave event
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
If SaveAsUI = True Then
'read destination path somehow
'perform business logic using the destination folder
End If
End Sub
Certain validation on the workbook content need to take place only if the file is saved to a certain destination, this may result in the save action being cancelled.
I have been unable to find a way to read what the user specified as the destination path. I need some help please as I am not a VBA specialist.

It appears to me the event fires before a destination path is chosen. You probably have to use the WorkbookAfterSave event and then perform the validation afterwards.
https://learn.microsoft.com/en-us/office/vba/api/excel.application.workbookaftersave

Related

RefreshAll BeforeSave

I am using power query to combine several tables together and output some info to another table, all within the same workbook.
I would like to ensure the output table is always up-to-date when the file is saved and don't want to depend on ppl using the 'Refresh All' button. Ideally I would have the queries update when the file is being saved.
For each query I have disabled the 'Enable background refresh' option in the query properties. I then have added the following vba code to ThisWorkbook:
Option Explicit
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
ThisWorkbook.RefreshAll
End Sub
This does cause the queries to be updated before the file is saved. However if a user clicks on the save button (causing the queries to update & file saved), and then closes the file they are prompted to save the file again as if something has been edited... I have tried adding a wait command to the BeforeSave method after the refresh however the same behaviour occurs. We could of course just save it again or close without saving (since it was saved when we first hit the save button) however both are not ideal (file is on a network drive, so even though it is only a couple MB it takes several seconds to save, and not a fan of closing without saving).
Any tips for stopping Excel from asking us to save a workbook that we just saved?
Edit
From comments and suggested answers it seems that BeforeSave can be inconsistent. I did want to allow users to be able to close the workbook without saving so wanted to avoid using BeforeClose(for example a user made large changes to the workbook and wanted to undo everything). By manually setting the workbook saved state to true in Aftersave seems to have resolved the issue; atleast in my testing so far (even though it should already be true since it just saved?).
Option Explicit
Private Sub Workbook_AfterSave(ByVal Success As Boolean)
If Success Then
ThisWorkbook.Saved = True
End If
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
ThisWorkbook.RefreshAll
End Sub
Workbook.RefreshAll
It seems like the BeforeSave isn't always working as expected so your feedback is most welcome.
Option Explicit
Private DoNotBeforeSave As Boolean
Private Sub Workbook_BeforeClose(Cancel As Boolean)
With Me
If Not .Saved Then
.RefreshAll
DoNotBeforeSave = True
.Save
Debug.Print "Just refreshed and saved via 'BeforeClose'. Closing!"
Else
Debug.Print "No action taken via 'BeforeClose'. Closing!"
End If
End With
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
If Not DoNotBeforeSave Then
With Me
If Not .Saved Then
.RefreshAll
Debug.Print "Just refreshed and saved via 'BeforeSave'!"
Else
Cancel = True
Debug.Print "No action taken via 'BeforeSave'!"
End If
End With
End If
End Sub

Strange behavior when closing a workbook twice

Strange issue when closing a workbook twice from VBA (Workbook_BeforeClose)
Hi. This problem appears to me in an extremely simple workbook: Workbook_BeforeClose only.
Option Explicit
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ThisWorkbook.Close SaveChanges:=False
End Sub
If I open and close the workbook twice, the main Excel screen looks like this, and it's impossible to do something, I can only close it from the status bar:
If all you are trying to do is to not prompt the user to save changes, just play with the appropriate flags to 'trick' Excel that changes have already been saved.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Me.Saved = True
End Sub
This will allow the workbook to close, without prompting any changes to be saved, but this does not actually save them.
Notice the subtle difference between the words: Me.Saved and Me.Save.
Saved is a property that gets flipped to False when Excel detects changes were made as of the last save.
Save is a method - not a property as above - that actually will save the workbook.
Your workbook is already closing, which is what fired this event to begin with. No need to try to close it again within this event. Just tell Excel that no changes have been made since the last save, and it should close all on it's own - without the prompts.
It's possible you're re-triggering the event. Try something like this:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Static InProgress As Boolean
If InProgress Then Exit Sub
InProgress = True
ThisWorkbook.Close SaveChanges:=False
End Sub

Excel VBA - Ambiguous Name Prompt

I get the ambiguous name prompt with this excel vba:
Private Sub Workbook_BeforeSave(ByVal SaveAsUi As Boolean, Cancel As Boolean)
ActiveWorkbook.CustomDocumentProperties(“DepartmentCode”).value = Range(“DepartmentCode”)
ActiveWorkbook.ContentTypeProperties(“DepartmentCode”).value = Range(“DepartmentCode”)
End Sub
There is another Public Sub Workbook_BeforeSave event in the same workbook which is also required. How do I work around this.
I have no knowledge of VBA. I found the string above on google. I am basically trying to synchronize data in excel with columns in SharePoint.
Would appreciate help on this.
How can I work around it? Sorry, I have no knowledge of vba. Just copied from google
Copy all the code in one event (that is, everything after the Private Sub line and before the End Sub line) and paste it into the other event, either right after the Private Sub or right before the End Sub. Then remove the whole event you copied from.

How do I write a script that will save an Excel file to another file at specific intervals?

I have a macro that creates a back-up copy of an Excel document.
How do I make it so that the macro runs automatically every time the document is saved?
Here is the code:
Sub BUandSave()
'Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
'Saves the current file to a backup folder and the default folder
'Note that any backup is overwritten
Application.DisplayAlerts = False
ActiveWorkbook.SaveCopyAs Filename:="G:\1 Processing\Christine\" & _
ActiveWorkbook.Name
ActiveWorkbook.save
Application.DisplayAlerts = True
End Sub
I got this code from online and have zero skills with VBA, please help!
EDIT: Alright, thank you for your answers and insight. now I have one other question. How do I make it so that the back-up copy saves under a different name. I want to make it something like DO NOT DELETE or DO NOT EDIT, something like that so that the person editing the file doesn't accendentally try to edit the wrong one. How do I add that into the code?
The answer is in the code you posted:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
'Saves the current file to a backup folder and the default folder
'Note that any backup is overwritten
Application.DisplayAlerts = False
ActiveWorkbook.SaveCopyAs Filename:="G:\1 Processing\Christine\" & ActiveWorkbook.Name
ActiveWorkbook.Save
Application.DisplayAlerts = True
End Sub
Place the above code in your ThisWorkbook module (Alt + F11 will get you into the VBA Editor).
Workbook_BeforeSave is a workbook Event. Code within it is executed whenever the event is triggered, in this case, before the workbook is saved. Events in Excel are pretty darn cool and a powerfull tool for code slingers :-)
The code you posted in your question is now no longer necessary.

Sub App_WorkbookBeforeSave doesn't work on VBA Add-in/Excel 2010

I am going to show a MessageBox before save workbook. I have tried with event handler Sub App_WorkbookBeforeSave() and Sub Workbook_BeforeSave but both doesn't work! Why?
There are my Sub in addin:
Private Sub App_WorkbookBeforeSave(ByVal Wb As Workbook, _
ByVal SaveAsUI As Boolean, Cancel As Boolean)
MsgBox "Good bye! Data is save."
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
MsgBox "Good bye! Data is save."
End Sub
UPDATE
I was put them in ThisWorkbook modules belong to Microsoft Excel Objects
This kind of functionality requires...
The code to be in ThisWorkbook module of the Add-In, OR
Using a class to hold the event handling code, while still kicking it off in the ThisWorkbook module
Either way, you need to create an instance of a WithEvents Application object which, while you don't touch the object directly after you create it, enables the events to be captured.
I like the second option (cleaner, makes you look like a boss, etc.). Create a class and call it something. I like to call my class ImAGoodListener. In the class, include the appropriate Subs for any application events you want to use
Public WithEvents App As Application
Private Sub App_WorkbookBeforeSave(ByVal Wb As Workbook, ByVal SaveAsUI As Boolean, Cancel As Boolean)
On Error Resume Next
MsgBox "Good bye!"
End Sub
With the arguments, you can do cool and mischievous things like prevent the workbook from being saved...
(I like On Error Resume Next for this so we don't risk not allowing a user to save his/her workbook should our code go haywire)
In the ThisWorkbook module put something like this...
Dim objAppLis As New ImAGoodListener
Private Sub Workbook_Open()
Set objAppLis.App = Application
End Sub
This will start the event listening when your Add-In is initially opened.
Alternatively, if you're using CustomUI for the ribbon, you use a Ribbon Onload event to trigger the start of listening (I do this when my events are used primarily for ribbon behavior so I can easy disable listening in the CustomUI xml).
Some other application events of use are:
App_SheetActivate
App_WorkbookActivate
App_WorkbookOpen
App_WorkbookBeforeClose
App_WorkbookBeforeSave
Here's a list of all events, but note that some of them are workbook (event handlers start with Workbook_ events which won't work for this sort of thing.
Chip goes into great detail about these sort of events on his site here.

Resources