How to match multiple criteria and get a message - excel

In Excel VBA I would like to match 3 criteria out 3 columns and get a message if there is any match.
My code so far is:
Private Sub Worksheet_Change(ByVal Target As Range)
If Range("A1:A10").Value = "America" And Range("B1:B10").Value = "cloudy"
And Range("C1:C10").Value > 30 Then
MsgBox "This is the promised land!"
End If
End Sub
I get an error that there is a problem with different values.

A different approach but works similar.
Dim i As Integer
For i = 2 To 10 ' Put something more variable instead of 10
If Range("A" & i).Value = "Value4" And Range("B" & i).Value = "Value8" And Range("C" & i).Value > 30 Then
MsgBox "Test"
End If
Next i

Loop over each row:
Sub ceckit()
Dim cell As Range, A As Range
Set A = Range("A1:A10")
For Each cell In A
With cell
If .Value = "America" And .Offset(0, 1).Value = "cloudy" And .Offset(0, 2).Value > 30 Then
MsgBox "This is the promised land!"
End If
End With
Next cell
End Sub

Related

Replace values with VBA and show with a MsgBox how many cells were changed

I'm trying to make a code to search and replace some values with an input. I'm stuck trying to figure out how to prompt a MsgBox showing how many cells were changed.
Thanks!
Sub find_and_replace_loop()
Dim find_value, replace_value As String
On Error Resume Next
find_value = InputBox("Which Product You Want to Replace?")
replace_value = InputBox("Please Enter the New Value")
i = 0
For Each Rng In Worksheets("Tabelle1").Range("A1:A23")
If Rng.Value Like "*" & find_value & "*" Then
Rng.Offset(0, 1).Value = replace_value
End If
i = i + 1 'counts changes
Next
MsgBox i
End Sub

How can I replace single cell references with ranges

I have 5 columns ((a)uptick, (b)downtick, (c)original, (d)current), and (e) Stored Value. All columns need to be a range of rows. When d2 changes I want to compare it to e2 and if d2>e2 then bump the counter in a2 by 1 (uptick), if d2<e2 then bump the counter in b2 (downtick). I have it working with many if and elseif statements but would rather use less code using variables for the range. To detect the changing cell I use "If Not Intersect (Target, Range("d2:d10")) Is Nothing Then...."
I cannot seem to figure out how to replace specific cell references with ranges. Any help would be most appreciated!
Sample Code below not using ranges yet.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("D2:D10")) Is Nothing Then
If Target.Value > Range("E2") Then
Range("A2") = Range("A2") + 1
Pause 2#
Range("E2") = Target.Value
ElseIf Target.Value < Range("E2").Value Then
Range("B2") = Range("B2") + 1
Pause 2#
Range("E2") = Target.Value
End If
End If
End Sub
I assume you want to change the cell value in the same row that the value was entered in column D, i.e. if D4 has been changed, then adjust A4 or B4. To do that, you need the row number of the changed cell. You can extract that with target.row. Throw that into a variable and use the variable instead of the row number in the Range() property.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("D2:D10")) Is Nothing Then
dim myRow as long
myRow = target.row
If Target.Value > Range("E" & myRow) Then
Range("A" & myRow) = Range("A" & myRow) + 1
Pause 2#
Range("E" & myRow) = Target.Value
ElseIf Target.Value < Range("E" & myRow).Value Then
Range("B" & myRow) = Range("B" & myRow) + 1
Pause 2#
Range("E" & myRow) = Target.Value
End If
End If
End Sub
You could use .Offset to get the same result. The following code assumes you're only interested in the range D2:D10 and aren't concerned if the value in column D equals the value in column E.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Range("D2:D10"), Target) Is Nothing Then
If Target.Rows.Count > 1 Then Exit Sub
If Target > Target.Offset(, 1) Then
Target.Offset(, -3) = Target.Offset(, -3) + 1
Else
If Target < Target.Offset(, 1) Then
Target.Offset(, -2) = Target.Offset(, -2) + 1
End If
End If
End If
End Sub

Comment Used To Track Changes

