Combining 3 Private Sub Worksheet_Change - excel

I am a first time poster and a newby to VBA. So i am hoping i make sense :)
I am trying to combine 3 private subs, but not sure how to code it together.
I have a spreadsheet that has data validation and i want a input box to appear depending on what is selected.
In column "I" is the first set of data validation, with the options of Accepted, Declined and Null invoid, if "Accepted" then nothing, but if either Declined or Null in Void, I would like a pop up box to appear for the user to input $0, and past that to Column "D"
In Column "M" is the next one for data validation, with the only options is blank and Complete. if blank then nothing, but if Complete, i would like a pop up for the user to input the Quotation value, and past that to Column "D".
Thank you in advance.
This is my code
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("I:I")) Is Nothing Then
If Target = "Declined" Then
roww = Target.Row
Application.EnableEvents = False
Cells(roww, "D").Value = Application.InputBox(Prompt:="Updated quoted value to 0", Type:=2)
Application.EnableEvents = True
End If
End If
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("I:I")) Is Nothing Then
If Target = "Null in Void" Then
roww = Target.Row
Application.EnableEvents = False
Cells(roww, "D").Value = Application.InputBox(Prompt:="Updated quoted value to 0", Type:=2)
Application.EnableEvents = True
End If
End If
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("M:M")) Is Nothing Then
If Target = "Complete" Then
roww = Target.Row
Application.EnableEvents = False
Cells(roww, "D").Value = Application.InputBox(Prompt:="Updated quoted value to the Quotation Value", Type:=2)
Application.EnableEvents = True
End If
End If
End Sub

Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("M:M")) Is Nothing Then
If Target = "Complete" Then
roww = Target.Row
Application.EnableEvents = FALSE
Cells(roww, "D").Value = Application.InputBox(Prompt:="Updated quoted value To the Quotation Value", Type:=2)
Application.EnableEvents = TRUE
End If
ElseIf Not Intersect(Target, Range("I:I")) Is Nothing Then
If Target = "Declined" Then
roww = Target.Row
Application.EnableEvents = FALSE
Cells(roww, "D").Value = Application.InputBox(Prompt:="Updated quoted value To 0", Type:=2)
Application.EnableEvents = TRUE
ElseIf Target = "Null in Void" Then
roww = Target.Row
Application.EnableEvents = FALSE
Cells(roww, "D").Value = Application.InputBox(Prompt:="Updated quoted value To 0", Type:=2)
Application.EnableEvents = TRUE
End If
End If
End Sub
see this official docs.

Related

Excel 2 Worksheets Events with Different Targets

I have an excel worksheet that I want to assign to it more than one Worksheet Event.
To be more specific, I want whenever a cell in column B is changed then one cell to the left (column A) gets the row number.
Also I want whenever a cell in column J is changed then one cell to the right (column K) gets today's date.
It worked for me for both of them individually but I think I may be doing something wrong using them together.
Any help will be much appreciated!
Private Sub AG1(ByVal a_Target As Range)
If Not Intersect(a_Target, Me.Range("B2:B3000")) Is Nothing Then
Application.EnableEvents = False
Cells(a_Target.Row, a_Target.Column - 1) = a_Target.Row
Application.EnableEvents = True
End If
End Sub
Private Sub AG2(ByVal b_Target As Range)
If Not Intersect(b_Target, Me.Range("J2:J3000")) Is Nothing Then
Application.EnableEvents = False
Cells(b_Target.Row, b_Target.Column + 1) = Date
Application.EnableEvents = True
End If
End Sub
edit - works now (I also added that column can be referred as letter):
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = True
If Split(Cells(1, Target.Column).Address(True, False), "$")(0) = "B" Then
Application.EnableEvents = False
Cells(Target.Row, Target.Column - 1) = Target.Row
Application.EnableEvents = True
ElseIf Split(Cells(1, Target.Column).Address(True, False), "$")(0) = "J" Then
Application.EnableEvents = False
Cells(Target.Row, Target.Column + 1) = Date
Application.EnableEvents = True
End If
End Sub
Copy the code in the Worksheet_Change event and that should fix your issue. This will trigger every time you enter a value for any cell and will only meet the condition if they intersect the range in the if statement.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.Range("B2:B3000")) Is Nothing Then
Application.EnableEvents = False
Cells(Target.Row, Target.Column - 1) = Target.Row
Application.EnableEvents = True
End If
If Not Intersect(Target, Me.Range("J2:J3000")) Is Nothing Then
Application.EnableEvents = False
Cells(Target.Row, Target.Column + 1) = Date
Application.EnableEvents = True
End If
End Sub

