I am trying to prevent an excel workbook from closing based-on the state of a checkbox.
My sample code that is placed in 'ThisWorkbook' :
Private Sub Workbook_BeforeClose(Cancel As Boolean)
If CheckBox0.Value = "FALSE" Then
b = MsgBox("Are you sure that you want to submit?", vbYesNo)
End If
If b = vbNo Then Cancel = True
End Sub
At the moment, I am getting a run-time error 424 , object required and the debug points at the If CheckBox0.Value..... line.
I am not sure what I am doing wrong and I'm not a regular VBA user.
Help, please.
I think you're using an embedded Checkbox (ActiveX). If so, you need to specify the sheet that the checkbox lives in. You can't just say Checkbox0 because you can have Checkbox0 on multiple sheets.
The other thing is that you can't check for "False" because it's not a string, but a boolean value, so you can just use False because that is an inherent VBA keyword.
Here's what I think you're looking for:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim b As Long
If (Sheets("Sheet1").CheckBox1.Value = False) Then
b = MsgBox("Are you sure that you want to submit?", vbYesNo)
End If
If b = vbNo Then Cancel = True
End Sub
EDIT:
Forgot to mention to switch "Sheet1" for the sheet name that your checkbox lives in.
Related
I developed many UDFs and macros in VBA for Excel 2016. One of my macros uses an Inputbox to get data used subsequently by the macro. I want to replace the Inputbox with a user form. I have created the user form, with one text box. I want to activate the user form, populating the text box with the default data, and return the text box data to the macro when OK is selected. I have searched extensively for an end-to-end example for all the the code needed to do this, with no luck. Does an example for this simple problem exist?
Add a Property to your user form. For this answer, let us use the following code within the user form.
Public Property Get MyResult() As String
' You may want to do any manipulation here
' including converting to a number, in which case the return type should be changed (*)
MyResult = TextBox1.Text
End Property
(*) If you are doing conversion, you can have another function in your user form to disable the "OK" button until they have valid convertible data in the text box.
You also want to know if they have hit "Cancel"
Public Property Get Cancelled() As Boolean
Cancelled = pCancelled ' Declare pCancelled as a Boolean in the scope of the form
End Property
Public Sub CancelButton_Click() ' Standard click event for the button
pCancelled = True
Me.Hide
End Sub
Public Sub OKButton_Click() ' Standard click event for the button
pCancelled = False
Me.Hide
End Sub
In your calling macro
MyForm.Show ' This is modal, so will block execution until a response is provided
If Not MyForm.Cancelled Then
Debug.Print MyForm.MyResult
'Do something with MyForm.MyResult
End If
UnLoad MyForm ' assuming you do not want to re-use this form as part of your logic.
There is an example of how you can pass the value to a form and get the result back. The approach uses Scripting.Dictionary object created within standard module scope and passed to userform to allow values to be changed. So it makes possible to send the default values to userform, and keep the result values in the dictionary even after the userform is closed and unloaded. You may have multiple values, just add the necessary quantity of keys to the dictionary, e. g. oData("property1"), oData("property2"), etc.
Add a standard module to the project and put the below code into it:
Option Explicit
Sub Test()
Dim oData
' Set default value and show form
Set oData = CreateObject("Scripting.Dictionary")
oData("") = "Some default text"
UserForm1.ShowForm oData
' Wait until user close form
Do While IsUserFormLoaded("UserForm1")
DoEvents
Loop
' Output returned value
MsgBox oData("")
End Sub
Function IsUserFormLoaded(UserFormName As String) As Boolean
Dim oUF As Object
For Each oUF In UserForms
If LCase(oUF.Name) = LCase(UserFormName) Then
IsUserFormLoaded = True
Exit Function
End If
Next
End Function
Add a userform module named UserForm1 to the project, place controls as shown:
And put the below code into the userform module :
Private opData
Public Sub ShowForm(oData)
Set opData = oData
Me.TextBox1.Value = opData("")
Me.Show
End Sub
Private Sub UserForm_Initialize()
If TypeName(opData) <> "Dictionary" Then Set opData = CreateObject("Scripting.Dictionary")
End Sub
Private Sub CommandButton1_Click()
Unload Me
End Sub
Private Sub CommandButton2_Click()
opData("") = Me.TextBox1.Value
Unload Me
End Sub
The VBA code below is meant to allow only certain users to tick & un-tick a checkbox. However, the problem is that if I check the box and then close the spreadsheet, when I re-open the excel file the 'tick' is no longer there. It's like the code does not save the 'tick' action. Basically, if I check the box I want that to stay like that, even after closing the spreadsheet. In the VBA code below i added ThisWorkbook.Save in order to save the "Tick" action but it simply saves the spreadsheet instead of saving the "Tick" in the check box. Could you please advise what's wrong in my code? I've asked this question before but unfortunately nobody seemed to be able to find a solution. thanks so much
Private Sub CheckBox1_Click()
If CheckBox1.Value = True Then
If (UCase(Environ("username")) = "TESTNAME") Then
'Do nothing
Else
'Uncheck because user not matching
CheckBox1.Value = False
MsgBox ("You are not authorized to tick this box.")
End If
End If
ThisWorkbook.Save
End Sub
on my sheet1 I have a commandButton (bShow) and in the code behind:
Private Sub bShow_Click()
UserForm1.Show
End Sub
then I have a UserForm named UserForm1 with a checkbox (named checkBox1) and a button named saveButton, and with a code behind:
Private Sub saveButton_Click()
Sheets(1).Cells(1, 1).Value = UserForm1.CheckBox1.Value
End Sub
with this setup in cell("A1") appears TRUE or FALSE depending on the checkbox state
i hope it helps
EDIT1:
by opening the Form reading the value from the sheet:
Private Sub UserForm_Activate()
UserForm1.CheckBox1.Value = Sheets(1).Cells(1, 1).Value
End Sub
EDIT2:
be aware of error handling (eg.: what if cell value is neither TRUE nor FALSE) But that I leave to you
I have an excel workbook with multiple sheets. Is there any way to password protect users from even opening a sheet within the workbook? The sheet has a large graph on it that I don't want everyone to be able to see, let alone edit.
Thanks in advance for your help
EDIT
I used the following code to allow users to click a formcontrol button to access the sheet in question.
Sub ShowHeatMap()
Dim S As String
S = InputBox("Enter Password")
If S = vbNullString Then
Exit Sub
ElseIf S <> "wiretransfer" Then
Exit Sub
Else
Worksheets("Training Heat Map").Visible = xlSheetVisible
End If
End Sub
This is associated with my button on a kind of "homepage" sheet that I added to the workbook.
But I can't get the sheet to remain hidden when you open the workbook again. I tried this code:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ThisWorkbook.Worksheets("Training Heat Map").Visible = xlSheetVeryHidden
End Sub
Any ideas? This code is inputted on the module for the sheet under general declarations
Via this answer, I think this might do the trick for you. Within VBA, put this within ThisWorkbook:
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Dim MySheets As String, Response As String
MySheet = "Sheet1"
If ActiveSheet.Name = MySheet Then
ActiveSheet.Visible = False
Response = InputBox("Enter password to view sheet")
If Response = "MyPass" Then
Sheets(MySheet).Visible = True
Application.EnableEvents = False
Sheets(MySheet).Select
Application.EnableEvents = True
End If
End If
Sheets(MySheet).Visible = True
End Sub
Obviously will require a bit of tailoring to your needs. Remember that you will also need to password protect your VBA code, otherwise anyone will be able to view it and find out the password.
First of all, I'm a total Excel interop noob.
I'm trying to get a date from a cell and then set the title of the document before the document gets saved, to be the month of the date. This is my code:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
ThisWorkbook.Title = DateTime.Month(ThisWorkbook.Sheets("Sheet1").Cell("A10"))
End Sub
I'm not sure that anything is working. I set a breakpoint on the code, but I can't "run" it because it's not a macro, but an event handler, so I don't think the breakpoint is going to work. I don't get any errors. I don't even know that ThisWorkbook.Title is what I want and I'm not even sure about getting the month from the cell.
To change the 'Title' built in property in Excel:
ActiveWorkbook.BuiltinDocumentProperties("Title") = "My Title Name"
The title of the document is a "Built In" property - this is the info that appears when you right click on the file and look at the properties.
The name of the spreadsheet is set on save, so you will want to save the file with a new name if you want to see the date on the file itself
A code something like this should give you the result you desire:
(note that this code is VBA, so it may need some tweaking to work in interop.
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Dim FilePath As String
Dim varName As String
On Error GoTo ErrorHandler
' This disables all Excel events.
Application.EnableEvents = False
' disable the default behaviour of the save like so:
Cancel = True
'you can leave this blank if you want it to save in the default directory
FilePath = "C:\The path\To\The File"
varName = Format(ThisWorkbook.Sheets("Sheet1").Cell("A10"),"mmmm")
ActiveWorkbook.SaveAs Filename:=FilePath & varName & ".xlsx"
ErrorExit:
' This makes sure events get turned back on again no matter what.
Application.EnableEvents = True
Exit Sub
ErrorHandler:
MsgBox "No value submitted - File Not Saved"
Resume ErrorExit
End Sub
I assume this would serve your purpose:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Application.Caption = MonthName(Month(ThisWorkbook.Sheets("Sheet1").Range("C10").Value))
End Sub
Another thing is:
This title would not be there next time you open the workbook. So:
Private Sub Workbook_Open()
Application.Caption = MonthName(Month(ThisWorkbook.Sheets("Sheet1").Range("C10").Value))
ThisWorkbook.Save
End Sub
I'm curious as to whether it's possible to pass the protection status of an excel worksheet to a cell of that worksheet.
e.g.
Sheet1 is locked for editing...cell A1 would be programmed to say "locked"
Sheet1 is unlocked...cell A1 would say "unlocked".
A button on the sheet would be used to toggle worksheet protection on and off.
My sheet will be locked upon opening using a workbook_open event.
This is for a sheet where I don't want the formulae getting all mucked up upon use, but where full access might be required. Its more as a reminder to the user that they are in "Unlocked" Mode so to be extra careful.
Is using VBA a foregone conclusion?
I'm a VBA noob but don't mind using code as a solution for this
Any thoughts or suggestions welcome
You could use code in an ActiveX button on Sheet1 to do this simply
Const strPAss = "test"
Private Sub CommandButton1_Click()
If ActiveSheet.ProtectContents Then
ActiveSheet.Unprotect strPAss
[a1].Value = "unlocked"
Else
[a1].Value = "locked"
ActiveSheet.Protect strPAss
End If
End Sub
Put this in the worksheet's code module, which will place a reminder in the Status Bar (this avoids needing to lock/unlock the sheet in order to write the status in to cell A1).
Put this in Sheet1 code module. The macro will execute every time sheet1 is activated.
Private Sub Worksheet_Activate()
If ActiveSheet.ProtectContents then
Application.StatusBar = "This sheet is protected"
Else:
Application.StatusBar = "This sheet is unprotected"
End If
End Sub
Private Sub Worksheet_Deactivate()
Application.StatusBar = False
End Sub
To protect/unprotect the worksheet you could add this to an Insert>Module. Then attach these macros to separate command buttons, or run from the Developer>Macros ribbon.
Const myPassword as String = "password" '<-- replace "password" with your password
Sub Sht1Protect()
Sheet1.Protect myPassword
End Sub
Sub Sht1Unprotect()
Sheet1.Unprotect myPassword
End Sub
To ensure the sheet is always protected when you close the file, insert this in the Workbook code module
Private Sub Workbook_Close()
Sht1Protect
End Sub
You may need additional handling to control whether the file is saved/not saved etc.