I have encountered a few issues with some code in VBA. I am trying to have the changes made to a cells on an excel sheet show up in comments on the cell the change was made to and I wish for these changes to be stored in a list so I can view them all later. I have tried lots of different pieces of code I have found to try and implement it into the code but none have worked.
Any ideas on how to get this to work?
Worksheet
The below code is what I am currently using
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Adding As Boolean, Finding As Boolean, Subtracting As Boolean
Dim f As Range, v
Select Case Target.Address(True, True)
Case "$A$4": Adding = True
Case "$C$4": Subtracting = True
Case "$E$4": Finding = True
Case Else: Exit Sub
End Select
v = Trim(Target.Value)
If Len(v) = 0 Then Exit Sub
Set f = Me.Range("C8").Resize(1000, 1).Find(v, lookat:=xlWhole)
If Adding Then
If f Is Nothing Then
'not found: add as new row
Set f = Me.Cells(Rows.Count, 3).End(xlUp).Offset(1, 0)
f.Value = v
End If
f.Offset(0, 1).Value = f.Offset(0, 1).Value + 1
doDate f.Offset(0, 2)
Target.Value = ""
ElseIf Subtracting Then
If f Is Nothing Then
MsgBox v & " not found for subtraction!"
Else
f.Offset(0, 1).Value = f.Offset(0, 1).Value - 1
doDate f.Offset(0, 3)
Target.Value = ""
End If
Else 'finding
If Not f Is Nothing Then
f.EntireRow.Select
Target.Value = ""
Else
MsgBox v & " not found."
End If
End If
If Adding Or Subtracting Then Target.Select
End Sub
Sub doDate(c As Range)
With c
.NumberFormat = "m/d/yyyy h:mm AM/PM"
.Value = Now
End With
End Sub
I have implemented a few formulas on the worksheet but don't see any reason why it would matter in this situation since they only track quantity of items with the same unique identifier.
I also tried some code that added comments to the cells as they were changed that worked but always returned the previous cell value as blank. It is not actually added into the current code though.
Option Explicit
Public preValue As Variant
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
Target.ClearComments
Target.AddComment.Text Text:="Previous Value was " & preValue & Chr(10) & "Revised " & Format(Date, "mm-dd-yyyy") & Chr(10) & "By " & Environ("UserName")
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
If Target = "" Then
preValue = "a blank"
Else: preValue = Target.Value
End If
End Sub
By and large, the code below should do what you want. I marveled at your use of A4 and C4 to express addition and subtraction. As it is, whatever you change in those two cells, apart from clearing them, will result in a quantity of 1 being added or subtracted. I would have expected that a quantity must be entered there which is processed. If the quantity is fixed at 1 the system appears too elaborate.
Anyway, here's the code. I guess you'll be able to modify it to better suit your needs.
Private Sub Worksheet_Change(ByVal Target As Range)
' 038
Dim LookUp As Variant ' subject
Dim Action As Variant ' add = 1, subtract = -1, find = 2
Dim Fnd As Range ' Result of Find method
Dim Txt As String ' comment text
With Target
If (.Row <> 4) Or (.CountLarge > 1) Then Exit Sub
LookUp = Cells(4, "E").Value
On Error Resume Next
Action = Array(0, 1, 0, -1, 0, 2)(.Column)
End With
If Action And (LookUp <> "") Then
' C8 to end of column C
With Range(Cells(8, "C"), Cells(Rows.Count, "C").End(xlUp))
Set Fnd = .Find(LookUp, .Cells(.Cells.Count), xlValues, xlWhole, xlByRows)
End With
End If
If Fnd Is Nothing Then
Select Case Action
Case -1
MsgBox """" & LookUp & """ not found.", vbInformation, "Can't subtract"
Action = -2
Case 2
MsgBox """" & LookUp & """ not found.", vbInformation, "No record"
Action = -2
Case Else
Set Fnd = Cells(Rows.Count, "C").End(xlUp).Offset(1)
Fnd.Value = LookUp
End Select
End If
With Fnd
If Abs(Action) <> 2 Then
With .Offset(0, 1)
If .Comment Is Nothing Then
.AddComment
Else
Txt = Chr(10)
End If
Txt = "Previous Qty = " & .Value & Chr(10) & _
"Revised " & Format(Date, "mm-dd-yyyy") & Chr(10) & _
"by " & Environ("UserName") & Txt
.Comment.Text Txt, 1, False
.Value = Val(.Value) + Action
With .Offset(0, 2)
.NumberFormat = "m/d/yyyy h:mm AM/PM"
.Value = Now
End With
End With
ElseIf Action = 2 Then
.EntireRow.Select
End If
End With
If Action <> 2 Then Target.Select
End Sub

How to insert data from userform to a specific row with a specific value

