Display MsgBox on cell click - even when the cell is already selected - vba

I want a MsgBox to appear when cell A1 is clicked. I want it to appear even if A1 is already active when it is clicked:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Application.EnableEvents = False
If Target.Row = 1 And Target.Column = 1 Then
MsgBox ("message")
End If
Application.EnableEvents = True
End Sub
This code works only if cell A1 is not already selected when I click on it. Currently the message box does not appear in this case.
Is there a way to fix this?

Your code is using Worksheet_SelectionChange which only fires when a different cell is selected (hence the name Selection Change).
Alternatively, if it's okay if your [unknown] goal is attained using double click or right click then there are other worksheet events that will help:
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
MsgBox Target.Address & " was double clicked"
Cancel = True 'don't edit cell
End Sub
 
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
MsgBox Target.Address & " was right clicked"
Cancel = True 'don't open context menu
End Sub
Note that the code for these event procedures need to be placed in the worksheet module.
Edit: More creative ways
Click Event via PeekMessage API
If it must be a single click, there are "sneakier" ways to accomplish this, such as adding a Click event. This is not a built-in feature of Excel VBA, and thus, this method is not generally recommended.
It involves checking for the WM_MOUSEMOVE message when a cell is mouse-clicked, which is accomplished by calling the PeekMessage API inside the Worksheet_SelectionChange event. More info and examples here.
Transparent command button
There could also be a round-about way to accomplish this using an ActiveX Command Button with no caption, with the BackStyle property set to frmBackStyleTransparent.
Neither of these methods have been tested and you might need to do some fancy coding to get them to work. Depending on how often the same cell will be clicked that is already selected (and therefore how that functionality is to you), you may want to simply re-think the layout of your worksheet.
For example, you could add an extra column and have the user click the cell next to the one with the value to activate your message box.
More Information:
MSDN : Worksheet.BeforeDoubleClick Event (Excel)
MSDN : Worksheet.BeforeRightClick Event (Excel)
Chip Pearson : Events in Excel VBA

Related

Identifying a cell by clicking on it, from an open user form

Is it possible to use the mouse to select a cell whilst a user form is open, then programmatically transfer that cell address into the user form (similar to defining a data source range for a chart)??
For that you will need to do two things:
1 - Show your UserForm as Modeless, to do so:
Sub ShowUserForm()
UserForm1.Show vbModeless
End Sub
2 - In the worksheet code, you will need to add an action under the SelectionChange:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If UserForm1.Visible Then
UserForm1.TextBox1.Text = Target.Address
End If
End Sub

Handling single click and double click events on activeX button in VBA

I would like to handle single click and double click events separately for an ActiveX button in VBA. My issue is that the single click event is called for both single and double clicks. Is there a way to supress/bypass the single click procedure when a double click event occurs? I'm sure there's a simple answer for this, but can't find anything on the web...
From Help
If there is code in the Click event, the DblClick event will never trigger, because the Click event is the first event to trigger between the two. As a result, the mouse click is intercepted by the Click event, so the DblClick event doesn't occur.
Try capturing Mouse Down and Mouse Up, wait 500 ms, if no Mouse Down, then it's a single click, if there is wait the time for a mouse down.
DoubleClickSpeed
HKCU\Control Panel\Mouse
Data type Range Default value
REG_SZ 100 - 900 (milliseconds in decimal) 500
Brad Yundt provides this clever workaround at Experts-Exchange in this post.
I have assumed you have asked this wrt Excel- pls let me know if I am mistaken
You might try using Application.OnTime to schedule a response to a
leftclick after say a 1 second delay. If a doubleclick or rightclick
occurs in the meantime, then the leftclick event in the OnTime sub
will not occur.
The following code goes in the code pane for the worksheet being watched. Note that it uses the code name for that worksheet, not the tab name.
As written, the code watches A1:A10 for either a leftclick, rightclick or doubleclick on a single cell. It then displays a message box naming the cell that was clicked and the type of click.
worksheet event code
Dim bTrapped As Boolean
Dim cel As Range, rgWatch As Range
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
If Not Intersect(cel, Target) Is Nothing Then
MsgBox "Doubleclick at " & cel.Address
bTrapped = True
Cancel = True
End If
End Sub
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
If Not Intersect(cel, Target) Is Nothing Then
MsgBox "Rightclick at " & cel.Address
bTrapped = True
Cancel = True
End If
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim targ As Range
Set rgWatch = Range("A1:A10")
Set targ = Intersect(Target, rgWatch)
If Not targ Is Nothing Then
If targ.Cells.Count = 1 Then
bTrapped = False
Set cel = targ.Cells(1, 1)
'Allow 1 second for user to complete a rightclick or doubleclick before trapping leftclick
Application.OnTime Now + 1 / 86400, "Sheet1.DelayedWatch" 'Note that Sheet1 is codename for worksheet (not tabname)
End If
End If
End Sub
Private Sub DelayedWatch()
If bTrapped = False Then
MsgBox "Leftclick at " & cel.Address
End If
End Sub
I know this reply is years late but to cancel an event, so as to prevent another event happening (on the same event) (ie. prevent single click for happening when you act on the double click) do the following;
Private Sub CheckBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
'Do your stuff in here to handle the doubleClick event
Cancel = True 'send back a true boolean to cancel the singleClick
End Sub

