How to split one column to three column in excel? - excel

How do i split the first picture(whole address) into second picture(address, city, state, zipcode). I have more than thousand data, so kindly suggest me the easy method?
All the whole address is formatted as 729 quail creek drive, frisco tx 75034
I need to split Address as 729 quail creek drive, City as frisco, State as tx and zipcode as 75034.
Thanks

If you know your data will always be of this format:
<address>, <city> <2-letter state> <5-digit zip code>
Then this is the easiest way I can think of:
Formula for <address>:
= LEFT(A1,FIND(",",A1)-1)
Formula for <city>:
= MID(A1,FIND(",",A1)+2,LEN(A1)-FIND(",",A1)-10)
Formula for <2-letter state>:
= MID(A1,LEN(A1)-7,2)
Formula for <5-digit zip code>:
= RIGHT(A1,5)
See below example.

This could be done with RegExp but instead of figuring out the RegExp pattern I've used the Split function and a couple of arrays. I've assumed that the Address is before the comma.
Sub SplitAddress()
Dim Addresses As Variant, results As Variant, tmp As Variant
Dim i As Long, j As Long
' Update for you range
With Sheet1
'Trick to get 1D array from range
Addresses = Application.Transpose(.Range(.Cells(2, "A"), .Cells(.Cells(.Rows.Count, "A").End(xlUp).Row, "A")))
End With
ReDim results(1 To UBound(Addresses), 1 To 4)
For i = 1 To UBound(results, 1)
tmp = Split(Addresses(i), ",")
results(i, 1) = Trim(tmp(0))
tmp = Split(Trim(tmp(1)), " ")
For j = LBound(tmp) To UBound(tmp)
results(i, j + 2) = Trim(tmp(j))
Next j
Next i
' Update for your destination
With Sheet1.Cells(2, "B")
Range(.Offset(0, 0), .Offset(UBound(results, 1) - 1, UBound(results, 2) - 1)).Value2 = results
End With
End Sub
Updated with RegExp
This method uses RegExp to split your strings
Sub splitAddressRegEx()
Dim ReGex As Object
Dim Addresses As Range
Dim j As Long
Dim c, m
' Update for your range
With Sheet1
Set Addresses = .Range(.Cells(2, "A"), .Cells(.Cells(.Rows.Count, "A").End(xlUp).Row, "A"))
End With
Set ReGex = CreateObject("VBScript.RegExp")
With ReGex
.Global = True
.IgnoreCase = True
.Pattern = "(.+?(?=,))|(\w+)"
End With
For Each c In Addresses
j = 1
If ReGex.Test(c.Value2) Then
For Each m In ReGex.Execute(c.Value2)
' Update for your output
c.Offset(0, j).Value2 = m
j = j + 1
Next m
End If
Next c
End Sub

Related

Count 2- and 3-word strings frequency in Excel

