I have a Workbook with multiple Sheets. I have a menu page (Worksheet) with multiple user choices (Enter a new order, update an order, etc.) Each choice has a check box beside it and depending on which check box is checked, cells F4:F21 change from 0 to 1 and, cell B1 changes to the name of the Worksheet where I want to go. I have the following VBA in the Main Menu worksheet but when I click a check box, nothing happens. Any ideas why?
CODE
Private Sub Worksheet_Activate()
ClearMenuForm
End Sub
Private Sub Worksheet_Change (ByVal Target As Range)
Dim sh As String
If Not Intersect(Target, Range("F4:F21")) Is Nothing Then
sh = Cells(1, "B").Value
Sheets(sh).Select
End If
End Sub
Clicking a check box does not activate the event Worksheet_Change (see this). That is why nothing happens.
Try changing one of the cells instead to see the effect.
What I think you want to do is assign an action to your Checkbox(es). You can do this in two ways:
Right clicking on the checkbox, and Assign Macro...
You have to create the associated macro, which will likely contain parts of the code that you already wrote, and/or calls to subs you have. You may bring the VBE (Alt+F11), insert a module in your VBA project, and write your Sub, e.g.,
Sub CheckBox1_Click()
MsgBox "Checkbox 1a has changed"
End Sub
Via VBA (e.g., this). With the sample code below, you would execute InitCBs, and that would associate CheckBox1Change with the checkbox (it actually assigns actions for both checkboxes in the figure; action for checkbox 2 is CheckBox2Change). You may also set InitCBs to be executed when opening the file.
Sub CheckBox1Change()
MsgBox "Checkbox 1b has changed"
End Sub
Sub InitCBs()
Dim cb As CheckBox
For Each cb In ActiveSheet.CheckBoxes
With cb
Dim action As String
'action = "CheckboxChange"
action = Replace(cb.Name, " ", "") & "Change"
.OnAction = action
End With
Next cb
End Sub
You've defined sh as a String. Since there is no sheet named "1", for example, your code will generate a "Subscript out of Range" runtime error. Try changing sh to a Long.
Dim sh As Long
Related
I've got two buttons on a worksheet that I've named "RemoveButton" and "AddButton". I've also added hyperlinks to both shapes and both shapes will point to the same cell once clicked. When I click both buttons, they point to cell A1 as expected, but the FollowHyperlink code does not recognize that a hyperlink has been clicked.
I wanted to use the FollowHyperlink worksheet event to recognize the shape that is clicked. I created the macro as below:
Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink)
Debug.Print "Clicked!"
End Sub
When clicking on the shapes, they just point to A1 and "Clicked!" never shows in my Immediate window. However, I created a test hyperlink that is text only and when selected, "Clicked!" appears. This indicates that Excel isn't treating the buttons as hyperlinks even though they have hyperlinks added to them.
The reason for the hyperlinks on the shape is for them to run code. I could use the assign macro feature to the shape, but in doing so I wouldn't be able to add a ScreenTip to the shape. I really want the ScreenTip as this will help future users know what the button is for.
Can someone please help me understand if this is possible?
Screenshot of buttons
There is a workaround for this problem. Instead of the Worksheet_FollowHyperlink event, you can use the Worksheet_SelectionChange event.
To do this, you need a cell that is completely covered up by your button. If the button is too small to cover up a cell, you can just hide a row and a column and place the button at the intersection of the hidden row and column.
Now, we link the button with the "hidden" cell, C5 in this example:
Now the hidden cell can only be selected by clicking the button.
So if the Target in the Worksheet_SelectionChange event is the cell C5, we know that the button has been clicked.
To leave the previous selection unaffected, you can use the following code in the worksheet's code module:
Option Explicit
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Const HIDDEN_CELL_ADDESS As String = "$C$5" '<--Set hidden cell address here
Static previousSelection As Range
If Target.Address = HIDDEN_CELL_ADDESS Then
'Make sure the linked cell doesn't stay selected, otherwise the next
'click on the button may not be recognized
Application.EnableEvents = False
If Not previousSelection Is Nothing Then previousSelection.Select
If TypeName(Selection) = "Range" Then
If Selection.Address = HIDDEN_CELL_ADDESS Then Target.Offset(1).Select
End If
Application.EnableEvents = True
Call ShapeClicked
Else
Set previousSelection = Target
End If
End Sub
Sub ShapeClicked()
MsgBox "The button has been clicked"
End Sub
GWD's answer correctly solves the issue. I also found a slightly different way to work around this as well. Please see below:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not Intersect(Target, Range("B11")) Is Nothing Then
Call dispatchLink(Target.Address)
End If
End Sub
I am trying since 2 days to find how to do the following without finding anything that suits the aim:
Steps by order :
user open excel file
he chose between folowing :
Paste an image directly in the worksheet (may be an limited area)
activate some video in the workbook (may be a webcam for start)
he select with a button to activate his clicks detection
he clicks anywhere on the picture and i get the coordinates of clicked points
So far i've seen ppl using (and tested myself) :
mouse event ==> this does not work as i need to know the name of what he is clicking on and it may be a brand new picture he just pasted
BeforeDoubleClick (same, i'd prefer avoid doubleclick but even then it doesnt work when i click on something else but cells)
Selectionchange ==> doesnt work if im not clicking on cells
Place hidden button over the area i want : i cant click a button if its not visible, and it becomes visible when i click it if i put as transparent
If anyone has ideas about this...
(nb: im not a pro of vba so i may have missed something)
Just forgot : my issue is not getting the coordinates of mouse, its just triggering the macro when i want, for now im jsut trying to get a simple msgbox to see if trigger works.
Thanks if anyone has any ideas
BR
Not sure if this fits your need (for example couldn't test it with a video).
a) Place a "button" of any kind on your sheet. I usually use a square shape for that and format it a little bit (color, shade, text). Assign the subroutine SetEvents to it.
b) Declare a global variable that remembers that click-activation is active
Option Explicit
Global EventCatchingActive As Boolean
c) In the event routine of your button, set the OnAction-method for all shapes of the sheet - see the routine setEvents. This ensures that even newly added images handle the click event.
Sub setEvents()
' This routine is called from the magic button.
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(1) ' Set this to whatever sheet you need
Dim button As Shape
Set button = ws.Shapes(Application.Caller)
If EventCatchingActive Then
EventCatchingActive = False
button.TextFrame2.TextRange.Characters.Text = "Start Clicking"
Else
Debug.Print "Setting EventHandler"
Dim sh As Shape
For Each sh In ThisWorkbook.Sheets(1).Shapes
' Debug.Print sh.Name, sh.Type
If sh.Name <> button.Name Then sh.OnAction = "ClickedMe"
Next
EventCatchingActive = True
button.TextFrame2.TextRange.Characters.Text = "Stop Clicking"
End If
End Sub
d) Declare a routine that is called if any of the shapes is clicked. With Application.Caller you can check what was clicked.
Sub ClickedMe(Optional target As Range = Nothing)
If Not EventCatchingActive Then Exit Sub
If target Is Nothing Then
Debug.Print "I clicked on " & Application.Caller
Else
Debug.Print "I clicked on cell " & target.Address
End If
End Sub
(note that code of steps b) to d) goes into a regular module)
e) If you also want to handle clicks on a cell, add the following into the sheet-module of the worksheet you are dealing with.
Private Sub Worksheet_SelectionChange(ByVal target As Range)
ClickedMe target
End Sub
I use the SendKeys method, for user-friendliness, with an InputBox, for selecting multiple cells to use for calculations.
I want to avoid having the user hold CTRL while clicking each cell or pressing Shift-F8 to select multiple cells.
I want the InputBox to pop up and to select cells that are not necessarily right next to one another, without having to do anything else.
Here is a sample of what I have.
Sub CalculateIt()
Dim calcRange As Range
On Error Resume Next
SendKeys "+{F8}"
Set calcRange = Application.InputBox("Select the cells you would like to use.", Type:=8)
If Err.Number = 424 Then Exit Sub
Dim stuff As Double
For Each calcCell in calcRange
If IsNumeric(calcCell.Value) Then stuff = stuff + calcCell.Value
Next calcCell
MsgBox "The Solution: " & Sqr(stuff)
End Sub
I want to avoid using the SendKeys method because I've read a lot about it being finicky and fragile, and that it can cause problems. I have run into some scenarios where it doesn't work and I have to hold CTRL or do Shift-F8 anyways.
Possible solution... Add a checkbox to the worksheet then go into the Microsoft Excel Objects | ThisWorkbook window and enter the following code. If the checkbox is checked, then whatever formula you'd like executed will be as the user clicks each cell.
Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
Dim nbrCell As Double
If IsNumeric(ActiveCell.Value) Then nbrCell = ActiveCell.Value Else nbrCell = 0
If ActiveSheet.CheckBox1.Value = True Then ActiveSheet.Range("A1").Value = ActiveSheet.Range("A1").Value + nbrCell
End Sub
You can also add a second checkbox to remove selected cells if you're concerned the user might accidentally click on the wrong cell and want that value removed.
I'm working in Excel. I'd like to press a button to cancel the value of the cell at the left of the button itself.
So the user experience should be the following:
When the user presses "button1", the cell at its left became 0. The same for "button2" and "button3"
How can I do?
By using a Macro?
Assign this macro to any and all buttons, and it'll delete the info. in the cell directly to the left.
Sub test()
Dim btnRow&, btnCol&
btnRow = ActiveSheet.Shapes(Application.Caller).TopLeftCell.Row
btnCol = ActiveSheet.Shapes(Application.Caller).TopLeftCell.Column
Cells(btnRow, btnCol).Offset(0, -1).ClearContents
End Sub
Or, thanks to #Rory, this can be:
Sub test()
Activesheet.Shapes(Application.Caller).TopLeftCell.offset(0,-1).ClearContents
End Sub
Note: Make sure your shapes are well placed, as this uses wherever the top left of the shape is to determine the row/column. This macro reduces the need to run three different ones, depending on where, and minimizes any If/Then type statements as it uses the Caller to determine which shape, which determines where it is.
May this help...
'Add three buttons on the sheet
'And imaging that you want to delete B4 B5 B6
'You can discover which button is, by double cliking on the desing mode
'on your excel
Private Sub CommandButton1_Click() 'This is the button on the cell C4
Range("B4").ClearContents
'Here B4 is the range of the cell you want to delete...
'This could be acomplish just pressing the button DELETE
'Same by the two other buttons... just adding 1 to the number
'B4...B5...B6
'With this you only can delete de contents of the cell...
End Sub
Private Sub CommandButton2_Click() 'This is the button on the cell C5
Range("B5").ClearContents
End Sub
Private Sub CommandButton3_Click() 'This is the button on the cell C6
Range("B6").ClearContents
End Sub
Hyperlink method is what I've done before. Like it, because it look like it can click.
Add below code on the Worksheet module, when a hyperlink clicked, it will trigger the sub
Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink)
If LCase(Target.Range.Text) Like "delete*" Then
ActiveCell.Offset(0, -1).ClearContents
End If
End Sub
You can use below code to generate as much as hyperlink you want.
Sheets(XXX).Hyperlinks.Add Anchor:=Selection, Address:="", SubAddress:= _
"", TextToDisplay:="Delete"
If your using command button
Option Explicit
Sub Button1_Click()
Range("A1") = 0
End Sub
or assign to worksheet
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not Intersect(Target, Range("B1")) Is Nothing Then _
Range("A1") = 0
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