I currently have a code that on startup checks if the option "Trust access to the VBA project object model" is enabled or not.
In the case that it is not enabled, I need the program to open the macro security settings for easy access for the user.
I've made some code that does this in most cases, but I've encountered one problem that I don't know how to get around.
The code is as follows:
Private Sub Workbook_Open
If Not VBATrusted() Then
MsgBox "Trust access to the VBA project object model is not enabled" & vbNewLine & vbNewLine & _
"Please allow access by ticking the checkbox in the window that appears after clicking Ok"
Application.CommandBars.ExecuteMso ("MacroSecurity")
End If
End Sub
Function VBATrusted() As Boolean
On Error Resume Next
VBATrusted = (Application.VBE.VBProjects.Count) > 0
End Function
This code does its job unless the macro settings are as default "Disable all macros with notification", in which case I activate the macro and then get a run-time error "-2147467259 (80004005) Method 'ExecuteMso' of object '_CommandBars' failed"
This error will only occur on the first startup, as I do not have to activate the macros on consecutive startups, unless I move the file location.
I've tried pausing the macro for two seconds, but that did nothing for me, and neither did an error handler that tried to grab the error and then try executing the Application.CommandBars.ExecuteMso ("MacroSecurity") line again. It ended up with the same error.
The debugger tells me that the error is in the Application.CommandBars.ExecuteMso ("MacroSecurity") line, but that's probably not much of a surprise with that error message.
Thinking outside the box here...
What if you put a big message on the sheet which tells the user to activate macros, and then have an auto start macro delete or hide that message. That would bring the message to those who need it, but not the others.
Simple solution as proposed by #CLR in comments above, but didn't work when I initially tested it (user error!). All code goes in ThisWorkbook module:
Option Explicit
Private Sub Workbook_Open()
If Not VBATrusted() Then
MsgBox "Trust access to the VBA project object model is not enabled. " & vbNewLine & _
"Please allow access by ticking the checkbox in the window that appears"
Application.OnTime Now + TimeValue("00:00:01"), "ThisWorkbook.SetSecurity"
End If
End Sub
Function VBATrusted() As Boolean
On Error Resume Next
VBATrusted = (Application.VBE.VBProjects.Count) > 0
End Function
Sub SetSecurity(Optional foo)
Application.CommandBars.ExecuteMso "MacroSecurity"
End Sub
Slightly more elaborate: Add an MSForms.CommandButton to the worksheet which will open the security settings pane after user clicks it. Have the MsgBox prompt the user to click the button and then change the security settings.
In Module1, the Button's click event handler:
Option Explicit
Sub Button1_Click()
Call ThisWorkbook.SetSecurity
End Sub
In ThisWorkbook module:
Option Explicit
Private Sub Workbook_Open()
If Not VBATrusted() Then
MsgBox "Trust access to the VBA project object model is not enabled. " & vbNewLine & _
"Please allow access by:" & vbNewLine & vbNewLine & _
"1. Clicking the button on this sheet" & vbNewLine & _
"2. Ticking the checkbox in the window that appears"
End If
End Sub
Function VBATrusted() As Boolean
On Error Resume Next
VBATrusted = (Application.VBE.VBProjects.Count) > 0
End Function
Sub SetSecurity(Optional foo)
Application.CommandBars.ExecuteMso "MacroSecurity"
End Sub
Related
I have a global template with a customized ribbon. When I try to open a document, I receive error 4248, which claims the command can't run because no document is open.
The code in the onLoad sub is checking to make sure that the active document isn't the template or Normal.dotm because I don't want document variables written to those files via the called procedures. This worked fine in Word 2013, but I'm noticing that in Word 2016, it seems the ribbon onLoad procedure is running before a document in Word is open.
I've pinpointed the issue to the ActiveDocument.Name line, where I can trap the error and resume next, but that doesn't help me run the additional code after the determination is made that this isn't the global template document or Normal.dotm.
Public myRibbonNewNormal As IRibbonUI
Public bVisible As Boolean
Dim bDocSaved As Boolean
Sub onLoad_newNormal(ribbon As IRibbonUI)
Set myRibbonNewNormal = ribbon
On Error GoTo onLoadError
If ActiveDocument.Name = "Styles.dotm" Or ActiveDocument.Name =
"newNormal.dotm" Then
Exit Sub
ElseIf ActiveDocument.ReadOnly Then
Exit Sub
Else
'Call checkDocType
Call uncheckUpdateStyles
Call removeClientFooter
Call checkTemplate
If bDocSaved <> True Then
Call preventSave
Else
'do nothing
End If
End If
Exit Sub
onLoadError:
If Err.Number = 0 Then
Resume Next
ElseIf Err.Number = 5 Then
Resume Next
ElseIf Err.Number = 5825 Then
Resume Next
ElseIf Err.Number = 5903 Then
Resume Next
'ElseIf Err.Number = 5155 Then
' Resume Next
ElseIf Err.Number = 4248 Then
Resume Next
Else
MsgBox "This error is in the onLoad sub in the newNormal RibbonControl" _
& vbCrLf & vbCfLf & "Error: " & Err.Number & vbCrLf & Err.Description, ,
"Error"
End If
End Sub
(Please excuse my error handling. I was in a hurry when I wrote this code and just haven't gotten back around to doing it properly.)
Is there a way for me to wait to execute the onLoad sub until Word has opened the document (by simple double-click)? I'm sure I'm missing something here, but I'm struggling to find any information about this online.
Move the code to an application level event handler. The code will run each time a new document is opened, but that can be remedied if needed (see code comments).
Create a new class module and name the class module EventMngr.
Place the following code in the class module:
Public WithEvents appevent As Application
Private Sub appevent_DocumentOpen(ByVal Doc As Document)
'This code will only allow the event to fire once
Static hasOpened As Boolean
If hasOpened Then Exit Sub Else hasOpened = True
'Place Code Here...
End Sub
Then you can place this line in a normal module before any other subs/functions
'application level event handler
Public myEventHandler As New EventMngr
And last, place this in your Ribbon OnLoad sub:
'application event handler
Set myEventHandler.appevent = Application
Similar to the previous answer but possibly simpler is to add autoopen and autonew procedures to your code and capture the activedocument in those procedures rather than the onload procedure.
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
I am currently working on a VBA-Project where I want to protect the Code with a password.
Furthermore, I want to use the following lines of code:
Public Sub main()
'Dim CodeModuleSoure As Variant
Dim CodeModuleDestination As Variant
With Application.VBE.ActiveVBProject.VBComponents
'Set CodeModuleSoure = Nothing
Set CodeModuleDestination = .Item(.Count)
CodeModuleDestination.codemodule.addfromstring "Private Sub Worksheet_Activate()" _
& vbCrLf & "Call RefreshRibbon" _
& vbCrLf & "End Sub"
End With
End Sub
This basically adds
Private Sub Worksheet_Activate()
Call RefreshRibbon
End Sub
to the code.
As this does not work while the project is still protected I had a "little" research and found this: Is there a way to crack the password on an Excel VBA Project
Lastly I created a function where I first call the "crack" and then the "code-writer":
Sub otherfuncts()
unprotected
Call Sheet4.main
End Sub
When I try to run the otherfuncts function with a Button it gives me this Error:
If I open the VBA-Project it actually is "cracked" and if I rerun the code after viewing the Project the button does not give me an error. Is there a solution that it works in the first try?
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
I have textbox and command button in the form1.
I will input path in the textbox
After the clicking the command button, workbook from the path location should open and need to the require macros code like copying , etc
when i tried using the . I getting error saying that file1.xlsx not found . plz help
Private Sub CommandButton1_Click()
Set wb1 = Workbooks.Open("file1")
End Sub
Private Sub TextBox1_Change()
Dim file1 As String
file1 = TextBox1.Value
End Sub
Private Sub UserForm_Click()
End Sub
The suggestions in the comments above will get you where you need to go, but if I may suggest... rather than using a textbox for the user to enter the name in, use the GetOpenFilename dialog. In this way you can ensure that the path is valid and the file actually exists. It also gives the user a nice GUI which is more like what they're used to for a File -> Open dialog. Something like this:
Private Sub CommandButton1_Click()
Dim vnt As Variant
On Error GoTo ErrorHandler
vnt = Application.GetOpenFilename("Excel Files (*.xlsx; *.xls; *.xlsm),*.xlsx;*.xls;*.xlsm", 1, "Please select the file to open")
If vnt = False Then Exit Sub
Application.Workbooks.Open (vnt)
ExitPoint:
Exit Sub
ErrorHandler:
MsgBox "Error " & Err.Number & vbCrLf & Err.Description
Resume ExitPoint
End Sub