Clearing cells in a table in excel when one cell is cleared

I have a table from A12 to AO29. The table headers are in row13.
I am working on a macro that deletes data in column D, E and I when the cell in column B is changed or deleted. The code below works fine, except that it is not deleting the data column D. Column D has a data validation list.
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = True
If Not Intersect(Target, Range("H6")) Is Nothing Then
Application.EnableEvents = False
Range("H8") = vbNullString
Range("H7") = vbNullString
Application.EnableEvents = True
End If
If Not Intersect(Target, Range("$H6")) Is Nothing Then
Range("A12:B29").ClearContents
Range("D12:E29").ClearContents
Range("I12:I29").ClearContents
Range("A33:F50").ClearContents
Range("J33:J50").ClearContents
Range("A54:H71").ClearContents
Range("L54:L71").ClearContents
Range("A75:H92").ClearContents
Range("L75:L92").ClearContents
Range("A96:E113").ClearContents
Range("I96:I113").ClearContents
Range("A117:B134").ClearContents
Range("F117:F134").ClearContents
Range("A138:C156").ClearContents
Range("G138:G159").ClearContents
Range("A160:C177").ClearContents
Range("G160:G177").ClearContents
Range("A181:C198").ClearContents
Range("G181:G198").ClearContents
End If
If Target.Count > 1 Then Exit Sub
If Not Intersect(Target, Range("A12:A29")) Is Nothing Then
On Error GoTo haveError
Application.EnableEvents = False
If Target.Column = 1 Then Target.Offset(0, 1).clearcontent
Target.EntireRow.Range("B1,D1,E1,I1").ClearContents
Application.EnableEvents = True
End If
If Not Intersect(Target, Range("B12:B29")) Is Nothing Then
On Error GoTo haveError
Application.EnableEvents = False
If Target.Column = 1 Then Target.Offset(0, 1).clearcontent
Target.EntireRow.Range("D1,E1,I1").ClearContents
End If
If Not Intersect(Target, Range("D12:D29")) Is Nothing Then
On Error GoTo haveError
Application.EnableEvents = False
If Target.Column = 1 Then Target.Offset(0, 1).clearcontent
Target.EntireRow.Range("E1,I1").ClearContents
End If
If Not Intersect(Target, Range("E12:E29")) Is Nothing Then
On Error GoTo haveError
Application.EnableEvents = False
If Target.Column = 1 Then Target.Offset(0, 1).clearcontent
Target.EntireRow.Range("I1").ClearContents
Application.EnableEvents = True
End If
Exit Sub
haveError:
Application.EnableEvents = True
This would be easier to manage:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim c As Range
If Target.Count > 1 Then Exit Sub
If Not Intersect(Target, _
Me.Range("A12:B29,D12:D29,E12:E29")) Is Nothing Then
On Error GoTo haveError
Application.EnableEvents = False
For Each c in Target.EntireRow.Range("B1,D1,E1,I1").Cells
If c.Column > Target.Column Then c.ClearContents
Next c
Application.EnableEvents = True
End If
Exit Sub
haveError:
Application.EnableEvents = True
End Sub
Note when using Range() in the context of EntireRow, the range is relative to the single row.
When you're checking the b12-b29 range, you're not unionizing your ranges so the call to clear contents only affects the last range you set it to which would be the i column.
You could also condense this down drastically by replacing it with one line like this
If Not Intersect(Target, Range("b12", "b29")) Is Nothing Then
Set rngDB = Union(Range("d" & Target.Row), Range("e" & Target.Row), Range("i" & Target.Row))
rngDB.ClearContents
End If

Correcting one code causes another to stop working

