Changing text after click - excel

how to adjust this code, so that it works for the whole column and not only for one cell?
Private Sub Worksheet_SelectionChange(ByVal Target As Excel.Range)
Application.EnableEvents = False
With Target
If .Address = Range("A11:A1").Address Then
Select Case .Value
Case "Excel"
.Value = "Word"
Case "Word"
.Value = "Outlook"
Case "Outlook"
.Value = "Excel"
Case Else
.Value = "Word"
End Select
End If
End With
Range("A2").Select
Application.EnableEvents = True
End Sub
Thank you very much!
Jeame

As follows but you are setting up a recurring chain if you select A2 at the end and your target is column A. I have removed.
Private Sub Worksheet_SelectionChange(ByVal Target As Excel.Range)
Application.EnableEvents = False
If Target.Column = 1 Then 'example column A
With Target
Select Case .Value
Case "Excel"
.Value = "Word"
Case "Word"
.Value = "Outlook"
Case "Outlook"
.Value = "Excel"
Case Else
.Value = "Word"
End Select
End With
End If
Application.EnableEvents = True
End Sub
Edit:
Following on from a change to requirements please see a re-write of your code. The Test sub is just for testing the event.
Option Explicit
Private Sub Test()
Call Worksheet_BeforeDoubleClick(Selection, True)
End Sub
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
If Target.Column = 2 Then
Dim var As Long
Dim targetRange As Range
var = Target.Row
Set targetRange = ActiveSheet.Range("A" & var & ":B" & var) '2 columns of interest for row that was triggered
With targetRange.Columns(2)
Select Case LCase(.Value) 'i.e. column B's value. Add add change to lowercase so test always matches
Case "active"
targetRange.Interior.ColorIndex = 16
.Value = "Finished"
Case "wip"
targetRange.Interior.ColorIndex = 2
.Value = "Done"
End Select
End With
End If
End Sub

Too complicated solution for me. Below is the code, which should work similar but with double click. Before I only did data valiation - listbox with two options. But somehow it does not work to me.
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Var = Target.Row
var2 = "b" + Var
If (Target.Column = 2) Then
If (Range(var2).Value = "Active") Then
var2 = "a" + Var
Range(var2).Interior.ColorIndex = 16
var2 = "b" + Var
Range(var2).Interior.ColorIndex = 16
Range(var2).Value = "Finished"
Else
Var = "b" + Var
If (Range(var2).Value = "WIP") Then
var2 = "a" + Var
Range(var2).Interior.ColorIndex = 2
var2 = "b" + Var
Range(var2).Interior.ColorIndex = 2
Range(var2).Value = "DONE"
End If
End If
End If
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
End Sub

Related

Hide rows with double click

Below is an example I found to hide/open complete rows in Excel with a doubleclick.
It works for a few lines but if I want to do this for 100 lines it's a terrible job.
Is it possible to make this more code-friendly?
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
If Target.Address(0, 0) = "A9" Then
Cancel = True
Rows("10:15").Hidden = Not Rows("10:15").Hidden
End If
If Target.Address(0, 0) = "A16" Then
Cancel = True
Rows("17:22").Hidden = Not Rows("17:22").Hidden
End If
If Target.Address(0, 0) = "A23" Then
Cancel = True
Rows("24:29").Hidden = Not Rows("24:29").Hidden
End If
If Target.Address(0, 0) = "A30" Then
Cancel = True
Rows("31:36").Hidden = Not Rows("31:36").Hidden
End If
If Target.Address(0, 0) = "A37" Then
Cancel = True
Rows("38:43").Hidden = Not Rows("38:43").Hidden
End If
If Target.Address(0, 0) = "A44" Then
Cancel = True
Rows("45:50").Hidden = Not Rows("45:50").Hidden
End If
Try this:
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
If Target.Column <> 1 Then Exit Sub
Dim r As Long
r = Target.Row
If (r - 2) Mod 7 = 0 And r > 2 Then
Rows(r + 1).Resize(6).Hidden = Not (Rows(r + 1).Resize(6).Hidden)
Cancel = True
End If
End Sub
You can use this code
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
If Target.Row < 9 then Exit Sub
If (Target.Row - 2) Mod 7 = 0 Then 'e.g. 9, 16, 23, 30
hideRows Target.Row + 1
End If
End Sub
Private Sub hideRows(startRow As Long)
With Me.Rows(startRow).Resize(6)
.Hidden = Not .Hidden
End With
End Sub
UPDATE after #foxfires comment:
If you like the expand/collapse idea, you can use this code:
Public Sub groupRows(ws As Worksheet)
Dim c As Range
Set c = ws.Cells(9, 1)
While LenB(c.Text) > 0
c.Offset(1).Resize(6).EntireRow.Group
Set c = c.Offset(7)
Wend
With ws.Outline
.SummaryRow = xlSummaryAbove
.ShowLevels 1
End With
End Sub

