Emptying specific cells in the same row of an amended cell - vba

I am relatively new to VBA.
Below is my code that works on just row 2.
Option Explicit
Public precedent
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.[D2]) Is Nothing Then
If Me.precedent <> Me.[D2].Value Then
Me.[F2] = ""
Me.[H2] = ""
Me.precedent = Me.[D2].Value
End If
End If
End Sub
I would like this code to run on every row except row 1 as this is my header.
How do I do this? Would I use a loop?

It shouldn't be so complicated. Just check Target.Row and Target.Column. If the former is greater than 1 and the latter is equal to 4, trigger whatever action you want.
Modify the following code accordingly.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Row > 1 And Target.Column = 4 Then
Range("F" & Target.Row) = vbNullString
Range("H" & Target.Row) = vbNullString
End If
End Sub
Let us know if this helps.

You wouldn't have to use a loop. Since you want to omit the first row, you should set a range that you want this code to fire when it is modified. Currently, you are checking it against D2 only. When your If statement is checking for your entire range, you can then use Target as the specific cell that was changed (instead of using D2.)
Here's some code that should do what you want:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rangeToCheck As Range
rangeToCheck = Range(Cells(2,4),Cells(Application.ActiveSheet.UsedRange.Rows.Count,4)) 'If your range isn't dynamic, you could put static numbers here
If Not Intersect(Target, rangeToCheck) Is Nothing Then 'Now checks against all of Column D, omitting Row 1
If Target.precedent <> Target.Value Then
Target.Offset(0,2).Value = "" 'Clear Column F in Target Row
Target.Offset(0,4).Value = "" 'Clear Column H in Target Row
Target.precedent = Target.Value
End If
End If
End Sub

Below is code that will skip row 1. Note the .Row and .Column properties of 'Target'
Option Explicit
Public precedent
Private Sub Worksheet_Change(ByVal Target As Range)
Debug.Print Target.Column
Debug.Print Target.Row
If Target.Row <> 1 Then
If Not Intersect(Target, Me.[D2]) Is Nothing Then
If Me.precedent <> Me.[D2].Value Then
Me.[F2] = ""
Me.[H2] = ""
Me.precedent = Me.[D2].Value
End If
End If
End If
End Sub

I think you need this one:
Sub Worksheet_Change(ByVal Target As Range)
If Target.Column <> 4 Then Exit Sub
If Me.Cells(Target.Row, 4) = "" Then
Me.Cells(Target.Row, 6) = ""
Me.Cells(Target.Row, 8) = ""
End If
End Sub

Related

Excel VBA: Automatically apply macro to cells

I'm currently learning the automatically triggered macro for a cell. I am curious if this can apply to a range of cells instead of 1 by 1?
My case is: If I input in any cell in column A, "Hello" will appear in column B in the corresponding row. My question is that what if, for instance, I input in A1 (then B1 will appear "Hello"), then I drag from A1 to A10, how can I make the macro automatically apply to B2 -> B10? Currently, I run into the "run time error '13' - Type mismatch".
My current script:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim i As Integer
i = Target.Row
If Not Intersect(Target, Range("A:A")) Is Nothing Then
If Target <> "" Then
Cells(i, 2) = "Hello"
Else
Cells(i, 2).ClearContents
End If
End If
End Sub
Use Offset, which is relative, and loop through Target if it is multiple cells.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim i As Integer, r As Range
If Not Intersect(Target, Range("A:A")) Is Nothing Then
For Each r In Intersect(Target, Range("A:A")
If r <> "" Then
r.Offset(, 1).Value = "Hello"
Else
r.Offset(, 1).ClearContents
End If
Next r
End If
End Sub

Locking specific cells in excel VBA

I have a macro I am working on currently.
Purpose
The objective in that once there is a value in column L , i need cells in the revelant row to lock. However this should not lock the whole worksheet, just the cells.
Code
Below is the code i have been been playing with. I am trying amend the code so to achieve my purpose above.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Row = 1 Then
If Target.Column = 3 Or Target.Column = 5 Then
Beep
Cells(Target.Row, Target.Column).Offset(0, 1).Select
End If
End If
End Sub
Example
The cells which will be locked are in yellow, if there is a date in column L
The reason why locking the whole worksheet wont overcome the problem is because any additional users will not be able to input there own data into the worksheet.
Merely locking the cells has no effect unless you protect the sheet. Firstly, unlock all the cells in the sheet, and then try this:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column <> 12 Or Target.Row = 1 Then Exit Sub
Range(Cells(Target.Row, 2), Cells(Target.Row, 11)).Locked = True
ActiveSheet.Protect
End Sub
Change the password in the first line of code with the actual password to unprotect the sheet.
Const PW As String = "123"
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.CountLarge > 1 Then Exit Sub
Dim r As Long
If Target.Column = 12 And Target.Row > 1 Then
ActiveSheet.Unprotect Password:=PW
r = Target.Row
If Target <> "" Then
Range("B" & r & ":K" & r).Locked = True
Else
Range("B" & r & ":K" & r).Locked = False
End If
ActiveSheet.Protect Password:=PW
End If
End Sub

Copy cell value to a range of cells

I'm new to VBA and I am trying to copy values from one cell to multiple cells when its value changes.
The value of A2 is constantly changing and when that happens I want that value to be copied to cells C2:C21 (and then eventually to cells D2:D21)
Here is an example of what I would like to achieve:
http://i.stack.imgur.com/xJZyZ.jpg
So far I wrote this code:
Sub Worksheet_Change(ByVal Target As Range)
For i = 0 To 19
If Not Intersect(Target, Range("AS2")) Is Nothing Then
Cells(Target.Row + i, 58).Value = Cells(Target.Row, 45).Value
End If
Next i
End Sub
but this only copies one single value of A2 to all the cells C2 to C22.
May anyone help me write this code properly?
Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("AS2")) Is Nothing Then
For CurCol = 3 to 4
For CurRow = 2 to 21
If Cells(CurRow, CurCol).Value = "" Then
Cells(CurRow, CurCol).Value = Target.Value
Exit Sub
EndIf
Next CurRow
Next CurCol
End If
End Sub
I guess this is what you're after:
Option Explicit
Sub Worksheet_Change(ByVal Target As Range)
Dim nVals As Long
If Not Intersect(Target, Range("A2")) Is Nothing Then
With Range("C2:D21")
nVals = WorksheetFunction.CountA(.Cells)
If nVals = .Count Then Exit Sub
Application.EnableEvents = False
On Error GoTo exitsub
.Cells(nVals Mod .Rows.Count + 1, IIf(nVals >= .Rows.Count, 2, 1)).Value = Target.Value
End With
End If
exitsub:
Application.EnableEvents = True
End Sub

