excel vba loop - repeat a command till somewhere - vba

Hello I would like to have a function that, every time I click in a certain cell (E6) it will lock cells on the left (A6:C6) or (E7) will lock (A7:C7).
Example of my sheet
I do not really know VBA I just need this one function.
I need to have this for as many cells as i want - for example every E2:E1000 will lock the row on the left from A2:C2, A3:C3 and so on...
Sub ProtectTheSheet()
Dim chCell As Range
Dim chRng As Range
ActiveSheet.Unprotect Password:="password"
Set chRng = ActiveSheet.Range("A6:C6")
'Check cell value in body and lock cells with content
For Each chCell In chRng.Cells
chCell.Locked = (chCell.Value <> "")
Next chCell
ActiveSheet.Protect Password:="password"
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Selection.Count = 1 Then
If Not Intersect(Target, Range("E6")) Is Nothing Then
Call ProtectTheSheet
End If
End If
End Sub
Thank you guys very much in advance.

I think, by reading you question, that the next code will solve your problem:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Selection.Count = 1 And Selection.Column = 5 Then
ThisWorkbook.ActiveSheet.Unprotect Password:="password"
For col = 1 To 3
ThisWorkbook.ActiveSheet.Cells(Selection.Row, col).Locked = True
Next col
ThisWorkbook.ActiveSheet.Protect Password:="password"
End If
End Sub
Please note that, in this case, you don't need ProtectTheSheet subroutine.

Related

How can I stop editing cell if it is not done with in set time?

In my office we tally bags with a barcode scanner, but some times the user edits the Excel cell, giving the bag number manually, so I want to stop manually writing in excel cell.
That cell must update only by scanner.
I've tried the code below, and it returns the keystroke count but not the time.
Private Sub Worksheet_Change(ByVal Target As Range)
'If Target.Address = Range("A1:A100") Then
'Enter Code or Call any Function if any process has to be performed
'When someone Edits the cell A1
If Range(ActiveCell, ActiveCell.Offset(numRows, numCols)).Offset.Value = "" Then
Call Demo
Else: End If
End Sub
Sub Demo()
'Specify a range (change to suit)
MsgBox CountKeystrokes(Sheets("Sheet1").Range("A:A"))
If Range(ActiveCell, ActiveCell.Offset(numRows, numCols)).Offset.Value <> "" Then
Range(ActiveCell, ActiveCell.Offset(numRows, numCols)).Select
Selection.ClearContents
Else
End If
End Sub
Function CountKeystrokes(rng As Range) As Long
Dim rCell As Range
Dim iCtr As Long
For Each rCell In rng
iCtr = iCtr + Len(rCell.Formula)
Next
CountKeystrokes = iCtr
End Function

Delete 0's from cell upon entry

I want a macro so that when you enter a 0 into a particular cell/range of cells that it clears the cell.
I wrote a simple macro like this
Sub RemoveZeros()
'to remove 0 values that may be a result of a formula or direct entry.
For Each cell In Range("A1:D20")
If cell.Value = "0" Then cell.Clear
Next
End Sub
However, I have to run this after I have entered my values for it to clear. I would like the cell to clear if a 0 is entered. How do I do this?
I found a solution
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
If Target.Value = 0 Then Target.ClearContents
Application.EnableEvents = True
End Sub
Thanks

VBA: How to automatically trigger macro without a button

