Enable/Disbale cells of dropdown list in excel - excel

I have created a simple dropdown list. It looks something like this.
Here user is allowed to have multiple selection.
I want if user has selected options other than Not Applicable, then it should disable Not Applicable cell and enable other cities to select. But if user first selects Not Applicable then other city option should be disable. Also clicking on same cell will enable and disable the cell.
For E.g. First user decides not to select any country so he clicks on Not Applicable option and automatically "New York, Berlin, Mumbai, Munich" options gets disable. But later if user decides to select City option and if he again clicks on Not Applicable then it should get disable and other countries should get enable.
Also I have associated values to the cities and I am printing values.
=SUMPRODUCT(--(ISNUMBER(SEARCH(Sheet2!A2:A6;Sheet1!A2))*Sheet2!B2:B6))
I have used follwoing multiple selection and removal code from the internet.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim xRng As Range
Dim xValue1 As String
Dim xValue2 As String
If Target.Count > 1 Then Exit Sub
On Error Resume Next
Set xRng = Me.Range("A2")
If xRng Is Nothing Then Exit Sub
Application.EnableEvents = False
If Not Application.Intersect(Target, xRng) Is Nothing Then
xValue2 = Target.Value
Application.Undo
xValue1 = Target.Value
Target.Value = xValue2
If xValue1 <> "" Then
If xValue2 <> "" Then
If InStr(1, xValue1, xValue2 & ",") > 0 Then
xValue1 = Replace(xValue1, xValue2 & ", ", "") ' If it's in the middle with comma
Target.Value = xValue1
GoTo jumpOut
End If
If InStr(1, xValue1, ", " & xValue2) > 0 Then
xValue1 = Replace(xValue1, ", " & xValue2, "") ' If it's at the end with a comma in front of it
Target.Value = xValue1
GoTo jumpOut
End If
If xValue1 = xValue2 Then ' If it is the only item in string
xValue1 = ""
Target.Value = xValue1
GoTo jumpOut
End If
Target.Value = xValue1 & ", " & xValue2
End If
jumpOut:
End If
End If
Application.EnableEvents = True
End Sub

Try the following (place it in the module from the sheet with the dropdown list):
Private Sub Worksheet_Change(ByVal Target As Range)
Dim searchNA As Range
Dim LRow As Long
If Not Intersect(Target, Range("A2")) Is Nothing Then
With ThisWorkbook.Sheets("Sheet2")
LRow = .Cells(.Rows.Count, "A").End(xlUp).Row
Set searchNA = .Range("A2:A" & LRow).Find(Target.Value, lookat:=xlWhole, MatchCase:=True)
If Target.Value = "Not Applicable" Then
.Range("A2:A" & LRow).Locked = True
searchNA.Locked = False
Else
.Range("A2:A" & LRow).Locked = False
searchNA.Locked = True
End If
End With
End If
End Sub
I have assumed the validation list is in Worksheet("Sheet1") and the small table with cities is in "Sheet2"

Related

VBA Deleting Rows for Changed Cells Debug Error

The following does what I want it to by adding formulas when a value is entered into the Target cell, and then deletes said value when the cell is empty.
However, I keep running into a Debug Error if I were to right-click and delete that row within the Target Range, is there a way to prevent this from happening?
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("C11:C1000")) Is Nothing Then
If Target.Value <> "" Then
Target.Offset(0, -1).Formula = "=VLOOKUP(" & Target.Address & ",UIDs!$F$3:$H$750,3,FALSE)"
Else:
Target.Offset(0, -1).Value = ""
End If
End If
End Sub
Debug Error:
Then it takes me to If Target.Value <> "" Then if I click Debug.
You can confirm that Target is only 1 cell (as it will be a lot more than that when you delete a row):
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not Intersect(Target, Range("C11:C1000")) Is Nothing Then
If Target.Count > 1 Then Exit Sub
Application.EnableEvents = False
If Target.Value <> "" Then
Target.Offset(0, -1).Formula = "=VLOOKUP(" & Target.Address & ",UIDs!$F$3:$H$750,3,FALSE)"
Else
Target.Offset(0, -1).Value = ""
End If
Application.EnableEvents = True
End If
End Sub

Converting Worksheet VBA to all Sheets

