Making a pop up window whenever there is a change in cell value - audio

I wrote a simple macro
=IF(C2=H2,1,))
so whenver value of C2 equals value of H2, pop up window saying "HI" appears
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
Dim rng As Range
Set rng = Range("H2")
If Not Intersect(Target, rng) Is Nothing Then
If rng = "1" Then
MsgBox "Cell " & _
rng.Address & " = hi"
End If
End If
Set rng = Nothing
End Sub
The problem is that I need it to make sound as well as pop-up and more importantly I need it to do it for a 1000 rows(ie. c2,c3,c4 so to c1000).
Don't tell me I need to paste and copy thousand time.

It is hard to understand what exactly you are trying to accomplish because your question is not very clear. If I understood correctly, when a value is changed in column H you would like to check to see if it matches the corresponding cell in column C. If the values match you want to display a message box and play a sound. This code will do exactly that. If I have misunderstood the goal please clarify and I will do what I can to help.
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
On Error Resume Next
If Target.Column = 8 Then
If Target.Value = Target.Offset(0, -5).Value Then
Beep
MsgBox "Cell " & Target.Address(False, False) & " = Hi"
End If
End If
On Error GoTo 0
End Sub

Try this
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo Whoa
Application.EnableEvents = False
If Not Intersect(Target, Range("C2:C1000")) Is Nothing Then
If Target.Value = Target.Offset(, 5).Value Then
Beep
MsgBox "Blah Blah"
End If
'~~> Added Code to handle changes in Col H as well. Thanks to ripster
ElseIf Not Intersect(Target, Range("H2:H1000")) Is Nothing Then
If Target.Value = Target.Offset(, -5).Value Then
Beep
MsgBox "Blah Blah"
End If
End If
Letscontinue:
Application.EnableEvents = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume Letscontinue
End Sub
I would always recommend using proper error handling. You might also want to see this?
The above code doesn't handle the situation if there is a multiple paste. Let me know if you want to check for that as well :)

Related

VBA Deleting Rows for Changed Cells Debug Error

The following does what I want it to by adding formulas when a value is entered into the Target cell, and then deletes said value when the cell is empty.
However, I keep running into a Debug Error if I were to right-click and delete that row within the Target Range, is there a way to prevent this from happening?
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("C11:C1000")) Is Nothing Then
If Target.Value <> "" Then
Target.Offset(0, -1).Formula = "=VLOOKUP(" & Target.Address & ",UIDs!$F$3:$H$750,3,FALSE)"
Else:
Target.Offset(0, -1).Value = ""
End If
End If
End Sub
Debug Error:
Then it takes me to If Target.Value <> "" Then if I click Debug.
You can confirm that Target is only 1 cell (as it will be a lot more than that when you delete a row):
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not Intersect(Target, Range("C11:C1000")) Is Nothing Then
If Target.Count > 1 Then Exit Sub
Application.EnableEvents = False
If Target.Value <> "" Then
Target.Offset(0, -1).Formula = "=VLOOKUP(" & Target.Address & ",UIDs!$F$3:$H$750,3,FALSE)"
Else
Target.Offset(0, -1).Value = ""
End If
Application.EnableEvents = True
End If
End Sub

Auto date fill in in Excel file

Can someone please help me with this code. It will insert the current date in H if I do any changes to I.
My problem is that this will not work if for example I fill in I1 with something, and then I drag down for copying in many cells at once. If for example I copy value from I1 once at a time in each cell( I2,I3 ETC) it will work.
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
'Updated by Extendoffice 2017/10/12
Dim xRg As Range, xCell As Range
On Error Resume Next
If (Target.Count = 1) Then
If (Not Application.Intersect(Target, Me.Range("I:I")) Is Nothing) Then _
Target.Offset(0, -1) = Date
Application.EnableEvents = False
Set xRg = Application.Intersect(Target.Dependents, Me.Range("I:I10"))
If (Not xRg Is Nothing) Then
For Each xCell In xRg
xCell.Offset(0, -1) = Date
Next
End If
Application.EnableEvents = True
End If
End Sub
Thank you !
Avoid the unnecessary use of On Error Resume Next. Handle the Error gracefully. I recommend reading THIS once when using Worksheet_Change
Also you have If (Target.Count = 1) Then because of which your code doesn't execute. When you drag, the count increases.
Is this what you are trying?
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo Whoa
Dim aCell As Range
Application.EnableEvents = False
If Not Intersect(Target, Range("I:I")) Is Nothing Then
For Each aCell In Target
'~~> Additional blank check for I. So that the date
'~~> is not inserted if the value is deleted. Remove this
'~~> if you want the date to be inserted even when the value is deleted
If Len(Trim(aCell.Value)) <> 0 Then
Range("H" & aCell.Row).Value = Date
Else
'Remove Date?
End If
Next aCell
End If
Letscontinue:
Application.EnableEvents = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume Letscontinue
End Sub
In action:

