VBA - Is it possible to have an error message that automatically pops-up based on condition? - excel

If the users fill in the serial no. column in col B (it doesn't have to be all 10 of them, as long as one is filled), they need to fill up the other columns from col C to col F. Hence, if col B is filled up but any of the cells in col C to F are not filled up, I want an error message to pop up. I hope the image below gives a clearer idea..:
I'm not sure if Worksheet_SelectionChange will do what I want to accomplish...because I don't want to include a command button. As some users may not bother clicking on the command button to verify their inputs. This is the code I have at the moment, please feel free to advise accordingly....thank you:)
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Range("B4").Value = "" Then
MsgBox "serial no. is a Mandatory field", vbExclamation, "Required Entry"
Range("B4").Select
End If
If Range("B4:B") <> "" Then
If Range("C4:C").Value = "" Then
MsgBox "Product is a Mandatory field", vbExclamation, "Required Entry"
Range("C4:C").Select
End If
' Adding values from sheet 2 for fruits drop-down list.
If Not Intersect(Target, Range("D3")) Is Nothing Then
Sheets("Sheet1").Range("D3") = "[Please Select]"
Dim col As New Collection
Dim rng As Range
Dim i As Long
Dim dvlist As String
'Loop thru the data range
For Each rng In Sheet2.Range("B2:B7")
'ignore blanks
If Len(Trim(rng.Value)) <> 0 Then
'create a unique list
On Error Resume Next
col.Add rng.Value, CStr(rng.Value)
On Error GoTo 0
End If
Next rng
'concatenate with "," as the delimiter
For i = 2 To col.Count
dvlist = dvlist & col.Item(i) & ","
Next i
With Sheet1.Range("C2:C").Validation
.Delete
.Add Type:=xlValidateList, _
AlertStyle:=xlValidAlertStop, _
Formula1:=dvlist
End With
End If
' Adding values from sheet 2 for country of origin drop-down list.
If Not Intersect(Target, Range("E4")) Is Nothing Then
Sheets("Screening Request").Range("E4") = "[Please Select]"
'Loop thru the data range
For Each rng In Sheet2.Range("A2:A7")
'ignore blanks
If Len(Trim(rng.Value)) <> 0 Then
'create a unique list
On Error Resume Next
col.Add rng.Value, CStr(rng.Value)
On Error GoTo 0
End If
Next rng
'concatenate with "," as the delimiter for list in Sheet 2
For i = 2 To col.Count
dvlist1 = dvlist1 & col.Item(i) & ","
Next i
'add it to the DV
With Sheet1.Range("D3").Validation
.Delete
.Add Type:=xlValidateList, _
AlertStyle:=xlValidAlertStop, _
Formula1:=dvlist1
End With
End If
' This is for the date (YYYYMMDD) column. I need it to be in YYYYMMDD format:
If Not Intersect(Target, Range("F4:F13")) Is Nothing Then
If Not IsNumeric(.Value) And Not cel.NumberFormat = "yyyymmdd" Then
MsgBox "Date format must be in YYYYMMDD"
cel.Value = ""
Exit Sub
Else: cel.NumberFormat = "yyyymmdd"
End If
End With
End If

