InputBox open after selecting a row - excel

I have simple macro which opens an InputBox when one of the cells in a range is selected:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not Application.Intersect(Target, Range("H18:H" & Worksheets("LookUpLists").Cells(2, "N").Value - 1)) Is Nothing Then
UserForm1.Show
End If
End Sub
Problem I'm facing is that InputBox opens also when I select the whole row.
Do you have any idea how to avoid this?

Check the amount of cells:
If Not Application.Intersect(Target, Range("H18:H" & _
Worksheets("LookUpLists").Cells(2, "N").Value - 1)) Is Nothing And _
Target.Cells.Count = 1 Then '// <~~ Check number of cells selected is 1
Userform1.Show
End If

If you want to allow all selections (1 or more) that are not an entire row, this should do it.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim bEntireRow as Boolean
With Target
bEntireRow = .Address = .EntireRow.Address
'/ Excel evaluates (.Address = .Entirerow.address) as a Boolean True/False and assigns it to bEntireRow
End With
If bEntireRow = false and Not Application.Intersect(Target, Range("H18:H" & Worksheets("LookUpLists").Cells(2, "N").Value - 1)) Is Nothing Then
UserForm1.Show
End If
End Sub

Related

How to repeat this function in VBA?

I have this function now in Excel VBA:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Cells.Count <> 1 Then Exit Sub
If Target.Address = Cells(1, 5).Address Then
Cells(1, 6) = Application.UserName
Cells(1, 7) = Now
Else
Debug.Print "This was not B1"
End If
End Sub
this works perfect for one cell on one line. Now I need to have it for multiple lines on this sheet. How do I do that? When just copying and updating the parameters in the Cells lines I get the error message that the eventname cannot be used twice.
Final solution for me would be that for all 15 lines on in this sheet I have this function.
You can only have one SelectionChange event per worksheet, so you need to handle everything in that event.
If you want to do different things use:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Cells.CountLarge <> 1 Then Exit Sub
If Target.Address = Cells(1, 5).Address Then
Cells(1, 6) = Application.UserName
Cells(1, 7) = Now
ElseIf Target.Address = … your other cell address … Then
'do something else
Else
Debug.Print "This was not B1"
End If
End Sub
If you want to do the same thing for multiple lines the do the following:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Cells.CountLarge <> 1 Then Exit Sub
If Not Intersect(Target, Me.Range(Me.Cells(1, 5), Me.Cells(10, 5))) Is Nothing Then
Target.Offset(ColumnOffset:=1) = Application.UserName
Target.Offset(ColumnOffset:=2) = Now
Else
Debug.Print "This was not B1"
End If
End Sub
This will work from row 1 Me.Cells(1, 5) to row 10 Me.Cells(10, 5) and will write the username to column 6 and time to column 7 of the selected row of column 5 in that range.

Restricting VBA code to certain range of cells within worksheet

I am currently running code that changes cell colour and value when clicked i.e. one click changes cell colour and sets value to 1, double click same cell to remove colour and number. This is to allow people to fill in a form in a visual way, and gives me the ability to count the "checked" cells. My problem is that I need it restricted to a certain range within that worksheet so that people can't overwrite other cells.
I have next to no coding experience, and the code below is a mix and match of a bunch of stuff found online.
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Cancel = True
Worksheet_SelectionChange Target
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
With Target
If .Range("E4:K79") Is Nothing Or .Count > 1 Then Exit Sub
Select Case .Value
Case ""
.Interior.ColorIndex = 40
Case 1
.Interior.ColorIndex = xlNone
.Value = vbNullString
Exit Sub
Case Else
Exit Sub
End Select
.Value = .Value + 1
End With
End Sub
Solved.
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Cancel = True
Worksheet_SelectionChange Target
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
With Target
If Intersect(.Cells, Range("E4:K120")) Is Nothing Or .Count > 1 Then Exit Sub
Select Case .Value
Case ""
.Interior.ColorIndex = 3
Case 1
.Interior.ColorIndex = xlNone
.Value = vbNullString
Exit Sub
Case Else
Exit Sub
End Select
.Value = .Value + 1
End With
End Sub

