I running a macro that pops up a message if the user inputs a value in column E having column D empty. therefore the user has to input value in D and then in E. once the user inputs a value in D, by Vlookup formula the sheet will display a number in column F.
The second macro should then check if value of column F is not equal to value input in column E, if not equal popup a message.
First part is working but not the second. any idea please. thanks
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = Cells(Target.Row, 5).Address And Target.Value <> "" And Cells(Target.Row, 4).Value = "" Then
MsgBox "Input value in column D"
Cells(Target.Row, 4).Select
Target.Clear
End If
Call Macro2
End Sub
Sub Macro2()
If Target.Address = Sheets(1).Cells(Target.Row, 5).Address And Target.Value <> "" And Target.Value <> Sheets(1).Cells(Target.Row, 6).Value Then
MsgBox "E and F don't match"
End If
End Sub
If the second one is the problem, then pass the Target to it:
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False '<--- Consider removing this line
If Target.Address = Cells(Target.Row, 5).Address _
And Target.Value <> "" _
And Cells(Target.Row, 4).Value = "" Then
MsgBox "Input value in column D"
Cells(Target.Row, 4).Select
Target.Clear
End If
Macro2 Target
Application.EnableEvents = True '<--- Consider removing this line
End Sub
Sub Macro2(Target As Range)
If IsError(Target) Then
MsgBox Target.Address & "is an error!"
ElseIf IsError(Sheets(1).Cells(Target.Row, 6)) Then
MsgBox Sheets(1).Cells(Target.Row, 6).Address & " is an error!"
ElseIf Target.Address = Sheets(1).Cells(Target.Row, 5).Address _
And Target.Value <> "" _
And Target.Value <> Sheets(1).Cells(Target.Row, 6).Value Then
MsgBox "E and F don't match"
End If
End Sub
However, it could be that Target.Clear is making a loop within the Worksheet_Change, because it changes the worksheet once again. Depending on whether this is ok or not ok, you may consider writing Application.EnableEvents = False and Application.EnableEvents = True at the start or at the end of the Sub.
Related
I am fairly new to writing code in excel VBA. Most of this code is some I have tried to replicated based on what other people have wrote. The problem I am having is I have a quantity counter and when a barcode is scanned into the cell (A4) it will add the barcode to a new cell (Starts at C8 and goes down) and if this barcode is already scanned once and is scanned again it will add one to the quantity. Now I am trying to add a date and time next to it as a barcode is scanned. This works but has an issue I can't figure out. The barcode must be scanned twice for the date to appear in the proper cell. This is an issue because it raises the quantity up one more than it should. Please help.
Private Sub Worksheet_Change(ByVal Target As Range)
Select Case Target.Address
Case "$A$4"
If Target.Value <> "" Then
On Error Resume Next
Set xitem = Range("C8", Range("C" & Rows.Count) _
.End(xlUp)).Find(Range("A4").Value)
With xitem.Offset(0, -1)
.Value = .Value + 1
.Offset(0, 1).Select
End With
With xitem.Offset(0, 1)
.Value = Date & " " & Time
.NumberFormat = "m/d/yyyy h:mm AM/PM"
End With
On Error GoTo 0
If xitem Is Nothing Then
With Range("C" & Rows.Count).End(xlUp).Offset(1, 0)
.Value = Target.Value
.Offset(0, -1) = 1
End With
End If
Range("A4") = ""
Range("A4").Select
End If
Adds quantity
Case "$C$4"
If Target.Value <> "" Then
On Error Resume Next
Set xitem = Range("C8", Range("C" & Rows.Count).End(xlUp)) _
.Find(Range("C4").Value)
With xitem.Offset(0, -1)
.Value = .Value - 1
End With
If xitem Is Nothing Then MsgBox Target & " cannot be found " _
& "and cannot be removed."
Range("C4") = ""
Range("C4").Select
On Error GoTo 0
End If
Removes quantity (I am going to add an out time to this just trying to get the initial scan time in first)
Case "$E$4" 'find
If Target.Value <> "" Then
On Error Resume Next
Set xitem = Range("C8", Range("C" & Rows.Count).End(xlUp)) _
.Find(Range("E4").Value)
If xitem Is Nothing Then
MsgBox Target & " was not found."
Range("E4").Select
End If
Range("E4") = ""
xitem.Select
On Error GoTo 0
End If
End Select
End Sub
This is what I am using to take me directly to a barcode that has already been scanned.
Sorry if this post is badly formatted never posted before. Any and all help with this issue is appreciated. A photo of the spread sheet is also attached.
You are repeating some things within your code which you only need to do once, like the Find() for example.
Here's one alternative approach:
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, -1)
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, -1)
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
if i double click in column g of any row that is defined i need the symbol to be shown in each column such as h,i,j,k,l,m of the row double clicked in column g
my vba code is
If Not Intersect(Target, Range("h3:m20")) Is Nothing Then
If Target.Value = "Ð" Then
Target.Value = "Ï"
Exit Sub
End If
If Target.Value = "x" Then Target.Value = "Ð"
If Target.Value = "Ï" Then Target.Value = "x"
If Target.Value = Empty Then Target.Value = "Ð"
End If
If Not Intersect(Target, Range("G3:G20")) Is Nothing Then
If Target.Value = "Ð" Then
Range("G" & Target.Row & "M" & Target.Row).Value = "Ï"
Exit Sub
End If
If Target.Value = "x" Then Range("G" & Target.Row & "M" & Target.Row).Value = "Ð"
If Target.Value = "Ï" Then Range("G" & Target.Row & "M" & Target.Row).Value = "x"
If Target.Value = Empty Then Range("G" & Target.Row & "M" & Target.Row).Value = "Ð"
End If
End Sub
this is not working...please help....thank you
Your Range references are missing a colon. You also mentioned in your explaination:
"if i double click in column g of any row that is defined i need the symbol to be shown in each column"
Right now you checking against an Intersect with the wrong Range. So try the below instead:
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
'Only activate when its a cell in range `G3:G20`
If Intersect(Target, Range("G3:G20")) Is Nothing Then Exit Sub
'Do something here with your values and IF statements
Target.Offset(0, 1).Resize(1, 6).Value = "TEST" 'Purely to test
End Sub
Not a finished code, but you'll be able to add the missing pieces to the puzzle at the bottom.
I am trying to write a VBA macro to track changes of a worksheet in a separate sheet(showing the history of changes) by displaying a comment box on the cell with some color, automatically when the user search and updates the data in the userform.
Below code is for search and update:
''this code is for updating the data in the userform''
Private Sub cmdupdate_Click()
If Me.TextBox1.Value = "" Then
MsgBox "SL No Can Not be Blank!!!", vbExclamation, "SL No"
Exit Sub
End If
SLNo = Me.TextBox1.Value
Sheets("Sheet1").Select
Dim rowselect As Double
rowselect = Me.TextBox1.Value
rowselect = rowselect + 1
Rows(rowselect).Select
Cells(rowselect, 2) = Me.TextBox2.Value
Cells(rowselect, 3) = Me.TextBox3.Value
Cells(rowselect, 4) = Me.TextBox4.Value
Cells(rowselect, 5) = Me.TextBox5.Value
Cells(rowselect, 6) = Me.TextBox6.Value
End Sub
''The below code is used to search from the excel sheet and displays in the userform''
Private Sub cmdSearch_Click()
Do
DoEvents
row_number = row_number + 1
item_in_review = Sheets("Sheet1").Range("A" & row_number)
If item_in_review = TextBox1.Text Then
TextBox2.Text = Sheets("Sheet1").Range("B" & row_number)
TextBox3.Text = Sheets("Sheet1").Range("C" & row_number)
TextBox4.Text = Sheets("Sheet1").Range("D" & row_number)
TextBox5.Text = Sheets("Sheet1").Range("F" & row_number)
TextBox6.Text = Sheets("Sheet1").Range("E" & row_number)
End If
Loop Until item_in_review = ""
End Sub
Now I try to add the below code for track changes after updating the excel sheet with userform but I am getting an error in this line "Target.Comment.Text Text:=OldVal" not able to get the solution to complete my task.
Sub Worksheet_Change(ByVal Target As Range)
Dim X As Integer
Set Wb = ThisWorkbook
ShtName = "Edits Log"
If Target.Cells.Count > 1 Then Exit Sub
X = EndRow + 1
Wb.Sheets(ShtName).Range("A" & X).Value = ActiveSheet.Name
Wb.Sheets(ShtName).Range("B" & X).Value = Target.Address
Wb.Sheets(ShtName).Range("C" & X).Value = OldVal
Wb.Sheets(ShtName).Range("D" & X).Value = Target.Value
Wb.Sheets(ShtName).Range("E" & X).Value = Now()
Wb.Sheets(ShtName).Range("F" & X).Value = Environ("username")
Target.Interior.ColorIndex = 6
On Error Resume Next
Target.AddComment
On Error GoTo 0
Target.Comment.Visible = False
Target.Comment.Text Text:=OldVal
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
OldVal = Target.Value
End Sub
From the comments, the error is thrown because oldVal is Empty. When a previously blank cell is changed, the Selection Change fires, and since there was no previous value in the cell, oldVal will be Empty.
The Worksheet Change code needs to handle that possibility, as well as the possibility that Target contains an error - e.g. #VALUE! or #N/A.
Stripping out the portion that writes to the "Edits Log" tab, your Worksheet Change might look something like the code below:
Option Explicit
Public oldVal 'should be a Variant
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
oldVal = Target.Value
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
Target.Interior.ColorIndex = 6
On Error Resume Next
Target.AddComment
On Error GoTo 0
With Target.Comment
.Visible = False
If Not IsEmpty(oldVal) And Not IsError(oldVal) Then
.Text CStr(oldVal)
Else
.Text "Previously blank or an error"
End If
End With
End Sub
To preface the situation, I am new to VBA programming so any help would be greatly appreciated.
I have two columns; one where the user can input a dollar value ("AL") and another where the user can input a percent value ("AK"). The object is to enable the user to input either value (% or $) and have the other value calculate. For instance, if the user inputs 10% in "AL", the applicable $ value will generate in "AK" and vice versa.
Below is the code I've come up with thus far but it isn't working. Any thoughts/suggestions would be greatly appreciated! Thank you!
Private Sub Worksheet_Change(ByVal Target As Range)
Dim cell As Range
Set cell = Range("AK9:AL50")
'Application.EnableEvents = False Application.EnableEvents = True'
If Not Application.Intersect(cell, Range(Target.Address)) Is Nothing Then
If Target.Column = 37 Then ' Value in first column changed
Range("AL" & Target.Row).Value = Range("AK" & Target.Row).Value / Range("V" & Target.Row).Value
Exit Sub
ElseIf Target.Column = 38 Then ' value in second column changed
Range("AK" & Target.Row).Value = Range("AL" & Target.Row).Value * Range("V" & Target.Row).Value
Exit Sub
'Application.EnableEvents = False Application.EnableEvents = True'
End If
End If
End Sub
You need to remove the Exit Subs
And the Application.EnableEvents = True needs to be outside the if.
The first time you ran it with the Application.EnableEvents = False line enabled it turned off the events and since you exited the sub before turning them back on it stayed off and the sub was never called again.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim cell As Range
Set cell = Range("AK9:AL50")
Application.EnableEvents = False
If Not Application.Intersect(cell, Range(Target.Address)) Is Nothing Then
If Target.Column = 37 Then ' Value in first column changed
Range("AL" & Target.Row).Value = Range("AK" & Target.Row).Value / Range("V" & Target.Row).Value
ElseIf Target.Column = 38 Then ' value in second column changed
Range("AK" & Target.Row).Value = Range("AL" & Target.Row).Value * Range("V" & Target.Row).Value
End If
Application.EnableEvents = True
End If
End Sub
My guess is right now your events are disabled.
Run this code after putting the correct code above in your sheet:
Sub foooo()
Application.EnableEvents = True
End Sub
This will turn the events back on. It is only needed once.
You can have a better use of your Worksheet_Change parameters, like Target.
1.Instead of:
Range("AL" & Target.Row).Value
you can use:
Target.Offset(, 1).Value
2.Instead of:
Range("AK" & Target.Row).Value
you can use:
Target.Value
3.Also Range(Target.Address) actually is Target
Code
Private Sub Worksheet_Change(ByVal Target As Range)
Dim cell As Range
Set cell = Range("AK9:AL50")
Application.EnableEvents = False
If Not Application.Intersect(cell, Target) Is Nothing Then
If Target.Column = 37 Then ' Value in first column changed
Target.Offset(, 1).Value = Target.Value / Range("V" & Target.Row).Value
ElseIf Target.Column = 38 Then ' value in second column changed
Target.Offset(, 2).Value = Target.Value * Range("V" & Target.Row).Value
End If
End If
Application.EnableEvents = True '<-- RESTORE SETTING OUTSIDE THE IF
End Sub
I have tried this code for creating mandatory fields but the problem is it is showing the error message before going to the cell.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim lastRow As Long
With ActiveSheet
lastRow = .Cells(.Rows.count, "A").End(xlUp).Row
Dim I, J As Integer
For I = 1 To lastRow
If Cells(I, "C").Value = "" Then
MsgBox "Please Enter Business Type Value", vbOKOnly
Exit Sub
End If
'If Cells(I, "D").Value = "" Then
'MsgBox "Please Enter Customer Account Code", vbOKOnly
'Exit Sub
'End If
'If Cells(I, "E").Value = "" Then
'MsgBox "Please Enter Transport Mode Value", vbOKOnly
'Exit Sub
'End If
'If Cells(I, "F").Value = "" Then
'MsgBox "Please Enter Incoterm Value", vbOKOnly
'Exit Sub
'End If
'If Cells(I, "K").Value = "" Then
'MsgBox "Please Enter From date Value", vbOKOnly
'Exit Sub
'End If
'If Cells(I, "L").Value = "" Then
'MsgBox "Please Enter To date Value", vbOKOnly
'Exit Sub
'End If
'If Cells(I, "K").Value > Cells(I, "L").Value Then
'MsgBox "To date value should greater than From value", vbOKOnly
'Exit Sub
'End If
'If Cells(I, "N").Value = "" Then
'MsgBox "Please Enter Origin Country Code Value", vbOKOnly
'Exit Sub
'End If
'If Cells(I, "O").Value = "" Then
'MsgBox "Please Enter Point of Origin Location Code Value", vbOKOnly
'Exit Sub
'End If
'If Cells(I, "R").Value = "" Then
'MsgBox "Please Enter Port of Loading Code Value", vbOKOnly
'Exit Sub
'End If
'If Cells(I, "S").Value = "" Then
'MsgBox "Please Enter Origin Clearance Location Value", vbOKOnly
'Exit Sub
'End If
'If Cells(I, "T").Value = "" Then
'MsgBox "Please Enter Destination Clearance Location Value", vbOKOnly
'Exit Sub
'End If
'If Cells(I, "U").Value = "" Then
'MsgBox "Please Enter Port of Discharge Code Value", vbOKOnly
'Exit Sub
'End If
If Cells(I, "Y").Value = "" Then
MsgBox "Please Enter Consignee Final Destination Location Code Value", vbOKOnly
Exit Sub
End If
If Cells(I, "Z").Value = "" Then
MsgBox "Please Enter Destination Country Code Value", vbOKOnly
Exit Sub
End If
If Cells(I, "AF").Value = "" Then
MsgBox "Please Enter Active status Value", vbOKOnly
Exit Sub
End If
If Cells(I, "AH").Value = "" Then
MsgBox "Please Enter Carrier Allocation Number Value", vbOKOnly
Exit Sub
End If
If Cells(I, "AI").Value = "" Then
MsgBox "Please Enter Carrier Allocation Valid From Date Value", vbOKOnly
Exit Sub
End If
If Cells(I, "AJ").Value = "" Then
MsgBox "Please Enter Carrier Nomination Sequence Number Value", vbOKOnly
Exit Sub
End If
Next I
End With
End Sub
This code
tracks A1:A10 to see if any cells are changed
then looks to see if the corresponding cell in row Y is empty
if empty a message is returned and the cell in A1:A10 that was changed is then blanked out
code
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng1 As Range
Dim rng2 As Range
Set rng1 = Intersect(Target, [a1:a10])
'exit if no cells in A1:A10 are changed
If rng1 Is Nothing Then Exit Sub
'turn off events to avoid code retriggering itself
Application.EnableEvents = False
For Each rng2 In rng1
If Cells(rng2.Row, "Y") = vbNullString Then
MsgBox "Please Enter Consignee Final Destination Location Code Value, your entry will be deleted", vbOKOnly
rng2.Value = vbNullString
End If
Next
Application.EnableEvents = True
End Sub
Another approach would be:
In your Worksheet_SelectionChange make all cells which do not pass your checks red. All who pass your checks green. You can do this with the following code. Do not produce any error messages in this procedure.
Range("A1").Interior.Color = RGB(255, 0, 0) 'red
Range("A1").Interior.Color = RGB(0, 255, 0) 'green
Do only allow saving the workbook if all your checks are passed. Therefore you can use the proceudre I have provided you in the other answer.
I think the event you are using may cause your problem.
You could implement mandatory fields with the Workbook_BeforeSave event. This will get fired, as soon as the user tries to save the excel file. Now you check all your fields which you define as mandatory and display the respective "error message".
When you set Cancel = True you can abort the saving process wich then really forces the user to add something in the required fields.
In the Workbook_BeforeSave event you can paste in all your checks you have already implemented.
More details on the Workbook_BeforeSave can be found here: https://msdn.microsoft.com/de-de/library/office/ff840057.aspx
Here you can find more info on how to implement the Workbook_BeforeSave event:http://www.positivevision.biz/blog/bid/153139/Excel-Tips-and-Tricks-Mandatory-Cell-Input