I want to create a userform that can find the "Sales" value in column E and then input the remaining data to the same row.
Set APAC = Sheet2
APAC.Activate
Range("E18:E1888").Select
For Each D In Selection
If D.Value = "TWO.Sales.Value" Then
Exit For
End If
Next D
Rows(D.Row).Select
D.Offset(0, 2).Value = TWO.RSA.Value
D.Offset(0, 3).Value = TWO.Part.Value
D.Offset(0, 4).Value = Application.WorksheetFunction.VLookup(TWO.Part.Value, Worksheets("DataEntry").Range("T2:U70").Value, 2, False)
D.Offset(0, 5).Value = TWO.Program.Value
D.Offset(0, 6).Value = TWO.QTY.Value
Sheet2.Activate
This is my code but
run time error '91'
occurs.
I am having error on the "Rows(D.Row).select" line – Jacob 2 mins ago
That means "TWO.Sales.Value" was not found in Range("E18:E1888") and hence D was nothing. You need to check if the value was found. Also I have a feeling that you wanted If D.Value = TWO.Sales.Value Then instead of If D.Value = "TWO.Sales.Value" Then
Also there is no need to Select/Activate. You can directly work with the objects. You may want to see How to avoid using Select in Excel VBA
Whenever you are working with VLookup, it is better to handle the error that may pop up when a match is not found. There are various ways to do it. I have shown one way in the code below.
Is this what you are trying? (UNTESTED)
Option Explicit
Sub Sample()
Dim APAC As Worksheet
Dim curRow As Long
Dim aCell As Range
Dim Ret
Set APAC = Sheet2
With APAC
For Each aCell In .Range("E18:E1888")
If aCell.Value = TWO.Sales.Value Then
curRow = aCell.Row
Exit For
End If
Next aCell
If curRow = 0 Then
MsgBox "Not Found"
Else
.Range("G" & curRow).Value = TWO.RSA.Value
.Range("H" & curRow).Value = TWO.Part.Value
On Error Resume Next
Ret = Application.WorksheetFunction.VLookup(TWO.Part.Value, _
Worksheets("DataEntry").Range("T2:U70").Value, 2, False)
On Error GoTo 0
If Ret <> "" Then .Range("I" & curRow).Value = Ret
.Range("J" & curRow).Value = TWO.Program.Value
.Range("K" & curRow).Value = TWO.QTY.Value
End If
End With
End Sub
NOTE: If the range .Range("E18:E1888") is dynamic then you may want to find the last row as shown HERE and then use the range as .Range("E18:E" & LastRow)

Worksheet Change Event - check cells in column for % difference

I am struggling to get a Worksheet_Change event to work with the goal of checking if there is a % difference greater than 10% between range G12:42 and range J12:42. I have a calculation in range G12:42, which seems to be causing me some of the headache.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim diffPercent
'Check that the data is changed between row 12 and 42 and it is even row. eg 12,14,16...42.
If (Target.Row > 12 And Target.Row < 42) And ((Target.Row Mod 2) = 0) Then 'And _
'(Target.Column = 7 Or Target.Column = 10) Then
'Get the values in J ang G columns of that particular row.
number1 = Range("G" & Target.Row).Value
number2 = Range("J" & Target.Row).Value
'Check for presence of both the inputs to calculate difference in percentage.
If Not chkInputs(number1, number2) Then
Exit Sub
End If
'Calculate the percentage difference.
diff = number2 - number1
diffPercent = (diff / number2) * 100
'Give alert if difference more than 10 percent
If diffPercent > 10 Then
MsgBox "Oppps. Your system is not working!"
End If
End If
End Sub
Function chkInputs(number1, number2)
chkInputs = False
If IsNumeric(number1) And IsNumeric(number2) Then
chkInputs = True
End If
End Function
The expected result is the triggering of a MsgBox providing a message.
No need to have a separate funciton. You can include it in the main code. Also use Intersect to work with the relevant range else the code will trigger if there is a change anywhere in that row range. One more thing. Check if the cell in column J is not 0 else you will get an Overflow error.
You may also want to see Working with Worksheet_Change
Is this what you are trying (Untested)?
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rngToCheck As Range
Dim NumA As Variant, NumB As Variant
Dim i As Long
On Error GoTo Whoa
'~~> Set the relevant range
Set rngToCheck = Union(Range("G12:G42"), Range("J12:J42"))
Application.EnableEvents = False
If Not Intersect(Target, rngToCheck) Is Nothing Then
For i = 12 To 42 Step 2 '<~~ Loop through only even rows
NumA = Range("G" & i).Value
NumB = Range("J" & i).Value
If IsNumeric(NumA) And IsNumeric(NumB) And NumB <> 0 Then
If ((NumA - NumB) / NumB) * 100 > 10 Then
MsgBox "Please check the value of Col G and J Cells in row " & i
Exit For
End If
End If
Next i
End If
Letscontinue:
Application.EnableEvents = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume Letscontinue
End Sub

Resources