Sub macro_to_copy_multiple_string_cells_into_one_1175711()
' Since this is a quick, and likely only used once, script, plus the
' types only occur once, the variables are single characters only for simplicity
Dim d As Object, r As Range, n As Integer, k As String
' Create a late binding VBA dictionary, d; this could be a early bound
' dictionary to enable intellisense, etc., but as this is Mr Excel, I have
' used late binding to avoid needing a Reference call, which then needs to
' be exaplained as well as being another thing that can fail. Refer:
' https://excelmacromastery.com/vba-dictionary/#Early_versus_Late_Binding
' for a better explanation.
Set d = CreateObject("Scripting.Dictionary")
' For expediency I have used the active sheet's used range. This means that
' if there is some rogue data in cell XFD1048576 (for example) it could add the
' whole sheet into the range, but I'll presume that the range is truly limited to
' a logical, used, area.
Set r = ActiveSheet.UsedRange
' Variables to hold the column numbers - extension to the original script so that
' it is more extensible.
Dim hc As Integer ' heading column number
Dim dc As Integer ' data column number
Dim oc As Integer ' output column number
' Request the user to enter the column letters. NB: there is no error handling
' so this should be added if it is not going to be a temporary / limited
' use script.
' Convert the column letters entered to integers for use with: cells(r, c)
hc = Range(InputBox("Heading column letter: ") & 1).Column
dc = Range(InputBox("Data column letter: ") & 1).Column
oc = Range(InputBox("Output column letter: ") & 1).Column
' Loop through the range, starting from the second row as the first appears to
' only have row header information as so we do not want to consider it.
For n = 2 To r.Rows.Count
' If the "heading" cell is only spaces (or empty) or and there is
' content in the corresponding data cell, then append the content to
' the dictionary with the key relating to the heading
If Len(Replace(Cells(n, hc), " ", "")) = 0 And Len(Replace(Cells(n, dc), " ", "")) > 0 Then
d.Item(k) = d.Item(k) + " | " + Cells(n, dc)
' Otherwise, if the "heading" cell has text other than just spaces, create
' a new dictionary item with the key for this heading. If it is a repeat heading
' (which is probably not allowed, but nonetheless) warn the user that the
' content will be added to that repeated heading.
ElseIf Len(Cells(n, hc)) > 0 Then
k = Trim(Cells(n, hc))
If d.Exists(k) Then
MsgBox "Case " & k & " is appearing more than once. Its content will be merged.", vbInformation
d.Item(k) = d.Item(k) + " | " + Cells(n, dc)
Else
d.Add Key:=k, Item:=Cells(n, dc)
End If
Else
'do nothing - this is a blank line
End If
Next n
' Now loop back through the range and...
For n = 2 To r.Rows.Count
' Where there is a dictionary item with the key that matches the (trimmed
' of spaces) heading, output the concatenated (with space-pipe-space)
' string associated with that heading. Note: if the heading is a repeat it
' will do that for each instance.
If d.Exists(Trim(Cells(n, hc))) Then
k = Trim(Cells(n, hc))
Cells(n, oc) = d.Item(k)
End If
Next n
End Sub