I am working on a document in which clickable cells place different values in column M on sheets 1 and 3. On sheet 1 when column M reads COMPLETE it will be cut from sheet 1 and pasted in sheet 2 when column M reads PARTIAL HOLD it will be cut from sheet 1 and pasted into sheet 3. I am having many problems with this but the problem I am asking for help on here is that in the following code the moves will work but i get a "run-time error '424' Object Required" and is not accepting Time as an object in my line of code Target.Offset(, 4).Value = Time but when I fix the issue in the code for the clickable cells the rows will no longer cut and paste.
This first code is the code that allows the rows to move but gets me an error
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rngDest As Range, rngDest2 As Range, rngDest3 As Range
If UCase(Target.Value) = "PARTIAL HOLD" Then
Set rngDest = Sheet3.Range("A5:Q5")
If Not Intersect(Target, Sheet1.Range("M5:M290")) Is Nothing Then
Application.EnableEvents = False
Target.EntireRow.Cut
rngDest.Insert Shift:=xlDown
Target.EntireRow.Delete
Application.EnableEvents = True
End If
ElseIf UCase(Target.Value) = "PROGRESSING" Then
Set rngDest3 = Sheet1.Range("A5:Q5")
If Not Intersect(Sheet3.Cells(Target.Row, Target.Column), Sheet3.Range("M5:M290")) Is Nothing Then
Application.EnableEvents = False
Target.EntireRow.Cut
rngDest3.Insert Shift:=xlDown
Target.EntireRow.Delete
Application.EnableEvents = True
End If
ElseIf UCase(Target.Value) = "COMPLETE" Then
Set rngDest2 = Sheet2.Range("A5:Q5")
If Not Intersect(Target, Sheet1.Range("M5:M290")) Is Nothing Then
Application.EnableEvents = False
Target.EntireRow.Cut
rngDest2.Insert Shift:=xlDown
Target.EntireRow.Delete
Application.EnableEvents = True
End If
End If
End Sub
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
If Target.Column = 11 Then
Cancel = True
Target.Offset(, 2).Value = "IN PROGRESS"
Target.Offset(, 4).Value = Time
ElseIf Target.Column = 12 Then
Cancel = True
Target.Offset(, 1).Value = "COMPLETE"
Target.Offset(, 4).Value = Time
ElseIf Target.Column = 14 Then
Cancel = True
Target.Offset(, -1).Value = "PARTIAL HOLD"
End If
End Sub
The next code is the correction I have made to the clickable cells, but this stops the rows from cutting and pasting
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rngDest As Range, rngDest2 As Range, rngDest3 As Range
If UCase(Target.Value) = "PARTIAL HOLD" Then
Set rngDest = Sheet3.Range("A5:Q5")
If Not Intersect(Target, Sheet1.Range("M5:M290")) Is Nothing Then
Application.EnableEvents = False
Target.EntireRow.Cut
rngDest.Insert Shift:=xlDown
Target.EntireRow.Delete
Application.EnableEvents = True
End If
ElseIf UCase(Target.Value) = "PROGRESSING" Then
Set rngDest3 = Sheet1.Range("A5:Q5")
If Not Intersect(Sheet3.Cells(Target.Row, Target.Column),
Sheet3.Range("M5:M290")) Is Nothing Then
Application.EnableEvents = False
Target.EntireRow.Cut
rngDest3.Insert Shift:=xlDown
Target.EntireRow.Delete
Application.EnableEvents = True
End If
ElseIf UCase(Target.Value) = "COMPLETE" Then
Set rngDest2 = Sheet2.Range("A5:Q5")
If Not Intersect(Target, Sheet1.Range("M5:M290")) Is Nothing Then
Application.EnableEvents = False
Target.EntireRow.Cut
rngDest2.Insert Shift:=xlDown
Target.EntireRow.Delete
Application.EnableEvents = True
End If
End If
End Sub
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Application.EnableEvents = False
On Error GoTo Xit:
If Target.Column = 11 Then
Cancel = True
Target.Offset(, 2).Value = "IN PROGRESS"
Target.Offset(, 4).Value = Time
ElseIf Target.Column = 12 Then
Cancel = True
Target.Offset(, 1).Value = "COMPLETE"
Target.Offset(, 4).Value = Time
ElseIf Target.Column = 14 Then
Cancel = True
Target.Offset(, -1).Value = "PARTIAL HOLD"
End If
Xit:
Application.EnableEvents = True
End Sub
What can I do to fix this?

