I am using VBA calendar to input dates in my workbook. I have added code to my worksheet to call calendar on double click of cell. So basically when I double click cell in range I get calendar form, where I pick up the date and then it is inserted in double clicked cell. The only problem is that after closing my calendar form my cell gets selected and I see formula inside my cell. How I can make it close my calendar form without selecting cell after it?
I have used this calendar:
https://trevoreyre.com/portfolio/excel-datepicker/
Code to call calendar form by double clicking cell in range:
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Dim xRg As Object
If Not Intersect(Target, Range("E7:F187")) Is Nothing Then dateVariable = CalendarForm.GetDate
if datevariable=0 then
exit sub
else
For Each xRg In Selection.Cells
xRg.Value = dateVariable
Next xRg
End if
'datevariable=0
End Sub
try, this. It seems that you can select another cell in the code.
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Dim rng As Range
Set rng = Target.Offset(1, 0)
If Not Intersect(Target, Range("E7:F187")) Is Nothing Then datevariable = CalendarForm.GetDate
If datevariable = 0 Then
rng.Select
Exit Sub
Else
Target.value = datevariable
rng.Select
End If
End Sub
Related
I load a userform via a double-click event executed on a range of cells. Once any of the cells in the range gets double clicked, my userform is loaded.
I would like the input boxes of the userform populated with data that is based on an offset of the triggering cell.
I am struggling with capturing the address of the cell that triggered the event, and consequently would need to figure out how to offset from that cell's column and obtain the relevant value for population in the userform.
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
If Not Application.Intersect(Target, Sheets("Daily Summary").Range("D27:D93")) Is Nothing Then
Cancel = True
CommentDetails.Show
End If
End Sub
a) How do I capture the dynamic cell address that triggered the userform load?
b) How do I offset three columns to the right, capture that cell's value and load it into the userform's input field named first_name?
Thanks to #Zwenn in the comments for pointing me in the right direction with Application.Caller. Updated code below, it executes but shows a Object Required error.
The name of the form is CommentDetails, the name of the input field is TextBoxArrival, both of which matches the code.
Private Sub Userform_initialize()
Me.TextBoxArrival.Value = Cells(Application.Caller.Row, Application.Caller.Column + 1)
'TextBoxArrival.Value = Cells(Application.Caller.Row, Application.Caller.Column + 1)
'MsgBox Cells(Application.Caller.Row, Application.Caller.Column + 1).Value, vbOKOnly
End Sub
I understand I have to declare application.caller along with the calling method, which in my case is Sub Worksheet_BeforeDoubleClick. Still getting the same error. I tried circumventing this by calling another separate sub before loading the userform.
Where do I define application.caller?
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Dim callingCellRow As Integer
If Not Application.Intersect(Target, Sheets("Daily Summary").Range("D27:D29")) Is Nothing Then
Select Case TypeName(Application.Caller)
Case "Range"
callingCellRow = Application.Caller.Row
callingCellColumn = Application.Caller.Column
Case "String"
callingCellRow = Application.Caller.Row
callingCellColumn = Application.Caller.Column
callingCellSheet = Application.Caller
Case "Error"
MySheet = "Error"
Case Else
MySheet = "unknown"
End Select
With CommentDetails
.Tag = callingCellRow '<~~ tell the UserForm there's something to bring in so that it'll fill controls from the sheet instead of initializing them
.Show
.Tag = ""
End With
Unload CommentDetails
End If
End Sub
There's 3 ways to do this explained on Daily Dose of Excel by Dick Kusleika (18 years ago!). I prefer the 3rd option as it handles the form instance with a variable.
In Worksheet_BeforeDoubleClick you can have this:
Option Explicit
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Dim objForm As UserForm1
If Not Application.Intersect(Target, Me.Range("B2:D2")) Is Nothing Then
Cancel = True
Set objForm = New UserForm1 ' <-- use a variable for the form instance
Set objForm.rngDoubleClicked = Target ' <-- set property of the form here with Target
objForm.Show
End If
End Sub
And then in the form code:
Option Explicit
Private m_rngDoubleClicked As Range
' set only
Public Property Set rngDoubleClicked(rng As Range)
Set m_rngDoubleClicked = rng
End Property
' use the property
Private Sub UserForm_Activate()
Dim strAddress As String
Dim rngOffset As Range
' m_rngDoubleClicked is now the range that was double clicked
strAddress = m_rngDoubleClicked.Parent.Name & "!" & m_rngDoubleClicked.Address
Set rngOffset = m_rngDoubleClicked.Offset(3, 0)
Me.TextBox1.Text = "The address of the double clicked cell is " & strAddress
Me.TextBox2.Text = "The value 3 rows down from double clicked cell is " & rngOffset.Text
End Sub
Private Sub UserForm_Initialize()
' no args for initialization unfortunately :(
End Sub
Example:
I want a msgbox to show up only once when formula result changes in my table range ("K2:K5"). Right now it shows twice.
In this range I have excel-formulas. Formula: H12*10
These formulas is refering to a dropdown-list (a list that I've created from "data validation" on the excel menu Data-tab).
The dropdown-list is located in cell H12.
The values in the dropdown is refering to range(D15:D17)
I've noticed though that the msgbox shows up once when I remove the dropdown and manualy type in values in H12.
Thankful for any help on this
Private Sub Worksheet_Calculate()
Dim Xrg As Range
Set Xrg = Range("K2:K5")
If Not Intersect(Xrg, Range("K2:K5")) Is Nothing Then
MsgBox "Hi"
End If
End Sub
I have also tried to add Application.enableEvents to the code but no success.
Private Sub Worksheet_Calculate()
Dim Xrg As Range
Set Xrg = Range("K2:K5")
Application.EnableEvents = False
If Not Intersect(Xrg, Range("K2:K5")) Is Nothing Then
MsgBox "Hi"
End If
Application.EnableEvents = True
End Sub
Your current code has no added value on a Worksheet_Calculate event due to comparing two exact same ranges and see if they intersect. That would always be the case. Your code would have the same effect as:
Private Sub Worksheet_Calculate()
MsgBox "Hi"
End Sub
Might you have more functions in your worksheet that could trigger this event unwanted outside range K2:K5, you should look into the Worksheet_Change event and return a messagebox when your referenced cell has changed value.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$H$12" Then MsgBox "Hi"
End Sub
Choose either one, but don't use both cause you'll end up with two msgbox's
I have a problem. How do I enable/disable a button depending on whether a cell is empty or not.
In excel sheet named "Sheet1" I have 1 button called "CommandButton1" assigned to a macro named "If_empty".
What I need to do is if column "F2" is empty I want to disable the button but if column "F2" has any values in it for the button to be enabled.
How do I achieve this?
Help is greatly appreciated
As #Slai and Doug suggested, use the code below (add it to your Worksheet_Change event).
Private Sub Worksheet_Change(ByVal Target As Range)
Dim WatchRange As Range
Dim IntersectRange As Range
Dim i, j As Integer
Set WatchRange = Range("F2")
Set IntersectRange = Intersect(Target, WatchRange)
If Not IntersectRange Is Nothing Then
If Target.Value = "" Then
CommandButton1.Enabled = False
Else
CommandButton1.Enabled = True
End If
End If
End Sub
I'm using a Worksheet_Change to ClearContents on specific cells. The cell being evaluated for the change is "A10". This value comes from a data validation list. I've noticed that when there is a value in this cell and I click the dropdown, even if I re-select the same value from this list, the clear contents performs. Is there a way to avoid this? I'm worried that the users of this sheet will want to view the options in the dropdown, but will ultimately keep the original A10 value and still lose the contents of the other cells.
Here is the code:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rang As Range
Set rang = Worksheets("Sheet1").Range("A10")
If Not Intersect(Target, rang) Is Nothing Then
Worksheets("Sheet1").Range("B10:B50000", "C10:C50000").ClearContents
End If
End Sub
Thanks in advance!
Here is a version of your macro that keeps track of the old value in A10
If no real change is made, it just goes away:
Dim OldValue As Variant
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rang As Range
Set rang = Worksheets("Sheet1").Range("A10")
If IsEmpty(OldValue) Then
OldValue = rang.Value
Exit Sub
End If
If Not Intersect(Target, rang) Is Nothing Then
If OldValue = rang.Value Then
Exit Sub
End If
OldValue = rang.Value
Application.EnableEvents = False
Worksheets("Sheet1").Range("B10:B50000", "C10:C50000").ClearContents
Application.EnableEvents = True
End If
End Sub
Because OldValue is DIM'ed above the sub, its value is preserved from call to call.
In excel 2000, is it possible to bind a vba function to be executed when a cell is clicked with the mouse?
Found a solution:
Make a named range for the cells you want to capture clickevent
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Application.EnableEvents = False
Application.ActiveSheet.Cells(1, 1).Value = Target.Address
If Not Intersect(Target, Range("MyNamedRange")) Is Nothing Then
' do your stuff
Range("A1").Select
Endif
Application.EnableEvents = True
End Sub
You can bind to a cell double click.
Open VBA, goto the worksheet you want to wire up the event
Select WorkSheet in the dropdown on the top left and BeforeDoubleClick in the top right
The check the Target.Address is equal to the address of the cell you care about and call the function you wish.
Something like this:
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
If Target.Address(True, True, xlA1) = "$A$1" Then
Call MyDemo
End If
End Sub
Private Sub MyDemo()
MsgBox "Hello"
End Sub