How to work with more Target.Address (range) - excel

In a cell, I have made a list to choose. However, one choice is not enough. I found some vba code that enables me to make more choices. But this code points to a specific cell. I want to use it more general in the sheet, probably a range.
I tried to put in a range as target.address but that won't work. It won't work with a range of one cell (J3) either. I found out that the formula below does not work after removing the dollar signs from $j$3.
Dim Oldvalue As String
Dim Newvalue As String
On Error GoTo Exitsub
TheCell = ActiveCell
If Target.Address = "$J$13" 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
Application.EnableEvents = True
Exitsub:
Application.EnableEvents = True
End Sub
I look for a solution to choose from all the list of more than one item. The formula should be changed in a way that is usable in a range of cells. These cells have al the same choice list.

Instead of
If Target.Address = "$J$13" Then
You can do an Intersect of your Target range with the range you like to check:
Dim AffectedRange As Range
Set AffectedRange = Intersect(Target, Me.Range("J13:J20")) 'put your range here
If Not AffectedRange Is Nothing Then
Dim Cell As Range
For Each Cell In AffectedRange 'loop through all affected cells
'here use Cell instead of Target
Next Cell
End If

Related

trying to add 2 events that happen in the same column in a worksheet

Good day
I am trying to make both of the macros work in the same range since I want the drop down it that is created there to be able to check if there is a value in the column next to it get that rows values and also still be able to run the first macro. see picture attached since I don't think I am explaining properly what I want.
So in the picture in column A is set number. Column B has the dropdown where the first macro was implemented which enables it to be able to get values from column A and also be able to add a value to show 2+3 , I need it then to be able to get the values of stream C and actually add them in column C
attached is my current code and a picture of a example that doesn't necessarily work with the code just an example show what I mean.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Oldvalue As String
Dim Newvalue As String
Dim nommer As Integer
Dim finder As Range
On Error GoTo Exitsub
If Target.Column = 3 Then <------- here is macro 1
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
If Not Intersect(Target, Range("J9")) Is Nothing Then
Select Case Range("J9")
Case "A": toets_my_ws
End Select
End If
Application.EnableEvents = True
Exitsub:
Application.EnableEvents = True
If Target.Column = "3" Then <------- here is macro 2
nommer = ActiveCell.Value
Else: If Target.Value = "" Then GoTo Exitsub Else
Set finder = Range("B9:B40").Find(what:=ActiveCell.Value,LookIn:=xlValues, lookat:=xlWhole)
ActiveCell.Offset(0, 3).Value = finder.Offset(0, 4).Value
ActiveCell.Offset(0, 5).Value = finder.Offset(0, 6).Value
End If
End Sub
]1
You can only have one event of this type as it works for the entire worksheet. So if you have multiple criteria for what happens when the worksheet changes you need to include all of that logic in the event. I have combined your logic in to one big thing but there is no way for me to tell if this was done correctly. You never use the variable nommer so that does nothing. It's also not clear what toets_my_ws is.
I would advise against using Worksheet change events as is slows down the worksheet considerably.
The better way to tackle this would be to use User Defined Functions (UDF). This way you can embed VBA in to a single cell without bogging down the whole sheet with logic every time you press a key.
HERE IS THE COMBINED LOGIC:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Oldvalue As String
Dim Newvalue As String
Dim nommer As Integer
Dim finder As Range
If Target.Value = vbNullString Then GoTo Exitsub
On Error GoTo Exitsub
If Target.Column = 3 Then
nommer = ActiveCell.Value
If Target.SpecialCells(xlCellTypeAllValidation) Is Nothing 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
Else
Set finder = Range("B9:B40").Find(what:=ActiveCell.Value, LookIn:=xlValues, lookat:=xlWhole)
ActiveCell.Offset(0, 3).Value = finder.Offset(0, 4).Value
ActiveCell.Offset(0, 5).Value = finder.Offset(0, 6).Value
End If
If Not Intersect(Target, Range("J9")) Is Nothing Then
Select Case Range("J9")
Case "A"
toets_my_ws
End Select
End If
Exitsub:
Application.EnableEvents = True
End Sub
HERE IS INFORMATION ABOUT UDFS:
https://excelchamps.com/excel-user-defined-function/

