I have a few Excel sheets with macros which I want any user to be able to run only from a particular location, in my case a particular sharepoint.
Should a user "SaveAs" the Excel file to any alternative location - he should get an error message.
I am looking for a VBA script to be put in these workbooks to allow me meet my objectives.
Can someone help please?
You can there display an error message and set the Cancel parameter to true if someone wants to save it to another location.
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
If Not ThisWorkbook.Path Like "//sharepoint/path/*" Then
MsgBox "You can't save the excel", vbCritical
Cancel = True
End if
End Sub
In the same way you can check in the Workbook_Open function if the Workbook is opened in a correct location:
Private Sub Workbook_Open()
If ThisWorkbook.Path Like "//sharepoint/path/*" Then
'Do things
Else
'Error message and close
End If
End Sub
Related
I created a simple userform for testing, but one issue comes up and i have no idea how to resolve it.
This is the case:
When I open .xlsm file for the first time and close the userform and workbook, this closes both of them.
But when I continue to click the .xlsm file again, close the userform and the workbook, it (the userform) pops up again.
It seems the workbook doesn't close.
Then i need to close the userform again to close this workbook.
I would like help to understand why the userform comes up again?
The userform only has one listbox controls.
The following code is in a module:
Private Sub Auto_Open()
UserForm1.Show
MsgBox "Close2"
ThisWorkbook.Close
End Sub
The userform contains the following code:
Private Sub UserForm_Initialize()
Application.Visible = False
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
MsgBox "Close1"
End Sub
You could try to put this into the workbook code section as followed.
And not put it in a separate module.
Private Sub Workbook_Open()
Application.Visible = False
userform1.Show
MsgBox "Close2"
ThisWorkbook.Close
End Sub
you can remove the code for the user form initialize.
The thing is as its hidden you might open it twice cause you do cause it does not respond directly.
As I very often have to problem, that the tick vanishes in the settings: Calculate before save. (I don't know the exact term as my office version is in German).
That's why I tried to use VBA to solve the problem. I used the following code in my Excel file:
Option Explicit
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, _
Cancel As Boolean)
If Application.CalculateBeforeSave = False Then
If MsgBox("Caution! Should >calculatebeforesave< be activated?", vbYesNo) = vbYes Then
Application.CalculateBeforeSave = True
Else
End If
Else
End If
End Sub
I put this into "Thisworkbook". But I would like this code to be ran in every workbook I work with (at least all these which allow for macros).
My suggestion was to write ActiveWorkbook_BeforeSave... instead of Workbook_BeforeSave and then put the code in a module in the PERSONAL Macro file. But this doesn't work.
I think you need to use the Excel Applications events rather than workbook events to achieve this, such as in this example
In your PERSONAL workbook right click and insert a a Class Module (Class 1)
Add something similar to below to Class 1:
Public WithEvents appevent As Application
Private Sub appevent_WorkbookBeforeClose(ByVal Wb As Workbook, Cancel As Boolean)
'Add what you would like to happen before a workbook closes
End Sub
Next open ThisWorksheet and add code along these lines (I think the PERSONAL workbook opens automatically when Excel starts):
Dim myobject As New Class1
Private Sub Workbook_Open()
Set myobject = Application
End Sub
When opening up a template a macro that is Auto_Open runs this code:
Sub Auto_Open()
UserForm.Show
End Sub
This then brings up a userform that says please save as and a Ok command button.
When Ok is clicked it has the this code.
Private Sub SaveAs_Click()
Dim bFileSaveAs As Boolean
bFileSaveAs = Application.Dialogs(xlDialogSaveAs).Show
If Not bFileSaveAs Then MsgBox "User cancelled", vbCritical
Unload Me
End Sub
Problem is after the Auto_Open is ran for the first SaveAs i want it to never run again. Because I want to be able to open it later with out the Userform popping up. So how do I disable the Auto_Open once its run and then save it disabled
I cant disable all macros because there are others in the workbook that still need to work.
Thanks
You have to use the Workbook.SaveAs method MSDN Found Here after you get the SaveAsFilename...
As for deleting a sub after it runs (I'd do this before saving) See here... You'll need your Auto Open Sub in a different module so you can delete the module before saving.
Private Sub SaveAs_Click()
Dim x As Object
Set x = Application.VBE.ActiveVBProject.VBComponents
x.Remove VBComponent:=x.Item("TestModule") 'Where TestModule is the module that holds the Auto Open script
Set NewBook = Workbooks.Add
Do
fName = Application.GetSaveAsFilename
Loop Until fName <> False
NewBook.SaveAs Filename:=fName
fName = False
Unload Me
End Sub
Exit auto_open if file name without specific wording.
For example: If file name is not starting from "N", auto_open will be exit.
Sub auto_open()
VBA_CODE = ActiveWorkbook.Name
If Left(VBA_CODE, 1) <> "N" Then Exit Sub
Q: What is recommended way of notifing user about loss of functionality unless User change macro security settings?
What I do now:
I display warning on the first sheet user see after opening Workbook, with explanation why things WONT work unless proper settings are set.
And I hide it on start up. (Which wont happen unless settings are OK)
But its not perfect solution:
That message is just one time. (While user could send that sheet to somebody else with different settings...)
Hiding and showing those few rows is treaded by Excel as changing document. (So just opening and closing excel will generate Save changed warning!)
Ok, here is best answer I could think off
(And big thx to #brettdj for suggestion!)
Sub HideMacroSecWarning()
Status = ThisWorkbook.Saved
Help.Range("Warning").rows.hidden = True
ThisWorkbook.Saved = Status
End Sub
Sub ShowMacroSecWarning()
Status = ThisWorkbook.Saved
Help.Range("Warning").rows.hidden = False
ThisWorkbook.Saved = Status
End Sub
Those are for showing and hiding macros. Saved state is preserved so only user actions can trigger "unsaved changes" dialogbox.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Call ShowMacroSecWarning
End Sub
Private Sub Workbook_Open()
Call HideMacroSecWarning
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Call ShowMacroSecWarning
End Sub
Private Sub Workbook_AfterSave(ByVal Success As Boolean)
Call HideMacroSecWarning
End Sub
Those assure that no matter the state of user settings warning will ALWAYS be displayed in SAVED FILE. (So even if for user Exel do not display that warning, somebody else who will open it on different machine will see that warning.)
I have a macro in my Excel file that is meant to determine whether a user can open it or not. However, it seems like, depending on the settings of the user's machine, Excel by default disables the macro. This ended up opening and revealing the contents in the xls file.
How can I make sure that the user has to accept running the macro or Excel will close the workbook?
UPDATED the code as it was not doing exactly what it was meant to...
This is pretty much the only way you can do this WITH a macro (thanks to #OlleSjögren for the insight :p)
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim Current As Worksheet
Worksheets.Add(Before:=Worksheets(1)).Name = "Protection"
Worksheets("Protection").Cells(1, 1) = "Please activate macros to view this workbook."
For Each Current In Worksheets
If Current.Name <> "Protection" Then
Current.Visible = xlSheetVeryHidden
End If
Next Current
End Sub
Private Sub Workbook_Open()
Dim Current As Worksheet
For Each Current In Worksheets
Current.Visible = xlSheetVisible
Next Current
Application.DisplayAlerts = False
Worksheets("Protection").Delete
Application.DisplayAlerts = True
End Sub
The property xlSheetVeryHidden means that it cannot be made visible through the UI (VBA code only can change it).
I think you can't do it. But we can make a workaround.
First of all you need to hide all your worksheet and prevent user to unhide it. Link. Following the link you will see that you can make a sheet veryHidden. As the link shows, you need to add a password to vba code too.
Then you can to create a macro that adds an InputBox with password
Sub CheckPassword()
Dim password As String
password = InputBox("Enter the password") 'You can use a Form with Textbox [PasswordChar] to put ****
If password = "myPass" Then
Sheets(3).Visible = xlSheetVisible
Sheets(3).Select
End If
End Sub
Finally you can attach a sub in the close event.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Sheets(3).Visible = xlSheetVeryHidden
End Sub