How to prefix cell with 0, dependant on character length

Private Sub Worksheet_Change(ByVal Target As Range)
If Len(Target) = 8 Then
Exit Sub
End If
If Range("AF1:AF1000").Value = "Q" Then
Exit Sub
End If
On Error Resume Next
Application.EnableEvents = False
If Target.Column = 30 Then
lTarget = Len(Target)
Target.NumberFormat = "#"
For i = 1 To 8 - lTarget
Target.Value = "0" & Target.Value
Next
End If
Application.EnableEvents = True
End Sub
I'm trying to get this to basically when putting the information into a certain cell, if you put any less that 8 digits in, it will prefix it with '0 until it is 8 which is does, but now i want to adapt it so that it doesn't do it if a certain cell has the text "Q" in it, its not working when i do this how ever, little help?
EDIT: to make this easier the whole AF thing... its the entire AF column not just 1 to 1000 so how do i change that with what i have so far... probably need to re-write the whole thing..lol :(
If you mean it should check column AF on the same row for a Q, try this:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rCell As Range
If Not Intersect(Target, Me.Columns(30)) Is Nothing Then
On Error Resume Next
Application.EnableEvents = False
For Each rCell In Intersect(Target, Me.Columns(30)).Cells
Select Case Len(rCell.Value)
Case 0, 8
' ignore if 8 characters or blank
Case Else
If Strings.UCase$(Cells(rCell.Row, "AF").Value) <> "Q" Then
rCell.NumberFormat = "#"
rCell.Value = VBA.Right$("0000000" & rCell.Value, 8)
End If
End Select
Next rCell
End If
Application.EnableEvents = True
End Sub

Creating a Timestamp VBA

Need Help with this Macro:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 2 Then
Application.EnableEvents = False
Cells(Target.Row, 3).Value = Date + Time
Application.EnableEvents = True
End If
End Sub
Sub DeleteCells()
For Each Cell In Range("B3:B25")
If IsBlank(Cell.Value) Then
Cell.Offset(0, 1).Clear
End If
Next
End Sub
The purpose of this macro is to create a timestamp. First macro works fine. If anything from row B is filled in, a timestamp will be created in row C. However, the delete cells function isn't working. I want it so that if someone deletes a cell in row B, the timestamp will also be deleted.
Try this:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng As Range, c As Range
'anything in ColB?
Set rng = Application.Intersect(Me.Columns(2), Target)
If rng Is Nothing Then Exit Sub 'nothing to process...
Application.EnableEvents = False
'could be >1 cell, so loop over them...
For Each c In rng.Cells
'skip any cells with errors
If c.Row>=3 And Not IsError(c.Value) Then '<<edit
c.EntireRow.Cells(3).Value = _
IIf(Len(c.Value) > 0, Now, "")
End If
Next c
Application.EnableEvents = True
End Sub