How do I get two Wocksheet_Changes in one sheet for multiple selection in a dropdown

I would like to have a multiple selection choise from a dropdown for multiple columns on one Excel sheet. I found a code for a multiple selection from a dropdown in one column per sheet, but i need five.
The Code it self works for one column.
I already tried to name the Worksheet_Changes in
Worksheet_Changes1
Worksheet_Changes2
that didn't work. The result is that I can't choose multiple Names for one cell from a dropdown
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rngDV As Range
Dim wert_old As String
Dim wertnew As String
On Error GoTo Errorhandling
If Not Application.Intersect(Target, Range("B4:B999")) Is Nothing Then
Set rngDV = Target.SpecialCells(xlCellTypeAllValidation)
If rngDV Is Nothing Then GoTo Errorhandling
If Not Application.Intersect(Target, rngDV) Is Nothing Then
Application.EnableEvents = False
wertnew = Target.Value
Application.Undo
wertold = Target.Value
Target.Value = wertnew
If wertold <> "" Then
If wertnew <> "" Then
Target.Value = wertold & ", " & wertnew
End If
End If
End If
Application.EnableEvents = True
End If
In the end I would like to select multiple names form a dropdown selection, in five different columns
If Not Application.Intersect(Target, Range("B4:B999")) Is Nothing Then
If Not Application.Intersect(Target, Range("C4:C999")) Is Nothing Then
If Not Application.Intersect(Target, Range("D4:B999")) Is Nothing Then
...
...
...
Use the Application.Union method to combine the ranges you want to run the code in. And then Intersect them with Target like:
If Not Application.Intersect(Target, Union(Me.Range("B4:B999"), Me.Range("C4:C999"), Me.Range("D4:B999"))) Is Nothing Then

Drop values saved comma separated in a cell in excel

I have a metadatasheet from which I am setting some parameters from which I am generating pivots. I am selecting these parameters through dropdown lists.
Here is what my metadata sheet looks like.
I am saving the values of dropdown in a comma separated manner in the corresponding cell. For that I have a macro on that sheet which is :
Private Sub Worksheet_Change(ByVal Target As Range)
'Set automatic formula calculation ON
Application.Calculation = xlAutomatic
Dim Oldvalue As String
Dim Newvalue As String
Application.EnableEvents = True
On Error GoTo Exitsub
If Target.Address = "$C$5" Or Target.Address = "$C$6" Or Target.Address = "$C$7" Or Target.Address = "$D$5" Or Target.Address = "$D$6" Or Target.Address = "$D$7" Or Target.Address = "$E$5" Or Target.Address = "$E$6" Or Target.Address = "$E$7" 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
My issues:
1) Rather than defining individual cells in the 10th line of macro, is there a way define a range? Basically I am defining all the cells of the range C5:E7 as individual cells using "Or"
2) I am not able to delete individual comma separated values, because while doing so it give me the following error.A user has restricted values that can be entered into the cell
I have to entire cell and then select the values again. Is there a way I can delete only single value?

Target.address for multiple rows in Excel

I need to reference an entire column of Excel spreadsheet, with a drop-down list using VBA. The code i got online works only for a single cell which is "$M$2". How can i define a range for the entire column?
Private Sub Worksheet_Change(ByVal Target As Range)
' To Select Multiple Items from a Drop Down List in Excel
Dim Oldvalue As String
Dim Newvalue As String
On Error GoTo Exitsub
If Target.Address = "$M$2" 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
Application.EnableEvents = True
Exitsub:
Application.EnableEvents = True
End Sub
Firstly, Target may be a single cell or multiple cells, depending on what the user changed
To test if any cell in (and only in) column M changed, use
If Target.EntireColumn.Address = "$M:$M" Then
To test if any cell in Target is in column M use
Dim rng As Range
Set rng = Application.Intersect(Target, Me.Columns("M"))
If Not rng Is Nothing Then
Note: the rest of your code will need to be modified to allow for Target being more than one cell