Data validation to a dynamic range

I have a column named "time" in my excel sheet. I want to write a code such that whenever user performs an entry in time column, if it is a whole number, it should accept, but if it is not a pop up should appear saying "only numbers allowed". Also, the validation should be dynamic i.e. should automatically validate next row if users enters a new entry
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
If Target.Column = Range("Meeting Time").Column Then
If Not (IsNumeric(Target.Value)) Then
MsgBox "only numbers allowed"
Target.Value = ""
Target.Select
End If
End If
End Sub
You could try:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
'1. Check if the column that affected is B (change to the column you want)
'2. Check if changed field is one (used to avoid errors if user change more than one cells at the same time)
If Not Intersect(Target, Columns("B:B")) Is Nothing And Target.Count = 1 Then
'Check if target is numeric
If Not IsNumeric(Target.Value) Then
Call Clear(Target)
End If
'Check if target.offset(1,0) is numeric
If Not IsNumeric(Target.Offset(1, 0).Value) Then
Call Clear(Target.Offset(1, 0))
End If
End If
End Sub
Sub Clear(ByVal rng As Range)
'Disable events in order to prevent code to re trigger when clear cell
Application.EnableEvents = False
rng.Value = ""
'Enable events
Application.EnableEvents = True
End Sub
EDITED VERSION:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
'1. Check if the column that affected is B (change to the column you want)
'2. Check if changed field is one (used to avoid errors if user change more than one cells at the same time)
If Not Intersect(Target, Columns("B:B")) Is Nothing And Target.Count = 1 Then
'Check if target is numeric
If Not IsNumeric(Target.Value) Then
Call Clear(Target)
ElseIf Target.Value > 160 Or (Target.Value = Int(Target.Value) = False) Then
Call Clear(Target)
End If
'Check if target.offset(1,0) is numeric
If Not IsNumeric(Target.Offset(1, 0).Value) Then
Call Clear(Target.Offset(1, 0))
ElseIf Target.Offset(1, 0).Value > 160 Or (Target.Offset(1, 0).Value = Int(Target.Offset(1, 0).Value) = False) Then
Call Clear(Target)
End If
End If
End Sub
Sub Clear(ByVal rng As Range)
'Disable events in order to prevent code to re trigger when clear cell
Application.EnableEvents = False
rng.Value = ""
'Enable events
Application.EnableEvents = True
End Sub
first you can create a range name for column you want your "time" and you can use the sample codes below.
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
If Target.Column = Range("time").Column Then
If Not (IsNumeric(Target.Value)) Then
MsgBox "only numbers allowed"
Target.Value = ""
Target.Select
End If
End If
End Sub

Identifying duplicates when copy/paste of multiple cells into excel column

So I am trying to find a solution where i can copy paste multiple values from one column into another column and have it leave out duplicates already existing.
I found this code but it only works if I copy paste one value at a time.
Is there a way to make it work so it will paste in unique copied values only, that does not exist in the column already?
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
''''''''''''''''''''''''''''''''''''''''''
'Prevents duplicate entries in Column A
''''''''''''''''''''''''''''''''''''''''''
If Target.Cells.Count > 1 Then Exit Sub
If Target.Column = 1 And Target <> vbNullString Then 'Column A
If WorksheetFunction.CountIf(Columns(1), Target) > 1 Then
MsgBox "Entry " & Target & " already exists!", _
vbCritical, "Dixons Travel Oslo"
Target = ""
Target.Select
End If
End If
End Sub
Maybe you find this usefull:
Below code assumes you just copy in all the values, even if they exist allready.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 1 Then
Range("A1", Range("A1").End(xlDown)).RemoveDuplicates Columns:=1, Header:=xlNo
End If
End Sub
It will look like this:
Change Header:=xlNo to Header:=xlYes if that applies to your situation.
Obviously, there are other ways. I just find this quite easy.
Using a similar methodology to your existing one, you could do the following:
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
Application.EnableEvents = False
For Each tcell In Target.Cells
With tcell
If .Column = 1 And .Value <> vbNullString Then 'Column A
If WorksheetFunction.CountIf(Columns(1), .Value) > 1 Then
tcell.Value = ""
End If
End If
End With
Next
Application.EnableEvents = True
End Sub
Here's another way - expanding and improving on JvdV's idea:
Private Sub Worksheet_Change(ByVal Target As Range)
With Target.Parent
If Not (Intersect(Target, .Columns(1)) Is Nothing) Then
Range("A1", Range("A" & .Rows.Count).End(xlUp)).RemoveDuplicates Columns:=1, Header:=xlNo
End If
End With
End Sub
This allows for multiple cells to be pasted - regardless of how many columns are affected and de-dupes the whole of column A.
You could try:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
If Target.Column = 1 Then
Application.EnableEvents = False
ThisWorkbook.Worksheets("Sheet1").Columns("A:A").RemoveDuplicates Columns:=1, Header:=xlNo
Application.EnableEvents = True
End If
End Sub
Notes:
You could change sheet name
Header option

