In Excel 2010, VBA, when the checkbox is unchecked, the code should not run. However it is running when the checkbox is unchecked. What am I missing?
EDIT: The unchecked checkbox results in "-4146" in the Immediate window. So I changed the IF condition to <> 1. Isn't an unchecked checkbox supposed to be equal to zero?
EDIT 2: I forgot to mention, this is a FORM CONTROL checkbox.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'delete range on the active row from column I to column M and shift up
'I=9, M = 13
Dim delAnswer As VbMsgBoxResult
Const WS_Range As String = "I:M"
'Checks to see if user wants macro turned on
If ActiveSheet.Shapes("Check Box 4").ControlFormat.Value = 0 Then Exit Sub
On Error GoTo ws_exit
Application.EnableEvents = False
'Check to see if user is in applicable range for macro to run
If Not Intersect(ActiveCell, Me.Range(WS_Range)) Is Nothing Then
'Ask user to confirm running macro
With Target
aR = ActiveCell.Row
delAnswer = MsgBox("Delete I" & aR & ":M" & aR & "?", vbYesNo)
'Macro - deletes range of cells on the active row
If delAnswer = vbYes Then
Range("I" & ActiveCell.Row).Resize(, 5).Delete Shift:=xlUp
Else: GoTo ws_exit
End If
End With
End If
ws_exit:
Application.EnableEvents = True
'Debug.Print Selection.Address(ReferenceStyle:=xlA1, RowAbsolute:=False, ColumnAbsolute:=False)
'Debug.Print "ar is " & aR
End Sub
Change
If ActiveSheet.Shapes("Check Box 4").ControlFormat.Value = 0
To
If ActiveSheet.Shapes("Check Box 4").ControlFormat.Value = -4146
-4146 is the numerical equivalent to an unchecked Form Control check box. To test if the check box is indeed checked, use = 1 instead of = -4146
I would determine if the form checkbox is not checked in the following manner:
If Not ActiveSheet.Shapes("Check Box 1").ControlFormat.Value = 1 Then
MsgBox ("unchecked")
End If
I referred to the following answer on how to detect checked value for Form or ActiveX controls: https://stackoverflow.com/a/11991419/5692872
I found these both work by changing:
If ActiveSheet.Shapes("Check Box 4").ControlFormat.Value = 0
to:
If ActiveSheet.Shapes("Check Box 4").ControlFormat.Value <> 1
or
If ActiveSheet.Shapes("Check Box 4").ControlFormat.Value = xloff
Related
I am currently trying to write a piece of code where someone is able to use a checkbox to choose which worksheets they would like to keep and what they would like removed. Here is what that looks like:
(currently debating if I should turn this into a userform but i would still be stuck at this point).
What I would like to do is if the checkbox is unchecked (false) on the worksheet called "Setup", delete the worksheet and move onto the next if statement. From the code below, I am prompt with the run-time error '1004': Unable to get the OLEObjects property of the worksheet class. I have checked and the Checkbox name is the same as what I have in my code.
Sub DeleteSheetCB()
If ThisWorkbook.Worksheets("Setup").OLEObjects("CheckBox1") = False Then
ThisWorkbook.Worksheets("Program Information").Delete
End If
If ThisWorkbook.Worksheets("Setup").OLEObjects("CheckBox2") = False Then
ThisWorkbook.Worksheets("Spend and Trx Data").Delete
End If
If ThisWorkbook.Worksheets("Setup").OLEObjects("CheckBox3") = False Then
ThisWorkbook.Worksheets("Requirements").Delete
End If
If ThisWorkbook.Worksheets("Setup").OLEObjects("CheckBox4") = False Then
ThisWorkbook.Worksheets("TMC Overview").Delete
End If
End Sub
Thank you in advance
EDIT:
I was able to get this piece of code to delete sheets but if possible, would someone be able to sense check this for me please?
Sub DeleteSheetCB()
If ThisWorkbook.Worksheets("Setup").Shapes("Check Box 1").ControlFormat.Value <> 1 Then
ThisWorkbook.Worksheets("Program Information").Delete
Else: End If
If ThisWorkbook.Worksheets("Setup").Shapes("Check Box 2").ControlFormat.Value <> 1 Then
ThisWorkbook.Worksheets("Spend and Trx Data").Delete
Else: End If
If ThisWorkbook.Worksheets("Setup").Shapes("Check Box 3").ControlFormat.Value <> 1 Then
ThisWorkbook.Worksheets("Requirements").Delete
Else: End If
If ThisWorkbook.Worksheets("Setup").Shapes("Check Box 4").ControlFormat.Value <> 1 Then
ThisWorkbook.Worksheets("TMC Overview").Delete
Else: End If
End Sub
The main thing I'd take from your second code is:
It will give you a warning before it deletes each sheet
You'll get a subscript out of range error if the sheet has already been deleted.
You have to update your code if you add a new tick box.
The code below assumes the caption of the checkbox is exactly the same as the name of the sheet to be deleted.
Sub DeleteSheetCB()
Dim chkBox As CheckBox
Dim sMissing As String
With ThisWorkbook.Worksheets("Setup")
For Each chkBox In .CheckBoxes 'Look at all checkboxes in Setup sheet.
If chkBox.Value = 1 Then 'If it's ticked.
If WorksheetExists(chkBox.Caption) Then 'Check worksheet exists.
Application.DisplayAlerts = False 'Turn off warnings about deleting a sheet.
ThisWorkbook.Worksheets(chkBox.Caption).Delete
Application.DisplayAlerts = True 'Turn on warnings about deleting a sheet.
Else
sMissing = sMissing & "- " & chkBox.Caption & vbCr
End If
End If
Next chkBox
End With
If sMissing <> "" Then
MsgBox "These sheet(s) could not be deleted as they were already missing: " & vbCr & vbCr & sMissing
End If
End Sub
Public Function WorksheetExists(SheetName As String) As Boolean
Dim wrkSht As Worksheet
On Error Resume Next
Set wrkSht = ThisWorkbook.Worksheets(SheetName) 'Try and set a reference to the sheet.
WorksheetExists = (Err.Number = 0) 'Was an error thrown?
On Error GoTo 0
End Function
Might also be worth mentioning that you can rename your checkboxes:
Select a check box so the Shape Format ribbon becomes visible.
Click Selection Pane under the Arrange section.
A sidebar will appear showing the shapes on the sheet. You can rename or change their visibility here.
chkRemoveProgramInfo makes more sense than Check Box 1.
I have this code but it only work for my first row.
It is suppose to look if the checkbox on B, C or D is checked, and if so, a date + username will automaticaly fill in F and G.
here is a picture of my table:
This is what my code looks like:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Range("B2") Or Range("C2") Or Range("D2") = True Then
Range("G2").Value = Environ("Username")
Range("F2").Value = Date
Else
Range("F2:G2").ClearContents
End If
End Sub
Enter this code in a regular module, select all your checkboxes and right-click >> assign macro then choose ReviewRows.
This will run the check whenever a checkbox is clicked - a bit of overhead since all rows will be checked, but should not be a big deal.
Sub ReviewRows()
Dim n As Long
For n = 1 To 100 'for example
With Sheet1.Rows(n)
If Application.CountIf(.Cells(2).Resize(1, 3), "TRUE") > 0 Then
If Len(.Cells(6).Value) = 0 Then 'only enter if currently empty?
.Cells(6) = Date
.Cells(7) = Environ("Username")
End If
Else
.Cells(6).Resize(1, 2).ClearContents
End If
End With
Next n
End Sub
If you want to be more precise then Application.Caller will give you the name of the checkbox which was clicked, and you can use that to find the appropriate row to check via the linkedCell.
Sub ReviewRows()
Dim n As Long, shp As CheckBox, c As Range, ws As Worksheet
Set ws = ActiveSheet
On Error Resume Next 'ignore error in case calling object is not a checkbox
Set shp = ActiveSheet.CheckBoxes(Application.Caller) 'get the clicked checkbox
On Error GoTo 0 'stop ignoring errors
If Not shp Is Nothing Then 'got a checkbox ?
If shp.LinkedCell <> "" Then 'does it have a linked cell ?
With ws.Range(shp.LinkedCell).EntireRow
If Application.CountIf(.Cells(2).Resize(1, 3), "TRUE") > 0 Then
If Len(.Cells(6).Value) = 0 Then 'only enter if currently empty?
.Cells(6) = Date
.Cells(7) = Environ("Username")
End If
Else
.Cells(6).Resize(1, 2).ClearContents
End If
End With
End If 'has linked cell
End If 'was a checkbox
End Sub
However this appraoch is sensitive to the exact positioning of your checkbox
You have a long way to go!
Unfortunately, If Range("B2") Or Range("C2") Or Range("D2") = True Then is beyond repair. In fact, your entire concept is.
Start with the concept: Technically speaking, checkboxes aren't on the worksheet. They are on a layer that is superimposed over the worksheet. They don't cause a worksheet event, nor are they responding to worksheet events. The good thing is that they have their own.
If Range("B2") Or Range("C2") Or Range("D2") = True Then conflates Range with Range.Value. One is an object (the cell), the other one of the object's properties. So, to insert sense into your syntax it would have to read, like, If Range("B2").Value = True Or Range("C2").Value = True Or Range("D2").Value = True Then. However this won't work because the trigger is wrong. The Worksheet_Change event won't fire when when a checkbox changes a cell's value, and the SelectionChange event is far too common to let it run indiscriminately in the hope of sometimes being right (like the broken clock that shows the correct time twice a day).
The answer, therefore is to capture the checkbox's click event.
Private Sub CheckBox1_Click()
If CheckBox1.Value = vbTrue Then
MsgBox "Clicked"
End If
End Sub
Whatever you want to do when the checkbox is checked must be done where it now shows a MsgBox. You can also take action when it is being unchecked.
I have a ActiveX CheckBox control on worksheet "A" and another on worksheet "B". When I check the CheckBox at "A", I want my macro to check the CheckBox at "B".
What I have tried so far:
This: Sheets("B").Shapes("CheckBox1").ControlFormat.Value = xlOn
And this: ThisWorkbook.Worksheets(1).Shapes("Check Box 1").OLEFormat.Object.Value = 1
Both codes give me an error saying that the the object doesn't accept this property or method.
So it's not possible to check a CheckBox from another worksheet?
I find it useful to use a With ... End With statement to reference a worksheet as it allows multiple operations.
With Worksheets("B")
' for Form Control Checkbox
.Shapes("Check Box 2").ControlFormat.Value = xlOn
' for ActiveX Control Checkbox
.Shapes("CheckBox1").OLEFormat.Object.Object.Value = xlOn
End With
The prefix period (aka . or full stop) applies the parent worksheet.
Checkbox1 in sheet 1 to change checkbox1 in sheet 2
Private Sub CheckBox1_Click()
If Me.CheckBox1 = True Then
Sheets("Sheet2").CheckBox1.Value = True
Else
Sheets("Sheet2").CheckBox1.Value = False
End If
End Sub
For me, replacing the numbers 1 and 0 as for, respectively, the
boolean "True" and "False" did not work. Some say that ActivexControl
has "False" equal to -4146 and FormControl has "False" as equal to 0. This did not work either. The snipped below is now working.
Dim i as Integer
For i = 1 to 502
If Sheets("Sheet1").Shapes("Alpha-" & i).ControlFormat.Value = 1 Then '<-- FormControl
Sheets("Sheet2").Shapes("beta" & i).OLEFormat.Object.Object.Value = 1 '<--ActivexControl
Else
Sheets("Sheet2").Shapes("beta" & i).OLEFormat.Object.Object.Value = 0 '<--ActivexControl
End If
next i
I'm current working with VBA which is quite new for me. I'am trying to embeeded my checkbox into it specific cells so that each time the cells (row) is hidden, the checkbox will be hidden also with the cell.
below is the code I'm currently using to insert the Checkbox
ActiveSheet.CheckBoxes.Add(Cells(lRow, "A").Left, _
Cells(lRow, "A").Top, _
72, 17.25).Select
With Selection
.Caption = ""
.Value = xlOff
.LinkedCell = "C" & i
.Display3DShading = False
End With
Thanks.
AFAIK, I don't think so.
There's also no known Event to trap hiding and un-hiding of rows (again AFAIK).
The closest I can give is something like:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
On Error GoTo halt
Application.EnableEvents = False
Dim cb As CheckBox
Set cb = Me.Shapes("Check Box 1").OLEFormat.Object
cb.Top = Me.Range("cbrange").Top
cb.Visible = IIf(Me.Range("cbrange").Height = 0, False, True)
forward:
Application.EnableEvents = True
Exit Sub
halt:
MsgBox Err.Description
Resume forward
End Sub
This doesn't automatically hides the Checkbox, not until you select another range.
Take note that we used a named range which is the range that contains your Checkbox.
This is to make sure that the Checkbox stays with that cell even if the you insert rows. HTH somehow.
I'm trying to use an IF-clause to determine whether my checkbox, named "Check Box 1", is checked.
My current code:
Sub Button167_Click()
If ActiveSheet.Shapes("Check Box 1") = True Then
Range("Y12").Value = 1
Else
Range("Y12").Value = 0
End If
End Sub
This doesn't work. The debugger is telling me there is a problem with the
ActiveSheet.Shapes("Check Box 1")
However, I know this code works (even though it serves a different purpose):
ActiveSheet.Shapes("Check Box 1").Select
With Selection
.Value = xlOn
My checkboxes (there are 200 on my page), are located in sheet1, by the name of "Demande". Each Checkbox is has the same formatted name of "Check Box ...".
Sub Button167_Click()
If ThisWorkbook.Worksheets(1).Shapes("Check Box 1").OLEFormat.Object.Value = 1 Then
Range("Y12").Value = 1
Else
Range("Y12").Value = 0
End If
End Sub
1 is checked, -4146 is unchecked, 2 is mixed (grey box)
Is this what you are trying?
Sub Sample()
Dim cb As Shape
Set cb = ActiveSheet.Shapes("Check Box 1")
If cb.OLEFormat.Object.Value = 1 Then
MsgBox "Checkbox is Checked"
Else
MsgBox "Checkbox is not Checked"
End If
End Sub
Replace Activesheet with the relevant sheetname. Also replace Check Box 1 with the relevant checkbox name.
Building on the previous answers, you can leverage the fact that True is -1 and False is 0 and shorten your code like this:
Sub Button167_Click()
Range("Y12").Value = _
Abs(Worksheets(1).Shapes("Check Box 1").OLEFormat.Object.Value > 0)
End Sub
If the checkbox is checked, .Value = 1.
Worksheets(1).Shapes("Check Box 1").OLEFormat.Object.Value > 0 returns True.
Applying the Abs function converts True to 1.
If the checkbox is unchecked, .Value = -4146.
Worksheets(1).Shapes("Check Box 1").OLEFormat.Object.Value > 0 returns False.
Applying the Abs function converts False to 0.
It seems that in VBA macro code for an ActiveX checkbox control, you use
If (ActiveSheet.OLEObjects("CheckBox1").Object.Value = True)
and for a Form checkbox control, you use
If (ActiveSheet.Shapes("CheckBox1").OLEFormat.Object.Value = 1)
Try: Controls("Check Box 1") = True