Disable buffer clearing at a given cell format (NumberFormat = "m/d/yyyy")

I have a macro:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim v
If Target.Cells.Count <> 1 Then Exit Sub
If Target.Column <> 1 Then Exit Sub
v = Target.Value
If VarType(v) <> vbDate Then
Application.EnableEvents = False
If v Like "???##" Or v Like "???-##" Then Target.Value = Left(v, Len(v) - 2) & "20" & Right(v, 2)
If VarType(Target.Value) <> vbDate Then Target.Value = Empty
Target.NumberFormat = "m/d/yyyy"
Application.EnableEvents = True
End If
End Sub
When copying (ex: may20, may-20) from another column to column A in Excel itself with this macro, it allows to paste only once - the next cell is no longer pasted, apparently, the clipboard is cleared after the first paste. I have to copy again from another column. How it can be corrected?
See below - if you need to paste the same value again.
The core problem is that the change event always clears the clipboard - there's no (easy) way I'm aware of to prevent that.
Private Sub Worksheet_Change(ByVal Target As Range)
Const MNTH_NM As String = "[A-Z][A-Z][A-Z]" 'a bit better than "???"
Dim v
If Target.Cells.Count <> 1 Then Exit Sub
If Target.Column <> 1 Then Exit Sub
v = Target.Value
If Len(v) > 0 Then
Application.EnableEvents = False
If UCase(v) Like MNTH_NM & "##" Or UCase(v) Like MNTH_NM & "-##" Then
v = Left(v, 3) & "-20" & Right(v, 2)
Target.NumberFormat = "m/d/yyyy"
Target.Value = v
Target.Copy
Else
Target.ClearContents 'if doesn't match the pattern, clear it
End If
Application.EnableEvents = True
End If 'non-zero length
End Sub

Userform listbox data not showing but seems to be in listbox