In general, you are making life much too hard for yourself. Use the tools that Excel provides (and there are many); you do not need to re-invent the wheel.
For example the lists for fruits and country of origin in your Sheet2 should be used as a list for data validation purposes in Sheet1 (Data Tab, Data Tools, Data Validation). Choose Allow List, make sure Ignore blank and In-cell dropdown are checked and select the range from Sheet2.
Similarly you can use data validation to validate dates in your last column.
You now do not need to validate these columns yourself, as they will always have blanks or valid values.
Combine this with my suggestion of conditional formatting (eg for the range c4:c13 you should enter =AND(B4<>"",ISBLANK(C4)) and for all three columns, you can produce a very simple verification routine. Something like:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Cancel = MissingEntries()
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Cancel = MissingEntries()
End Sub
Private Function MissingEntries() As Boolean
Dim i As Integer
Dim j As Integer
Dim atLeastOneLine As Boolean
atLeastOneLine = False
For i = 4 To 13
If (Cells(i, 2) <> "") Then
atLeastOneLine = True
For j = 3 To 6
If Cells(i, j) = "" Then
MsgBox ("Please supply values for highlighted cells")
MissingEntries = True
Exit Function
End If
Next
If WrongSerialNumber(i) Then
MissingEntries = True
Exit Function
End If
End If
Next
If Not atLeastOneLine Then
MsgBox ("Please supply values for at least one line")
MissingEntries = True
Else
MissingEntries = False
End If
End Function
Private Function WrongSerialNumber(i As Integer) As Boolean
Dim yr As Integer
Dim serialNo As String
Dim yrStr As String
Dim yrCell As String
serialNo = Cells(i, 2)
If Len(serialNo) < 3 Then
WrongSerialNumber = True
MsgBox "Serial Number for row no. " + CStr(i - 3) + " is too short. Please correct."
Exit Function
End If
yrCell = Cells(i, 6)
If Len(yrCell) = 8 Then
yr = CInt(Left(Cells(i, 6), 4))
If yr > 1968 Then
If Mid(yrCell, 3, 2) <> Mid(serialNo, 2, 2) Then
WrongSerialNumber = True
MsgBox "Serial Number for row no. " + CStr(i - 3) + " has wrong second and third digits. These should match the third and fourth digits of the date. Please correct."
Exit Function
End If
End If
End If
WrongSerialNumber = False
End Function
Note that I validate on both close and save. The former is optional.
Because of the highlighting, a simple message suffices, you are spared the work of informing the user, which cells are missing. In this way the combination of in-built Data Validation and Conditional Formatting makes the remainder of your task so much easier.

Related

Return text in cell based on value entered in another cell

I have columns in my table (F -> I) with potentially unlimited rows, which are drop downs with a simple Yes/No list.
It starts as an empty row and the user inputs data in other rows and then selects either Yes/No based on the questions.
What I'm looking for is some VBA to say If the user has selected 'No' in Column F, then in Column K, prepopulate with "Column F: ". The idea is that anything that is selected as "No", is populated in K so the user can add their notes and reference Column F. For example: "Column F: This did not meet requirements because xxxxx"
I have tried a few examples whilst searching the net but nothing seems to work:
R = 4
'loop to the last row
Do Until Range("F" & R) = ""
'check each cell if if contains 'apple' then..
'..place 'Contains Apple' on column B
If InStr(1, Range("F" & R), "No") Then
Range("K" & R) = "Test Plan"
End If
R = R + 1
Loop
I also tried putting that in a worksheet change sub but it didn't work as expected.
Any help appreciated. Thanks
Is this what you are trying? I have commented the code. For more explanation, I would recommend going through How to handle Worksheet_Change
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim aCell As Range
'~~> Error handling
On Error GoTo Whoa
'~~> Switch off events
Application.EnableEvents = False
'~~> Check of the change happened in Col F
If Not Intersect(Target, Columns(6)) Is Nothing Then
'~~> Loop through all the cells in col F where
'~~> the change happened
For Each aCell In Target.Cells
'~~> Check if the value is NO
If UCase(aCell.Value2) = "NO" Then
'~~> Update Col K
Range("K" & aCell.Row).Value = "Test Plan"
Else
'~~> If not NO then WHAT ACTION? For example user
'~~> deletes the existing NO
End If
Next
End If
Letscontinue:
'~~> Switch events back on
Application.EnableEvents = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume Letscontinue
End Sub
In Action
Try this code in the Worksheet_Change
Option Explicit
Option Compare Text
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 6 And Target.Value = "No" Then
Target.Parent.Range("K" & Target.Row).Value = "Column F: "
End If
End Sub

VBA Excel If statement returns wrong answer

I prepared the if statement for checking my cells in the specific row. I have several cells, which I have to check. Their values are mostly "x" but sometimes they vary.
The problem is, that even if one of the value is different than "x", I am still getting the msgbox, that everything is good as per the code, which I prepared.
Sub AuditCheck()
If Range("C33,C39:C40,C43,C53:C54,C57:C59,C68").Value = "x" Or Range("C33,C39:C40,C43,C53:C54,C57:C59,C68").Value = "0" Then
'Rows(39).Delete
Range("C58").Activate 'taking a look just in case
MsgBox ("All good!") ' if so we can hide X
ActiveSheet.Range("$A$5:$IF$77").AutoFilter Field:=1, Criteria1:="<>x", Criteria2:="<>0"
Else
MsgBox ("You have to change the pricing!")
If Range("C39").Value <> "x" Then 'C39 CASE
MsgBox ("Install duct Upturns/upturn section must be removed!")
Call RemoveUpturn
Call New_version_upturn
End If
Exit Sub 'the macro is terminated because you have to change the prices
End If
End Sub
Is there something, which I haven't mentioned in the code?
Try the next code, please:
Sub AuditCheck()
Dim sh As Worksheet, rng As Range, ar As Range, countX As Long, zCount As Long
Set sh = ActiveSheet
Set rng = Range("C33,C39:C40,C43,C53:C54,C57:C59,C68")
For Each ar In rng.Areas
countX = countX + WorksheetFunction.CountIf(ar, "x")
zCount = zCount + WorksheetFunction.CountIf(ar, "0")
Next
If countX = rng.cells.count Or zCount = rng.cells.count Then 'here, you maybe want adding the two counts...
Range("C58").Activate 'taking a look just in case
MsgBox ("All good!") ' if so we can hide X
ActiveSheet.Range("$A$5:$IF$77").AutoFilter field:=1, Criteria1:="<>x", Criteria2:="<>0"
Else
MsgBox ("You have to change the pricing!")
If Range("C39").Value <> "x" Then 'C39 CASE
MsgBox ("Install duct Upturns/upturn section must be removed!")
Call RemoveUpturn
Call New_version_upturn
End If
End If
End Sub
It looks strange checking of counted "x" or "0". If you wanted to count them together, you should add them an compare with total range cells count...
If counting zero does not count (anymore), you just delete the second condition.
You must use CountIf (doc here) which will counts the number of cells within a range that meets the given criteria to do that you would have done something like that :
Sub Try_Me()
Dim Myrng As Range
Dim NumCheck as Long
Dim StrCheck as String
StrCheck = "x"
NumCheck = 0
Set Myrng = Range("C33,C39:C40,C43,C53:C54,C57:C59,C68")
If WorksheetFunction.CountIf(Myrng, NumCheck ) = Myrng.Count Or WorksheetFunction.CountIf(Myrng, StrCheck ) = Myrng.Count Then
Range("C58").Activate 'taking a look just in case
MsgBox ("All good!") ' if so we can hide X
ActiveSheet.Range("$A$5:$IF$77").AutoFilter Field:=1, Criteria1:="<>x", Criteria2:="<>0"
Else
MsgBox ("You have to change the pricing!")
If Range("C39").Value <> "x" Then 'C39 CASE
MsgBox ("Install duct Upturns/upturn section must be removed!")
Call RemoveUpturn
Call New_version_upturn
End If
Exit Sub 'the macro is terminated because you have to change the prices
End If
End Sub
EDIT According to #chris neilsen you should do as below since CountIf does not work with non-contiguous range.
So I would suggest you to just count the number of X in your range if it does match with the excepted number of x or 0 the the if condition will return true :
Sub Try_Me()
Dim Myrng As Range
Dim NumCheck as Long
Dim StrCheck as String
Dim NumExceptedX as Int
Dim NumeExceptedZ
NumExceptedX = 11
NumeExceptedZ = 15
StrCheck = "x"
NumCheck = 0
Set Myrng = Range("C33:C68")
If WorksheetFunction.CountIf(Myrng, NumCheck ) = NumeExceptedZ Or WorksheetFunction.CountIf(Myrng, StrCheck ) = NumExceptedX Then
Range("C58").Activate 'taking a look just in case
MsgBox ("All good!") ' if so we can hide X
ActiveSheet.Range("$A$5:$IF$77").AutoFilter Field:=1, Criteria1:="<>x", Criteria2:="<>0"
Else
MsgBox ("You have to change the pricing!")
If Range("C39").Value <> "x" Then 'C39 CASE
MsgBox ("Install duct Upturns/upturn section must be removed!")
Call RemoveUpturn
Call New_version_upturn
End If
Exit Sub 'the macro is terminated because you have to change the prices
End If
End Sub

How do i target a specific range of cells from selection?

What i want is to be able to select any amount of cells and press a button that will register information . all information is put horizontally, meaning that if i select L10 and press the button, N10,O10, and P10 will be changed according to what i tell them to.
i've been successful in doing this but it has a slight issue. as long as the information on the selected cells are unique, it works fine. but i want to be able to use column L, which will have random numbers that may frequently be the same as in other cells.
If cel.Value = Range("g16") Then
Range("ff16").Value = True
Range("p16").Value = Now
If Range("m16").Value <= 0 Then
Range("o16").Value = Range("o16").Value & " | " & VarNUMCB
Else
End If
Else
If cel.Value = Range("e16") Then
Range("ff16").Value = True
Range("p16").Value = Now
If Range("m16").Value <= 0 Then
Range("o16").Value = Range("o16").Value & " | " & VarNUMCB
Else
End If
Else
End If
End If
expected:
L10 Selected,L11 Selected,L18 Selected,L23 Selected -> button is pressed -> Pop-up box asking for signature ->N10,N11,N18,N23 gets ticked, O10,O11,O18,O23 shows signature and P10,P11,P18,P23 shows date and time.
happens:
if the value from L happens to be the same as any other random L cell, it will apply the changes to both, which i dont want to.
Maybe something like this is what you're looking for:
Sub tgr()
Dim rSelected As Range
Dim rCell As Range
Dim sSignature As String
Dim dtTimeStamp As Date
'Verify that the current selection is a range (and not a chart or something)
If TypeName(Selection) <> "Range" Then
MsgBox "Invalid selection. Exiting Macro.", , "Error"
Exit Sub
End If
'Get the signature
sSignature = InputBox("Provide Signature", "Signature")
If Len(sSignature) = 0 Then Exit Sub 'Pressed cancel
'Get the current date and time
dtTimeStamp = Now
'Only evaluate selected cells in column L, ignore other selected cells
Set rSelected = Intersect(Selection.Parent.Columns("L"), Selection)
If rSelected Is Nothing Then
MsgBox "Must select cell(s) in column L. Exiting Macro.", , "Error"
Exit Sub
End If
'Loop through each selected L cell
For Each rCell In rSelected.Cells
'"Tick" same row, column N
rCell.Offset(, 2).Value = "Tick"
'Signature in same row, column O
rCell.Offset(, 3).Value = sSignature
'Date and time in same row, column P
rCell.Offset(, 4).Value = dtTimeStamp
Next rCell
End Sub

Excel VBA Dynamic data validation drop downs with multiple criteria ranking

I am trying to create a dynamic drop down data validation list that will rank multiple criteria (#2 or more) from a worksheet, there are 300 items in my list and I want to rank them based on information in another worksheet in a table.
Based on the rank (1 to 300) I would like the drop down data validation list to contain top 10, top 25 and top/bottom # values calculated from their rank. I don't mind helper columns. If the data/table I am ranking from changes, and/or if I want to add a criteria I would like the top 10, top 25 etc to change accordingly.
I have recorded with the macro recorder when I use the advanced filter and also the top 25 in this case values.
Sub Makro2()
Selection.AutoFilter
Range("T[#All]").AdvancedFilter Action:=xlFilterInPlace, CriteriaRange:= _
Range("A1:J3"), Unique:=False
Range("T[[#Headers],[2017]]").Select
ActiveSheet.ShowAllData
Selection.AutoFilter
ActiveSheet.ListObjects("T").Range.AutoFilter Field:=2, Criteria1:="25", _
Operator:=xlTop10Items
End Sub
Is this possible in Excel 2016 with or without VBA?
Edit: I found this thread Data Validation drop down list not auto-updating and this code in that thread could be what I am looking for.
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
' Ensure all lists are made from tables and that these tables are named
' in the Name Manager.
' When creating your Data Validation List, instead of selecting a range
' in 'Source', click within 'Source' and press 'F3'. Finally select your
' tables name.
Dim strValidationList As String
Dim strVal As String
Dim lngNum As Long
On Error GoTo Nevermind
strValidationList = Mid(Target.Validation.Formula1, 2)
strVal = Target.Value
lngNum = Application.WorksheetFunction.Match(strVal, ThisWorkbook.Names(strValidationList).RefersToRange, 0)
' Converts table contents into a formula
If strVal <> "" And lngNum > 0 Then
Application.EnableEvents = False
Target.Formula = "=INDEX(" & strValidationList & ", " & lngNum & ")"
End If
Nevermind:
Application.EnableEvents = True
End Sub
Update:
I am using the LARGE function to get the top 15 values of Table1. I am then using INDEX and MATCH to find the names of the top 15 values (column 2).
I am then using the OFFSET function and a NAMED RANGE to get a data validation list that auto updates when I add something to the bottom of the list.
Now I want the data validation list to be dependent on the first drop down. How can I achieve this?
You are approaching it correctly, sorting or filtering your list data prior to loading the list. I am confused about your question but it appears you are wondering how to create the data validation drop down after you have manipulated your list?
Here is an example of how this is done with a simple test code written to build a state list and then a county list based on the state chosen. Maybe this helps you build your validation lists.
There are two worksheets:
1) one for Data List items ThisWorkbook.Worksheets("DataList")
2) one for the drop downs ThisWorkbook.Worksheets("DD Report Testing")
In a module Create_State_List
Option Explicit
'This is a two part validation, select a state and then select a county
Sub CreateStateList()
Dim FirstDataRow As Double, LastDataRow As Double
Dim StateCol As Double, CountyCol As Double
Dim DataListSht As Worksheet
Dim DDReportSht As Worksheet
Dim StateListLoc As String
Dim StateRange As Range
Set DataListSht = ThisWorkbook.Worksheets("DataList")
Set DDReportSht = ThisWorkbook.Worksheets("DD Report Testing")
FirstDataRow = 3 'First row with a State
StateCol = 2 'States are in Col 2 ("B")
LastDataRow = DataListSht.Cells(DataListSht.Rows.Count, StateCol).End(xlUp).Row
Set StateRange = DataListSht.Range(DataListSht.Cells(FirstDataRow, StateCol), DataListSht.Cells(LastDataRow, StateCol))
StateListLoc = "D3" 'This is where the drop down is located / will be updated
DDReportSht.Range(StateListLoc).ClearContents 'Clear the list as we build dynamically
DDReportSht.Range(StateListLoc).Validation.Delete 'Clear the Validation
'Create the State List
With Range(StateListLoc).Validation
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
xlBetween, Formula1:="=DataList!" & StateRange.Address
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = ""
.ErrorMessage = ""
.ShowInput = True
.ShowError = True
End With
End Sub
In a module Create_County_List
Option Explicit
Private Sub CreateCountyList(StateChosen As String)
Dim DataListSht As Worksheet
Dim DDReportSht As Worksheet
Dim StateRow As Double
Dim NumStateCols As Double
Dim StartStateCol As Double
Dim i As Integer
Dim LastDataRow As Double
Dim CountyRange As Range
Dim CountyListLoc As String
Set DataListSht = ThisWorkbook.Worksheets("DataList")
Set DDReportSht = ThisWorkbook.Worksheets("DD Report Testing")
NumStateCols = 51 'We count the District of Columbia
StateRow = DataListSht.Range("C2").Row
StartStateCol = DataListSht.Range("C2").Column
For i = 0 To NumStateCols 'Account for starting at zero rather than 1
If CStr(Trim(DataListSht.Cells(StateRow, StartStateCol + i))) = StateChosen Then
'find the last Data row in the column where the match is
LastDataRow = DataListSht.Cells(DataListSht.Rows.Count, StartStateCol + i).End(xlUp).Row
'Make the Dynamic list of Counties based on the state chosen
Set CountyRange = DataListSht.Range(DataListSht.Cells(StateRow + 1, StartStateCol + i), DataListSht.Cells(LastDataRow, StartStateCol + i))
CountyListLoc = "D4"
DDReportSht.Range(CountyListLoc).ClearContents
DDReportSht.Range(CountyListLoc).Validation.Delete
'Create the County List
With Range(CountyListLoc).Validation
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
xlBetween, Formula1:="=DataList!" & CountyRange.Address
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = ""
.ErrorMessage = ""
.ShowInput = True
.ShowError = True
End With
'Break loop
i = 1000 ' should break loop off right here
Else 'do not build a list
End If
Next i
End Sub
The Worksheet contains the Cell selection code
Option Explicit
'This routine will react to changes to a cell in the worksheet
Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim DDReportSht As Worksheet
Dim StateString As String
Set DDReportSht = ThisWorkbook.Worksheets("DD Report Testing")
Call CheckStatusBar 'Lets update the Status bar on selection changes
'If the cell change is D3 on DD report (they want state so build list for state)
If Not Intersect(Target, DDReportSht.Range("D3")) Is Nothing Then
'Clear the county list until the state is chosen to avoid mismatch
DDReportSht.Range("D4").ClearContents
DDReportSht.Range("D4").Validation.Delete
'*** Create the State Drop Down
Call CreateStateList
Else 'Do nothing
End If
'If the cell change is D4 on DD report (they want the county list so build it based on the state in D3)
If Not Intersect(Target, DDReportSht.Range("D4")) Is Nothing Then
'If there was a change to the state list go get the county list set up
StateString = DDReportSht.Range("D3")
Application.Run "Create_County_List.CreateCountyList", StateString
Else 'Do nothing
End If
'If cell is D7 build a rig list
If Not Intersect(Target, DDReportSht.Range("D7")) Is Nothing Then
'Build the Rig List
Call CreateRigList
Else 'Do nothing
End If
End Sub
DataSet:
Test Validation Worksheet in practice, again it is just a demo:
EDIT: you want to change code to xlDescending, but same idea applies
Prior to worksheet_change event firing, we see that range is unsorted. The first ten items showing as options in the cell D1 are the first ten items in the range.
When we make a change to a value in range I1:I20 we trigger the worksheet_change event. Inside this function we have code that will sort the range H1:I20.
Here is the code for the worksheet_change function, and where it is to be placed that is inside the worksheet module of the worksheet that you are working with
Finally here is how to link your data validation restrictions with the range. Changes to the range H1:I10 (aka the top ten) will change the options available to you in the box.
The snippet of code
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rangeOfTable As Range
Set rangeOfTable = ActiveSheet.Range("H1:I20")
If Not Application.Intersect(Target, rangeOfTable) Is Nothing Then
rangeOfTable.Sort Range("I1:I20"), xlAscending
End If
End Sub
EDIT: Works with dropDown boxes too
EDIT: this code will give you idea RE how to sort multiple values
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rangeOfTable As Range
Set rangeOfTable = ActiveSheet.Range("H1:J20")
If Not Application.Intersect(Target, rangeOfTable) Is Nothing Then
With rangeOfTable
.Sort key1:=ActiveSheet.Range("I1:I20"), order1:=xlAscending, _
key2:=ActiveSheet.Range("J1:J20"), Order2:=xlAscending
End With
End If
End Sub
here is the data after the event has triggered, notice that the top ten in the list are the only ten available in the drop down box

