As it is not clear what you mean by "new row" I give you both solutions.
I always recommend to not have the business functionality within the event itself. But instead call a sub whose name is self-explanatory.
You pass the first cell to this sub - in this case it contains the selected value.
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo err_WorksheetChange
If Not Intersect(Target.Cells(1, 1), Me.Range("L9")) Is Nothing Then
addSelectedValueToEndOfColumn Target.Cells(1, 1)
'combineMultipleValuesInOneCell Target.Cells(1, 1) 'uncomment if you want this solution
End If
exit_WorksheetChange:
Exit Sub
err_WorksheetChange:
Application.EnableEvents = True
End Sub
addSelectedValueToEndOfColumn first checks if there is a value below the cell with the validation list.
If not: no value was yet selected. Value is inserted below (.offset(1) the current cell.
If yes: the range below the validation cell is checked for the selected value (using application.MATCH). Only if this function returns 0, the new value is added at the end of the list.
Private Sub addSelectedValueToEndOfColumn(c As Range)
If c.Value = "" Then Exit Sub
Application.EnableEvents = False
If c.Offset(1).Value = "" Then 'first selection
c.Offset(1) = c.Value
Else
Dim rgCurrentValues As Range
Set rgCurrentValues = Range(c, c.End(xlDown)).Offset(1)
With Application 'omitting .worksheetfunction prevents an error due to .match returning nothing
If .IfError(.Match(c.Value, rgCurrentValues, 0), 0) = 0 Then 'new value
c.End(xlDown).Offset(1).Value = c.Value
Else
'duplicate - don't insert
End If
End With
End If
c.Value = ""
Application.EnableEvents = True
End Sub
This is the refactored code you provided in your question.
Hopefully a bit more readable than yours :-)
Private Sub combineMultipleValuesInOneCell(c As Range)
If c.Value = "" Then Exit Sub
Dim newValue As String, oldValue As String
Application.EnableEvents = False
newValue = c.Value
Application.Undo
oldValue = c.Value
If oldValue = "" Then 'no selection yet
c.Value = newValue
ElseIf InStr(oldValue, newValue) = 0 Then 'new value not yet selected
c.Value = oldValue & vbCrLf & newValue
Else 'new value already selected
c.Value = oldValue
End If
Application.EnableEvents = True
End Sub