Hi I have a search form which shows a listbox of results. It starts out empty and when I conduct a search then rows are created but no data is visible. I have checked a few obvious things like color and all seem normal black font etc. If I have the worksheet with the sourcedata in view the data in the list is visible, but in everyday practice that would not be the case. I think it is conducting the search on the correct results but then displaying the equivalent rows from another worksheet. I'm just not sure how to edit the code to avoid this.
My userform code is this, I assume the problem is where it is calling the Results range but I have tried adding a worksheet reference of the source data to the start of Range.Records and that doesn't seem to help:
Option Explicit
' Display All Matches from Search in Userform ListBox
'
Dim FormEvents As Boolean
Private Sub ClearForm(Except As String)
' Clears the list box and text boxes EXCEPT the text box
' currently having data entered into it
Select Case Except
Case "srchStCat"
FormEvents = False
srchStID.Value = ""
srchStSurname.Value = ""
Results.Clear
FormEvents = True
Case "srchStID"
FormEvents = False
srchStCat.Value = ""
srchStSurname.Value = ""
Results.Clear
FormEvents = True
Case "srchStSurname"
FormEvents = False
srchStID.Value = ""
srchStCat.Value = ""
Results.Clear
FormEvents = True
Case Else
FormEvents = False
srchStCat.Value = ""
srchStID.Value = ""
srchStSurname.Value = ""
Results.Clear
FormEvents = True
End Select
End Sub
Private Sub CmdClear_Click()
ClearForm ("")
End Sub
Private Sub CmdClose_Click()
Me.Hide
End Sub
Private Sub srchStCat_Change()
If FormEvents Then ClearForm ("srchStCat")
End Sub
Private Sub srchStID_Change()
If FormEvents Then ClearForm ("srchStID")
End Sub
Private Sub srchStSurname_Change()
If FormEvents Then ClearForm ("srchStSurname")
End Sub
Private Sub CmdSearch_Click()
Dim SearchTerm As String
Dim SearchColumn As String
Dim RecordRange As Range
Dim FirstAddress As String
Dim FirstCell As Range
Dim RowCount As Integer
' Display an error if no search term is entered
If srchStCat.Value = "" And srchStID.Value = "" And srchStSurname.Value = "" Then
MsgBox "No search term specified", vbCritical + vbOKOnly
Exit Sub
End If
' Work out what is being searched for
If srchStCat.Value <> "" Then
SearchTerm = srchStCat.Value
SearchColumn = "Current Role"
End If
If srchStID.Value <> "" Then
SearchTerm = srchStID.Value
SearchColumn = "ID Token"
End If
If srchStSurname.Value <> "" Then
SearchTerm = srchStSurname.Value
SearchColumn = "Surname"
End If
Results.Clear
' Only search in the relevant table column i.e. if somone is searching srchStSurname
' only search in the srchStSurname column
With Worksheets("Staff").Range("StaffFullData[" & SearchColumn & "]")
' Find the first match
Set RecordRange = .Find(SearchTerm, LookIn:=xlValues)
' If a match has been found
If Not RecordRange Is Nothing Then
FirstAddress = RecordRange.Address
RowCount = 0
Do
' Set the first cell in the row of the matching value
Set FirstCell = Range("A" & RecordRange.Row)
' Add matching record to List Box
Results.AddItem
Results.List(RowCount, 0) = FirstCell(1, 2)
Results.List(RowCount, 1) = FirstCell(1, 7)
Results.List(RowCount, 2) = FirstCell(1, 5)
Results.List(RowCount, 3) = FirstCell(1, 18)
RowCount = RowCount + 1
' Look for next match
Set RecordRange = .FindNext(RecordRange)
' When no further matches are found, exit the sub
If RecordRange Is Nothing Then
Exit Sub
End If
' Keep looking while unique matches are found
Loop While RecordRange.Address <> FirstAddress
Else
' If you get here, no matches were found
Results.AddItem
Results.List(RowCount, 0) = "Nothing Found"
End If
End With
End Sub
Private Sub UserForm_Initialize()
FormEvents = True
End Sub
Private Sub Results_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Dim i As Long
With Me.Results
For i = 0 To .ListCount - 1
If .Selected(i) Then
Me.TextBoxGetStaffFName.Value = .List(i, 1)
Me.TextBoxGetStaffSurname.Value = .List(i, 2)
Me.TextBoxGetStaffID.Value = .List(i, 0)
Exit For
End If
Next
End With
End Sub
Ok just figured out I need to specify the sheet in two places not just one. I needed to edit this section where asterixed
*With Sheet11.Range("StaffFullData[" & SearchColumn & "]")*
' Find the first match
Set RecordRange = .Find(SearchTerm, LookIn:=xlValues)
' If a match has been found
If Not RecordRange Is Nothing Then
*FirstAddress = Sheet11.RecordRange.Address*
Got the solution:
Use
Range.Address(,,,1) to get the full address

How can I use InStr to test for a broader value?