Excel VBA user event

I am working with Excel VBA and I have a macro that is fired everytime a specific cell is changed. That macro affects the value and properties of many cells on the worksheet, so I used
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
[...] 'mycode
Application.EnableEvents = True
End Sub
At the beginning and end of the macro. Otherwise whenever I change the cell that fires the macro, the macro changes cell and thus fires itself over and over again.
I would like for the macro to be fired if I manually change a cell (without having to insert a command button that fires the macro or something similar)
Is that possible?
Thanks for the help
Private Sub Worksheet_Change(ByVal Target As Range)
If (Target.Column =4) Then
MsgBox ("mycell changed")
End If
End Sub
This basically says if the column change occurs in Index 4 (D) then msgbox.
if you didn't have the if statement the messgbox would occur anytime a change occurs to any cell in the worksheet.

Excel VBA: How to trigger an Event from code?

I have a Worksheet_BeforeDoubleClick event that opens a listbox in the target cell. I was asked to provide the same functionality via a button instead of (or in addition to) the double-click.
In the button's Click event I entered:
Call Worksheet_BeforeDoubleClick(Selection,true)
...so the button simply "doubleclicks" the cell. It seems to work well, but before I start using this technique throughout my project, I'd like to know if there are pitfalls I should be aware of.
What are the best practices when calling an event, either from another event or from a standard code module?
I'd like to know if there are pitfalls I should be aware of.
Yes there is one major pitfall. The Selection necessarily might not be a range. See this example
Insert a button
Insert a blank chart
Insert an image in the chart. Let the image be highlighted
Let's say we have this code
Private Sub CommandButton1_Click()
Call Worksheet_BeforeDoubleClick(Selection, True)
End Sub
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
MsgBox Target.Address
End Sub
Now press the button and you will get an error.
The worksheet events WILL fire when they NEED too... They won't when the selection is not appropriate.
Having said that you CAN make your command button code work like this
Private Sub CommandButton1_Click()
'~~> Check if what the user selected is a valid range
If TypeName(Selection) = "Range" Then
Call Worksheet_BeforeDoubleClick(Selection, True)
Else
MsgBox "Not a Valid Range"
End If
End Sub
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
MsgBox Target.Address
End Sub
But then where all and what all CHECKS will you place :) The best way is to place it in a Sub as #Sam suggested and then call it either from Button/Worksheet_BeforeDoubleClick.
If you still want to call it from a button then ensure that all relevant checks are in place including a proper error handler.

VBA - leave current cell

I have some code that reacts to a double click. This action works just fine, my question though.. after filling in the form that pops up due to the double click action the form is unloaded, no problem here, but the user is left in edit mode inside the cell he double clicked on.
Now normally in Excel you can press CTRL-Enter and the cell will just simply be selected and you out of edit mode. How do I achieve this in VBA ?
All I can seem to work is moving the cell up one, but really just want the user to exit Edit mode and stay on the current cell, the one he double clicked on.
Private Sub Cancel_Click()
Cells(ActiveCell.Column, ActiveCell.Row - 1).Activate
Cells(ActiveCell.Column, ActiveCell.Row).Activate
Unload Term
End Sub
Any suggestions ?
Use the BeforeDoubleClick's Cancel argument, which ... cancels clicking into the cell:
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Cancel = True
UserForm1.Show
End Sub