Excel VBA - Comma Separated Cells to Rows - vba

Please help me with some advice regarding the below excel. In the incipient form looks like this:
A B C
1 A1 ;100;200;300;400;500;
2 A2 ;716;721;428;1162;2183;433;434;1242;717;718;
3 A3 ;100;101;
And i want to reach this result:
A B C
1 A1 100
1 200
1 300
1 400
1 500
2 A2 716
2 721
2 428
2 1162
2 2183
2 433
2 434
2 1242
2 717
2 718
3 A3 100
3 101
I tried using this code, but it does not return the expected result.
Sub SliceNDice()
Dim objRegex As Object
Dim X
Dim Y
Dim lngRow As Long
Dim lngCnt As Long
Dim tempArr() As String
Dim strArr
Set objRegex = CreateObject("vbscript.regexp")
objRegex.Pattern = "^\s+(.+?)$"
'Define the range to be analysed
X = Range([a1], Cells(Rows.Count, "b").End(xlUp)).Value2
ReDim Y(1 To 2, 1 To 1000)
For lngRow = 1 To UBound(X, 1)
'Split each string by ";"
tempArr = Split(X(lngRow, 2), ";")
For Each strArr In tempArr
lngCnt = lngCnt + 1
'Add another 1000 records to resorted array every 1000 records
If lngCnt Mod 1000 = 0 Then ReDim Preserve Y(1 To 2, 1 To lngCnt + 1000)
Y(1, lngCnt) = X(lngRow, 1)
Y(2, lngCnt) = objRegex.Replace(strArr, "$1")
Next
Next lngRow
'Dump the re-ordered range to columns C:D
[c1].Resize(lngCnt, 2).Value2 = Application.Transpose(Y)
End Sub
Thanks in advance!

Try this:
Option Explicit
Sub DoSomething()
Dim i As Integer, j As Integer, k As Integer
Dim srcwsh As Worksheet, dstwsh As Worksheet
Dim sTmp As String, sNumbers() As String
Set srcwsh = ThisWorkbook.Worksheets("Sheet1")
Set dstwsh = ThisWorkbook.Worksheets("Sheet2")
i = 1
j = 1
Do While srcwsh.Range("A" & i) <> ""
sTmp = srcwsh.Range("C" & i)
sNumbers = GetNumbers(sTmp)
For k = LBound(sNumbers()) To UBound(sNumbers())
dstwsh.Range("A" & j) = srcwsh.Range("A" & i)
dstwsh.Range("B" & j) = srcwsh.Range("B" & i)
dstwsh.Range("C" & j) = sNumbers(k)
j = j + 1
Next
i = i + 1
Loop
Set srcwsh = Nothing
Set dstwsh = Nothing
End Sub
Function GetNumbers(ByVal sNumbers As String) As String()
Dim sTmp As String
sTmp = sNumbers
'remove first ;
sTmp = Left(sTmp, Len(sTmp) - 1)
'remove last ;)
sTmp = Right(sTmp, Len(sTmp) - 1)
GetNumbers = Split(sTmp, ";")
End Function
Note: i'd suggest to add error handler. For further information, please see: Exception and Error Handling in Visual Basic

This code will work for you
Sub SplitAndCopy()
Dim sh As Worksheet
Set sh = ThisWorkbook.Worksheets("YourTargetSheet")
Dim i As Long, j As Long, k As Long
k = 2
For i = 2 To Cells(Rows.Count, "A").End(xlUp).Row
For j = LBound(Split(Range("C" & i).Value, ";")) + 1 To UBound(Split(Range("C" & i).Value, ";")) - 1
sh.Range("A" & k).Value = Range("A" & i).Value
If j = LBound(Split(Range("C" & i).Value, ";")) + 1 Then
sh.Range("B" & k).Value = Range("B" & i).Value
End If
sh.Range("C" & k).Value = Split(Range("C" & i).Value, ";")(j)
k = k + 1
Next j
Next i
End Sub