I currently use this code to search for a specific value entered by the user. However, I'd like it to test for the value if it's located within the string, for example, if the user typed "Jon" the search results could be "Jon, Jonathan, Jones" etc. I'm thinking I need to utilize the InStr function somehow, but I'm not sure how to set it up... Any help would be appreciated.
Private Sub CommandButton1_Click()
ActiveSheet.Range("H1").Select
Dim MyValue As String
MyValue = TextBox1.Value
If MyValue = "" Then
MsgBox "Please enter a sales managers name!"
TextBox1.SetFocus
Else
Application.EnableEvents = False
Worksheets("Sheet2").Activate
Range("A3:I200").Select
Selection.ClearContents
Worksheets("Sheet1").Activate
Me.Hide
Set i = Sheets("Sheet1")
Set E = Sheets("Sheet2")
Dim d
Dim j
d = 2
j = 2
Do Until IsEmpty(i.Range("A" & j))
If i.Range("A" & j) = MyValue Then
d = d + 1
E.Rows(d).Value = i.Rows(j).Value
End If
j = j + 1
Loop
Application.EnableEvents = True
Worksheets("Sheet2").Activate
ActiveSheet.Range("H1").Select
If Range("A3").Value = "" Then
MsgBox "No results were found."
Else
MsgBox "Results were found!"
End If
End If
Unload Me
End Sub
I'd use AutoFilter(), and make some little refactoring as follows:
Private Sub CommandButton1_Click()
Dim MyValue As String
MyValue = Me.TextBox1.Value
If MyValue = "" Then
MsgBox "Please enter a sales managers name!"
Me.TextBox1.SetFocus
Else
With Worksheets("Sheet1")
With .Range("A1", .Cells(.Rows.count, 1).End(xlUp))
.AutoFilter field:=1, Criteria1:=MyValue & "*"
If Application.WorksheetFunction.Subtotal(103, .Cells) > 1 Then
Worksheets("Sheet2").UsedRange.ClearContents
Intersect(.Parent.UsedRange, .Resize(.Rows.count - 1).Offset(1).SpecialCells(xlCellTypeVisible).EntireRow).Copy Worksheets("Sheet2").Range("A3")
MsgBox "Results were found."
Else
MsgBox "No results were found."
End If
End With
.AutoFilterMode = False
End With
Me.Hide '<--| hide the userform and move 'Unload UserformName' command to the sub that's calling the Userform
End If
End Sub
You can do this pretty easily with a regular expression in the form of something like:
(^Jon\s)|(\sJon\s)|(\sJon$)
I'd wrap it in a function to allow building the pattern dynamically from user input. This is just an example - you'd either need to do some more escaping beyond just the . or (probably better) add input restrictions on the TextBox.
'Add reference to Microsoft VBScript Regular Expressions
Private Function ContainsWord(target As String, search As String) As Boolean
Const template As String = "(^<word>\s)|(\s<word>\s)|(\s<word>$)"
Dim expression As String
expression = Replace$(template, "<word>", Replace$(search, ".", "\."))
With New RegExp
.Pattern = expression
ContainsWord = .Test(target)
End With
End Function
Sample usage:
Public Sub Example()
Debug.Print ContainsWord("foo bar baz", "bar") 'True
Debug.Print ContainsWord("foo barbaz", "bar") 'False
Debug.Print ContainsWord("foobar baz", "bar") 'False
Debug.Print ContainsWord("bar foo baz", "bar") 'True
Debug.Print ContainsWord("foo baz bar", "bar") 'True
End Sub
In your code, you'd just replace the line...
If i.Range("A" & j) = MyValue Then
...with:
If ContainsWord(i.Range("A" & j).Value, MyValue) Then
Note that since you are calling it in a loop, you'd probably want to cache the RegExp in your case though to avoid repeatedly creating it if you have a ton of cells to check.

SKU random alphanumeric values generator

I have a code
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, _
Cancel As Boolean)
Dim ltr, rNum, AlphaLtrs
AlphaLtrs = "ABCDEFGHIGKLMNOPQRSTUVWXYZ"
selLtr = Application.RoundUp(Rnd() * 26, 0)
ltr = Mid(AlphaLtrs, selLtr, 1)
rNum = Application.RoundUp(Rnd() * 999999, 0)
ActiveCell.Value = ltr & rNum
Target.Offset(0, 1).Select
End Sub
what I need is, to change the doubleclick function into Enter
and also if possible can I add the value of Column A in to the generated code beginning like Jeans-A545145
This adds a value to any cell that selected in column B, as long as only one cell is selected. Paste it into the code module for that sheet:
EDIT: Not sure if this is what you want, but now only does it if Target cell is empty:
EDIT 2: Woops, found a bug in the IF. If you select more than one cell, it errors on the IF Target.Value = "" part. I separated that into a second IF:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim ltr, rNum, AlphaLtrs, selLtr
If Not Intersect(Target, Me.Columns(2)) Is Nothing And _
Target.Cells.Count = 1 Then
If Target.Value = "" Then
AlphaLtrs = "ABCDEFGHIGKLMNOPQRSTUVWXYZ"
selLtr = Application.RoundUp(Rnd() * 26, 0)
ltr = Mid(AlphaLtrs, selLtr, 1)
rNum = Application.RoundUp(Rnd() * 999999, 0)
Target.Value = Me.Range("A" & Target.Row) & "-" & ltr & rNum
End If
End If
End Sub
Perhaps:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Application.EnableEvents = False
Dim ltr, rNum, AlphaLtrs
AlphaLtrs = "ABCDEFGHIGKLMNOPQRSTUVWXYZ"
selLtr = Application.RoundUp(Rnd() * 26, 0)
ltr = Mid(AlphaLtrs, selLtr, 1)
rNum = Application.RoundUp(Rnd() * 999999, 0)
ActiveCell.Value = ltr & rNum
Target.Offset(0, 1).Select
Application.EnableEvents = True
End Sub

Resources