Macro Add Texts On Double-Click - excel

I made the following code that adds a text when double-clicking a cell. But i need a routine where if i double-click again in the same cell it will add a different text, if i click a third time it will add another text, and so on. This loop should continue for 6 different texts.
Thanks in advance for any help.
Private Sub Worksheet_BeforeDoubleClick( _
ByVal Target As Range, Cancel As Boolean)
Dim rInt As Range
Dim rCell As Range
Set rInt = Intersect(Target, Range("H2:H2000"))
If Not rInt Is Nothing Then
For Each rCell In rInt
rCell.Value = "Info"
Next
End If
Set rInt = Nothing
Set rCell = Nothing
Cancel = True
End Sub

You'll need to test what the cell already has in it, and add the required word based on that
Private Sub Worksheet_BeforeDoubleClick( _
ByVal Target As Range, Cancel As Boolean)
Dim Words(0 To 5) As String
Words(0) = "1st word"
' etc to fill array
Dim rInt As Range
Set rInt = Intersect(Target, Me.Range("H2:H2000"))
If Not rInt Is Nothing Then
Select Case Target.Value2
Case Words(5)
'Already has last word
Case Words(4)
Target.Value2 = Words(5)
Case 'etc for other Words 3..0
Case Else
Target.Value2 = Words(0)
End Select
Cancel = True
End If
End Sub

Cycle Array Values on Double-Click
Option Explicit
Private Sub Worksheet_BeforeDoubleClick( _
ByVal Target As Range, Cancel As Boolean)
Const fcAddress As String = "H2"
Dim Strings As Variant
Strings = VBA.Array("One", "Two", "Three", "Four", "Five", "Six")
With Me.Range(fcAddress)
With .Resize(Me.Rows.Count - .Row + 1)
If Intersect(.Cells, Target) Is Nothing Then Exit Sub
End With
End With
Cancel = True
Dim IsFound As Boolean
Dim siValue As Variant: siValue = Target.Value
If Not IsError(siValue) Then
If Len(siValue) > 0 Then
Dim siIndex As Variant
siIndex = Application.Match(siValue, Strings, 0)
If IsNumeric(siIndex) Then
If siIndex <= UBound(Strings) Then
IsFound = True
End If
End If
End If
End If
If IsFound Then
Target.Value = Strings(siIndex)
Else
Target.Value = Strings(0)
End If
End Sub

Related

VBA code is not working using Private Sub Worksheet_Change Function

I am trying to use selection from cell E73 to hide or display rows on two different tabs. my vba code below only works for one tab and not both. Can you spot where my issue is? Any help is appreciated.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng As Range
If Target.CountLarge > 1 Then Exit Sub
Select Case Target.Address(0, 0)
Case "E73"
Set rng1 = Sheets("Proposal").Rows("349:403")
Set rng2 = Sheets("Binder").Rows("350:404")
Case "E128"
Set rng1 = Sheets("Proposal").Rows("404:462")
Set rng2 = Sheets("Binder").Rows("405:463")
End Select
If rng Is Nothing Then Exit Sub
Select Case Target.Value
Case "Included"
rng1.Hidden = False
rng2.Hidden = False
Case "Excluded"
rng1.Hidden = True
rng2.Hidden = True
End Select
End Sub
If rng Is Nothing Then Exit Sub
This is always True, because rng is never Set.
A guess as to what you want:
Select Case Target.Address(0, 0)
Case "E73"
Set rng1 = Sheets("Proposal").Rows("349:403")
Set rng2 = Sheets("Binder").Rows("350:404")
Case "E128"
Set rng1 = Sheets("Proposal").Rows("404:462")
Set rng2 = Sheets("Binder").Rows("405:463")
Case Else
Exit Sub
End Select
Select Case Target.Value
Case "Included"
rng1.Hidden = False
rng2.Hidden = False
Case "Excluded"
rng1.Hidden = True
rng2.Hidden = True
End Select
End Sub

Limit Worksheet Event Macro to Certain Columns