I am trying to take some code is functioning on a single sheet and convert it so that it applies to all worksheets in the book. I thought I could move the code a module and then use the Workbook_SheetChange "wrapper" described in Worksheet change event for every sheet in the workbook. However, the Multiple Select dropdown still only works on the original sheet, despite the "Named_Range" being defined on all sheets.
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
With Sh
Dim OldVal As String
Dim NewVal As String
' If more than 1 cell is being changed
If Target.Count > 1 Then Exit Sub
If Target.Value = "" Then Exit Sub
If Not Intersect(Target, ActiveSheet.Range("Named_Range")) Is Nothing Then
' Turn off events so our changes don't trigger this event again
Application.EnableEvents = False
NewVal = Target.Value
' If there's nothing to undo this will cause an error
On Error Resume Next
Application.Undo
On Error GoTo 0
OldVal = Target.Value
' If selection is already in the cell we want to remove it
If InStr(OldVal, NewVal) Then
'If there's a comma in the cell, there's more than one word in the cell
If InStr(OldVal, ",") Then
If InStr(OldVal, ", " & NewVal) Then
Target.Value = Replace(OldVal, ", " & NewVal, "")
Else
Target.Value = Replace(OldVal, NewVal & ", ", "")
End If
Else
' If we get to here the selection was the only thing in the cell
Target.Value = ""
End If
Else
If OldVal = "" Then
Target.Value = NewVal
Else
' Delete cell contents
If NewVal = "" Then
Target.Value = ""
Else
' This IF prevents the same value appearing in the cell multiple times
' If you are happy to have the same value multiple times remove this IF
If InStr(Target.Value, NewVal) = 0 Then
Target.Value = OldVal & ", " & NewVal
End If
End If
End If
End If
Application.EnableEvents = True
Else
Exit Sub
End If
End With
End Sub
Regular modules don't have events. They are host agnostic. The SheetChange event is in the workbook object. So this means you must place your code into the ThisWorkBook object.
Now looking at your code I see a With Sh block that does nothing. You never use that object. The only place where it makes sense to use the sheet object is where you cite ActiveSheet. We always want to use Sh and we never want to assume that the correct sheet is active.
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Dim OldVal As String
Dim NewVal As String
' If more than 1 cell is being changed
If Target.Count > 1 Then Exit Sub
If Target.Value = "" Then Exit Sub
If Not Intersect(Target, Sh.Range("Named_Range")) Is Nothing Then
' Turn off events so our changes don't trigger this event again
Application.EnableEvents = False
NewVal = Target.Value
' If there's nothing to undo this will cause an error
On Error Resume Next
Application.Undo
On Error GoTo 0
OldVal = Target.Value
' If selection is already in the cell we want to remove it
If InStr(OldVal, NewVal) Then
'If there's a comma in the cell, there's more than one word in the cell
If InStr(OldVal, ",") Then
If InStr(OldVal, ", " & NewVal) Then
Target.Value = Replace(OldVal, ", " & NewVal, "")
Else
Target.Value = Replace(OldVal, NewVal & ", ", "")
End If
Else
' If we get to here the selection was the only thing in the cell
Target.Value = ""
End If
Else
If OldVal = "" Then
Target.Value = NewVal
Else
' Delete cell contents
If NewVal = "" Then
Target.Value = NewVal
Else
' This IF prevents the same value appearing in the cell multiple times
' If you are happy to have the same value multiple times remove this IF
If InStr(Target.Value, NewVal) = 0 Then
Target.Value = OldVal & ", " & NewVal
End If
End If
End If
End If
Application.EnableEvents = True
Else
Exit Sub
End If
End Sub
Finally, there is a logic flaw at the bottom of your if tree. If oldval is not in newval, oldval is not blank and new val is not blank you end up in that final place where it optinally adds a comma. If the that isn't needed then you're in a state where you have run .Undo on the change and you haven't set Target.Value at all. This might make it so you can't change the contents of a cell to a new value. I'm not sure if you intended that behavior.

Remember the previous value of formulas