Hello smart human beings out there
I have this setup in my Excel
Basically, what I'm trying to achieve here is automatically grab every single string from column A (and paste to column H) and return the frequency in column I. The script is below
Sub WordCountTester()
Dim d As Object, k, i As Long, ws As Worksheet
Set ws = ActiveSheet
With ws.ListObjects("Table3")
If Not .DataBodyRange Is Nothing Then
.DataBodyRange.Delete
End If
End With
Set d = WordCounts(ws.Range("A2:A" & ws.Cells(Rows.Count, "A").End(xlUp).Row), _
ws.Range("F2:F" & ws.Cells(Rows.Count, "F").End(xlUp).Row))
'list words and frequencies
For Each k In d.keys
ws.Range("H2").Resize(1, 2).Offset(i, 0).Value = Array(k, d(k))
i = i + 1
Next k
End Sub
'rngTexts = range with text to be word-counted, defined in set d= above
'rngExclude = 'range with words to exclude from count, defined in set d= above
Public Function WordCounts(rngTexts As Range, rngExclude As Range) As Object 'dictionary
Dim words, c As Range, dict As Object, regexp As Object, w, wd As String, m
Set dict = CreateObject("scripting.dictionary")
Set regexp = CreateObject("VBScript.RegExp") 'see link below for reference
With regexp
.Global = True
.MultiLine = True
.ignorecase = True
.Pattern = "[\dA-Z-]{3,}" 'at least 3 characters
End With
'loop over input range
For Each c In rngTexts.Cells
If Len(c.Value) > 0 Then
Set words = regexp.Execute(LCase(c.Value))
'loop over matches
For Each w In words
wd = w.Value 'the text of the match
If Len(wd) > 1 Then 'EDIT: ignore single characters
'increment count if the word is not found in the "excluded" range
If IsError(Application.Match(wd, rngExclude, 0)) Then
dict(wd) = dict(wd) + 1
End If
End If '>1 char
Next w
End If
Next c
Set WordCounts = dict
End Function
However, it currently count the string with 1 word only. I want to count strings with 2 and 3 words (and I will consider drive-by as 2 words). Can someone please tell me where in this code I have to fix to achieve that? I still want to keep column F there because there can be 2- or 3- word strings that I want to exclude. Thanks!
If you changed your mind and consider that also two words pairs 2-3, 4-5, 6-7 and so on are necessary, please test the next solution:
Private Sub WordPairsCountTester()
Dim d As Object, k, i As Long, ws As Worksheet, arrFin
Set ws = ActiveSheet
'Attention, please! The last parameter of the called function means How Many Consecutive Words to be counted
Set d = WordPairCountsSp(ws.Range("A2:A" & ws.cells(rows.count, "A").End(xlUp).row), _
ws.Range("F2:F" & ws.cells(rows.count, "F").End(xlUp).row), 3)
arrFin = Application.Transpose(Array(d.Keys, d.items)) 'place the dictionary in an array
'clear contents of the columns where a previous result was returned, if any...:
ws.Range("H2:I" & ws.Range("H" & ws.rows.count).End(xlUp).row).ClearContents
ws.Range("H2").Resize(UBound(arrFin), 2).Value = arrFin 'drop the array content at once
End Sub
Private Function WordPairCountsSp(rngTexts As Range, rngExclude As Range, nrNeigh As Long) As Object
Dim dict As Object, arr, arrCell, i As Long, pairWd As String, j As Long, k As Long
arr = rngTexts.Value 'place the range in an array for faster iteration
Set dict = CreateObject("scripting.dictionary")
For i = 1 To UBound(arr) 'iterate between the array elements
arrCell = Split(Replace(Replace(Replace(Replace(arr(i, 1), ",", ""), ".", ""), "?", ""), "!", "")) 'split the string by default delimiter (space)
If UBound(arrCell) + 1 >= nrNeigh Then
For j = 0 To UBound(arrCell) - nrNeigh + 1 'iterate between the array elements
pairWd = arrCell(j)
For k = 1 To nrNeigh - 1
pairWd = pairWd & " " & arrCell(j + k) 'create a string from nrNeigh neighbour words
Next k
If IsError(Application.match(pairWd, rngExclude, 0)) Then
dict(pairWd) = dict(pairWd) + 1 'place the unique pairs as keys and add occurrences as items
End If
Next j
End If
Next i
Set WordPairCountsSp = dict 'return the above created dictionary
End Function

How can i use VBA Code to Copy and Paste Specific Cells if Condition is Met in two or more worksheets to different areas of another worksheet

