I have 2 columns in an Excel sheet. A1 contains a drop down with the values "Enable" and "Disable". Cell B1 and C1 needs to be enabled or disabled based on the A1 drop down selection.
I tried using Data Validation but it does not work. Can anyone suggest how I might use Data Validation to accomplish this?
A | B
------------------------
1 Suggestions| (This cell should disable (B1))
------------------------
2 Errors| (Now here drop down will come with values(B2))
------------------------
Current VBA
Private Sub Worksheet_Change(ByVal Target As Range)
ThisRow = Target.Row
If Target = Range("A1") Then
If Target.Value = "Suggestions" Then
Worksheets("Code Review").Range("B:C").Locked = True
End If
Else
Worksheets("Code Review").Range("B:C").Locked = False
End If
End Sub
Also tried like this
Private Sub Worksheet_Change(ByVal Target As Range)
Dim cel As Range
If Not Intersect(Range("A:A"), Target) Is Nothing Then
Application.EnableEvents = False
Me.Unprotect
For Each cel In Intersect(Range("A:A"), Target)
cel.Offset(ColumnOffset:=1).Resize(ColumnSize:=2).Locked = _
cel.Value = "Suggestion"
Next cel
Me.Protect
Application.EnableEvents = True
End If
But this locks everything :( I want just 2 cells to be locked.
Related
I am trying to clear the contents of some cells if the value in a corresponding cell changes.
In the code below, if the value in O1 changes, the contents of Z1 to AD1, and P1 are cleared.
How can I apply this to all rows below, i.e. if O2 changes, the contents of Z2 to AD2, and P2 should be cleared, the same thing for row 3 and so on.
I'd like if new columns/rows are inserted in the worksheet, things won't break.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "O1" Then
Range("Z1:AD1").ClearContents
Range("P1").ClearContents
End If
End Sub
This should get you started
Only looks for changes that occur in Column O
Only triggers if ONE cell is changed at a time.
(you will need to switch to loop if many cells in Column O can be changed in one action such as pasting a range)
Be sure to turn events OFF before making any other changes to worksheet else you will end up in infinite loop leading to your instance of excel crashing
Make dynamic by clearing cells that are on the same row as the changed cell i.e. Target.Row
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("O:O")) Is Nothing Then
If Target.Count = 1 Then
Application.EnableEvents = False
Range(Cells(Target.Row, "Z"), Cells(Target.Row, "AD")).ClearContents
Cells(Target.Row, "P").ClearContents
Application.EnableEvents = True
End If
End If
End Sub
This should work.
Private Sub Worksheet_Change(ByVal Target As Range)
tCol = Target.Column
tRow = Target.Row
If tCol = 15 Then
For i = tRow To tRow + Target.Rows.Count - 1
Range(Cells(i, 26), Cells(i, 30)).ClearContents
Cells(i, 16).ClearContents
Next
End If
End Sub
Use Target.Column and Target.Row to get the number of the targets column and row which can then be used in Cells().
This is a simple answer but one I cannot find.
I have two columns of data.
Column A (1) has yes/no data validation list options in every cell.
Column B also has data validation with say 6 strings of text options in every cell.
But I only want each the corresponding cell (column B) to update in the same row as column A
e.g A20 toggled, then B20 is updated. Like so
A20 is selected “Yes” from the dropdown option and B20 is updated with the string “complete” which is one of the states you can select in the dropdown boxes manually in every cell in column B.
I had some code but I would have to write an argument for every cell and then two macros for every yes / no.
This is code that works for one cell only but this is not ideal for many cells but it works
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("A20")) Is Nothing Then
Select Case Range("A20")
Case "Yes": Macro_001
Case "No": Macro_002
End Select
End If
End Sub
Sub Macro_001()
Application.Calculation = xlManual
Application.ScreenUpdating = False
Sheets("August 2020").Select
Sheets("August 2020").Range("B20").Select
ActiveCell.FormulaR1C1 = "Complete"
Application.ScreenUpdating = True
Application.Calculation = xlAutomatic
End Sub
Sub Macro_002()
Application.Calculation = xlManual
Application.ScreenUpdating = False
Sheets("August 2020").Select
Sheets("August 2020").Range("B20").Select
ActiveCell.FormulaR1C1 = ""
Application.ScreenUpdating = True
Application.Calculation = xlAutomatic
End Sub
There much be an easier way with .range perhaps
Thanks in advance
In the developer tab click view code, choose the sheet you want the macro to run on, make sure the upper left drop down says worksheet and the upper right says Change (I'll assume your sheet has headers):
Private Sub Worksheet_Change(ByVal Target As Range)
Dim KeyCells As Range
Dim ChangeCell As Range
Dim numrows As Long
numrows = Cells(Rows.Count, 1).End(xlUp).Row
Set TriggerCells = Range("A1")
Set KeyCells = Range("B2:B" & numrows)
If Application.Intersect(TriggerCells, Range("A1")) = "[Column Header Text]" Then
If Not Application.Intersect(KeyCells, Range(Target.Address)) Is Nothing Then
If Target.Value = "Yes" Then
Range("B" & Target.Row).Value = "Completed"
End If
End If
End If
End Sub
Try that, see if it works for you.
I have a cell which i declared as active cell using developers tool in excel
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Range("C1").Value = ActiveCell.Value
End Sub
this cell is equals to the value of a drop down cell i created from data validation.
My Problem is cell C1 is not changing when i select a new value from the drop down
Here you go. When B1 is changed C1 is assigned the value of B1. It doesn't matter how the change was carried out, from the keyboard or by selection from a drop-down.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = Range("B1").Address Then
' prevent the coming change from causing a call of this procedure
Application.EnableEvents = False
Cells(1, "C").Value = Target.Value
Application.EnableEvents = True
End If
End Sub
New user, was referred to your helpful website by a friendly team member.
Problem: Trying to force a user in excel to fill in a cell in a column (column O) before filling in a cell in columns I-L. The problem lies in that not every cell in the columns needs to be filled in. I've found a VBA code that has somewhat helped but the problem is the pop up will still occur if column O is filled before there is text in just one of the cells in column I-L (and therefore the error occurs unless all 4 cells in the row are filled in). As mentioned, the goal is (for example) to get O264 to be filled in first before any of the cells in column I,J,K or L264 are filled in.
Further exacerbating this issue is there are multiple rows I need this applied to, believe this is where the range fits in. However, playing with the range line in excel does not work in the way I've tried.
Code below:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("I:L")) Is Nothing Then
If Target.Cells.Count > 1 Or IsEmpty(Target) Then Exit Sub
If Target.Offset(, -1).Value = "" Then
MsgBox "You must first enter feedback in column ""O"""
Target.Value = ""
Target.Offset(, -1).Select
End If
End If
End Sub
This could be a case where you might need to aid the user a little more. You could do that by hiding the dependent cells, by locking them, by greying them out, etc. My feeling is that displaying a message box whenever a user enters data in the wrong order is a little too reactive.
In the example below, the target cells are locked and greyed until something is entered in column 'O'. You'd also need to create a list of target rows if you have more than one.
In your code behind the appropriate sheet, the skeleton code below should get you started. I've included a couple of helper functions to make the code a little clearer for you:
Option Explicit
Private Const SHEET_PASSWORD As String = "xyz" 'whatever password you choose.
Private Const TARGET_ROWS As String = "2,4,6" 'your target rows, separated by commas.
Private Const TARGET_COLUMN As String = "O"
Private Const DEPENDENT_COLUMNS As String = "I:L"
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng As Range, cell As Range
Set rng = Intersect(Target, Me.Columns(TARGET_COLUMN))
'Exit routine if we're not in the target column.
If rng Is Nothing Then Exit Sub
'Process the target column cells.
For Each cell In rng.Cells
If IsTargetRow(cell.Row) Then
SetDependentStates cell
End If
Next
End Sub
Private Sub SetDependentStates(cell As Range)
Dim DependentRange As Range
'Define the Dependent range based on passed cell row.
Set DependentRange = Intersect( _
cell.EntireRow, _
Me.Range(DEPENDENT_COLUMNS) _
)
'Lock/unlock and paint Dependent rows, based on
'contents of passed cell.
Application.EnableEvents = False 'prevent capture of change event.
Me.Unprotect SHEET_PASSWORD
With DependentRange.Cells
If Len(cell.Value) = 0 Then
.ClearContents
.Locked = True
With .Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorDark1
.TintAndShade = -0.249977111117893
.PatternTintAndShade = 0
End With
Else
.Locked = False
With .Interior
.Pattern = xlNone
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End If
End With
Me.Protect SHEET_PASSWORD
Me.EnableSelection = xlUnlockedCells
Application.EnableEvents = True
End Sub
Private Function IsTargetRow(rowNum As Long) As Boolean
Dim v As Variant
'Tests if the pass row number is in the target row list.
For Each v In Split(TARGET_ROWS, ",")
If CLng(v) = rowNum Then
IsTargetRow = True
Exit Function
End If
Next
End Function
Public Sub InitialiseDependentStates()
Dim v As Variant
Dim cell As Range
'Define your unlocked cells.
'This is a simple example, adjust as you wish.
With Me
.Unprotect SHEET_PASSWORD
.Cells.Locked = False
.Protect SHEET_PASSWORD
.EnableSelection = xlUnlockedCells
End With
For Each v In Split(TARGET_ROWS, ",")
Set cell = Me.Range(TARGET_COLUMN & v)
SetDependentStates cell
Next
End Sub
You'll likely want to initialise the dependent states when the workbook is opened. Do this in the code behind the Workbook:
Private Sub Workbook_Open()
Sheet1.InitialiseDependentStates 'use whichever sheet you're using.
End Sub
I have rows from 1-100.
I know how to target specific cells and get data from them, but how would I do this when any row from 1 to 100 can be changed?
Say you put anything into Row A3. How would you write "Updated" into row B3 via VBA?
I want this to apply to rows A1-A100.
Thanks
Place the following event macro in the worksheet code area:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim A As Range, Intersection As Range, Cell As Range
Set A = Range("A1:A100")
Set Intersection = Intersect(Target, A)
If Intersection Is Nothing Then Exit Sub
Application.EnableEvents = False
For Each Cell In Intersection
Cell.Offset(0, 1).Value = "Updated"
Next Cell
Application.EnableEvents = True
End Sub
Open VBA Editor
Double click on the sheet you event take action (sheets appears in the left top box)
Select Worksheet on the left box above code box
Select change on the right box above code box
Paste the code
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
With ThisWorkbook.Worksheets("Sheet1")
If Not Intersect(Target, .Range("A1:A100")) Is Nothing Then
Application.EnableEvents = False
.Range("B" & Target.Row).Value = "Updated"
Application.EnableEvents = True
End If
End With
End Sub