Change cell color base on another cells data but keep it that way if data changes again

I have been looking for days to solve this and have only come up with half the solution.
What I can do:
I would simply like to have one cell turn green inside with an x inserted when another cells data has the word "Complete" inside it.
What I cannot do:
I would like that same cell that turned green with an x inserted into it when the word "Complete" is changed to "Rework" to stay green with an x.
So Cell A1 is blank then in cell B1 the word "Complete" is added. Then cell A1 changes to green and has an x inside it. If later B1 changes to "Rework" I would like A1 to stay green with the x inside. So I can know that at one time the status of B1 was at one time "Complete"
I have been trying Conditional Formatting with rules but cannot get it to stay. I think the "Stop If True" check box within would be part of the solution but not sure what the code would be.
I already have a different macro running on this sheet so if the answer is a macro I will need it to be added to it. Below is the macro in the sheet already. Thank you.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("N:N,Y:Y"), Range("10:" & Rows.Count)) Is Nothing Then
If Target.Count < Columns.Count Then
On Error GoTo bm_Safe_Exit
Application.EnableEvents = False
Dim r As Range
For Each r In Intersect(Target, Range("N:N,Y:Y"), Range("10:" & Rows.Count))
With r.Offset(0, 1)
.Value = Now 'use Now to retain the time as well as the date
.NumberFormat = "mm/dd/yy" 'change to what you prefer
End With
Next r
End If
End If
bm_Safe_Exit:
Application.EnableEvents = True
End Sub
Ideally you'd split this up into separate subs to handle each of the change types, but this should give you an idea:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng As Range, r as Range
'skip full-row changes (row insert/delete?)
If Target.Columns.Count = Columns.Count Then Exit Sub
Set rng = Intersect(Target, Range("N:N,Y:Y"), Range("10:" & Rows.Count))
If Not rng Is Nothing Then
On Error GoTo bm_Safe_Exit
Application.EnableEvents = False
For Each r In rng.Cells
With r.Offset(0, 1)
.Value = Now 'use Now to retain the time as well as the date
.NumberFormat = "mm/dd/yy" 'change to what you prefer
End With
Next r
End If
Set rng = Intersect(Target, Range("B:B"), Range("10:" & Rows.Count))
If Not rng Is Nothing Then
On Error GoTo bm_Safe_Exit
Application.EnableEvents = False
For Each r In rng.Cells
If r.Value = "Complete" Then
With r.Offset(0, -1)
.Value = "x"
.Interior.Color = vbGreen
End With '<<EDIT thanks #BruceWayne
End If
Next r
End If
bm_Safe_Exit:
Application.EnableEvents = True
End Sub
You'll need two worksheet events, and some If statements. The following should help you get started, unless I'm overlooking something.
Dim oldVal as String ' Public variable
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'Debug.Print Target.Address
If Target.Cells.Count <> 1 Then Exit Sub
oldVal = Target.Value
End Sub
The above will make note of the oldValue.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim newVal As String
newVal = Target.Value
If newVal = oldVal Then
Debug.Print "Same Values"
ElseIf oldVal = "Complete" And newVal = "Rework" Then
Debug.Print "Stay green with X"
ElseIf oldVal = "" And (newVal = "Complete" Or newVal = "complete") Then
Debug.Print "Change cell to Green, add an 'X'"
Target.Interior.ColorIndex = 10
Target.Value = Target.Value & " x"
End If
End Sub
Then, add/tweak those If statements as necessary, and add the color changing/reverting code to the appropriate block.
(There may of course be a better mousetrap, but I think this should get you going).

Resources