=Text.Combine([ColumnName from Step2][Attribute]," ,") & " deg"
Rather than highlight the merged cell where you want the answer, why don't you illustrate what the answer should look like ....
Also are you tied to this current layout? Are the column headers you want to return (C1:G1 in your example) related to the Angle drawn? I believe you'd be better off having your result table J2:L3, structured in a more granular manner; yes, it may be possible to break out the constituents of the cells L2 and L3, but it's a hell of a lot of formula writing to make up for poor data structure.
Thank a lot, Chihiro! But I'm stuck at one step.Now to concatenate row values in PowerQuery.
1. Select Test Name and Angles column and group by.
2. Name new column whatever you like, and choose "All Rows" from dropdown.
3. Add custom column with formula (replace column name as needed.)
4. Remove the aggregate column.Code:=Text.Combine([ColumnName from Step2][Attribute]," ,") & " deg"
Done.
View attachment 46428
Public Sub BuildFailureSummary()
Dim i As Long, j As Long, lngLastCol As Long
Dim strCurrTest As String, strConcat As String, strOutput As String
Range("J:K").ClearContents '\\ Columns where summary is pasted. Adjust Column Ref
lngLastCol = Cells(1, Columns.Count).End(xlToLeft).Column
'\\ Loop through rows
For i = 2 To Range("A" & Rows.Count).End(xlUp).Row
If strCurrTest <> Range("A" & i).Value Then
strCurrTest = Range("A" & i).Value
If Len(strOutput) <> 0 Then Range("J" & Rows.Count).End(xlUp).Offset(0, 1).Value = strOutput '\\ Adjust Column Ref
Range("J" & Rows.Count).End(xlUp).Offset(1, 0).Value = strCurrTest '\\ Adjust Column Ref
strOutput = ""
strConcat = ""
For j = 3 To lngLastCol
If Trim(LCase(Cells(i, j).Value)) = "fail" Then
strConcat = IIf(Len(strConcat) = 0, "", strConcat & ",") & Cells(1, j).Value
End If
Next j
If Not Len(strConcat) = 0 Then
strOutput = Cells(i, 2).Value & " Draw Angle : " & strConcat
End If
Else
strConcat = ""
For j = 3 To lngLastCol
If Trim(LCase(Cells(i, j).Value)) = "fail" Then
strConcat = IIf(Len(strConcat) = 0, "", strConcat & ",") & Cells(1, j).Value
End If
Next j
If Not Len(strConcat) = 0 Then
If Len(strOutput) <> 0 Then
strOutput = strOutput & vbCrLf & Cells(i, 2).Value & " Draw Angle : " & strConcat
Else
strOutput = Cells(i, 2).Value & " Draw Angle : " & strConcat
End If
End If
End If
If i = Range("A" & Rows.Count).End(xlUp).Row Then Range("J" & Rows.Count).End(xlUp).Offset(0, 1).Value = strOutput '\\ Adjust Column Ref
Next
End Sub
Following is traditional sledgehammer VBA approach. Make sure following:
1. Adjust column references where commented in the code.
2. Test it on a backup
Code:Public Sub BuildFailureSummary() Dim i As Long, j As Long, lngLastCol As Long Dim strCurrTest As String, strConcat As String, strOutput As String Range("J:K").ClearContents '\\ Columns where summary is pasted. Adjust Column Ref lngLastCol = Cells(1, Columns.Count).End(xlToLeft).Column '\\ Loop through rows For i = 2 To Range("A" & Rows.Count).End(xlUp).Row If strCurrTest <> Range("A" & i).Value Then strCurrTest = Range("A" & i).Value If Len(strOutput) <> 0 Then Range("J" & Rows.Count).End(xlUp).Offset(0, 1).Value = strOutput '\\ Adjust Column Ref Range("J" & Rows.Count).End(xlUp).Offset(1, 0).Value = strCurrTest '\\ Adjust Column Ref strOutput = "" strConcat = "" For j = 3 To lngLastCol If Trim(LCase(Cells(i, j).Value)) = "fail" Then strConcat = IIf(Len(strConcat) = 0, "", strConcat & ",") & Cells(1, j).Value End If Next j If Not Len(strConcat) = 0 Then strOutput = Cells(i, 2).Value & " Draw Angle : " & strConcat End If Else strConcat = "" For j = 3 To lngLastCol If Trim(LCase(Cells(i, j).Value)) = "fail" Then strConcat = IIf(Len(strConcat) = 0, "", strConcat & ",") & Cells(1, j).Value End If Next j If Not Len(strConcat) = 0 Then If Len(strOutput) <> 0 Then strOutput = strOutput & vbCrLf & Cells(i, 2).Value & " Draw Angle : " & strConcat Else strOutput = Cells(i, 2).Value & " Draw Angle : " & strConcat End If End If End If If i = Range("A" & Rows.Count).End(xlUp).Row Then Range("J" & Rows.Count).End(xlUp).Offset(0, 1).Value = strOutput '\\ Adjust Column Ref Next End Sub
1.5 Draw Angle : 20 deg
2 Draw Angle : 21, 24 deg
3 Draw Angle : 22 deg
4 Draw Angle : 23 deg
1.5 Draw Angle : 20 deg
2.0 Draw Angle : 21, 24 deg
3.0 Draw Angle : 22 deg
4.0 Draw Angle : 23 deg
Public Sub BuildFailureSummary()
Dim i As Long, j As Long, lngLastCol As Long
Dim strCurrTest As String, strConcat As String, strOutput As String
Range("J:K").ClearContents '\\ Columns where summary is pasted. Adjust Column Ref
lngLastCol = Cells(1, Columns.Count).End(xlToLeft).Column
'\\ Loop through rows
For i = 2 To Range("A" & Rows.Count).End(xlUp).Row
If strCurrTest <> Range("A" & i).Value Then
strCurrTest = Range("A" & i).Value
If Len(strOutput) <> 0 Then Range("J" & Rows.Count).End(xlUp).Offset(0, 1).Value = strOutput '\\ Adjust Column Ref
Range("J" & Rows.Count).End(xlUp).Offset(1, 0).Value = strCurrTest '\\ Adjust Column Ref
strOutput = ""
strConcat = ""
For j = 3 To lngLastCol
If Trim(LCase(Cells(i, j).Value)) = "fail" Then
strConcat = IIf(Len(strConcat) = 0, "", strConcat & ",") & Cells(1, j).Value
End If
Next j
If Not Len(strConcat) = 0 Then
strOutput = Format(Cells(i, 2).Value, "0.0") & " Draw Angle : " & strConcat & " deg"
End If
Else
strConcat = ""
For j = 3 To lngLastCol
If Trim(LCase(Cells(i, j).Value)) = "fail" Then
strConcat = IIf(Len(strConcat) = 0, "", strConcat & ",") & Cells(1, j).Value
End If
Next j
If Not Len(strConcat) = 0 Then
If Len(strOutput) <> 0 Then
strOutput = strOutput & vbCrLf & Format(Cells(i, 2).Value, "0.0") & " Draw Angle : " & strConcat & " deg"
Else
strOutput = Format(Cells(i, 2).Value, "0.0") & " Draw Angle : " & strConcat & " deg"
End If
End If
End If
If i = Range("A" & Rows.Count).End(xlUp).Row Then Range("J" & Rows.Count).End(xlUp).Offset(0, 1).Value = strOutput '\\ Adjust Column Ref
Next
End Sub
Like this:
Code:Public Sub BuildFailureSummary() Dim i As Long, j As Long, lngLastCol As Long Dim strCurrTest As String, strConcat As String, strOutput As String Range("J:K").ClearContents '\\ Columns where summary is pasted. Adjust Column Ref lngLastCol = Cells(1, Columns.Count).End(xlToLeft).Column '\\ Loop through rows For i = 2 To Range("A" & Rows.Count).End(xlUp).Row If strCurrTest <> Range("A" & i).Value Then strCurrTest = Range("A" & i).Value If Len(strOutput) <> 0 Then Range("J" & Rows.Count).End(xlUp).Offset(0, 1).Value = strOutput '\\ Adjust Column Ref Range("J" & Rows.Count).End(xlUp).Offset(1, 0).Value = strCurrTest '\\ Adjust Column Ref strOutput = "" strConcat = "" For j = 3 To lngLastCol If Trim(LCase(Cells(i, j).Value)) = "fail" Then strConcat = IIf(Len(strConcat) = 0, "", strConcat & ",") & Cells(1, j).Value End If Next j If Not Len(strConcat) = 0 Then strOutput = Format(Cells(i, 2).Value, "0.0") & " Draw Angle : " & strConcat & " deg" End If Else strConcat = "" For j = 3 To lngLastCol If Trim(LCase(Cells(i, j).Value)) = "fail" Then strConcat = IIf(Len(strConcat) = 0, "", strConcat & ",") & Cells(1, j).Value End If Next j If Not Len(strConcat) = 0 Then If Len(strOutput) <> 0 Then strOutput = strOutput & vbCrLf & Format(Cells(i, 2).Value, "0.0") & " Draw Angle : " & strConcat & " deg" Else strOutput = Format(Cells(i, 2).Value, "0.0") & " Draw Angle : " & strConcat & " deg" End If End If End If If i = Range("A" & Rows.Count).End(xlUp).Row Then Range("J" & Rows.Count).End(xlUp).Offset(0, 1).Value = strOutput '\\ Adjust Column Ref Next End Sub
One more update is required. I am getting many values, just want to add "-" or "to" in between consecutive values. I have many such lines in single cell.Like this:
Code:Public Sub BuildFailureSummary() Dim i As Long, j As Long, lngLastCol As Long Dim strCurrTest As String, strConcat As String, strOutput As String Range("J:K").ClearContents '\\ Columns where summary is pasted. Adjust Column Ref lngLastCol = Cells(1, Columns.Count).End(xlToLeft).Column '\\ Loop through rows For i = 2 To Range("A" & Rows.Count).End(xlUp).Row If strCurrTest <> Range("A" & i).Value Then strCurrTest = Range("A" & i).Value If Len(strOutput) <> 0 Then Range("J" & Rows.Count).End(xlUp).Offset(0, 1).Value = strOutput '\\ Adjust Column Ref Range("J" & Rows.Count).End(xlUp).Offset(1, 0).Value = strCurrTest '\\ Adjust Column Ref strOutput = "" strConcat = "" For j = 3 To lngLastCol If Trim(LCase(Cells(i, j).Value)) = "fail" Then strConcat = IIf(Len(strConcat) = 0, "", strConcat & ",") & Cells(1, j).Value End If Next j If Not Len(strConcat) = 0 Then strOutput = Format(Cells(i, 2).Value, "0.0") & " Draw Angle : " & strConcat & " deg" End If Else strConcat = "" For j = 3 To lngLastCol If Trim(LCase(Cells(i, j).Value)) = "fail" Then strConcat = IIf(Len(strConcat) = 0, "", strConcat & ",") & Cells(1, j).Value End If Next j If Not Len(strConcat) = 0 Then If Len(strOutput) <> 0 Then strOutput = strOutput & vbCrLf & Format(Cells(i, 2).Value, "0.0") & " Draw Angle : " & strConcat & " deg" Else strOutput = Format(Cells(i, 2).Value, "0.0") & " Draw Angle : " & strConcat & " deg" End If End If End If If i = Range("A" & Rows.Count).End(xlUp).Row Then Range("J" & Rows.Count).End(xlUp).Offset(0, 1).Value = strOutput '\\ Adjust Column Ref Next End Sub
1.0 Draw Angle : -25,-24,-23,-22,-21,-20,-19,-18,-17,-16,-15,-14,-13,-12,-11,-4,-3,-2,-1,0,1,2,3,4 deg
1.0 Draw Angle : -25 to -11,-4 to 4 deg
Yes, these are column headers that will be consecutive.What defines consecutive?
- Column Numbers that you define at the top successively A,B,C or
- Normal consecutive numbers e.g. 19,20,21 i.e. separated by 1° always.
- Do you always have angles as integers and no decimal points i.e. you don't have 19.50, 22.25 etc.
But I'm stuck at one step.
=Text.Combine([Count][Failed Degree]," ,") & " deg"
Public Sub BuildFailureSummary()
Dim i As Long, j As Long, lngLastCol As Long
Dim strCurrTest As String, strConcat As String, strOutput As String
Range("J:K").ClearContents '\\ Columns where summary is pasted. Adjust Column Ref
lngLastCol = Cells(1, Columns.Count).End(xlToLeft).Column
'\\ Loop through rows
For i = 2 To Range("A" & Rows.Count).End(xlUp).Row
If strCurrTest <> Range("A" & i).Value Then
strCurrTest = Range("A" & i).Value
If Len(strOutput) <> 0 Then Range("J" & Rows.Count).End(xlUp).Offset(0, 1).Value = strOutput '\\ Adjust Column Ref
Range("J" & Rows.Count).End(xlUp).Offset(1, 0).Value = strCurrTest '\\ Adjust Column Ref
strOutput = ""
strConcat = ""
For j = 3 To lngLastCol
If Trim(LCase(Cells(i, j).Value)) = "fail" Then
strConcat = IIf(Len(strConcat) = 0, "", strConcat & ",") & Cells(1, j).Value
End If
Next j
If Not Len(strConcat) = 0 Then
strConcat = BuildSummaryList(strConcat) '\\Note Line Added
strOutput = Format(Cells(i, 2).Value, "0.0") & " Draw Angle : " & strConcat & " deg"
End If
Else
strConcat = ""
For j = 3 To lngLastCol
If Trim(LCase(Cells(i, j).Value)) = "fail" Then
strConcat = IIf(Len(strConcat) = 0, "", strConcat & ",") & Cells(1, j).Value
End If
Next j
If Not Len(strConcat) = 0 Then
If Len(strOutput) <> 0 Then
strConcat = BuildSummaryList(strConcat) '\\Note Line Added
strOutput = strOutput & vbCrLf & Format(Cells(i, 2).Value, "0.0") & " Draw Angle : " & strConcat & " deg"
Else
strConcat = BuildSummaryList(strConcat) '\\Note Line Added
strOutput = Format(Cells(i, 2).Value, "0.0") & " Draw Angle : " & strConcat & " deg"
End If
End If
End If
If i = Range("A" & Rows.Count).End(xlUp).Row Then Range("J" & Rows.Count).End(xlUp).Offset(0, 1).Value = strOutput '\\ Adjust Column Ref
Next
End Sub
'\\ Function to deal with the pattern
Public Function BuildSummaryList(strInput As String)
Dim varInArray, varOutArray()
Dim i As Long
varInArray = Split(strInput, ",")
If UBound(varInArray) < 2 Then
BuildSummaryList = strInput
Else
'\\ First Pass Find Consecutives
ReDim varOutArray(UBound(varInArray))
varOutArray(LBound(varOutArray)) = varInArray(LBound(varInArray))
For i = (LBound(varInArray) + 1) To (UBound(varOutArray) - 1)
If (CLng(varInArray(i)) - 1 = CLng(varInArray(i - 1))) And _
(CLng(varInArray(i)) + 1 = CLng(varInArray(i + 1))) Then
varOutArray(i) = ""
Else
varOutArray(i) = varInArray(i)
End If
Next i
varOutArray(UBound(varOutArray)) = varInArray(UBound(varInArray))
'\\ Second Pass Test
For i = LBound(varOutArray) To UBound(varOutArray)
If i < UBound(varOutArray) Then
If Len(varOutArray(i)) > 0 Then
BuildSummaryList = IIf(Right(BuildSummaryList, 2) = "to", BuildSummaryList, BuildSummaryList & " ") & varOutArray(i)
If Len(varOutArray(i + 1)) = 0 Then
BuildSummaryList = BuildSummaryList & "to"
End If
End If
Else
BuildSummaryList = IIf(Right(BuildSummaryList, 2) = "to", BuildSummaryList, BuildSummaryList & " ") & varOutArray(i)
End If
Next i
BuildSummaryList = Replace(Replace(Trim(BuildSummaryList), " ", ", "), "to", " to ")
End If
End Function
I have added a function and function call.
- Make sure you read comments and edit the column references marked as before.
- Test it on a backup as usual
Code:Public Sub BuildFailureSummary() Dim i As Long, j As Long, lngLastCol As Long Dim strCurrTest As String, strConcat As String, strOutput As String Range("J:K").ClearContents '\\ Columns where summary is pasted. Adjust Column Ref lngLastCol = Cells(1, Columns.Count).End(xlToLeft).Column '\\ Loop through rows For i = 2 To Range("A" & Rows.Count).End(xlUp).Row If strCurrTest <> Range("A" & i).Value Then strCurrTest = Range("A" & i).Value If Len(strOutput) <> 0 Then Range("J" & Rows.Count).End(xlUp).Offset(0, 1).Value = strOutput '\\ Adjust Column Ref Range("J" & Rows.Count).End(xlUp).Offset(1, 0).Value = strCurrTest '\\ Adjust Column Ref strOutput = "" strConcat = "" For j = 3 To lngLastCol If Trim(LCase(Cells(i, j).Value)) = "fail" Then strConcat = IIf(Len(strConcat) = 0, "", strConcat & ",") & Cells(1, j).Value End If Next j If Not Len(strConcat) = 0 Then strConcat = BuildSummaryList(strConcat) '\\Note Line Added strOutput = Format(Cells(i, 2).Value, "0.0") & " Draw Angle : " & strConcat & " deg" End If Else strConcat = "" For j = 3 To lngLastCol If Trim(LCase(Cells(i, j).Value)) = "fail" Then strConcat = IIf(Len(strConcat) = 0, "", strConcat & ",") & Cells(1, j).Value End If Next j If Not Len(strConcat) = 0 Then If Len(strOutput) <> 0 Then strConcat = BuildSummaryList(strConcat) '\\Note Line Added strOutput = strOutput & vbCrLf & Format(Cells(i, 2).Value, "0.0") & " Draw Angle : " & strConcat & " deg" Else strConcat = BuildSummaryList(strConcat) '\\Note Line Added strOutput = Format(Cells(i, 2).Value, "0.0") & " Draw Angle : " & strConcat & " deg" End If End If End If If i = Range("A" & Rows.Count).End(xlUp).Row Then Range("J" & Rows.Count).End(xlUp).Offset(0, 1).Value = strOutput '\\ Adjust Column Ref Next End Sub '\\ Function to deal with the pattern Public Function BuildSummaryList(strInput As String) Dim varInArray, varOutArray() Dim i As Long varInArray = Split(strInput, ",") If UBound(varInArray) < 2 Then BuildSummaryList = strInput Else '\\ First Pass Find Consecutives ReDim varOutArray(UBound(varInArray)) varOutArray(LBound(varOutArray)) = varInArray(LBound(varInArray)) For i = (LBound(varInArray) + 1) To (UBound(varOutArray) - 1) If (CLng(varInArray(i)) - 1 = CLng(varInArray(i - 1))) And _ (CLng(varInArray(i)) + 1 = CLng(varInArray(i + 1))) Then varOutArray(i) = "" Else varOutArray(i) = varInArray(i) End If Next i varOutArray(UBound(varOutArray)) = varInArray(UBound(varInArray)) '\\ Second Pass Test For i = LBound(varOutArray) To UBound(varOutArray) If i < UBound(varOutArray) Then If Len(varOutArray(i)) > 0 Then BuildSummaryList = IIf(Right(BuildSummaryList, 2) = "to", BuildSummaryList, BuildSummaryList & " ") & varOutArray(i) If Len(varOutArray(i + 1)) = 0 Then BuildSummaryList = BuildSummaryList & "to" End If End If Else BuildSummaryList = IIf(Right(BuildSummaryList, 2) = "to", BuildSummaryList, BuildSummaryList & " ") & varOutArray(i) End If Next i BuildSummaryList = Replace(Replace(Trim(BuildSummaryList), " ", ", "), "to", " to ") End If End Function
Aikun Samadhan Watala!Thanks a lot, again, Shrivallabha! I am just stunned with this example that how many things can be done using vba in excel.
Aikun Samadhan Watala!
Translation: Happy to hear(know) this!