How to fix "Run-time error '1004'" cause by Target.Formula function

I have a file where I want to check if cell "$A$2" is empty and if that's true I want to add the formula (=VLOOKUP($I$2;'Raw Data'!$A$1:$AH$5000;4;FALSE) in this cell. Went I run the code below it generates a
Run-tim error '1004' (Application-defined or object defined error).
I already played with the target formula and if I take simple formulas like =B1+B2 it works and I don^t get an error message. So it seems to be something about the Vlookup formula that causes the error.
Private Sub Worksheet_Change(ByVal Target As Range)
If (Target.Cells.Address = "$A$2" And Target = vbNullString) Then
Target.Formula = "=VLOOKUP($I$2;'Raw Data'!$A$1:$AH$5000;4;FALSE)"
End If
End Sub
I expect the cell "$A$2" to show the result of the formula =VLOOKUP($I$2;'Raw Data'!$A$1:$AH$5000;4;FALSE) unless the cell is overwritten manually.
Thanks for your help #Pᴇʜ #eirikduade #Gareth!
Now I am trying to do the same for all cells in Column A where there is a value in column I of the same row and I struggle with the .Range function. Could you please give me any suggestions how to fix the following code:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim lastRowF As Integer
lastRowF = Sheet3.Cells(Sheet3.Rows.Count, "I").End(xlUp).Row
For j = 1 To lastRowF
If Intersect(Target, Me.Range(Cells(j, 2))) Is Nothing Then Exit Sub
If Me.Range(.Cells(j, 2)) = vbNullString Then
Me.Range(.Cells(j, 2)).Formula = "=VLOOKUP(""" & cells.(y, 1) & """,'Raw Data'!$A$1:$AH$5000,4,FALSE)"
Exit For
End If
Next j
End Sub
The main issue
You need to switch the ; to , because the .Formula needs to be the original english version of the formula which uses ,.
Your code will fail if Target is a range of multiple cells
Note that your code will fail if you eg. copy paste a range (not a single cell).
Change it to the following:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Me.Range("A2")) Is Nothing Then Exit Sub
Application.EnableEvents = False
On Error Goto ENABLE_EVENTS
If Me.Range("A2").Value = vbNullString Then
Me.Range("A2").Formula = "=VLOOKUP($I$2,'Raw Data'!$A$1:$AH$5000,4,FALSE)"
End If
ENABLE_EVENTS:
Application.EnableEvents = True
If Err.Number <> 0 Then Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
End Sub
If you need to do it for multiple cells in column A it would look like this:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim AffectedRange As Range
Set AffectedRange = Intersect(Target, Me.Range("A2:A" & Me.Rows.Count))
Application.EnableEvents = False
On Error Goto ENABLE_EVENTS
If Not AffectedRange Is Nothing Then
Dim iCell As Range
For Each iCell In AffectedRange.Cells
If iCell.Value = vbNullString Then
iCell.Formula = "=VLOOKUP($I" & iCell.Row & ",'Raw Data'!$A$1:$AH$5000,4,FALSE)"
End If
Next iCell
End If
ENABLE_EVENTS:
Application.EnableEvents = True
If Err.Number <> 0 Then Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
End Sub
Note that you probably mean to use
"=VLOOKUP($I" & iCell.Row & ", 'Raw Data'!$A$1:$AH$5000,4,FALSE)"
instead of
"=VLOOKUP($I$2, 'Raw Data'!$A$1:$AH$5000,4,FALSE)"
In VBA code, you must use commas to separate arguments in functions, even if your local delimiter is semi-colons.
I.e. change the line
Target.Formula = "=VLOOKUP($I$2;'Raw Data'!$A$1:$AH$5000;4;FALSE)"
to
Target.Formula = "=VLOOKUP($I$2,'Raw Data'!$A$1:$AH$5000,4,FALSE)"
and see if that works

Change cell color base on another cells data but keep it that way if data changes again

I have been looking for days to solve this and have only come up with half the solution.
What I can do:
I would simply like to have one cell turn green inside with an x inserted when another cells data has the word "Complete" inside it.
What I cannot do:
I would like that same cell that turned green with an x inserted into it when the word "Complete" is changed to "Rework" to stay green with an x.
So Cell A1 is blank then in cell B1 the word "Complete" is added. Then cell A1 changes to green and has an x inside it. If later B1 changes to "Rework" I would like A1 to stay green with the x inside. So I can know that at one time the status of B1 was at one time "Complete"
I have been trying Conditional Formatting with rules but cannot get it to stay. I think the "Stop If True" check box within would be part of the solution but not sure what the code would be.
I already have a different macro running on this sheet so if the answer is a macro I will need it to be added to it. Below is the macro in the sheet already. Thank you.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("N:N,Y:Y"), Range("10:" & Rows.Count)) Is Nothing Then
If Target.Count < Columns.Count Then
On Error GoTo bm_Safe_Exit
Application.EnableEvents = False
Dim r As Range
For Each r In Intersect(Target, Range("N:N,Y:Y"), Range("10:" & Rows.Count))
With r.Offset(0, 1)
.Value = Now 'use Now to retain the time as well as the date
.NumberFormat = "mm/dd/yy" 'change to what you prefer
End With
Next r
End If
End If
bm_Safe_Exit:
Application.EnableEvents = True
End Sub
Ideally you'd split this up into separate subs to handle each of the change types, but this should give you an idea:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng As Range, r as Range
'skip full-row changes (row insert/delete?)
If Target.Columns.Count = Columns.Count Then Exit Sub
Set rng = Intersect(Target, Range("N:N,Y:Y"), Range("10:" & Rows.Count))
If Not rng Is Nothing Then
On Error GoTo bm_Safe_Exit
Application.EnableEvents = False
For Each r In rng.Cells
With r.Offset(0, 1)
.Value = Now 'use Now to retain the time as well as the date
.NumberFormat = "mm/dd/yy" 'change to what you prefer
End With
Next r
End If
Set rng = Intersect(Target, Range("B:B"), Range("10:" & Rows.Count))
If Not rng Is Nothing Then
On Error GoTo bm_Safe_Exit
Application.EnableEvents = False
For Each r In rng.Cells
If r.Value = "Complete" Then
With r.Offset(0, -1)
.Value = "x"
.Interior.Color = vbGreen
End With '<<EDIT thanks #BruceWayne
End If
Next r
End If
bm_Safe_Exit:
Application.EnableEvents = True
End Sub
You'll need two worksheet events, and some If statements. The following should help you get started, unless I'm overlooking something.
Dim oldVal as String ' Public variable
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'Debug.Print Target.Address
If Target.Cells.Count <> 1 Then Exit Sub
oldVal = Target.Value
End Sub
The above will make note of the oldValue.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim newVal As String
newVal = Target.Value
If newVal = oldVal Then
Debug.Print "Same Values"
ElseIf oldVal = "Complete" And newVal = "Rework" Then
Debug.Print "Stay green with X"
ElseIf oldVal = "" And (newVal = "Complete" Or newVal = "complete") Then
Debug.Print "Change cell to Green, add an 'X'"
Target.Interior.ColorIndex = 10
Target.Value = Target.Value & " x"
End If
End Sub
Then, add/tweak those If statements as necessary, and add the color changing/reverting code to the appropriate block.
(There may of course be a better mousetrap, but I think this should get you going).

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