Embeding Checkbox to a specific cells - excel

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.

Related

Multiple VBA targets for data validation on a single sheet

There are similar posts relating to my question, but I have struggled to adapt them to my problem. I currently have the following code which works just fine:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
Application.ScreenUpdating = True
Set Target = Range("B4")
If Target.Value = "Yes" Then
Call DropDownListOn
Else
Call DropDownListOff
End If
Application.EnableEvents = True
End Sub
and the macros that are being called are:
Option Explicit
Sub DropDownListOn()
Sheet1.Activate
Sheet1.Range("A5").Value = "Plot default probability"
Sheet1.Range("B5").Validation.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Formula1:="Yes, No"
End Sub
and
Option Explicit
Sub DropDownListOff()
Sheet1.Range("A5").Value = ""
Sheet1.Range("B5").Validation.Delete
End Sub
Essentially what it does is as follows: Cell B4 is dropdown list. If "Yes" is chosen, then by calling the macro "DropDownListOn", it generates a new dropdown list in cell B5. This part works just fine; but, say, that once the dropdown list in cell B5 appears, I want to call another macro if B5 is chosen to be "Yes" (e.g., generating another dropdown list in cell B6). Given that only one target can be assigned to each sheet, this does not seem to be very straightforward. There seem to be suggestions for ways around this obstacle on Stackoverflow, but I struggle to adopt these to my own case. Any help and/or sample code will very much be appreciated.
Please, try the next updated event:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address(0, 0) = "B4" Then
If Target.Value = "Yes" Then
Call DropDownListOn 'it let it creating the drop-down in "B5", TRIGGERING the change event
'but delete the charts ONE BY ONE!
Else
Application.EnableEvents = False
Call DropDownListOff 'the event is not triggered here.
'if you want to also clear "B6", you should place such a code line in the above Sub...
Application.EnableEvents = True
End If
ElseIf Target.Address(0, 0) = "B5" Then
Application.EnableEvents = False
'Place here the sub able to create the drop-down validation in "B6"
'it let it creating something else, but without triggering the event
Application.EnableEvents = Trud
End If
End Sub

How to apply code to all the following rows

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.

After user input, and I have autofilled 2 other textboxes, how do I stop my macro from running a search on the other boxes?

I have 3 textboxes, of which when you input data into any one of the textboxes, the other 2 will populate.
the codes are very long, so I've just added what it does at every line of code
Private Sub tbAC_AfterUpdate()
'Declarations
textbox 1 = tbAC
textbox 2 = tbAN
textbox 3 = tbIC
If tbAC is Nothing Then
tbAC = ""
Elseif tbAC.TextLength > 0 Then
'Find tbAC in column AGC
Set MCodef = wsa.Columns(AGC).Find(what:=tbAC, LookIn:=xlValues, Lookat:=xlPart)
If MCodef is Nothing Then
Msgbox ("Invalid Code")
Else
Mcoder = Mcodef.Row
tbAN = wsa.Range(AGN & Mcoder).Value
tbIC = wsa.Range(AIC & Mcoder).Value
End if
End If
End Sub
'It's pretty much the same if you fill in tbAN or tbIC
Private Sub tbAN_AfterUpdate()
End Sub
Private Sub tbIC_AfterUpdate()
End Sub
Given that user input in tbAN, I only want excel to run the sub tbAN_AfterUpdate and not the others. Any help would be appreciated, thanks in advance!
If you have code that is triggered by entering data into the text box, but don't want that code to execute when using an alternate function in VBA, you can use:
Application.EnableEvents = False
So if you are entering into TextBox1 and want to update TextBox2 when you enter into TextBox1, put this into TextBox1's Code. You would use this when the code is first initialized, but you need to remember to reverse that at the end of the code or prior to the code terminating (e.g. through Exit Sub or some other forced command) as once EnableEvents = False, no code will trigger without setting it to:
Application.EnableEvents = True

Excel VBA - event change doesn't work

I'm quite new to VBA but so far I'm coming along. Till this moment, where I'm stuck with this challenge.
My goal is to select a percentage (10, 90 or 100) from a drop down menu in a cell in column B, C, D or E and when one of the percentages is selected, I want the same cell to calculate the selected percentage of the value in column A.
So when the cell in column A has a value of "500" and in the same row in Column C I select "90" I want 90 to be replaced with 450 (0.9*500)
The code given here is what I've got so far, including some code already 'borrowed' from another topic. Though it works in a new, clean excel Sheet, it won't work in the document where I want it to work.
Do some of you have any ideas where the flaw can be found?
(I even created a commandbutton with only the task: Application.EnableEvents = True)
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo Whoa
If Not Intersect(Target, Range("B:D")) Is Nothing Then
Application.EnableEvents = False
If Target.Value = 90 Then Target.Value = 0.9 * Cells(Target, 1).Value
ElseIf Target.Value = 10 Then Target.Value = 0.1 * Cells(Target, 1).Value
ElseIf Target.Value = 100 Then Target.Value = Cells(Target, 1).Value
Else
MsgBox "Not a valid percentage"
End If
Letscontinue:
Application.EnableEvents = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume Letscontinue
End Sub
Sounds like you want Workbook_SheetChange event. Add your logic to ThisWorkbook in VBA editor.
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
MsgBox "Cell changed. Target: " & Target.Worksheet.Name & "!" & Target.Address
End Sub
With the above code added to ThisWorkbook changes on any sheet in the workbook will trigger the event.
You don't need VBA to do what you're asking. Data Validation, and a formula will work:
meaning you got stopped by an error while application.enableevents=false, and u ran the thing again without application.enableevents=true in between ...
i actually have a button for this issue, just when i'm debugging code, or in the VB editor, Ctrl+G, in the immediate window , you can write application.enableevents=true

Show/Hide Rows Depending on Dropdown Selection

This is the first time I'm working with Macros.
I've created a dropdown in B2 with a "Yes" and "No" options.
If User selects "Yes", Row 10 Shows / Row 11 Hides
If User Selects "No", Row 11 Shows / Row 10 Hides
I used this code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$B$2" Then
If Range("B2") = Yes Then
ActiveSheet.Rows("10:10").EntireRow.Hidden = False
ActiveSheet.Rows("11:11").EntireRow.Hidden = True
ElseIf Range("B2") = No Then
ActiveSheet.Rows("10:10").EntireRow.Hidden = True
ActiveSheet.Rows("11:11").EntireRow.Hidden = False
End If
End If
End Sub
I Created a new Module in Sheet1, and put it there. I saved the excel as a Macro Enabled Tamplate, however nothing happens when I change the dropdown.
Thanks for your help!
Do yourself a huge favor and get in the habit of writing Option Explicit at the top of every module of VBA code you write.
I have added comments as well explaining your needed revisions.
'this requires you to dimension all variables
'when you used '= yes' VBA thought you were saying
'the same as, = aVariable
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$B$2" Then
If Range("B2").Value = "Yes" Then
'You can reference the row directly on the same sheet
'and do not need ActiveSheet
Rows("10:10").EntireRow.Hidden = False
Rows("11:11").EntireRow.Hidden = True
ElseIf Range("B2").Value = "No" Then
Rows("10:10").EntireRow.Hidden = True
Rows("11:11").EntireRow.Hidden = False
End If
End If
End Sub
Also be aware this is only using "Yes" - using "yes" or "YES" will cause problems. You can use the UCase method as follows if you want to avoid these situations in the future:
If UCase(Range("B2").Value) = "YES" Then
If Range("B2") = "Yes" Then
and similarly with the "No " option

Resources