enter link description hereI want to limit below vba code to the column A in dynamic range ONLY. Right now if I enter something outside the range, it shows error and disrupts other functions in Workbook_SheetChange.
I attach my file for easy ref.
Please HELP ! HELP
'Formate Column A
If Target.Column = 1 Then
Dim s As String
Dim arr As Variant
s = Target.Value
If s = "" Then
Target.NumberFormat = "General"
Else
With CreateObject("vbscript.regexp")
.Pattern = "[^0-9]"
.Global = True
.IgnoreCase = True
arr = Split(Application.Trim(.Replace(s, " ")), " ")
End With
Target.Value = arr
Target.Value = Target.Value * 1
Target.NumberFormat = """REQ0000000""General"
End If
'Excel file link : https://drive.google.com/file/d/13w-AbgY83g02qHGqBrHr_6N26UkNpWKr/view?usp=sharing
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Call Module1.DeleteCheck
End Sub
Private Sub Workbook_Open()
Call Module1.CreateCheck
'Application.MoveAfterReturnDirection = xlToRight
'Application.MoveAfterReturn = True
End Sub
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Select Case Sh.Name
Case "Agents"
Exit Sub
Case Else
End Select
If Target.Column > 4 Or Target.CountLarge > 1 Then Exit Sub
If Target.Row = 1 Then Exit Sub
Application.EnableEvents = False
If InStr(1, Cells(Target.Row, "A"), "REQ") <> "" And Cells(Target.Row, "B") <> "" Then
Cells(Target.Row, "C") = ActiveSheet.Name
Cells(Target.Row, "C").Font.Name = "Times New Roman"
Cells(Target.Row, "C").Font.Size = 12
Cells(Target.Row, "C").HorizontalAlignment = xlRight
Cells(Target.Row, "D").ShrinkToFit = True
Cells(Target.Row, "A").Font.Name = "Times New Roman"
Cells(Target.Row, "A").Font.Size = 12
Cells(Target.Row, "A").HorizontalAlignment = xlLeft
Cells(Target.Row, "B").Font.Name = "Times New Roman"
Cells(Target.Row, "B").Font.Size = 12
Cells(Target.Row, "B").HorizontalAlignment = xlLeft
End If
'Formate Column A
If Target.Column = 1 Then
Dim s As String
Dim arr As Variant
s = Target.Value
If s = "" Then
Target.NumberFormat = "General"
Else
With CreateObject("vbscript.regexp")
.Pattern = "[^0-9]"
.Global = True
.IgnoreCase = True
arr = Split(Application.Trim(.Replace(s, " ")), " ")
End With
Target.Value = arr
Target.Value = Target.Value * 1
Target.NumberFormat = """REQ0000000""General"
End If
End If
'Set Cell Movement within The Range
'https://www.mrexcel.com/board/threads/set-movement-of-cells-in-dynamic-range-only.1172539/
If Target.CountLarge > 1 Then Exit Sub
Dim rng As Range
Set rng = Range("A1").CurrentRegion
If rng.Rows.Count > 1 Then
Set rng = Intersect(Target, rng.Offset(1, 0).Resize(rng.Rows.Count - 1, rng.Columns.Count))
Else
Set rng = Nothing
End If
If Not rng Is Nothing Then
If Target.Column = 2 And Not (IsEmpty(Target)) Then
Target.Offset(, 2).Select
Else
Target.Offset(, 1).Select`enter code here`
End If
End If
Application.EnableEvents = True
End Sub
Private Sub Workbook_SheetBeforeRightClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean)
Select Case Sh.Name
Case "Agents"
Exit Sub
Case Else
End Select
If Target.Column <> 5 Or Application.CountA(Cells(Target.Row, 1).Resize(, 2)) < 2 Then Exit Sub
Cancel = True
Call Module3.SelectOLE3
End Sub
Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
Select Case Sh.Name
Case "Agents"
Exit Sub
Case Else
End Select
If g_blnWbkShtSelChange Then Exit Sub
If Selection.Count = 1 Then
If Not Intersect(Target, Range("C1")) Is Nothing Then
g_blnWbkShtSelChange = True
Call Module1.CheckSheet
End If
End If
End Sub
Related
Below code is working good with same workbook. But when I am trying to get VLOOKUP value from another workbook, it is not getting the value.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rngCell As Range, m1 As Variant ', m2 As Variant
On Error GoTo Hello:
If Application.Intersect(Target, Range("C2:C100001")) Is Nothing Then Exit Sub
For Each rngCell In Intersect(Target, Range("C2:C100001"))
If Len(rngCell.Value) > 0 Then
'This line is working good
'm1 = Application.VLookup(rngCell.Value, ThisWorkbook.Sheets("AllVehicleNumbers").Range("B2:C100001"), 2, False)
'But this is not working
m1 = Application.VLookup(rngCell.Value, Workbooks(ThisWorkbook.Path & "\VehicleNumbers.xlsx").Worksheets("AllVehicleNumbers").Range("B2:C100001"), 2, False)
If Not IsError(m1) Then
Application.EnableEvents = False
rngCell.Value = m1
Application.EnableEvents = True
End If
End If
Next
Hello:
End Sub
This will work on a closed workbook:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim c As Range, rng As Range, v, frm
On Error GoTo haveError
Set rng = Application.Intersect(Target, Me.Range("C2:C100001"))
If rng Is Nothing Then Exit Sub
'Note your formula will vary a little if you're looking up numeric values
' (no quotes around the lookup value)
frm = "=VLOOKUP(""<v>"",'" & ThisWorkbook.Path & _
"\[VehicleNumbers.xlsx]AllVehicleNumbers'!B2:C100001,2,FALSE)"
For Each c In rng.Cells
v = Trim(c.Value)
If Len(v) > 0 Then
Application.EnableEvents = False
c.Formula = Replace(frm, "<v>", v)
c.Calculate
If IsError(c.Value) Then
c.Value = v 'no match - replace the original value
c.Font.Color = vbRed 'flag no match
Else
c.Value = c.Value 'convert to value
c.Font.Color = vbBlack 'clear any flag
End If
Application.EnableEvents = True
End If
Next
Exit Sub
haveError:
Application.EnableEvents = True
End Sub
I'm trying to get a macro to operate by calling out another macro to unlock a worksheet to allow a RFID reader to scan and input data and then protect the document again to allow it from being edited.
Private Sub Worksheet_Change(ByVal Target As Range)
' call another macro
Call UnProtect
' End Sub
' Dim i As Integer
' MsgBox (Target.Row & ":" & Target.Column)
' For i = 8 To 200
If Target.Column = 3 And Target.Row <= 12 Then
If Cells(Target.Row, Target.Column).Value <> "" And Cells(Target.Row, "E").Value = "" Then
' Cells(Target.Row, "E").Value = Now()
' Cells(Target.Row, "E").NumberFormat = "h:mm AM/PM"
End If
End If
' Next
' Range("E:E").EntireColumn.AutoFit
' End Sub
' Private Sub Worksheet_Change(ByVal Target As Range)
' Dim i As Integer
' MsgBox (Target.Row & ":" & Target.Column)
' For i = 8 To 200
If Target.Column = 1 And Target.Row <= 17 Then
If Cells(Target.Row, Target.Column).Value <> "" And Cells(Target.Row, "B").Value = "" Then
Cells(Target.Row, "B").Value = Now()
' Cells(Target.Row, "F").NumberFormat = "h:mm AM/PM"
End If
End If
' Next
' Range("F:F").EntireColumn.AutoFit
' End Sub
' Private Sub Worksheet_Change(ByVal Target As Range)
' Dim i As Integer
' MsgBox (Target.Row & ":" & Target.Column)
' For i = 8 To 200
If Target.Column = 3 And Target.Row >= 15 Then
If Cells(Target.Row, Target.Column).Value <> "" And Cells(Target.Row, "D").Value = "" Then
Cells(Target.Row, "D").Value = Now()
Cells(Target.Row, "D").NumberFormat = "mm/dd/yyy"
End If
End If
' Next
Range("D:D").EntireColumn.AutoFit
' End Sub
' call another macro
Call Protect
End Sub
The two macros it is calling to are
Sub UnProtect()
'Unprotect a worksheet
Sheets("Sign in Sheet").UnProtect
End Sub
and
Sub Protect()
'Protect a worksheet
Sheets("Sign in Sheet").Protect
End Sub
However, when I only include the unlock macro, the code will work fine. But when I add the protect macro, an error code will come up
Run-Time Error '1004':
Unable to set the NumberFormat property of the Range class
and it points to
Cells(Target.Row, "D").NumberFormat = "mm/dd/yyyy"
Any ideas as to what exactly is happening.
I see no provision for a case when Target is more than a single cell and there's a pretty good chance that the Worksheet_Change is trying to run on top of itself.
Cycle through each range object in Target and disable event triggers.
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo safe_exit
Application.EnableEvents = False
Call Unprotect
Dim t As Range
If Not Intersect(Target, Range("A1:A17")) Is Nothing Then
For Each t In Intersect(Target, Range("A1:A17"))
If t.Value <> vbNullString And t.Offset(0, 1).Value <> vbNullString Then
t.Offset(0, 1) = Now
t.Offset(0, 1).NumberFormat = "h:mm AM/PM"
End If
Next t
End If
If Not Intersect(Target, Range("C1:C12")) Is Nothing Then
For Each t In Intersect(Target, Range("C1:C12"))
If t.Value <> vbNullString And t.Offset(0, 2).Value <> vbNullString Then
t.Offset(0, 2) = Now
t.Offset(0, 2).NumberFormat = "h:mm AM/PM"
End If
Next t
'I don't understand why column F comes into play here
' Range("F:F").EntireColumn.AutoFit
End If
If Not Intersect(Target, Range("C15:C999999")) Is Nothing Then
For Each t In Intersect(Target, Range("C15:C999999"))
If t.Value <> vbNullString And t.Offset(0, 1).Value <> vbNullString Then
t.Offset(0, 1) = Now
t.Offset(0, 1).NumberFormat = "mm/dd/yyy"
End If
Next t
Range("D:D").EntireColumn.AutoFit
End If
Call Protect
safe_exit:
Application.EnableEvents = True
End Sub
Currently I have this code. In Column A, I have a current a "YES" or "No" Selection.
Private Sub worksheet_change(ByVal Target As Range)
If Not Intersect(Target, Range("A:A")) Is Nothing Then
ActiveSheet.Unprotect
If Target = "YES" Then
'Column B to S
For i = 1 To 18
With Target.Offset(0, i)
.Locked = False
.FormatConditions.Add Type:=xlExpression, Formula1:="=ISBLANK(" & Target.Offset(0, i).Address & ")"
With .FormatConditions(.FormatConditions.Count)
.SetFirstPriority
.Interior.ColorIndex = 4
End With
End With
Next i
ElseIf Target = "NO" Then
For i = 1 To 73
With Target.Offset(0, i)
.Value = ""
.Locked = True
.FormatConditions.Delete
End With
Next i
End If
ActiveSheet.Protect
End If
End Sub
Now when the user click the cell in Column T (19), I want to display a warning message to the user that this is not applicable for "Yes" selection.
This seems like it should do the task you are asking.
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("A:A")) Is Nothing Then
On Error GoTo bm_SafeExit
Application.EnableEvents = False
Me.Unprotect
Dim trgt As Range
For Each trgt In Intersect(Target, Range("A:A"))
If LCase(trgt.Value2) = "yes" Then
With trgt.Offset(0, 1).Resize(1, 18)
.Locked = False
With .FormatConditions.Add(Type:=xlExpression, Formula1:="=ISBLANK(B" & trgt.Row & ")")
.Interior.ColorIndex = 4
End With
End With
Else
With trgt.Offset(0, 1).Resize(1, 73)
.Value = vbNullString
.Locked = True
.FormatConditions.Delete
End With
End If
Next trgt
End If
bm_SafeExit:
Application.EnableEvents = True
Me.Protect Userinterfaceonly:=True
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not Intersect(Target, Range("T:XFD")) Is Nothing Then
On Error GoTo bm_SafeExit
Application.EnableEvents = False
Dim trgt As Range
For Each trgt In Intersect(Target, Range("T:XFD"))
If LCase(Me.Cells(trgt.Row, "A").Value2) = "yes" Then
MsgBox "Don't try to put Yes here", vbCritical + vbOKOnly, "Bad Choice"
Me.Cells(trgt.Row, "A").Select
End If
Next trgt
End If
bm_SafeExit:
Application.EnableEvents = True
End Sub
Set watches and breakpoints and use [F8] and [Ctrl]+[F8} to walk through the code.
I am creating an Excel spreadsheet. I have 2 separate functions that I need to combine but I am not sure how to smash them together. I know I can only have 1 change event. The first function will unprotect the sheet (column c is locked), auto populate column C when data is entered in to column A or erase C when A is erased and re-protect when complete. The second will return the cell focus to the next row, column A, when data is entered into A and B. Separately they work as needed.
Private Sub Worksheet_Change(ByVal Target As Range)
On Error Resume Next
Unprotect Password:="my password"
If Target.Column = 1 Then
Dim A As Range, B As Range, Inte As Range, r As Range
Set A = Range("A:A")
Set Inte = Intersect(A, Target)
If Target.Offset(0, 1 - Target.Column).Value = "" Then
Target.Offset(0, 3 - Target.Column).Clear
Exit Sub
End If
Application.EnableEvents = False
For Each r In Inte
r.Offset(0, 2).Value = Date & " " & Time
r.Offset(0, 2).NumberFormat = "m/d/yyyy h:mm am/pm"
Next r
Application.EnableEvents = True
End If
Protect Password:="my password"
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo Whoa
Application.EnableEvents = False
If Not Target.Cells.CountLarge > 1 Then
If Not Intersect(Target, Columns(1)) Is Nothing Then
Target.Offset(, 1).Select
ElseIf Not Intersect(Target, Columns(2)) Is Nothing Then
Target.Offset(1, -1).Select
End If
End If
Letscontinue:
Application.EnableEvents = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume Letscontinue
End Sub
How about this, seems to do what you want, as I understand the question.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rngIntersect As Range
Dim rngCell As Range
On Error GoTo TidyUp
Application.EnableEvents = False
If Target.Column = 1 Then
Set rngIntersect = Intersect(Range("A:A"), Target)
For Each rngCell In rngIntersect
If rngCell.Value = "" Then
rngCell.Offset(0, 2).Value = ""
Else
rngCell.Offset(0, 2).Value = Date & " " & Time
rngCell.Offset(0, 2).NumberFormat = "m/d/yyyy h:mm am/pm"
End If
Next rngCell
End If
If Target.Column < 3 And Target.Value <> "" Then ' lose the 'And Target.Value <> ""' as desired
Cells(Target.Row + Target.Rows.Count, 1).Select
End If
TidyUp:
Set rngIntersect = Nothing
Set rngCell = Nothing
Application.EnableEvents = True
End Sub
I'd also suggest using UserInterfaceOnly in your worksheet.Protect, then you don't have to unprotect the sheet for VBA to act on the sheet.
Implement it in two Sub-Procedures on a modul, then just call both of them in the Event-Procedure.
I am using the spreadsheet to do inventory- scanning parts in bin
I am trying to add a A2 Value next to the (Target.Row, 5)(row 6)
how do I make A2 or A9 or the next scan Value show up on Column F so if column E & F don't match I know the part is sitting on the wrong bin
I have tried .Value = Target.Worksheet.Cells(Target.Row, 1).Value but not working
Here is my complete code
Option Explicit
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
If Target.Cells.Count > 1 Or IsEmpty(Target) Or Target.Column <> 1 Then Exit Sub
If Not SheetExists("WarehouseInventory") Then Exit Sub
Dim Result As Variant
Set Result = Sheets("WarehouseInventory").Cells.Range("E:E").Find(Target)
If Result Is Nothing Then
Target.Worksheet.Cells(Target.Row, 2) = "Data New Bin"
Else
Target.Worksheet.Cells(Target.Row, 2) = Result.Worksheet.Cells(Result.Row, 4)
Target.Worksheet.Cells(Target.Row, 3) = Result.Worksheet.Cells(Result.Row, 5)
Target.Worksheet.Cells(Target.Row, 4) = Result.Worksheet.Cells(Result.Row, 6)
Target.Worksheet.Cells(Target.Row, 5) = Result.Worksheet.Cells(Result.Row, 7)
End If
End Sub
Public Function SheetExists(SheetName As String) As Boolean
Dim ws As Worksheet
SheetExists = False
For Each ws In ThisWorkbook.Worksheets
If ws.Name = SheetName Then SheetExists = True
Next ws
End Function
this an example how you can achieve required result
Private Sub Worksheet_Change(ByVal Target As Range)
Dim x&, y&
If Target.Column = 6 Then
y = 5: x = Target.Row
While Cells(x, y) <> "": x = x - 1: Wend
If Cells(Target.Row, 5) <> "" Then Cells(Target.Row, 6) = Cells(x, 1)
End If
End Sub
output
UPDATE
here your updated code, tested, works fine, insert it into "Cycle Count" sheet
Private Sub Worksheet_Change(ByVal Target As Range)
Dim x&, y&, Result As Range, ws As Worksheet
Application.EnableEvents = 0
If Target.Count > 1 Then
Application.EnableEvents = 1
Exit Sub
End If
If Not Intersect(Target, [A1:A99999]) Is Nothing Then
With ThisWorkbook
For Each ws In .Worksheets
If ws.Name = "WarehouseInventory" Then
Set ws = .Worksheets("WarehouseInventory")
Set Result = ws.[E:E].Find(Target.Value)
Exit For
End If
Next ws
If Result Is Nothing Then
Target.Offset(, 1).Value = "Data New Bin"
Application.EnableEvents = 1
Exit Sub
Else
Target.Offset(, 1).Value = ws.Range(Result.Address).Offset(, -1).Value
Target.Offset(, 2).Value = ws.Range(Result.Address).Value
Target.Offset(, 3).Value = ws.Range(Result.Address).Offset(, 1).Value
Target.Offset(, 4).Value = ws.Range(Result.Address).Offset(, 2).Value
y = 5: x = Target.Row
While .ActiveSheet.Cells(x, y) <> "": x = x - 1: Wend
Target.Offset(, 5).Value = .ActiveSheet.Cells(x, 1).Value
End If
End With
End If
Application.EnableEvents = 1
End Sub
sample file here http://www.filedropper.com/book1_5
What about Target.Worksheet.Cells(Target.Row, 6).Value = Target.Worksheet.Cells(Target.Row,1).Value ?
If you want only A2, in all rows substitute Target.Row with 2