The following code will update cells to 1-5 based on doubleclicks on the cell.
I'm looking to limit this to a few columns in the spreadsheet (e.g. if I doubleclick on A2, nothing should happen).
Clearly the .Columns("B:C") is not in the right spot.
Private Sub Worksheet.Columns("B:C")_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Cancel = True
If Target.Value < 5 Then
Target.Value = Target.Value + 1
Else
Target.Value = 5
End If
End Sub
As mentioned by Scott Craner in the comments, the proper way to handle this is to test if the Target range intersects the columns.
I would also recommend setting Cancel = True. This prevents the cell from going into edit mode.
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
If Not Intersect(Columns("B:C"), Target) Is Nothing Then
If Target.Value < 5 Then
Target.Value = Target.Value + 1
Else
Target.Value = 5
End If
Cancel = True
End If
End Sub
A Worksheet Before Double-Click: Increment Cell Value
Adjust the values in the event procedure.
Option Explicit
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
' Reference (set) the range (columns).
Dim srg As Range: Set srg = SetColumnsUR(Me, "B2:C2,E2,G2:H2")
' Check if the double-clicked cell ('Target') doesn't intersect.
If Intersect(srg, Target) Is Nothing Then Exit Sub
' Write the integer according to the logic.
Target.Value = MyIntegerLogic(Target.Value, 1, 5)
' Suppress the default behavior of double-clicking a cell.
Cancel = True
End Sub
Function SetColumnsUR( _
ByVal ws As Worksheet, _
ByVal FirstRowAddress As String) _
As Range
With ws.Range(FirstRowAddress)
With .Areas(1).Resize(ws.Rows.Count - .Row + 1)
Set SetColumnsUR = Intersect(.Cells, ws.UsedRange)
End With
If .Areas.Count = 1 Then Exit Function
Set SetColumnsUR = Intersect(SetColumnsUR.EntireRow, .EntireColumn)
End With
End Function
Function MyIntegerLogic( _
ByVal Value As Variant, _
ByVal MinInteger As Long, _
ByVal MaxInteger As Long) _
As Long
Dim Number As Long: Number = MinInteger - 1
If VarType(Value) = vbDouble Then ' is a number
If Int(Value) = Value Then ' is a whole number (integer)
Select Case Value
Case MinInteger To MaxInteger - 1: Number = Value + 1 ' 1.)
Case MaxInteger: Number = MaxInteger ' 2.)
Case Else ' covered below
End Select
End If
End If
If Number = MinInteger - 1 Then Number = MinInteger ' 3.) all other cases
MyIntegerLogic = Number
End Function

vba - add multiple criteria: if entering word #1, #2 and so on in a cell, then messagebox

I'd like to add multiple criteria to this code:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Const srcCol As String = "A"
Const Criteria As String = "*high*"
Dim rng As Range: Set rng = Intersect(Columns(srcCol), Target)
If rng Is Nothing Then
Exit Sub
End If
Application.EnableEvents = False
Dim aRng As Range
Dim cel As Range
Dim foundCriteria As Boolean
For Each aRng In rng.Areas
For Each cel In aRng.Cells
If LCase(cel.Value) Like LCase(Criteria) Then
MsgBox ("Please check 2020 assessment")
foundCriteria = True
Exit For
End If
Next cel
If foundCriteria Then
Exit For
End If
Next aRng
Application.EnableEvents = True
End Sub
At the current state, this works in this way: if a cell of column "A" contains word "high", alert pop up.
I would like to add more criteria: if cell in column "A" contains "high" but ALSO if a cell in column "A" contains "critic", show me the same alert box.
I started from row "Const Criteria As String = "high", and tried adding "And", "Or", "If", "& _", but nothing seems working to add the second criteria.
Any hint?
A Worksheet Change: Target Contains One of Multiple Strings
If you plan on using exclusively contains for the various criteria, you can do the following changes:
Const CriteriaList As String = "high,critic" ' add more
If LCase(cel.Value) Like "*" & LCase(Criteria(n)) & "*" Then
The Code
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Const srcCol As String = "A"
Const Delimiter As String = "," ' change if you need "," in the criterias
Const CriteriaList As String = "*high*,*critic*" ' add more
Dim rng As Range: Set rng = Intersect(Columns(srcCol), Target)
If rng Is Nothing Then
Exit Sub
End If
Dim Criteria() As String: Criteria = Split(CriteriaList, Delimiter)
Application.EnableEvents = False
Dim aRng As Range
Dim cel As Range
Dim n As Long
Dim foundCriteria As Boolean
For Each aRng In rng.Areas
For Each cel In aRng.Cells
For n = 0 To UBound(Criteria)
If LCase(cel.Value) Like LCase(Criteria(n)) Then
MsgBox ("Please check 2020 assessment")
foundCriteria = True
Exit For
End If
Next n
Next cel
If foundCriteria Then
Exit For
End If
Next aRng
Application.EnableEvents = True
End Sub

Two Private Subs in One Worksheet [duplicate]