Add items to a dynamic drop-down list based on cell value

This is a question about whether or not it is possible to do what I'm looking to do in excel. I have a caselist sheet that looks like this:
And an encounter form that looks like this:
On the Encounter Sheet, I want to make a dropdown list that only contains names of people assigned to a specific case manager. So, if I enter SH in the CM column, only those cases from the Caselist sheet where 'Assigned CM' is SH will populate the drop down menu.
Is this possible to do in Excel? Thanks for the assistance.
You may try the code given below.
The code assumes that you have two sheets in the workbook called "Encounter" and "CaseList". Headers on both the sheets are in row1. On Encounter Sheet, column A contains CM (a drop down to choose CM) and column B will have a dependent drop down list inserted by the code to choose the Names depending on the selected CM in col. A. On CaseList Sheet, Col. A is First Name, Col. B is Last Name and col. C is CM.
When above mentioned all the conditions are met, place the code given below on Encounter Sheet Module. To do so, right click on Encounter Tab --> View Code and place the code given below into the opened code window --> Close the VB Editor --> Save your workbook as Macro-Enabled Workbook.
So after selecting a CM in col. A on Encounter Sheet as soon as you select the corresponding cell in col. B, the code will create a data validation list in that cell so you can choose the first name and last name separated by a space from the list. And once you select an item, the first name and last name will be entered in the cell separate by a comma.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.CountLarge > 1 Then Exit Sub
Dim sws As Worksheet
Dim lr As Long, n As Long, i As Long
Dim x, dict
Application.ScreenUpdating = False
Set sws = Sheets("CaseList")
lr = sws.Cells(Rows.Count, "C").End(xlUp).Row
x = sws.Range("A2:C" & lr).Value
If Target.Column = 2 And Target.Row > 1 Then
On Error Resume Next
n = Target.Offset(0, -1).Validation.Type
If n = 3 Then
Set dict = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(x, 1)
If x(i, 3) = Target.Offset(0, -1).Value Then
dict.Item(x(i, 1) & " " & x(i, 2)) = ""
End If
Next i
With Target.Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
xlBetween, Formula1:=Join(dict.keys, ",")
End With
End If
End If
Application.ScreenUpdating = True
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.CountLarge > 1 Then Exit Sub
If Target.Column = 2 And Target.Row > 1 Then
If Target <> "" Then
Application.EnableEvents = False
Target = WorksheetFunction.Substitute(Target.Value, " ", ", ", 1)
Application.EnableEvents = True
End If
End If
End Sub

Resources