I would rather go this way:
Private Type data
col1 As Integer
col2 As String
col3 As String
End Type
Sub SplitAndCopy()
Dim x%, y%, c%
Dim arrData() As data
Dim splitCol() As String
ReDim arrData(1 To Cells(1, 1).End(xlDown))
x = 1: y = 1: c = 1
Do Until Cells(x, 1) = ""
arrData(x).col1 = Cells(x, 1)
arrData(x).col2 = Cells(x, 2)
arrData(x).col3 = Cells(x, 3)
x = x + 1
Loop
[a:d].Clear
For x = 1 To UBound(arrData)
Cells(c, 2) = arrData(x).col2
splitCol = Split(Mid(arrData(x).col3, 2, Len(arrData(x).col3) - 2), ";")
' sort splitCol
For y = 0 To UBound(splitCol)
Cells(c, 1) = arrData(x).col1
Cells(c, 3) = splitCol(y)
c = c + 1
Next y
Next x
End Sub
I am not totally sure if you need your third column sorted, in case you can add a sorting function.

Related

Is there anything I can do to speed up my code?

I have a script I use that goes down a column in a second worksheet and pulls only the managers (their employees data) that I specify.
It takes about .8-.9 seconds for each file to form from both arrays (one for storing and the second for a faster printing to a new wb)
Are there any revisions you would make in order to drastically speed it up? I know that the majority of the time spent is saving/password protecting.
script:
Option Explicit
Sub HR_Assessment()
Dim j As Long, k As Long, x As Long ' counters
Dim varArray() As Variant
Dim varArray2() As Variant
ReDim varArray(1 To 75, 1 To 1)
Dim strManager As String
Dim BASEPATH As String, strNewPath As String, strFileName As String
Dim Wb As Workbook
Dim mgrRow As Long ' counter
Dim colManager As Long ' the column manager appears in
colManager = 1
BASEPATH = "M:\Raw Reports\HR\"
Call Ludicrous(True) - this is just a separate module that turns off calculations/screen updating/etc....
For mgrRow = 2 To ThisWorkbook.Worksheets("Mgrs").UsedRange.Rows.Count
If ThisWorkbook.Worksheets("Mgrs").Cells(mgrRow, 1) <> "" Then
strManager = ThisWorkbook.Worksheets("Mgrs").Cells(mgrRow, 1)
With ThisWorkbook.Worksheets("Sheet1")
ReDim varArray(1 To UBound(varArray, 1), 1 To 1)
x = 1
For k = 1 To UBound(varArray, 1)
varArray(k, x) = .Cells(1, k)
Next
For j = 1 To .UsedRange.Rows.Count + 1
If strManager = .Cells(j, colManager) Then
x = x + 1
ReDim Preserve varArray(1 To UBound(varArray, 1), 1 To x)
For k = 1 To UBound(varArray, 1)
varArray(k, x) = .Cells(j, k)
strManager = .Cells(j, colManager)
Next
End If
Next
End With
strNewPath = BASEPATH & "11.01.18" & "\"
If Len(Dir(strNewPath, vbDirectory)) = 0 Then
MkDir strNewPath
End If
' Path is now "constant path"
strFileName = strManager & " - " & "HR_Assessment" & ".xlsx"
ReDim varArray2(1 To UBound(varArray, 2), 1 To UBound(varArray, 1))
Set Wb = Workbooks.Add(XlWBATemplate.xlWBATWorksheet)
With Wb
With .Worksheets("Sheet1")
For j = 1 To UBound(varArray, 2)
For k = 1 To UBound(varArray, 1)
varArray2(j, k) = varArray(k, j)
Next
Next
.Range(.Cells(1, 1), .Cells(UBound(varArray, 2), UBound(varArray, 1))) = varArray2
.Range("A:B").Columns.AutoFit
End With
.SaveAs strNewPath & strFileName, Password:="password", FileFormat:=51
.Saved = True
.Close
End With
Set Wb = Nothing
End If
Next
Call Ludicrous(False)
End Sub

Loading data range or string from excel file to an array then split in array