I am looking to limit my workbook users to 1000 characters over a range of cells (Example: A5:A30).
In other words limit the total characters in the range A5:A30 to 1000 characters.
When a user fills in a cell that sends the range over the 1000 character limit, it will call Application.undo which should just remove the last text that they added.
However since I have another Private Sub Worksheet_Change(ByVal Targe As Range) on the worksheet, it causes a bug.
Below is both Worksheet_Change subs. Both use the same cells.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim charCount As Long
If Not Intersect(Target, Range("E6,E11,E16")) Is Nothing Then
Dim arrValues As Variant
arrValues = Range("E6,E11,E16").Value2
Dim i As Long
Dim tempSplit As Variant
Dim j As Long
For i = LBound(arrValues) To UBound(arrValues)
tempSplit = Split(arrValues(i, 1), " ")
For j = LBound(tempSplit) To UBound(tempSplit)
charCount = charCount + Len(tempSplit(j))
Next j
Next i
End If
If charCount > 1000 Then
Application.Undo
MsgBox "Adding this exceeds the 1000 character limit"
End If
If Not Intersect(Target, Range("D6")) Is Nothing Then
If Target.Value2 = "Material" Then
'assumes the comment cell is one column to the right
Target.Offset(0, 1) = "**"
End If
End If
If Not Intersect(Target, Range("D7")) Is Nothing Then
If Target.Value2 = "Material" Then
'assumes the comment cell is one column to the right
Target.Offset(-1, 1) = "**"
End If
End If
If Not Intersect(Target, Range("D8")) Is Nothing Then
If Target.Value2 = "Material" Then
Target.Offset(-2, 1) = "**"
End If
End If
End Sub
Is there a way around this so I can have two Worksheet_Change on the same worksheet?
You cannot have two Worksheeet_Change events in one sheet. But, one is quite enough:
Private Sub Worksheet_Change(ByVal Target As Range)
Select Case True
Case Not Intersect(ActiveCell, Range("A5:A30")) Is Nothing
DoThingOne
Case Not Intersect(ActiveCell, Range("B5:B30")) Is Nothing
DoThingTwo
End Select
End Sub
Private Sub DoThingOne()
Debug.Print "THING ONE"
End Sub
Private Sub DoThingTwo()
Debug.Print "THING TWO"
End Sub
How about this revision using Vityata's idea?
Private Sub Worksheet_Change(ByVal Target As Range)
Select Case True
Case Not Intersect(Target, Range("E6,E11,E16")) Is Nothing
Dim charCount As Long
Dim arrValues As Variant
arrValues = Range("E6,E11,E16").Value2
Dim i As Long
Dim tempSplit As Variant
Dim j As Long
For i = LBound(arrValues) To UBound(arrValues)
tempSplit = Split(arrValues(i, 1), " ")
For j = LBound(tempSplit) To UBound(tempSplit)
charCount = charCount + Len(tempSplit(j))
Next j
Next i
If charCount > 1000 Then
With Application
.EnableEvents = False
.Undo
.EnableEvents = True
End With
MsgBox "Adding this exceeds the 1000 character limit"
End If
Case Not Intersect(Target, Range("D6")) Is Nothing
If Target.Value2 = "Material" Then
'assumes the comment cell is one column to the right
Target.Offset(0, 1) = "**"
End If
Case Not Intersect(Target, Range("D7")) Is Nothing
If Target.Value2 = "Material" Then
'assumes the comment cell is one column to the right
Target.Offset(-1, 1) = "**"
End If
Case Not Intersect(Target, Range("D8")) Is Nothing
If Target.Value2 = "Material" Then
Target.Offset(-2, 1) = "**"
End If
End Select
End Sub

Double click to insert character on merged cells

I want to insert or remove a "X" inside cells inside a certain range ("A1:A19"), by double clicking. The code below is placed on the "Microsoft Excel Objects\ThisWorkbook" in the project macro.
Private Sub Workbook_SheetBeforeDoubleClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean)
If Not Intersect(Target, Range("A1:A19")) Is Nothing Then
If Len(Trim(Target)) = 0 Then
Target.Value = "X"
Cancel = True
ElseIf UCase(Trim(Target)) = "X" Then
Target.ClearContents
Cancel = True
End If
End If
End Sub
This code works for non merged cells. However, I have a situation where the cells must be merged ( 2 by 2, in the column), and in this situation I get the following error:
"Run-time error '13'"
Type mismatch
How must be the code modified to prevent this?
try
Private Sub Workbook_SheetBeforeDoubleClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean)
If Not Intersect(Target, Range("A1:A19")) Is Nothing Then
If Target.Cells.Count = 1 Then ' handle single cell
If Len(Trim(Target)) = 0 Then
Target.Value = "X"
Cancel = True
ElseIf UCase(Trim(Target)) = "X" Then
Target.ClearContents
Cancel = True
End If
Else ' handle merged
Dim theAddress As String
theAddress = Split(Target.Address, ":")(0) & ":" & Split(Target.Address, ":")(0)
If Len(Trim(Range(theAddress))) = 0 Then
Target.Value = "X"
Cancel = True
ElseIf UCase(Trim(Range(theAddress))) = "X" Then
Target.ClearContents
Cancel = True
End If
End If
End If
End Sub
When your cells are merged, target is returning a range of multiple cells and it is trying to put a value into cells it can't put values into. Try this:
Private Sub Workbook_SheetBeforeDoubleClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean)
Dim myRange As Range
Set myRange = Target.Cells(1, 1)
If Not Intersect(myRange, Range("A1:A19")) Is Nothing Then
If Len(Trim(myRange)) = 0 Then
myRange.Value = "X"
Cancel = True
ElseIf UCase(Trim(myRange)) = "X" Then
Target.ClearContents
Cancel = True
End If
End If
End Sub
It returns a range reference as being the top left cell in your merged range and allows you to enter values based on that.

Resources