I've been trying to reproduce a checkbox on Excel with 2 images (1 for Tick and 1 for Untick), but I got a problem because I simply never coded in VBA; apart from macros.
I got multiple checkboxes that are meant to be ticked/unticked.
I could record a macro for each of them, but doing so would be tedious and unefficient (there's 22 checkboxes in total)
The Macro Code looks like this.
Sub Tick()
ActiveSheet.Shapes.Range(Array("Picture 23")).Select
Selection.ShapeRange.ZOrder msoSendToBack
End Sub
Sub Untick()
ActiveSheet.Shapes.Range(Array("Picture 22")).Select
Selection.ShapeRange.ZOrder msoSendToBack
End Sub
My question is easy : How do I fetch the reference of the image I clicked in order to inject this same reference to the code and set its ZOrder ?
I can't use Excel's Checkboxes because they're too small.
Try following
Sub TickToggle()
On Error GoTo EH
Dim caller As Variant
caller = Application.caller
If Not IsError(caller) Then
ActiveSheet.Shapes(caller).ZOrder msoSendToBack
Select Case caller
Case "Checkbox1_tick":
' your code for when the checkbox1 is unticked
Case "Checkbox1_untick":
' your code for when the checkbox1 is ticked
End Select
End If
EH:
End Sub
Also, try using more meaningful names for those shapes (like above) in order to use select case on the caller value and do different things depending on what has been clicked. You can assign TickToggle to all checkbox shapes, this is preferred (re-usability).
Related
I have a sheet with a bunch of ComboBoxes(form control) and I want to detect when a user changes any one of them and write text in a cell. Using Worksheet_Change on the target cells doesn't work. I have tried a bunch of things that don't work. I'm not sure what needs to be in the private sub line or the if statement.
Private Sub DropDowns_DropButtonClick()
If ActiveSheet.DropDowns.Value > 1 Then
Cells(13, 5).Font.Bold = True
Cells(13, 5).Font.Color = vbRed
Cells(13, 5).Value = "!!! Selections have been changed. !!!"
End If
End Sub
I have tried
ComboBox_AfterUpdate()
ComboBox_Change()
DropDowns_AfterUpdate()
DropsDowns_Change()
and anything else I could find. I've also tried a few different things in the if statement with no luck.
I appreciate any help.
Chris
If I'm reading you correctly, you're comboboxes are in a userform. If I'm correct, simply open your userform in 'Visual Basic' and double click on the relavant combobox. This will open the code pane and create an empty Private Sub routine called 'Private Sub <Combobox Name> ()'.
Enter your code to place your data in the sheet (or whatever else you want) into the subroutine and Bob should be your uncle.
Apologies in advance if there's something I've missed.
RannochRob
Edit...
OK, my mistake, it's a form control.
My first comment is that it's easier to use an activex control if you can... however, with a form control, should (a) Use the cell link box in the 'Format Control' drop down ('Control' tab) to place the result in a cell... however, that result will not be the content of the box but an integer equal to the position of the selected entry on the list of entries in the combobox. You then need to (b) assign a macro to the combobox which will pick up the result and use it to get the required information from the range containing the list of entries. Like I say, much easier with an activex control...
RannochRob
Here's how you can do it by assigning a macro to the combobox (right click on the combobox>assign macro) as #BigBen mentioned in the comments section:
Option Explicit
Sub DropDown1_Change()
Dim sht As Worksheet
Dim dd As DropDown
Set sht = ThisWorkbook.Worksheets("Name of your Worksheet") 'Name of the worksheet in which the combobox is located
Set dd = sht.DropDowns("Drop Down 1") 'name of your combobox
sht.Range("G1").Value = "The selected value is: " & dd.List(dd.Value) 'dd.value returns the index of the selected value
End Sub
You can use the same code for each one of your comboboxes.
For demonstration purposes i have used the following set-up:
You can easily modify the code to best fit your needs.
I am struggling try to solve an easy problem.
I have check boxes in Sheet 1 and check boxes in sheet 2 that have to assume the same value (TRUE or FALSE) of the ones in Sheet 1.
The problem is that when I open Sheet 2 they are not marked but I have to click on them with the mouse.
I'm using this code:
Sheet2.chk_2A.Value = Sheet1.chk_1a.Value
Am I forgetting an auto update command or something similar?
As far as I can tell there is no need for VBA code here if you link the two check boxes to the same cell. Just assign both check boxes the same cell in Format Control..., Control, Cell link:. If that's not an option then you'll have to place your code into a sub and assign this sub to these check boxes upon click.
In this case your code depends if you used form controls or ActiveX controls. For Form controls you'd have to use
Sheet2.Shapes("chk_2A").controlformat.value = Sheet1.Shapes("chk_1a").controlformat.value
and for ActiveX controls your code suggestion should work if the check boxes are named correctly.
Sheet2.chk_2A.value = Sheet1.chk_1a.value
In both cases I assume that you used either form controls or ActiveX controls. If you used one form control and one ActiveX control then you'll have to adjust the above code suggestions accordingly. The following code can help you determine what you used.
Public Sub AllShapes()
For Each ws In ActiveWorkbook.Worksheets
For Each shp In ws.Shapes
Debug.Print shp.Name
Select Case shp.Type
Case 8
Debug.Print "Form Control"
Case 12
Debug.Print "ActiveX Control"
Case Else
Debug.Print shp.Type
End Select
Next shp
Next ws
End Sub
Scenario: I have tons of images in a single worksheet,and many of them are overlapping with each other.
How can I write a VBA code so when user click on any image in that worksheet and Excel will automatically bring that image to the front?
If you have an object myObject that you want to bring to the front you use
myObject.ShapeRange.Zorder msoBringToFront
http://msdn.microsoft.com/en-us/library/office/aa213680(v=office.11).aspx
Your object might for example be the selection:
set myObject = Selection
As for responding to a click - that's trickier. There doesn't appear to be an event for "selecting a picture" . But there is a solution...
You can make a single macro called Picture_click(), and assign that macro to each picture. There doesn't appear to be an event-driven way to achieve this, but the following works:
Add the following to a module:
Sub picture_click()
ActiveSheet.Shapes(Application.Caller).Select
Selection.ShapeRange.ZOrder (msoBringToFront)
End Sub
Sub connect_all()
Dim sh As Shape
For Each sh In ActiveSheet.Shapes
sh.OnAction = "picture_click"
Next sh
End Sub
You have to run the connect_all sub just once, to assign the picture_click macro to each shape. Now, when you click a picture (or other shape) it comes to the front.
Note - the Application.Caller tells you what object was clicked - in other words, what caused the call to picture_click. This is necessary because the "click" doesn't cause the picture to be selected yet - that happens after the macro has run. So you can't just use the selection. Tricky, that.
I referenced this earlier post to come up with this solution - specifically, RichJ's solution.
afterthought
If you don't want the picture to be selected after you clicked it, you can modify the picture_click() sub to the following:
Sub picture_click()
ActiveSheet.Shapes(Application.Caller).ZOrder msoBringToFront
End Sub
This will move the picture to the front but doesn't select it. There is something to be said for that approach.
With every shape, assign the BringToFront macro, then put the following in a module
Sub BrintToFront
Selection.ShapeRange.ZOrder msoBringToFront
end sub
Assign this macro to all Shapes:
Sub lux()
ActiveSheet.Shapes(Application.Caller).ZOrder msoBringToFront
End Sub
I have a macro which is basically working as I want (alerting the user when two conflicting checkboxes are selected) - code below. The 1 in G2 is the value generated to indicate this case.
The error message fires on SelectionChange, but this appears to be only when another cell is selected by mouse. The worksheet contains a series of checkboxes for the user to select from, and the intention is for the user to only use the checkboxes, never needing to select or input directly into cells. In which case, the error message would never fire even when the scenario described has occurred.
Is there a way of having a msgbox macro trigger by the update of any checkbox on the sheet?
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Range("G2") = 1 Then
MsgBox "ERROR - Select AND Reject checked"
End If
End Sub
Also, I would like to extend the range to apply to all the cells in column G, I just can't seem to get this to work for me. I have seen a few examples citing "G:G" but I have so far only got this to work for one cell.
Apologies in advance for any glaring errors, I've used Excel for a while now - but I'm brand new to using VBA.
Mutually exclusive options are usually indicated with option buttons (also known as radio buttons) instead of checkboxes. Is there any reason you're not using option buttons for this task?
As far as calling the same code for all checkboxes, the checkboxes would have to be Form Controls (not ActiveX Controls), and you could assign them to this macro:
Sub CheckBox_Clicked()
Dim chk As CheckBox
Set chk = ActiveSheet.CheckBoxes(Application.Caller)
MsgBox chk.Name
End Sub
And lastly, for your SelectionChange event to monitor an entire column, it would look similar to this:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim ClickedCell As Range
Dim rngClicked As Range
Application.EnableEvents = False
Set rngClicked = Intersect(Columns("G"), Target)
If Not rngClicked Is Nothing Then
For Each ClickedCell In rngClicked.Cells
If ClickedCell.Value = 1 Then MsgBox "ERROR - Select AND Reject checked"
Next ClickedCell
End If
Application.EnableEvents = True
End Sub
I am working on pulling data out of a standardized form in excel. There is a Forms Control CheckBox that I need the state of. Apparently the only way to get this is from the cell link, where the value is placed into a cell. The problem is, whomever put this form together did not set a cell link. Is there any way to do this using VBA at run time. There are many of these forms that I must go through, so I'm trying to avoid doing it manually.
I think you are referring to a forms checkbox control placed on a worksheet, in which case you can get the state of the control without setting a cell link. Like this:
Sub HTH()
Dim iLoop As Integer
'// Get value of check box by its index
MsgBox (GetCheckBoxState(1))
'// Get value of check box by its name
MsgBox (GetCheckBoxState("Check Box 1"))
'// Loop through all checkboxes and get values
For iLoop = 1 To ActiveSheet.CheckBoxes.Count
MsgBox (GetCheckBoxState(iLoop))
Next
End Sub
Function GetCheckBoxState(vCheckBox As Variant) As String
Select Case ActiveSheet.CheckBoxes(vCheckBox).Value
Case xlOn
GetCheckBoxState = "Checked"
Case xlOff
GetCheckBoxState = "UnChecked"
Case xlMixed
GetCheckBoxState = "Mixed"
End Select
End Function
If you are referring to a check box control on a userform then as Tim pointed out it should be a case of something like:
MsgBox (UserForm1.CheckBox1.Value)