Looking for a little more help please. I was here a month ago a RiskyPenguin gave me a great bit of code. I would like to add to this.
This is the part that works:
So if the "invoice" spreadsheet (sheet 5), if cell G4 (for example is I111) matches any of the data in the first column of the "income" spreadsheet (sheet 1) (starting at row 6) then the corresponding data in columns 2 3, 8 & 9 will copy over to the "invoice" spreadsheet in columns 2, 3, 4 & 5 (starting at row 13).
Sub FindAndCopyData2()
Dim shData As Worksheet, shReport As Worksheet
Set shData = Sheet1
Set shReport = Sheet6
Dim strInvoceNumber As String
strInvoceNumber = shReport.Cells(4, "E").Value
Dim intLastRow As Integer
intLastRow = shData.Cells(Rows.Count, 1).End(xlUp).Row
Dim intReportRow As Integer
intReportRow = 13
shReport.Range("B13:E20").ClearContents
Dim i As Integer
For i = 1 To intLastRow
If shData.Cells(i, 1).Value2 = strInvoceNumber Then
shReport.Cells(intReportRow, 2).Value2 = shData.Cells(i, 3).Value2
shReport.Cells(intReportRow, 3).Value2 = shData.Cells(i, 4).Value2
shReport.Cells(intReportRow, 4).Value2 = shData.Cells(i, 8).Value2
shReport.Cells(intReportRow, 5).Value2 = shData.Cells(i, 9).Value2
intReportRow = intReportRow + 1
End If
Next i
End Sub
I would then like to (hopefully using the same search)
Take the "invoice" spreadsheet (sheet 5), if cell G4 (for example is I111) matches any of the data in the second column of the "expenses" spreadsheet (sheet 2) (starting at row 11) then the corresponding data in columns 3, 5, & 7 will copy over to the "invoice" spreadsheet in columns 2, 4 & 6 (starting at row 13).
Is this possible or does it have to be a separate piece of programming?
Many Thanks for any advise.
Assuming this could be useful for others I made a function out of it and refactored the initial code to handle the copy in memory. I setup your first lookup so you just need to edit the variables to get your second lookup:
Option Explicit
''''''''''''''''''''''''''''''''''''''
''Main Sub
''''''''''''''''''''''''''''''''''''''''''''''''''
Sub main()
'Set some vars
Dim sourceArr, targetArr, sourceCls, targetCls, sourceStartRw As Long, targetStartRw As Long, dict As Object, j As Long, sourceLookupCl As Long, Matchkey As Long
''''''''''''''''''''''''''''''''''''''
''Lookup 1
''''''''''''''''''''''''''''''''''''''''''''''''''
Matchkey = Sheet5.Range("G4").Value2 'lookupKey
sourceCls = Split("2,3,8,9 ", ",") 'Columns to copy from
targetCls = Split("2,3,4,5", ",") 'Columns to copy to
sourceStartRw = 6
targetStartRw = 13
sourceLookupCl = 1 'matching column
'get data in memory = array
sourceArr = Sheet1.Range("A1").CurrentRegion.Value2
'call our function
targetArr = reorder(sourceArr, sourceCls, targetCls, sourceStartRw, sourceLookupCl, Matchkey)
'dump to sheet
With Sheet5
.Range(.Cells(targetStartRw, 1), .Cells(UBound(targetArr) + targetStartRw - 1, UBound(targetArr, 2))).Value2 = targetArr
End With
''''''''''''''''''''''''''''''''''''''
''Lookup 2 => change source and target cols to your need
''''''''''''''''''''''''''''''''''''''''''''''''''
Matchkey = Sheet5.Range("G4").Value2
sourceCls = Split("2,3,8,9 ", ",")
targetCls = Split("2,3,4,5", ",")
sourceStartRw = 6
targetStartRw = 13 'must be the same as previous lookup if you want to keep the targetArr from previous lookups
sourceLookupCl = 1
'get data in memory = array
sourceArr = Sheet1.Range("A1").CurrentRegion.Value2
'call our function keeping the data from the first lookup
targetArr = reorder(sourceArr, sourceCls, targetCls, sourceStartRw, sourceLookupCl, Matchkey, targetArr)
'dump to sheet
With Sheet5
.Range(.Cells(targetStartRw, 1), .Cells(UBound(targetArr) + targetStartRw - 1, UBound(targetArr, 2))).Value2 = targetArr
End With
End Sub
''''''''''''''''''''''''''''''''''''''
''Supporting function
''''''''''''''''''''''''''''''''''''''''''''''''''
Private Function reorder(sourceArr, sourceCls, targetCls, sourceStartRw As Long, sourceLookupCl As Long, Matchkey As Long, Optional targetArr) As Variant
Dim dict As Object, j As Long
'if the target array overlaps the previous lookups pass it to the function
If IsMissing(targetArr) Then
ReDim targetArr(1 To UBound(sourceArr), 1 To UBound(sourceArr, 2))
End If
'build a dict to compare quickly
Set dict = CreateObject("Scripting.Dictionary") 'create dictionary lateB
For j = 1 To UBound(sourceArr) 'traverse source
dict(sourceArr(j, sourceLookupCl)) = Empty
Next j
'check if key exists in dict and copy data
Dim i As Long, ii As Long ': ii = 1
If dict.Exists(Matchkey) Then
For j = sourceStartRw To UBound(sourceArr)
For i = 1 To UBound(sourceArr, 2)
If i = sourceCls(ii) Then
targetArr(j - sourceStartRw + 1, targetCls(ii)) = sourceArr(j, i)
ii = IIf(ii < UBound(sourceCls), ii + 1, ii)
End If
Next i
ii = 0
Next j
End If
reorder = targetArr
End Function