Selection Change affecting cells outside of range

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Const Col As Long = 2
If Not Intersect(Target, Range("L7:L98")) Is Nothing Then
Application.EnableEvents = False
Target.Value = "T"
Target.Offset(, 1).Resize(, Col).ClearContents
Application.EnableEvents = True
End If
If Not Intersect(Target, Range("M7:M98")) Is Nothing Then
Application.EnableEvents = False
Target.Value = "I"
Target.Offset(, 1).ClearContents
Target.Offset(, -1).ClearContents
Application.EnableEvents = True
End If
If Not Intersect(Target, Range("N7:N98")) Is Nothing Then
Application.EnableEvents = False
Target.Value = "D"
Range(Target.Offset(, -1), Target.Offset(, -2)).ClearContents
Application.EnableEvents = True
End If
End Sub
This code is causing a slight problem for me. Any time I select an entire row within the ranges, every cell within the range gets changed to "T". Given the consistency of the code, if I delete the string with "T", then the entire row would be filled with "I"
What can be adjusted to trigger only if cells within the range are selected?
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Const Col As Long = 2
If Target.Count > 1 Then
Exit Sub
End If
Added this to the top of the code, it will now exit the Sub if more than one cell is selected even if one of the selected cells are within the appropriate range.
After checking to see if the Selection intersects with the various ranges, only deal with the part of Target that intersects with the various ranges.
Option Explicit
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Const Col As Long = 2
If Not Intersect(Target, Range("L7:L98")) Is Nothing Then
Application.EnableEvents = False
With Intersect(Target, Range("L7:L98"))
.Value = "T"
.Offset(, 1).Resize(, Col).ClearContents
End With
End If
If Not Intersect(Target, Range("M7:M98")) Is Nothing Then
Application.EnableEvents = False
With Intersect(Target, Range("M7:M98"))
.Value = "I"
.Offset(, 1).Resize(, Col).ClearContents
End With
End If
If Not Intersect(Target, Range("N7:N98")) Is Nothing Then
Application.EnableEvents = False
With Intersect(Target, Range("N7:N98"))
.Value = "D"
.Offset(, 1).Resize(, Col).ClearContents
End With
End If
Application.EnableEvents = True
End Sub
Optional Alternative:
Option Explicit
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Const Col As Long = 2
If Not Intersect(Target, Range("L7:L98")) Is Nothing Then
Application.EnableEvents = False
With Intersect(Target, Range("L7:L98"))
.Value = "T"
.Offset(, 1).Resize(, Col).ClearContents
End With
ElseIf Not Intersect(Target, Range("M7:M98")) Is Nothing Then
Application.EnableEvents = False
With Intersect(Target, Range("M7:M98"))
.Value = "I"
.Offset(, 1).Resize(, Col).ClearContents
End With
ElseIf Not Intersect(Target, Range("N7:N98")) Is Nothing Then
Application.EnableEvents = False
With Intersect(Target, Range("N7:N98"))
.Value = "D"
.Offset(, 1).Resize(, Col).ClearContents
End With
End If
Application.EnableEvents = True
End Sub

Excel VBA Target.address worksheet.onchange infinite loop

I have cell A1, cell B1 and cell C1, I need check if value changed in A1 by user or by VBA. Whith out If statment on Target.Address A1 makes infinite loop
Private Sub Worksheet_Change(ByVal Target As range)
If Target.Address = B1 or Target.Address = C1 Then
If IsEmpty(Cell("B1")) then
Cell("A1").value = "Enter value"
If IsEmpty(Cell("C1")) then
Cell("A1").value = ""
Else
Cell("A1").value = "=C1/B1"
End IF
End IF
End IF
If Target.Address = A1
IF "changed by user typing" Then
Cell("B1").value = ""
Cell("C1").value = ""
Else
End IF
End IF
End Sub
How to determine what Target was changed by user not from VBA?
I suspect you want something like this:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("A1")) Is Nothing Then
Application.EnableEvents = False
Range("B1:C1").Value = ""
Application.EnableEvents = True
ElseIf Not Intersect(Target, Range("B1:C1")) Is Nothing Then
Application.EnableEvents = False
If IsEmpty(Range("B1")) Then
Range("A1").Value = "Enter value"
ElseIf IsEmpty(Range("C1")) Then
Range("A1").Value = ""
Else
Range("A1").Value = "=C1/B1"
End If
Application.EnableEvents = True
End If
End Sub

Resources