Is there someone can help me? I have here code that can duplicate entire row to have 2 rows. After duplicating the first entire row , I want to load string from range "G" into array so that I can get certain string that Am planning to insert in "Thickness" and "width" column for me to use to calculate the "Weight" of the "Profile Type". If you will see I have an array in the code .But that array work differently for me and I had a hard time fulfilling the requirements I need. The array in my code split the String using "X" as delimiter . Once the string was split it will add another cells for each split string. what I want is to do the split not in the column but in the array only so that I can maintain the data in G . I will use the string assigned in the array to get "Thickness and Width" of the profile which is "15 as Thickness and 150 as width". If there's any way to do same thing using other code it will be more helpful to simplify the code.
Reminder that Profiletype string vary its length . Sometimes profile width are 4 digits (LB1000X4500X12/15)
Below are the snapshot of my worksheet for you to identify what the result will be.
Private Sub CommandButton2_Click()
Dim lastrow As Long
Dim i As Integer
Dim icount As Integer
Dim x As Long
For x = ActiveSheet.UsedRange.Rows.CountLarge To 1 Step -1
If Cells(x, "F") = "LB" Then
Cells(x, "F") = "ComP"
Cells(x + 1, "F").EntireRow.Insert
Cells(x, "F").EntireRow.Copy Cells(x + 1, "F").EntireRow
'array
'Columns("G:G").NumberFormat = "#"
Dim c As Long, r As Range, v As Variant, d As Variant
For i = 2 To Range("G" & Rows.Count).End(xlUp).Row '2 to 16 cell
'v = Split (range("G" & i), "X")
v = Split((Cells(x, "G") & i), "x")
c = c + UBound(v) + 1
'Next i
For i = 2 To c
If Range("G" & i) <> "" Then
Set r = Range("G" & i)
Dim arr As Variant
arr = Split(r, "X")
Dim j As Long
r = arr(0)
For j = 1 To UBound(arr)
Rows(r.Row + j & ":" & r.Row + j).Insert Shift:=xlDown
r.Offset(j, 0) = arr(j)
r.Offset(j, -1) = r.Offset(0, -1)
r.Offset(j, -2) = r.Offset(0, -2)
Next j
End If
Next i
End If
Next x
End Sub
Does this do what you want? Run in copy of workbook to be safe.
Option explicit
Private Sub CommandButton2_Click()
'Bit redundant, would be better if you fully qualify workbook and worksheet with actual names.'
Dim TargetWorksheet as worksheet
Set TargetWorksheet = Activesheet
With application
.screenupdating = false
.calculation = xlcalculationmanual
End with
With TargetWorksheet
.range("G:G").numberformat = "#"
Dim RowIndex As Long
For RowIndex = .usedrange.rows.countlarge to 1 step -1
If .Cells(RowIndex, "F").value2 = "LB" Then
.Cells(RowIndex, "F").value2 = "ComP"
.Cells(RowIndex + 1, "F").EntireRow.Insert
.Cells(RowIndex, "F").EntireRow.Copy .Cells(RowIndex + 1, "F").EntireRow
Dim SplitProfileType() as string
SplitProfileType = split(mid(.cells(RowIndex+1,"G").value2,3), "X") ' assumes first two characters will always be LB, that it is safe to ignore them and start from third character.'
' Write thickness'
.cells(RowIndex+1, "H").value2 = cdbl(mid(SplitProfileType(ubound(SplitProfileType)),instrrev(SplitProfileType(ubound(SplitProfileType)),"/",-1,vbbinarycompare)+1)
' Write width'
.cells(RowIndex+1, "i").value2 = cdbl(SplitProfileType(1))
' Calculate weight'
.cells(RowIndex+1,"K").value2 = .cells(RowIndex+1,"H").value2 * .cells(RowIndex+1,"I").value2 * .cells(RowIndex+1,"J").value2
End if
' I think because you are inserting a row below (rather than above/before), your RowIndex remains unaffected and no adjustment is needed to code. I could be wrong. I would need to test it to be sure.'
Next rowindex
End with
With application
.screenupdating = true
.calculation = xlcalculationautomatic
End with
End sub
Untested as written on mobile.
It works without duplication.
Sub test2()
Dim vDB, vR()
Dim i As Long, n As Long, k As Long, j As Integer
Dim r As Integer
Dim s As String
vDB = Range("A2", "K" & Range("A" & Rows.Count).End(xlUp).Row)
n = UBound(vDB, 1)
For i = 1 To n
If vDB(i, 6) = "LB" Then
r = 2
Else
r = 1
End If
k = k + r
ReDim Preserve vR(1 To 11, 1 To k)
s = vDB(i, 7)
For j = 1 To 11
If r = 1 Then
vR(j, k) = vDB(i, j)
Else
vR(j, k - 1) = vDB(i, j)
vR(j, k) = vDB(i, j)
End If
Next j
If r = 2 Then
vR(6, k - 1) = "comp"
vR(6, k) = "comp"
vR(8, k) = Split(s, "/")(1)
vR(9, k) = Split(s, "X")(1)
vR(9, k - 1) = vR(9, k - 1) - vR(8, k)
vR(11, k - 1) = (vR(8, k - 1) * vR(9, k - 1) * vR(10, k - 1) * 7.85) / 10 ^ 6 '<~~ k2 weight
vR(11, k) = (vR(8, k) * vR(9, k) * vR(10, k) * 7.85) / 10 ^ 6 '<~~ k3 weight
End If
Next i
Range("f1") = "Type"
Range("a2").Resize(k, 11) = WorksheetFunction.Transpose(vR)
End Sub
It is faster to use an array than to enter it one-to-one in a cell.
Sub test()
Dim vDB, vR()
Dim i As Long, n As Long, k As Long, j As Integer
Dim s As String
vDB = Range("A2", "K" & Range("A" & Rows.Count).End(xlUp).Row)
n = UBound(vDB, 1)
ReDim vR(1 To n * 2, 1 To 11)
For i = 1 To n
k = k + 2
s = vDB(i, 7)
For j = 1 To 11
vR(k - 1, j) = vDB(i, j)
vR(k, j) = vDB(i, j)
Next j
vR(k - 1, 6) = "comp"
vR(k, 6) = "comp"
vR(k, 8) = Split(s, "/")(1)
vR(k, 9) = Split(s, "X")(1)
vR(k, 11) = Empty '<~~ This is calculated Weight value place
Next i
Range("f1") = "Type"
Range("a2").Resize(n * 2, 11) = vR
End Sub

Vba Excel - concatenate cell value and loop to all columns

I need help.
In a sheet I need concatenate with a loop the columns "a" + "b" + "c", next the columns "d" + "e" + "f", etc ... an go up to the last column.
My script is locked to the second loop...
The concatenated results are to appear in a second sheet.
this is my incorrect code:
Sub concatena()
Dim x As String
Dim Y As String
b = 1 'colonna selezionata
For c = 1 To 5 'colonne concatenate da riportare
For q = 1 To 10 'righe su cui effettuare l'operazione
For t = 1 To 3 'numero celle da concatenare
For Each cell In Worksheets(1).Cells(q, t)
If cell.Value = "" Then GoTo Line1
x = x & cell(1, b).Value & "" & ""
Next
Next t
Line1:
On Error GoTo Terminate
Worksheets(2).Cells(q, c).Value = Mid(x, 1, Len(x))
x = "" 'mantiene la formattazione
Next q
b = 3 + 1 ' sposta il concatena di 3 celle la selezione delle colonne
Next c
Terminate: 'error handler
End Sub
Thank you all for the help!
This one uses arrays to speed it up a little:
Sub concatena()
Dim inArr() As Variant
Dim oArr() As Variant
Dim i&, j&
Dim ws As Worksheet
Dim rng As Range
Set ws = Worksheets("Sheet9") ' change to your worksheet
With ws
Set rng = .Range(.Cells(1, 1), .Cells(.Cells(.Rows.Count, 1).End(xlUp).Row, .Cells(1, .Columns.Count).End(xlToLeft).Column))
inArr = rng.Value
ReDim oArr(1 To UBound(inArr, 1), 1 To UBound(inArr, 2) / 3)
For i = LBound(inArr, 1) To UBound(inArr, 1)
For j = LBound(inArr, 2) To UBound(inArr, 2) Step 3
oArr(i, Int((j - 1) / 3) + 1) = inArr(i, j) & inArr(i, j + 1) & inArr(i, j + 2)
Next j
Next i
rng.Clear
.Range("A1").Resize(UBound(oArr, 1), UBound(oArr, 2)).Value = oArr
End With
you can try this code:
Option Explicit
Sub concatena()
Dim iRow As Long, iCol As Long, iCol2 As Long
Dim arr As Variant
With Worksheets("numbers")
With .Cells(1, 1).CurrentRegion
ReDim arr(1 To .Rows.Count, 1 To .Columns.Count / 3 + .Columns.Count Mod 3)
For iRow = 1 To .Rows.Count
iCol2 = 1
For iCol = 1 To .Columns.Count Step 3
arr(iRow, iCol2) = Join(Application.Transpose(Application.Transpose(.Cells(iRow, iCol).Resize(, 3).Value)), "")
iCol2 = iCol2 + 1
Next iCol
Next iRow
Worksheets("results").Range("A1").Resize(.Rows.Count, UBound(arr, 2)).Value = arr
End With
End With
End Sub
This solution provides flexibility as it uses the variable bClls to hold the number of cells to be concatenated.
Assuming the source range is B2:M16 and you want to concatenate the value of every 3 cells for each row.
It avoids the use of redim.
Sub Range_Concatenate_Cells_TEST()
Dim rSel As Range
Dim bClls As Byte
Dim rCllOut As Range
bClls = 3 'change as required
Set rSel = ThisWorkbook.Sheets("Sht(0)").Range("B2:M16") 'change as required
Set rCllOut = ThisWorkbook.Sheets("Sht(1)").Cells(2, 2) 'change as required
Call Range_Concatenate_Cells(bClls, rSel, rCllOut)
End Sub
Sub Range_Concatenate_Cells(bClls As Byte, rSel As Range, rCllOut As Range)
Dim lRow As Long, iCol As Integer
Dim lRowOut As Long, iColOut As Integer
Dim vResult As Variant
With rSel
For lRow = 1 To .Rows.Count
lRowOut = 1 + lRowOut
iColOut = 0
For iCol = 1 To .Columns.Count Step 3
iColOut = 1 + iColOut
vResult = .Cells(lRow, iCol).Resize(1, 3).Value2
vResult = WorksheetFunction.Index(vResult, 0, 0)
vResult = Join(vResult, "")
rCllOut.Offset(-1 + lRowOut, -1 + iColOut).Value = vResult
Next: Next: End With
End Sub

VBA loop with arrays duplicating output

I'm new to using arrays (and VBA in general) and I'm trying to incorporate a series of arrays into a module that formats SPSS syntax output in worksheets in a single workbook. Below is my code, which works, but is duplicating the results that are found. I think it has something to do with the order of my loops but I can't seem to figure out how to fix it. Any thoughts would be greatly appreciated.
Sub FindValues()
Call CreateSummary
'This code will build the initial summary file
Dim ws As Excel.Worksheet
'Application.ScreenUpdating = False
MsgBox ("It will take a moment for data to appear, please be patient if data does not immediately appear")
Dim LastRow As Long
Dim i As Integer
Dim i2 As Integer
Dim x As Integer
Dim y As Integer
Dim CopiedRows As Integer
Dim LocationA(4) As String
Dim LocationB(4) As String
Dim LocationC(4) As String
Dim LocationD(4) As String
Dim VariableA(4) As Integer
Dim VariableB(4) As Integer
Dim ColumnA(4) As String
Dim ColumnB(4) As String
Dim n As Long
'Find DateTime Info
LocationA(1) = "Date_Time"
LocationB(1) = "Quarter"
LocationC(1) = "N"
LocationD(1) = "Minimum"
VariableA(1) = 1
VariableB(1) = 1
ColumnA(1) = "B"
ColumnB(1) = "C"
LocationA(2) = "Dur*"
LocationB(2) = "Methodology_ID"
LocationC(2) = "Mean"
LocationD(2) = "N"
VariableA(2) = 1
VariableB(2) = 1
ColumnA(2) = "C"
ColumnB(2) = "D"
LocationA(3) = "WebTimeout"
LocationB(3) = "Methodology_ID"
LocationC(3) = "Mean"
LocationD(3) = "N"
VariableA(3) = 1
VariableB(3) = 1
ColumnA(3) = "C"
ColumnB(3) = "D"
'LocationA(4) = "Crosstabulation"
'LocationB(4) = "Quarter"
'LocationC(4) = "N"
'LocationD(4) = "Minimum"
'VariableA(4) = 1
'Find OSAT Data
'LocationA(2) = "*Report*"
'LocationB(2) = "*CallMonth*"
'LocationC(2) = "Mean*"
'LocationD(2) = "*Overall*"
'VariableA(2) = 2
For Each ws In Application.ThisWorkbook.Worksheets
'Starting row
i = 1
'Find LastRow
LastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
If ws.Name <> "Run Macros" Then
Do While i <= LastRow
For x = 1 To 3
If ws.Range("A" & i).Value Like LocationA(x) And ws.Range("A" & i + 1).Value Like LocationB(x) And ws.Range(ColumnA(x) & i + VariableA(x)).Value Like LocationC(x) And ws.Range(ColumnB(x) & i + VariableB(x)).Value Like LocationD(x) Then
CopiedRows = 0
i2 = i
Do While ws.Range("A" & i2 + 1).Borders(xlEdgeLeft).LineStyle = 1 And ws.Range("A" & i2 + 1).Borders(xlEdgeLeft).Weight = 4
i2 = i2 + 1
CopiedRows = CopiedRows + 1
Loop
n = Sheets("Summary").Cells(Rows.Count, "A").End(xlUp).Row + 4
ws.Rows(i & ":" & i + CopiedRows).Copy Sheets("Summary").Range("A" & n)
On Error Resume Next
End If
Next x
i = i + 1
Loop
End If
Next
'Application.ScreenUpdating = True
End Sub
This works if anyone want to reuse this code...
For x = 1 To 3 Step 1
For Each ws In Application.ThisWorkbook.Worksheets
'Starting row
i = 1
'Find LastRow
LastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
Do While i <= LastRow
If ws.Name <> "Run Macros" Or ws.Name <> "Summary" Then
If ws.Range("A" & i).Value Like LocationA(x) And ws.Range("A" & i + 1).Value Like LocationB(x) And ws.Range(ColumnA(x) & i + VariableA(x)).Value Like LocationC(x) And ws.Range(ColumnB(x) & i + VariableB(x)).Value Like LocationD(x) Then
CopiedRows = 0
i2 = i
Do While ws.Range("A" & i2 + 1).Borders(xlEdgeLeft).LineStyle = 1 And ws.Range("A" & i2 + 1).Borders(xlEdgeLeft).Weight = 4
i2 = i2 + 1
CopiedRows = CopiedRows + 1
Loop
n = Sheets("Summary").Cells(Rows.Count, "A").End(xlUp).Row + 4
ws.Rows(i & ":" & i + CopiedRows).Copy Sheets("Summary").Range("A" & n)
Exit For
On Error Resume Next
End If
End If
i = i + 1
Loop
Next
Next x

Split delimited 2nd and 3rd column data into new rows

I have the following table
ID. ID2. String
123. 567, 986 ABC;BCD;ACD
142. 134, 654,1134 AA;BB
I want it to be displayed
ID ID2 String
123 567 ABC
123 986 BCD
123 ACD
142 134 AA
142 654 bb
142 1134
The values in the ID column are unique.
Is there an efficient macro solution to this? I have a very huge set of data.
Try this.
Sub FlattenData()
Dim rng As Range, arr() As Variant, i As Long, rw As Long, j As Long
Set rng = Range("A1:C2") //Update for your range
arr() = rng
rng.ClearContents
rw = 0
For i = 1 To UBound(arr, 1)
colBTemp = VBA.Split(arr(i, 2), ",")
colCTemp = VBA.Split(arr(i, 3), ";")
colBTempLength = UBound(colBTemp, 1) + 1
colCTempLength = UBound(colCTemp, 1) + 1
requiredRows = WorksheetFunction.Max(colBTempLength, colCTempLength)
For j = 1 To requiredRows
Range("A" & rw + j) = arr(i, 1)
If j <= colBTempLength Then
Range("B" & rw + j) = colBTemp(j - 1)
Else
Range("B" & rw + j) = vbNullString
End If
If j <= colCTempLength Then
Range("C" & rw + j) = colCTemp(j - 1)
Else
Range("C" & rw + j) = vbNullString
End If
Next j
rw = rw + requiredRows
Next i
End Sub
With only the starting, concatenated data in the active sheet and ID is in A1, run this macro.
Sub split_out()
Dim v As Long, vVALs As Variant, vID2s As Variant, vSTRs As Variant
Dim rw As Long, lr As Long, mx As Long
With ActiveSheet
lr = .Cells(Rows.Count, 1).End(xlUp).Row
.Cells(1, 1).CurrentRegion.Rows(1).Copy Destination:=.Cells(lr + 2, 1)
For rw = 2 To lr
vVALs = Application.Index(.Cells(rw, 1).Resize(1, 3).Value, 1, 0)
vID2s = Split(vVALs(2), Chr(44))
vSTRs = Split(vVALs(3), Chr(59))
mx = Application.Max(UBound(vID2s), UBound(vSTRs))
For v = LBound(vID2s) To mx
.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0) = vVALs(1)
If UBound(vID2s) >= v Then _
.Cells(Rows.Count, 1).End(xlUp).Offset(0, 1) = vID2s(v)
If UBound(vSTRs) >= v Then _
.Cells(Rows.Count, 1).End(xlUp).Offset(0, 2) = vSTRs(v)
Next v
Next rw
End With
End Sub
The flattened data will be populated below the existing data. Your results should be similar to the following.