VBA code to list all months between a range of dates

I am new to VBA in Excel. I have looked through through the forum, but have not found an answer for my specific date VBA I am looking for. I have three date ranges in excel cells per row of data elements representing testing dates. Each of the three ranges has a start date and an end date columns A-F.
For each row of test date ranges, I would one cell in column G to calculate the month and year "MMMYY" for any months covered in any of the three date ranges. If the date ranges over three months, the resulting cell would list all three months.
Any help would be greatly appreciated. Thank you in advance.
Marc
Calculated VBA column G
A B C D E F G
1 T1 Start T1 End T2 Start T2 End T3 Start T3 End Months
2 02Nov20 16Nov20 17Nov20 19Nov20 02Nov20 1Jan21 Nov20
Dec20
Jan21
3 28Oct19 15Nov19 28Oct19 01Nov19 28Oct19 1Nov19 Oct20
Nov20
4 20Jul20 21Aug20 Jul20
Aug20
5 11Sep20 29Sep20 20Sep20 22Sep20 20Sep20 Sep20
Here is a macro that outputs ALL of the included month/year.
In order to find the data table, I used the .CurrentRegion property of the cell that contains T1 Start. Because of this, if the output were adjacent to the table, the second run would include that column. Accordingly, I wrote the results one column over (and hid the intervening column. But you could make any number of changes in determining the source table size if that is undesireable.
I also was not certain, from your screenshot, if the Dates were "real Excel Dates" formatted to look like ddmmmyy (except for Column F in your text table) or if they are strings. So there is code to account for the different things I see. Code could be simplified if the data is in a known format.
The output is text strings and the column is formatted as text. If you want the output to be real dates formatted as mmmyy, then code will need to be added so Excel does not erroneously convert 2 digit years to day of the month.
Be sure to read the notes in the macro, as it will help you understand what's going on.
Option Explicit
Sub mthList()
Dim cM As Collection
Dim rg As Range, dStart As Date, dEnd As Date
Dim vSrc As Variant, vRes As Variant
Dim i As Long, J As Long, K As Long
Dim d1 As Double, d2 As Double 'start and end dates
Dim WS As Worksheet, rRes As Range
'Find the table and read it into VBA array
Set WS = ThisWorkbook.Worksheets("Sheet1")
With WS
Set rg = .Cells.Find(what:="T1 Start", after:=.Cells(.Rows.Count, .Columns.Count), _
LookIn:=xlFormulas, lookat:=xlWhole, searchorder:=xlByRows, searchdirection:=xlNext, MatchCase:=False)
If rg Is Nothing Then
MsgBox "No Data Table"
Exit Sub
End If
vSrc = rg.CurrentRegion
ReDim vRes(1 To UBound(vSrc, 1), 1 To 1)
End With
'Collect all the included dates
'Convert date strings to real dates if they are strings
For i = 2 To UBound(vSrc, 1)
Set cM = New Collection
For J = 1 To UBound(vSrc, 2) Step 2 'can have N pairs of dates
If vSrc(i, J) <> "" Then
d1 = theDate(vSrc(i, J)) ' need to make sure this is a date and not a text string
If vSrc(i, J + 1) = "" Then
d2 = d1
Else
d2 = theDate(vSrc(i, J + 1))
End If
On Error Resume Next 'remove duplicates since Collection cannot have two entries with same key
For K = d1 To d2
cM.Add Format(K, "mmmyy"), Format(K, "mmmyy")
Next K
On Error GoTo 0
End If
Next J
'Output the data to results array
For K = 1 To cM.Count
vRes(i, 1) = vRes(i, 1) & vbLf & cM(K)
Next K
vRes(i, 1) = Mid(vRes(i, 1), 2)
Next i
'write the results
'formatting is optional, and Styles may not work with non-English versions
Set rRes = rg.Offset(0, rg.CurrentRegion.Columns.Count + 1)
Set rRes = rRes.Resize(UBound(vRes, 1), UBound(vRes, 2))
With rRes
.EntireColumn.Clear
.EntireColumn.NumberFormat = "#"
.Value = vRes
.WrapText = True
.EntireRow.AutoFit
.EntireColumn.AutoFit
.Style = "output"
.Offset(0, -1).EntireColumn.Hidden = True
End With
With rg.CurrentRegion
.VerticalAlignment = xlCenter
.HorizontalAlignment = xlCenter
.Style = "Input"
End With
End Sub
Private Function theDate(d) As Double
If Not IsDate(d) Then
theDate = CDate(Left(d, Len(d) - 5) & " " & Mid(d, Len(d) - 4, 3) & " " & Right(d, 2))
Else
theDate = d
End If
End Function
EDIT:
To use my algorithm as a function, just need to remove all that stuff with regard to finding the table and writing results back to the worksheet:
Option Explicit
Function mthList(rg As Range) As String
Dim cM As Collection
Dim dStart As Date, dEnd As Date
Dim vSrc As Variant
Dim I As Long, J As Long, K As Long
Dim d1 As Double, d2 As Double 'start and end dates
Dim S As String
'Collect all the included dates
'Convert date strings to real dates if they are strings
vSrc = rg
Set cM = New Collection
For J = 1 To UBound(vSrc, 2) Step 2 'can have N pairs of dates
If vSrc(1, J) <> "" Then
d1 = theDate(vSrc(1, J)) ' need to make sure this is a date and not a text string
If vSrc(1, J + 1) = "" Then
d2 = d1
Else
d2 = theDate(vSrc(1, J + 1))
End If
On Error Resume Next 'remove duplicates since Collection cannot have two entries with same key
For K = d1 To d2
cM.Add Format(K, "mmmyy"), Format(K, "mmmyy")
Next K
On Error GoTo 0
End If
Next J
'Output the data to a string
For K = 1 To cM.Count
S = S & vbLf & cM(K)
Next K
mthList = Mid(S, 2)
End Function
Private Function theDate(d) As Double
If Not IsDate(d) Then
theDate = CDate(Left(d, Len(d) - 5) & " " & Mid(d, Len(d) - 4, 3) & " " & Right(d, 2))
Else
theDate = d
End If
End Function
As said in the comments one could use a dictionary
Function listMthYear(rg As Range) As String
' Goto Tools/Reference and check Microsoft Scripting Runtime
Dim dict As Dictionary
Set dict = New Dictionary
Dim sngCell As Range
For Each sngCell In rg
If IsDate(sngCell.Value) Then
Dim mth As Long
Dim yr As Long
Dim dte As Date
dte = sngCell.Value
mth = VBA.Month(dte)
yr = VBA.year(dte)
dte = VBA.DateSerial(yr, mth, 1)
' This will create an unique entry in the dictionary if not already created
dict(dte) = dte
End If
Next sngCell
Dim output As Variant, i As Long
output = dict.Keys
For i = LBound(output) To UBound(output)
output(i) = Format(output(i), "MMMYY")
Next i
listMthYear = Join(output, vbLf)
End Function
You could use the function as an UDF or like that
Sub TestIt()
Dim rg As Range
Set rg = Range("A3:E3")
MsgBox listMthYear(rg)
End Sub

How to remove leading spaces and/or "/" or "\"

I am new to VBA in Excel. I have a spreadsheet that always has 172 columns. A:FP. It may have 2 to many rows. For every cell in the spreadsheet, I want to remove all leading and trailing spaces along with any leading or trailing "/" or "\". A string can contain a back or forward slash, just not at the beginning or end of the string. My code removes leading and trailing blank spaces. It removes trailing back or forward slashes. However, it does not remove leading slashes. I cannot understand why. Is there a better way of accomplishing my goal? Thank you for your help.
For Each Rng In ActiveSheet.UsedRange
CellVal = Trim(Rng.Value)
LengT = Trim(Len(CellVal))
If CellVal <> "" Then
If Not Rng.HasFormula Then
While Trim(Left(CellVal, 1) = Chr(47)) Or Trim(Left(CellVal, 1) = Chr(92)) Or Trim(Right(CellVal, 1) = Chr(47)) Or Trim(Right(CellVal, 1) = Chr(92))
If Trim(Left(CellVal, 1) = Chr(47)) Or Trim(Left(CellVal, 1) = Chr(92)) Then
CellVal = Trim(Mid(CellVal, 2, LengT))
ElseIf Trim(Right(CellVal, 1) = Chr(47)) Or Trim(Right(CellVal, 1) = Chr(92)) Then
LengT = Len(CellVal)
CellVal = Trim(Left(CellVal, LengT - 1))
Rng.Value = CellVal
LengT = LengT - 1
End If
Wend
End If
End If
Next Rng
First, I'd say try to avoid UsedRange but find a way to get your last used row and column. Then, instead of making a ton of calls to the Worksheet object, I'd run over your values in memory through the use of an array.
Last, you can do many replacements etc. But maybe using a regular expression isn't out of place here. Just for inspirations, I'll put down the following:
Sub Test()
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Sheet1")
Dim lr As Long, lc As Long, x As Long, y As Long
Dim arr As Variant
Dim RegEx As Object: Set RegEx = CreateObject("vbscript.regexp")
'Set up regular expression first
RegEx.Global = True
RegEx.Pattern = "^[ \/\\]*(.*?)[ \/\\]*$"
With ws
lr = .Cells(.Rows.Count, 1).End(xlUp).Row
lc = .Cells(1, .Columns.Count).End(xlToLeft).Column
arr = .Range(.Cells(1, 1), .Cells(lr, lc)).Value
For x = LBound(arr, 1) To UBound(arr, 1)
For y = LBound(arr, 2) To UBound(arr, 2)
If RegEx.Test(arr(x, y)) Then arr(x, y) = RegEx.Execute(arr(x, y))(0).submatches(0)
Next
Next
.Range(.Cells(1, 1), .Cells(lr, lc)).Value = arr
End With
End Sub
So in the end it's reading back the cleaned data to the worksheet.
Regex Demo

Divide a string in a single cell into several cells

I have data that I need to split into individual points. My macro charts the data, as a scatter plot, with: Column A as the title of the chart, Column B as the X axis, and Columns C and D as the Y axis. What I need is for when the Product ID has more than 1 number listed to split the numbers out into their own rows and keep the columns B, C, and D the same for each row created form the original. So for row 167, I would want 3 rows (001,002,003) each with packaging, 200, and 100, in B, C, and D respectively. I am not sure where to begin. I tried to build a macro but, I immediately got tripped up when I tried to record a "Find" Formula to run on the data. Any help would be greatly appreciated.
Column A: 001, 002, 003 // Column B:packaging // Column C:200 // Column D:100
Sorry I couldn't post a screenshot of my data, the forum won't let me. If you have any questions please let me know, I will be sure to check in frequently.
Thanks in advance.
I worte this VERY quickly and without much care for efficiency, but this should do the trick:
Sub SplitUpVals()
Dim i As Long
Dim ValsToCopy As Range
Dim MaxRows As Long
Dim ValToSplit() As String
Dim CurrentVal As Variant
MaxRows = Range("A1").End(xlDown).Row
For i = 1 To 10000000
ValToSplit = Split(Cells(i, 1).Value, ",")
Set ValsToCopy = Range("B" & i & ":D" & i)
For Each CurrentVal In ValToSplit
CurrentVal = Trim(CurrentVal)
Cells(i, 1).Value = CurrentVal
Range("B" & i & ":D" & i).Value = ValsToCopy.Value
Cells(i + 1, 1).EntireRow.Insert
i = i + 1
MaxRows = MaxRows + 1
Next
Cells(i, 1).EntireRow.Delete
If i > MaxRows Then Exit For
Next i
End Sub
As a note, make sure there's no data in cells beneath your data as it might get deleted.
You will need to parse the data in column A. I would do this by splitting the string in to an array, and then iterate over the array items to add/insert additional rows where necessary.
Without seeing your worksheet, I would probably start with something like this, which will split your cell value from column A in to an array, and then you can iterate over the items in the array to manipulate the worksheet as needed.
Sub TestSplit()
Dim myString as String
Dim myArray() as String
Dim cell as Range
Dim i as Long
For each cell in Range("A2",Range("A2").End(xlDown))
myString = cell.Value
myArray = Split(myString, ",") '<-- converts the comma-delimited string in to an array
For i = lBound(myArray) to uBound(myArray)
If i >= 1 Then
'Add code to manipulate your worksheet, here
End If
Next
Next
End Sub
This is a better solution (now that I had more time :) ) - Hope this does the trick!
Sub SplitUpVals()
Dim AllVals As Variant
Dim ArrayIndex As Integer
Dim RowLooper As Integer
AllVals = Range("A1").CurrentRegion
Range("A1").CurrentRegion.Clear
RowLooper = 1
For ArrayIndex = 1 To UBound(AllVals, 1)
ValToSplit = Split(AllVals(ArrayIndex, 1), ",")
For Each CurrentVal In ValToSplit
CurrentVal = Trim(CurrentVal)
Cells(RowLooper, 1).Value = CurrentVal
Cells(RowLooper, 2).Value = AllVals(ArrayIndex, 2)
Cells(RowLooper, 3).Value = AllVals(ArrayIndex, 3)
Cells(RowLooper, 4).Value = AllVals(ArrayIndex, 4)
RowLooper = RowLooper + 1
Next
Next ArrayIndex
End Sub
Sub DivideData()
'This splits any codes combined into the same line, into their own separate lines with their own separate data
Dim a, b, txt As String, e, s, x As Long, n As Long, i As Long, ii As Long
With Range("a1").CurrentRegion
a = .Value
txt = Join$(Application.Transpose(.Columns(1).Value))
x = Len(txt) - Len(Replace(txt, ",", "")) + .Rows.Count
ReDim b(1 To x * 2, 1 To UBound(a, 2))
For i = 1 To UBound(a, 1)
For Each e In Split(a(i, 1), ",")
If e <> "" Then
For Each s In Split(e, "-")
n = n + 1
For ii = 1 To UBound(a, 2)
b(n, ii) = a(i, ii)
Next
b(n, 1) = s
Next
End If
Next
Next
With .Resize(n)
.Columns(1).NumberFormat = "#"
.Value = b
End With
End With
End Sub

Resources