Insert data in same row when a value in a cell is changed

I have code that retrieves information from SQL and VFP and populates a dropdown list in every cell in column "A" except A1 - this is a header.
I need to populate the "G" column on the row where the user selects the value from a dropdown in the "A" column.
I believe I need to be in Private Sub Worksheet_SelectionChange(ByVal Target As Range) which is in the sheet object.
Below is something similar to what I want to do.
If cell "a2".valuechanged then
Set "g2" = "8000"
End if
If cell "a3".valueChanged then
Set "g3" = "8000"
End if
The code above doesn't work, but I think it is easy to understand. I want to make this dynamic, so I don't have too many lines of code.
I have already explained about events and other things that you need to take care when working with Worksheet_Change HERE
You need to use Intersect with Worksheet_Change to check which cell the user made changes to.
Is this what you are trying?
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo Whoa
'~~> Check if user has selected more than one cell
If Target.Cells.CountLarge > 1 Then Exit Sub
Application.EnableEvents = False
'~~> Check if the user made any changes in Col A
If Not Intersect(Target, Columns(1)) Is Nothing Then
'~~> Ensure it is not in row 1
If Target.Row > 1 Then
'~~> Write to relevant cell in Col G
Range("G" & Target.Row).Value = 8000
End If
End If
Letscontinue:
Application.EnableEvents = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume Letscontinue
End Sub
Try this
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Row > 1 And Target.Column <> 7 Then
Cells(Target.Row, "G").Value = 8000
End If
End Sub
If you only need it to fire on column A then
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Row > 1 And Target.Column = 1 Then
Cells(Target.Row, "G").Value = 8000
End If
End Sub
can you not put an if statement in column G , as in
If (A1<>"", 8000,0)
Other wise something like this will get you going:
Private Sub Worksheet_Change(ByVal Target As Range)
On Error Resume Next
If Target.Column = 1 Then
If Target.Value2 <> "" Then
Target.Offset(0, 6) = "8000"
Else
Target.Offset(0, 6) = ""
End If
End If
On Error GoTo 0
End Sub
Thanks
Ross
I had a similar problem. I used Siddharth Rout's code. My modifications allow a user to paste a range of cells in column a (ex. A3:A6) and have multiple cells modified (ex. H3:H6).
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo Whoa
'~~> Check if user has selected more than one cell
If Target.Cells.CountLarge < 1 Then Exit Sub
If Target.Cells.CountLarge > 500 Then Exit Sub
Debug.Print CStr(Target.Cells.CountLarge)
Application.EnableEvents = False
Dim the_row As Range
Dim the_range As Range
Set the_range = Target
'~~> Check if the user made any changes in Col A
If Not Intersect(the_range, Columns(1)) Is Nothing Then
For Each the_row In the_range.Rows
'~~> Ensure it is not in row 2
If the_row.Row > 2 Then
'~~> Write to relevant cell in Col H
Range("H" & the_row.Row).Value = Now
End If
Next
End If
Letscontinue:
Application.EnableEvents = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume Letscontinue
End Sub

Resources