After a deep research on the internet I managed to find a VBA code that allows me to remember the previous result of a formula. I would like to modify this code to obtain the previous value of the formulas in one column in another column next to it.
For example: if '' B2: B80 "contains formulas, I would like" D2: D80 "to show the previous value of those formulas.
The code that I show does not keep the previous values ​​in a single cell but continuously populates a column down and my goal is to obtain the previous value of each formula in a single cell, but of several cells of a column.
Dim xVal As String
Private Sub Worksheet_Change(ByVal Target As Range)
Static xCount As Integer
Application.EnableEvents = False
If Target.Address = Range("C2").Address Then
Range("D2").Offset(xCount, 0).Value = xVal
xCount = xCount + 1
Else
If xVal <> Range("C2").Value Then
Range("D2").Offset(xCount, 0).Value = xVal
xCount = xCount + 1
End If
End If
Application.EnableEvents = True
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
xVal = Range("C2").Value
End Sub
Please try this simple code. I think it will do what you want.
Sub CopyValues()
With Worksheets("Sheet1") ' enter your tab's name here
.Range("B2:B80").Copy
.Cells(2, "D").PasteSpecial xlValues
End With
Application.CutCopyMode = False
End Sub
i use something similar to track changes on another sheet. Maybe this will help?
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Dim sSheetName As String
sSheetName = "Data"
If ActiveSheet.Name <> "LogDetails" Then
Application.EnableEvents = False
Sheets("LogDetails").Range("A" & Rows.Count).End(xlUp).Offset(1, 0).Value = ActiveSheet.Name & " - " & Target.Address(0, 0)
Sheets("LogDetails").Range("A" & Rows.Count).End(xlUp).Offset(0, 1).Value = oldValue
Sheets("LogDetails").Range("A" & Rows.Count).End(xlUp).Offset(0, 2).Value = Target.Value
Sheets("LogDetails").Range("A" & Rows.Count).End(xlUp).Offset(0, 3).Value = Environ("username")
Sheets("LogDetails").Range("A" & Rows.Count).End(xlUp).Offset(0, 4).Value = Now
Sheets("LogDetails").Columns("A:E").AutoFit
Application.EnableEvents = True
End If
End Sub
Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
On Error GoTo ErrHandler:
n = 1 / 0
Debug.Print n
oldValue = Target.Value
oldAddress = Target.Address
Exit Sub
ErrHandler:
n = 1
' go back to the line following the error
Resume Next
oldValue = Target.Value
oldAddress = Target.Address
End Sub
This tracks each change made in all sheets bar the LogDetails so would record all your changes.
I believe if you add the last sub into yours and change the reference it should work.

Apply excel macro to a cell within the same row if a value within another column

I'm trying to apply an excel macro to a cell if there is a certain value in that same row but in a different column. For example, if column A4 has "Yes", then the macro runs on A5.
Currently, I am listing out each of the cells where I need to apply the macro, but I don't want to have to change the macro every single time I need another cell to be added.
The code I have currently right now is as below.
Thank you!
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rngDV As Range
Dim oldVal As String
Dim newVal As String
Dim lUsed As Long
Dim iselect As Range
If Target.Count > 1 Then GoTo exitHandler
On Error Resume Next
Set rngDV = Cells.SpecialCells(xlCellTypeAllValidation)
On Error GoTo exitHandler
If rngDV Is Nothing Then GoTo exitHandler
If Intersect(Target, rngDV) Is Nothing Then
'do nothing
Else
Application.EnableEvents = False
newVal = Target.Value
Application.Undo
oldVal = Target.Value
Target.Value = newVal
Set iselect = Application.Intersect(Target, Range("F28,F30,F77,F125,F176:F183,F185,F194,F196,F198:F205,F226,F364,F397,F400,F403,F451,F456,F545,F570,F572,F600,F605,F632,F638,F641,F646,F648,F673,F704,F706,F708,F712,F714,F716,F736,F765,F768,F798,F821,F823,F855,F884,F908,F947,F983:F984,F1009,F1015,F1026,F1033"))
If Intersect(Target, iselect).Address = Target.Address Then
If oldVal = "" Then
'do nothing
Else
If newVal = "" Then
'do nothing
Else
lUsed = InStr(1, oldVal, newVal)
If lUsed > 0 Then
If Right(oldVal, Len(newVal)) = newVal Then
Target.Value = Left(oldVal, Len(oldVal) - Len(newVal) - 2)
Else
Target.Value = Replace(oldVal, newVal, "")
End If
Else
Target.Value = oldVal _
& "," & Chr(10) & newVal
End If
End If
End If
End If
End If
exitHandler:
Application.EnableEvents = True
End Sub

Number format of a cell based on info given on an adjacent cell (VBA)

Trying to set the number format of a cell based on the currency selected on an adjacent cell using VBA. See sample below.
So far I am using the below code but I cannot seem to make the format to appear properly
Option Explicit
Public preValue As Variant
Private Sub Worksheet_Change(ByVal Target As Range)
Dim cell As Range
Dim Rng As Range
Dim ccy As String
ccy = Range("A3").Value
pctFormat = "0.000%"
fxFormat = ccy + " " + pctFormat
If Target.Cells.Count > 1 Then Exit Sub
On Error Resume Next
If Not Intersect(Target, Range("A2:A10")) Is Nothing Then
If Target.Value <> preValue And Target.Value <> "" Then
Application.EnableEvents = False
Cells(Target.Row, Target.Column + 1).NumberFormat = fxFormat
Application.EnableEvents = True
End If
End If
On Error GoTo 0
End Sub
you could try this option to set your fxFormat variable:
fxFormat = "[$" & ccy & "] 0.000%"
perhaps:
fxFormat = chr(34) & ccy & chr(34) & " " & pctFormat

Resources