Could someone please help me with the below VBA code. Instead of displaying the results in different rows of the same cell, I want to display in different rows of the same column.
Your help would be very much appreciated!!!
Private Sub Worksheet_Change(ByVal Target As Range)
**' To Select Multiple Items from a Drop Down List in Excel and display the
' result in different rows for further calculations.**
Dim Oldvalue As String
Dim Newvalue As String
Application.EnableEvents = True
On Error GoTo Exitsub
If Target.Column = 8 Then
If Target.SpecialCells(xlCellTypeAllValidation) Is Nothing Then
GoTo Exitsub
Else: If Target.Value = "" Then GoTo Exitsub Else
Application.EnableEvents = False
Newvalue = Target.Value
Application.Undo
Oldvalue = Target.Value
If Oldvalue = "" Then
Target.Value = Newvalue
Else
If InStr(1, Oldvalue, Newvalue) = 0 Then
***Target.Value = Oldvalue & Chr(10) & Newvalue***
Else:
Target.Value = Oldvalue
End If
End If
End If
End If
Application.EnableEvents = True
Exitsub:
Application.EnableEvents = True
End Sub
This sub passes the old value a cell below the range that triggered the sub. And passes the new value 2 cells below that same range.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Oldvalue As String '<~ declare old value
Dim Newvalue As String '<~ declare new value
Application.EnableEvents = True '<~enable events( idunno why)
On Error GoTo ExitSub '<~ simple error handler
If Not Target.Column = 8 Then GoTo ExitSub '<~ if the change not happened in col8 then exit
If Target.SpecialCells(xlCellTypeAllValidation) Is Nothing Then GoTo ExitSub
If Target.Value = "" Then GoTo ExitSub '<~ if the new value is blank then exit
Application.EnableEvents = False '<~ disableevents
Newvalue = Target.Value '<~ pass new value into a variable
Application.Undo '<~ force undo
Oldvalue = Target.Value '<~ pass previous value into a variable
Target.Value = Newvalue '<~ give new value
If Not Oldvalue = "" Then '<~ check if old value is blank
If InStr(1, Oldvalue, Newvalue) = 0 Then '<~ check if the old value
Target.Offset(1, 0).Value = "Old Value: " & Oldvalue '<~ pass old value to a cell below the
Target.Offset(2, 0).Value = "New Value: " & Newvalue '<~ range that made a change
End If
End If
ExitSub:
Application.EnableEvents = True
End Sub
Related
I have set up a spreadsheet with several columns, some of which have data validation dropdown lists. I need users to be able to select multiple options from the dropdown list. I have achieved this for one column using the VBA below, however I am struggling to find the right way to apply this to multiple columns. Please could someone help.
At the moment I have used 'Target.Column = 9', however I need to apply this to columns 3,4,5,6,9.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Oldvalue As String
Dim Newvalue As String
Application.EnableEvents = True
On Error GoTo Exitsub
If Target.Column = 9 Then
If Target.SpecialCells(xlCellTypeAllValidation) Is Nothing Then
GoTo Exitsub
Else: If Target.Value = "" Then GoTo Exitsub Else
Application.EnableEvents = False
Newvalue = Target.Value
Application.Undo
Oldvalue = Target.Value
If Oldvalue = "" Then
Target.Value = Newvalue
Else
If InStr(1, Oldvalue, Newvalue) = 0 Then
Target.Value = Oldvalue & ", " & Newvalue
Else:
Target.Value = Oldvalue
End If
End If
End If
End If
Application.EnableEvents = True
Exitsub:
Application.EnableEvents = True
End Sub
Thanks in advance
You could extend your If
If Target.Column = 9 or Target.Column = 3 etc
but sometimes Select Case is a bit tidier.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Oldvalue As String
Dim Newvalue As String
Application.EnableEvents = True
On Error GoTo Exitsub
Select Case Target.Column
Case 3, 4, 5, 6, 9
If Target.SpecialCells(xlCellTypeAllValidation) Is Nothing Then
GoTo Exitsub
Else: If Target.Value = "" Then GoTo Exitsub Else
Application.EnableEvents = False
Newvalue = Target.Value
Application.Undo
Oldvalue = Target.Value
If Oldvalue = "" Then
Target.Value = Newvalue
Else
If InStr(1, Oldvalue, Newvalue) = 0 Then
Target.Value = Oldvalue & ", " & Newvalue
Else:
Target.Value = Oldvalue
End If
End If
End If
End Select
Exitsub:
Application.EnableEvents = True
End Sub
I have a couple of lists within an excel spreadsheet that I would like to add the multi-select option to. I am well aware of how to do this thanks to contexture:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rngDV As Range
Dim oldVal As String
Dim newVal As String
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
If Target.Column = 3 Then
If oldVal = "" Then
'do nothing
Else
If newVal = "" Then
'do nothing
Else
Target.Value = oldVal _
& ", " & newVal
' NOTE: you can use a line break,
' instead of a comma
' Target.Value = oldVal _
' & Chr(10) & newVal
End If
End If
End If
End If
exitHandler:
Application.EnableEvents = True
End Sub
The problem is that I only want particular lists to be multi-select, i have a couple of other lists within this excel spreadsheet that must remain as one option lists. This code works but it affects every list within excel. I attempted to modify it to work on only certain Cells by adding an if statement like below
If Target.Address = "$C$5" Or Target.Address = "$C$6" Or Target.Address = "$C$82" Then
This still is not working for me, how can I make this code cell specific?
For anyone else who stumbles upon this in hopes of finding an answer on how to make a specific list have the multi-select option I was able to figure it out on my own.
Private Sub Worksheet_Change(ByVal Target As Range)
Application.ScreenUpdating = False
Dim rngDV As Range
Dim oldVal As String
Dim newVal As String
Dim strVal As String
Dim i As Long
Dim lCount As Long
Dim Ar As Variant
On Error Resume Next
Dim lType As Long
If Target.Count > 1 Then GoTo ExitHandler
lType = Target.Validation.Type
If lType = 3 Then
Application.EnableEvents = False
newVal = Target.Value
Application.Undo
If Target.Value = "Select all that apply" Then
oldVal = ""
Else
If Target.Value = newVal Then
newVal = "Select all that apply"
Else
oldVal = Target.Value
End If
End If
'oldVal = Target.Value
Target.Value = newVal
'This is where specific cells will be referenced
If Target.Address = "$F$8" Or Target.Address = "$G$6" Or Target.Address = "$H$3" Or Target.Address = "$CJ$29" Then
If oldVal = "" Then
Else
If newVal = "" Then
Else
On Error Resume Next
Ar = Split(oldVal, ", ")
strVal = ""
For i = LBound(Ar) To UBound(Ar)
Debug.Print strVal
Debug.Print CStr(Ar(i))
If newVal = CStr(Ar(i)) Then
strVal = strVal
lCount = 1
Else
strVal = strVal & CStr(Ar(i)) & ", "
End If
Next i
If lCount > 0 Then
Target.Value = Left(strVal, Len(strVal) - 2)
Else
Target.Value = strVal & newVal
End If
End If
End If
End If
End If
In order to use this specific solution you will also need to add
ExitHandler:
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
To the very end of your code.
I utilized the code by Sumit Bansal at trumpexcel.com, however, the code doesn't seem to work. It is supposed to select more than one of the texts from the drop down without repetition. The drop down is for cells C8, C22, C36, until C134. Here is the code, thanks in advance.
Option Explicit
Private Sub DropDown(ByVal Target As Range)
'Code by Sumit Bansal from https://trumpexcel.com
' To Select Multiple Items from a Drop Down List in Excel
Dim Oldvalue As String
Dim Newvalue As String
Dim x As Double
Application.EnableEvents = True
On Error GoTo Exitsub
For x = 1 To 10
If Target.Address = Worksheets("BSOAP").Range("C" & (14 * x - 6)) Then
If Target.SpecialCells(xlCellTypeAllValidation) Is Nothing Then
GoTo Exitsub
Else: If Target.Value = "" Then GoTo Exitsub Else
Application.EnableEvents = False
Newvalue = Target.Value
Application.Undo
Oldvalue = Target.Value
If Oldvalue = "" Then
Target.Value = Newvalue
Else
If InStr(1, Oldvalue, Newvalue) = 0 Then
Target.Value = Oldvalue & ", " & Newvalue
Else:
Target.Value = Oldvalue
End If
End If
End If
End If
Next x
Application.EnableEvents = True
Exitsub:
Application.EnableEvents = True
End Sub
All you need to do is leave the code exactly as it was given and place it in your worksheet, with the following modifications:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
'Code by Sumit Bansal from https://trumpexcel.com
'Modified by TheEngineer from https://stackoverflow.com/
' To Select Multiple Items from a Drop Down List in Excel
Dim Oldvalue As String
Dim Newvalue As String
Dim i As Long
Dim b As Boolean
Dim arr(1 To 10) As String
For i = 1 To 10
arr(i) = "$C$" & (14 * i - 6)
Next i
On Error GoTo Exitsub
If Contains(arr, Target.Address) Then
If Target.SpecialCells(xlCellTypeAllValidation) Is Nothing Then
GoTo Exitsub
Else: If Target.Value = "" Then GoTo Exitsub Else
Application.EnableEvents = False
Newvalue = Target.Value
Application.Undo
Oldvalue = Target.Value
If Oldvalue = "" Then
Target.Value = Newvalue
Else
Target.Value = Oldvalue & ", " & Newvalue
End If
End If
End If
Exitsub:
Application.EnableEvents = True
End Sub
Function Contains(arr, v) As Boolean
Dim rv As Boolean, lb As Long, ub As Long, i As Long
lb = LBound(arr)
ub = UBound(arr)
For i = lb To ub
If arr(i) = v Then
rv = True
Exit For
End If
Next i
Contains = rv
End Function
The Function was found here: Matching values in string array
This will allow you to select multiple items from the dropdown lists in the ten cells you referenced.
It is worth noting that this code uses the Undo function, so any time you use it to select multiple items, you will lose your ability to Undo anything before that point.
I am trying to have 2 Worksheet_Change Events on one worksheet that are being triggered seperatly.
For example if I write in "C3" a Number a vlookup is either giving back a name or jumping to OnError GoTo NoSupplier, if i write in "C9" an other vlookup is either giving back a name or jumping to On Error GoTo NoCOMS.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim suppname As String
Dim COMS As String
If Target.Address(0, 0) = "C3" Then
If Target <> "" Then
On Error GoTo NoSupp
suppname = Application.VLookup(Target.Value, Workbooks("Articlepassport.xlsm") _
.Sheets("Suppliernames").Range("A2:B1000"), 2, False)
Range("C5") = suppname
Else
Range("C5") = ""
End If
Exit Sub
NoSupp: Range("C5") = "Supplier Data not maintained!"
End If
If Target.Address(0, 0) = "C9" Then
If Target <> "" Then
On Error GoTo NoCOMS
COMS = Application.VLookup(Target.Value, Workbooks("Articlepassport.xlsm") _
.Sheets("Tabelle2").Range("A2:B11000"), 2, False)
Range("C11") = COMS
Else
Range("C11") = ""
End If
Exit Sub
NoCOMS: Range("C11") = "COMS does not exist!"
End If
End Sub
You need to add Application.EnableEvents = False so the Sub won't be triggerred multiple times. Before leaving the Sub, you need to restore the settings to the original value with Application.EnableEvents = True.
Note: I've removed your orginal Error Handlers, and I've added a way to deal with the VLookup errors, by adding If IsError(suppname) Then and If IsError(COMS) Then.
Code
Private Sub Worksheet_Change(ByVal Target As Range)
Dim suppname As Variant
Dim COMS As Variant
Application.EnableEvents = False
If Not Intersect(Range("C3"), Target) Is Nothing Then
If Target.Value <> "" Then
suppname = Application.VLookup(Target.Value, Workbooks("Articlepassport.xlsm") _
.Sheets("SupplierNames").Range("B2:H1000"), 4, False)
If IsError(suppname) Then
Range("C5").Value = "Supplier Data not maintained!"
Else
Range("C5").Value = suppname
End If
Else
Range("C5") = ""
End If
End If
If Not Intersect(Range("C9"), Target) Is Nothing Then
If Target.Value <> "" Then
COMS = Application.VLookup(Target.Value, Workbooks("Articlepassport.xlsm") _
.Sheets("Tabelle2").Range("A2:B11000"), 2, False)
If IsError(COMS) Then
Range("C11").Value = "COMS does not exist!"
Else
Range("C11").Value = ""
End If
Else
Range("C11").Value = ""
End If
End If
Application.EnableEvents = True ' reset settings when leaving this Sub
End Sub
Edited function; generally for worksheet change events, you should deactivate events (and screenupdating) then allow re-activating on error, or sub completion.
Rewritten function (untested)
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
On Error GoTo ExitSub
Application.EnableEvents = False
Application.ScreenUpdating = False
Select Case Target
Case Range("C3")
If Target.Value = "" Then
Range("C5") = ""
GoTo ExitSub
End If
Dim SupplierName As String
On Error Resume Next
SupplierName = Application.VLookup(Target.Value, Workbooks("Articlepassport.xlsm") _
.Sheets("SupplierNames").Range("B2:H1000"), 4, False)
On Error GoTo ExitSub
Range("C5").Value = IIf(SupplierName <> "", SupplierName, "Supplier data not maintained!")
Case Range("C9")
If Target.Value = "" Then
Range("C11") = ""
GoTo ExitSub
End If
Dim COMS As String
On Error Resume Next
COMS = Application.VLookup(Target.Value, Workbooks("Articlepassport.xlsm") _
.Sheets("Tabelle2").Range("A2:B11000"), 2, False)
On Error GoTo ExitSub
Range("C11").Value = IIf(COMS <> "", COMS, "COMS does not exist!")
Case Else
End Select
ExitSub:
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I am trying to select multiple values in excel from two different drop down lists. I have code that can select multiple values on one drop down and would like to be able to do the same for another drop down list with different values. Can I use the code below and modify it or is there another easier way to do this?
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rngDV As Range
Dim oldVal As String
Dim newVal As String
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
If Target.Column = 7 Or Target.Column = 45 Then
If oldVal = "" Then
'do nothing
Else
If newVal = "" Then
'do nothing
Else
Target.Value = oldVal _
& ", " & newVal
End If
End If
End If
End If
exitHandler:
Application.EnableEvents = True
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rngDV As Range
Dim oldVal As String
Dim newVal As String
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
If Target.Column = 7 Or Target.Column = 45 Then
If oldVal = "" Then
'do nothing
Else
If newVal = "" Then
'do nothing
Else
Target.Value = oldVal _
& ", " & newVal
End If
End If
End If
End If
exitHandler: Application.EnableEvents = True End Sub
I used a conditional Or to make it possible to select multiple values from two different drop down lists. This is shown in the code If Target.Column = 7 Or Target.Column = 45 Then