I have made a macro that auto fill the formula on sheet1 whenever the row number of sheet2 is changed.
Is it possible to trigger it automatically without a button when i have any update on sheet2?
Sub Autofill()
Dim sg As Sheets
Dim Row As Long
Dim fillRow As Integer
Application.EnableEvents = False
Row = Worksheets("Sheet2").Cells(Rows.Count, 1).End(xlUp).Row
fillRow = Row - 1
Sheets("Sheet1").Select
Range("A1:E1").Select
Selection.Autofill Destination:=Range("A1:E" & fillRow), Type:=xlFillDefault
Application.EnableEvents = True
End Sub
You could try to create a sub like following:
Paste the following code. And change:
1) "D4" with your cells you want to "monitor"
2) Paste your macro in the line "Do things"
The problem is, your code is run everytime the focus is changed to another cell.
But you could also use Worksheet_BeforeDoubleclick if this is enough. Then every time you clicke twice the code will run
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Selection.Count = 1 Then
If Not Intersect(Target, Range("D4")) Is Nothing Then
'Do things
End If
End If
End Sub
Right-click on the sheet tab at the bottom of the scree, click 'view
code' then insert this following code in there.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Row As Long
Dim fillRow As Integer
This next line will exit the code if column A is not what is being
changed on the sheet. Delete it if you want the code to be triggered
by any change on any cell of the sheet.
if InRange(Target,Worksheets("Sheet2").range("A:A") = false then exit sub
Row = Worksheets("Sheet2").Cells(Rows.Count, 1).End(xlUp).Row
fillRow = Row - 1
Sheets("Sheet1").Select
Range("A1:E1").Select
Selection.Autofill Destination:=Range("A1:E" & fillRow), Type:=xlFillDefault
End Sub
Function InRange(Range1 As Range, Range2 As Range) As Boolean
InRange = Not (Application.Intersect(Range1, Range2) Is Nothing)
End Function
use a Worksheet.SelectionChange-Event.
in the Worksheet-VBA for sheet2 add:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Call Autofill()
End Sub
(This will be triggered if cell is changed, even if user does not leave the row, so check parameter Target.)

Vba code for Date today in data validation

I have a spreadsheet that has data validation in cells A2-A999 with the only option in the drop down menu being "Today" (without the quotation marks). I have a VBA code that changes the cell's value to today's date when "Today" is selected in the cell. However, this code has a problem. When I clear the contents of a group of cells, including the cell that has today's date in it, the spreadsheet thinks, then debugs and then closes; for example clearing A1 & B1 simultaneously.
However, if I clear A1 by itself, it clears the cell with no problems.
P.S. By " I clear", I meant to say: "I select the group of cells with the mouse and then hit the backspace button."
Can you guys help me fix the code so that I can clear many cells at the same time, including the cell with data validation.
The code that I am using is pasted in the worksheet section and is as the following:
Private Sub Worksheet_Change(ByVal Target As Range)
selectedVal = Target.Value
If Target.Column = 1 Then
selectedNum = Application.VLookup(selectedVal, Worksheets("DATA-
O").Range("DateToday"), 2, False)
If Not IsError(selectedNum) Then
Target.Value = selectedNum
End If
End If
End Sub
The answer to your problem is (as Dirk Reichel just mentioned in a comment) to loop through each of the affected cells:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim c As Range
If Not Intersect(Columns(1), Target) Is Nothing Then
For Each c In Intersect(Columns(1), Target).Cells
selectedVal = c.Value
selectedNum = Application.VLookup(selectedVal, Worksheets("DATA-O").Range("DateToday"), 2, False)
If Not IsError(selectedNum) Then
Application.EnableEvents = False 'As recommended by K Paul
c.Value = selectedNum
Application.EnableEvents = True
End If
Next
End If
End Sub
However, based on what you say that the code is doing, I'm not sure why you don't just use:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim c As Range
If Not Intersect(Columns(1), Target) Is Nothing Then
For Each c In Intersect(Columns(1), Target).Cells
If c.Value = "Today" Then
Application.EnableEvents = False 'As recommended by K Paul
c.Value = Date
Application.EnableEvents = True
End If
Next
End If
End Sub
If you want to be fast, there are 2 ways.
Use Evaluate to do it array-like:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Columns(1), Target) Is Nothing Then
With Intersect(Columns(1), Target)
If Evaluate("AND(" & .Address & "<>""Today"")") Then Exit Sub
.Value = Evaluate("IF(" & .Address & "=""Today"",TODAY()," & .Address & ")")
End With
End If
End Sub
or use Range.Replace which also can be very fast:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Columns(1), Target) Is Nothing Then
Intersect(Columns(1), Target).Replace "Today", Date, xlWhole, , True, , False, False
End If
End Sub
A small hint: hitting ctrl & ; will directly input todays date

VBA define ranges and static date stamps

I need some help with this code as it doesn't work properly.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Cell As Range
For Each Cell In Target
With Cell
If .Column = Range("W:W").Column Then
Cells(.Row, "AC").Value = Int(Now)
End If
End With
Next Cell
End Sub
I am trying to get automatic static date stamps in column "AC" every time I fill in cells in column "W" and I want to start with row "19".
Tried to use
If .Column = Range("W19").End(xldown) Then
but it doesn't work.
I've just started using macro and vba and it will really help me if you can explain any solutions to me.
Thank you
Always turn off events if you are going to write to the worksheet in order that the Worksheet_Change event macro does not try to run on top of itself.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Columns("W:W")) Is Nothing Then
On Error GoTo bm_Safe_Exit
Application.EnableEvents = False
Dim rng As Range
For Each rng In Intersect(Target, Columns("W:W"))
If rng.Row > 18 Then _
rng.Offset(0, 6) = Date 'or Now for datetime
Next rng
End If
bm_Safe_Exit:
Application.EnableEvents = True
End Sub
This should handle multiple changes to column W like a block range paste.