I have about 800 rows of data in a single column. The data in the column looks like this:
|Column A |
|195Marriott International127,500|
How can I have excel break this out into columns so it looks like as follows:
|Column A| |Column B| |Column C|
|195| |Marriott International| |127,500|
Thank you!
EDIT:
But you do have some patterns that you can use. Note that you have numbers in the first and third column items. Select column A, extract last character with =RIGHT(). You will only need 9 replacements to make (1 - 9), then concatenate the value. Do the same with the first number in the 3rd Column. You will then have delimiting values to use text to column.
====
you can use the Text to Column tool under the data tab on excel.
You can split the contents of one or more cells in a column, and then distribute those contents as individual parts across other cells in adjacent columns. For example, if your worksheet contains a column of full names, you can split that column into separate first name and last name columns.
I see you found a solution from Solar Mike's comment, but here's an alternative.
Below is a short piece of VBA that will preprocess the data, inserting a delimiter that will work. I tested it on a limited amount of data, so it may generate errors that need to be corrected.
The VBA ...
Option Explicit
Sub MakeDelimiters()
Dim LastRow As Long, iLoop As Long
Dim myDelim As String, myStr As String
Dim theRng As Range, theSht As Worksheet, theCell As Range
myDelim = ";"
Set theSht = Worksheets("Sheet1")
LastRow = theSht.Range("A" & theSht.Rows.Count).End(xlUp).Row
Set theRng = theSht.Range("A1:A" & LastRow)
For Each theCell In theRng
myStr = theCell.Value
For iLoop = 1 To Len(myStr)
If IsNumeric(Mid(myStr, iLoop, 1)) And _
Not IsNumeric(Mid(myStr, iLoop + 1, 1)) And _
Mid(myStr, iLoop + 1, 1) <> "," Then
myStr = Left(myStr, iLoop) & myDelim & Right(myStr, Len(myStr) - iLoop)
End If
If IsNumeric(Mid(myStr, iLoop + 1, 1)) And _
Not IsNumeric(Mid(myStr, iLoop, 1)) And _
Mid(myStr, iLoop, 1) <> "," And _
Mid(myStr, iLoop, 1) <> myDelim Then
myStr = Left(myStr, iLoop) & myDelim & Right(myStr, Len(myStr) - iLoop)
End If
Next iLoop
theCell.Value = myStr
Next theCell
End Sub
Converted this ...
to this ...
UPDATE:
The idea that a future visitor's data would look oversimplified ...
Is the lhs always 3 numbers, never 2 or 4? And the right 3,3? -SolarMike
... is laughable. So I came up with this solution. This answer is predicated on the comments:
Are columns A and C always going to be numeric? Or more precisely, will column A always end with a number, and will column C always start with a number? – OldUgly
#OldUgly - yes, that is the case here – BigMike
To answer your original question about "Text to Columns", I have no idea. However, this was tagged excel-formula, so I gave it a shot and came up with this ...
... which assumes you really want the data in columns A-C. The two helper array formulas (Ctrl+Shift+Enter)in E2 and F2 respectively are ...
=MIN(FIND(0,SUBSTITUTE(D2,CHAR(ROW(INDIRECT("65:90"))),0)&0))
=MIN(FIND(0,SUBSTITUTE(D2,CHAR(ROW(INDIRECT("48:57"))),0)&0,E2+1))
The formulas in A2, B2, and C2 respectively are (pretty obvious) ...
=LEFT(D2,E2-1)
=MID(D2,E2,F2-E2)
=RIGHT(D2,LEN(D2)-F2)
Ah, good old ASCII tables
Related
The TextToColumns method of the Range object automatically converts strings to numbers, but it would be nice to suppress this feature. The method has a TextQualifier parameter, but it doesn't seem to do what I'm looking for. The following data illustrates the issue. Strings in column A are delimited with semicolons that separate a text part from a number part. Note that the numbers all begin with zero, and that numbers in row 4-6 are prefixed with an apostrophe:
Column A
StringRow1;01000
StringRow2;02000
StringRow3;03000
StringRow4;'01000
StringRow5;'02000
StringRow6;'03000
The following macro splits the strings into a text part in Column B and a number part in Column C.
Sub TTC()
Application.DisplayAlerts = False
Dim rToSplit As Range
Set rToSplit = ThisWorkbook.Worksheets(1).Range("A1:A6")
rToSplit.TextToColumns _
Destination:=Range("B1"), _
DataType:=xlDelimited, _
Semicolon:=True, _
TextQualifier:=xlTextQualifierNone
End Sub
The last column illustrates the desired output:
Column A Column B Column C
Data Output Output Desired Output
StringRow1;01000 StringRow1 1000 01000
StringRow2;02000 StringRow2 2000 02000
StringRow3;03000 StringRow3 3000 03000
StringRow4;'01000 StringRow4 '01000 01000
StringRow5;'02000 StringRow5 '02000 02000
StringRow6;'03000 StringRow6 '03000 03000
I have tried formatting column C ahead of the split, like this:
rToSplit.Offset(, 3).NumberFormat = "#", but it has no effect. Switching the TextQualifier parameter to xlTextQualifierSingleQuote has the effect of treating rows 4-6 in the same way as rows 1-3.
Am I asking for the impossible? Or is there maybe some application level setting I'm not aware of? Or could I do something smart with the strings in column A?
(I could of course loop through Column C after the split and fix the issue, but for large data sets that's not attractive. For my particular application, the strings in column A are generated by code that searches for patterns in tens of thousands of text rows in several different text files; each match is added to a dictionary and then I use array() = Dictionary.Items and DestinationRange.Value = Application.WorksheetFunction.Transpose(array) to read the data to the worksheet. This is very fast. My workaround to deal with the issue described here is to save the number strings in a separate dictionary which is read to column C after the split. This works well, so I posted this out of curiosity to see what I can learn...)
You can use the FieldInfo property to set the data type for each column. You will need to know how many columns you have beforehand though, or know which column will contain the numbers.
The FieldInfo parameter takes an array of arrays, with each of the sub-arrays having 2 values. The first value represents the column number (starting at 1), and the second number is the XLColumnDataType you would like that column to be formatted as.
In this case, you'd like everything to be formatted as text (instead of a number, like it's currently doing), so you would use xlTextFormat (this is just a system defined constant equal to 2).
x.TextToColumns _
Destination:=Range("B1"), _
DataType:=xlDelimited, _
Semicolon:=True, _
TextQualifier:=xlTextQualifierNone, _
FieldInfo:=Array(Array(1, xlTextFormat), Array(2, xlTextFormat)) 'Format columns 1 and 2 as text
If you are willing to do it with a loop:
Sub TTC()
Dim row As Long, lastRow As Long, splitSpot As Integer, cellValue As String
Application.ScreenUpdating = False
With ThisWorkbook.Worksheets(1)
lastRow = .Cells(.Rows.Count, "A").End(xlUp).row
For row = 1 To lastRow
cellValue = CStr(.Range("A" & row).Value)
splitSpot = InStr(cellValue, ";")
.Range("B" & row & ":C" & row).NumberFormat = "#"
.Range("B" & row).Value = Left(cellValue, splitSpot - 1)
If Mid(cellValue, splitSpot, 1) = "'" Then
.Range("C" & row).Value = Right(cellValue, Len(cellValue) - splitSpot + 1)
Else
.Range("C" & row).Value = Right(cellValue, Len(cellValue) - splitSpot)
End If
Next
End With
End Sub
ss:
I am looking for a way to extract text between 2 characters and copy them to a column at the end of the spreadsheet.
For example, my text looks like [abcdefg], all in Column A, I am looking to extract the text between the "[" and copy it to a new column at the end of the worksheet (as a new column)
Thanks
I would resort to functions since they're just the easiest. To pull the data between 2 characters, you'd use a mixture of MID and FIND functions.
So, assuming your data was in cell A1, you could put this formula in the cell where you want the parsed value:
=MID(A1,FIND("[",A1)+1,FIND("]",A1)-FIND("[",A1)-1)
If you wanted to automate it, you could put it into a macro then copy / paste-special values to remove the function and keep the values.
This is for text in Cell 1, 1 but you can toss some variables in there as you loop through your rows. It will grab the values within square brackets & trim it, additional text can be in front or behind the brackets.
Dim iPos1 As Integer
Dim iPos2 As Integer
iPos1 = InStr(Sheet1.Cells(1, 1), "[")
iPos2 = InStr(Sheet1.Cells(1, 1), "]")
Sheet1.Cells(1, 2) = Trim(Mid(Sheet1.Cells(1, 1), iPos1 + 1, iPos2 - iPos1 - 1))
If you want to write this into a vba module, looping through all entries in the A column and extracting the text inside the [] into an entry in column B, it might look something like:
Dim ws as Worksheet
Dim i as integer
Dim lastRow as Integer
Dim brack1pos as Integer
Dim brack2pos as Integer
Set ws = ThisWorkbook.Worksheets("My Sheet Name")
for i = 1 to lastRow 'I'll leave to you how to find the last row
brack1pos = InStr(ws.Range("A" & i), "[")
brack2pos = InStr(ws.Range("A" & i), "]")
ws.Range("B" & i) = Trim(Mid(ws.Range("A" & i), brack1pos + 1, brack2pos - brack1pos - 1))
next
I have a spreadsheet with a load of random text and numbers in column A like so:
Column A
Row 1 = 471806121601 5205569 - 0007 Standard White Toilet Tissue 27
Row 2 = 471814121601 5206177 - 0014 Premium White Toilet Tissue 6
Row 3 = 471814121601 5206178 - 0007 Premium White Toilet Tissue 27
Row 4 = 471806121601 5206180 - 0014 Premium Kitchen Towel 2x75l 6
I have about 2000 lines in total. In each cell, is a Purchase order number (12 digits) and an item number next to it (7 digits).
I am trying to extract the po number and put it into column B and extract the item number and put it into column C
Column B Column C
471806121601 5205569
471814121601 5206177
471814121601 5206178
471806121601 5206180
Here is my code:
Option Explicit
Sub main()
Dim cell As Range
Dim arr As Variant, arrElem As Variant
With Worksheets("Orders") '<--| change "Strings" to your actual worksheet name
For Each cell In .Range("A1", .Cells(.Rows.Count, "A").End(xlUp))
arr = Split(Replace(cell.Value, " ", " "), " ") '<--| change "A"'s to your actual relevant column index
For Each arrElem In arr
If IsNumeric(arrElem) Then
If Len(arrElem) = 12 Then cell.Offset(0, 1).Value = arrElem
End If
Next arrElem
Next cell
End With
Dim cell2 As Range
Dim arr2 As Variant, arrElem2 As Variant
With Worksheets("Orders") '<--| change "Strings" to your actual worksheet name
For Each cell2 In .Range("A1", .Cells(.Rows.Count, "A").End(xlUp))
arr2 = Split(Replace(cell2.Value, " ", " "), " ") '<--| change "A"'s to your actual relevant column index
For Each arrElem2 In arr2
If IsNumeric(arrElem2) Then
If Len(arrElem2) = 7 Then cell2.Offset(0, 3).Value = arrElem2
End If
Next arrElem2
Next cell2
End With
End Sub
This code does work. However it takes absolutely ages and only does one line at a time...Slowly.
Is there a quicker way of doing this? Thanks
If your PO and IN are always the same length in col B put
=MID(A2, 1, 12)
And in col C
=MID(A2, 14, 7)
However if your number change but are always the first two swap the above for,
=MID(A2,1,FIND(" ",A2,1)-1)
And
=MID(A2, FIND(" ", A2, 1)+1, 7)
Respectively.
just use split(string,delimiter)(0) and (1) why replace the space, just use that as the delim. If Row # is in, then use (1) and (2), or you could consider split(split(input,"-")," ") maybe a little faster, not sure though. Also, once you're done no need to complete the loop, so consider, do until with flags rather than for next, although exit for is available
Formula wise, it could be done using something like this
=MID(D1,FIND("é",SUBSTITUTE(D1," ","é",3)),FIND("é",SUBSTITUTE(D1," ","é",4))-FIND("é",SUBSTITUTE(D1," ","é",3)))
and
=MID(D1,FIND("é",SUBSTITUTE(D1," ","é",4)),FIND("é",SUBSTITUTE(D1," ","é",5))-FIND("é",SUBSTITUTE(D1," ","é",4)))
Good afternoon all,
I have an issue where I have users who have multiple bank account details. I need to try and create a new row for each employee who has more than one bank account, with the second bank account being allocated a new row.
Employee Number User ID BSB Account number
10000591 WOODSP0 306089,116879 343509,041145273
10000592 THOMSOS0 037125 317166
I need it to look something like this:
Employee Number User ID BSB Account number
10000591 WOODSP0 306089 343509
10000591 WOODSP0 116879 041145273
10000592 THOMSOS0 037125 317166
Any thoughts? Your input is greatly appreciated!
Screenshots are here to demonstrate:
Right click on the tab and choose "View Code"
Paste this code in:
Sub SplitOnAccount()
Dim X As Long, Y As Long, EmpNo As String, UserID As String, BSB As Variant, AccNo As Variant
Range("F1:I1") = Application.Transpose(Application.Transpose(Array(Range("A1:D1"))))
For X = 2 To Range("A" & Rows.Count).End(xlUp).Row
EmpNo = Range("A" & X).Text
UserID = Range("B" & X).Text
BSB = Split(Range("C" & X).Text, ",")
AccNo = Split(Range("D" & X).Text, ",")
For Y = LBound(AccNo) To UBound(AccNo)
Range("F" & Range("F" & Rows.Count).End(xlUp).Row).Offset(1, 0).Formula = EmpNo
Range("G" & Range("G" & Rows.Count).End(xlUp).Row).Offset(1, 0).Formula = UserID
Range("H" & Range("H" & Rows.Count).End(xlUp).Row).Offset(1, 0).Formula = BSB(Y)
Range("I" & Range("I" & Rows.Count).End(xlUp).Row).Offset(1, 0).Formula = AccNo(Y)
Next
Next
End Sub
Close the window to go back to excel
Press ALT-F8
Choose SplitOnAccount and click run.
Note, this is going to populate the split data to rows F to I, make sure there is nothing in there. If there is post back and we can change it.
Also format columns F - I as text before you run it or Excel will strip leading zeros off as it will interpret it as a number.
Here is another sub that appears to perform what you are looking for.
Sub stack_accounts()
Dim rw As Long, b As Long
Dim vVALs As Variant, vBSBs As Variant, vACTs As Variant
With ActiveSheet '<-define this worksheet properly!
For rw = .Cells(Rows.Count, 1).End(xlUp).Row To 2 Step -1
vVALs = .Cells(rw, 1).Resize(1, 4).Value
vBSBs = Split(vVALs(1, 3), Chr(44))
vACTs = Split(vVALs(1, 4), Chr(44))
If UBound(vBSBs) = UBound(vBSBs) Then
For b = UBound(vBSBs) To LBound(vBSBs) Step -1
If b > LBound(vBSBs) Then _
.Rows(rw + 1).Insert
.Cells(rw - (b > LBound(vBSBs)), 1).Resize(1, 4) = vVALs
.Cells(rw - (b > LBound(vBSBs)), 3).Resize(1, 2).NumberFormat = "#"
.Cells(rw - (b > LBound(vBSBs)), 3) = CStr(vBSBs(b))
.Cells(rw - (b > LBound(vBSBs)), 4) = CStr(vACTs(b))
Next b
End If
Next rw
End With
End Sub
I was originally only going to process the rows that had comma delimited values in columns C and D but I thought that processing all of them would allow the macro to set the Text number format and get rid of the Number as text error warnings and keep the leading zero in 041145273.
You Can definitely use Power Query to transform the data to generate new rows using split column option.
Check this article it explains the process in detail.
Load Data in Power Query section of excel.
Create an Index (Not required step)
Use Split column function with advance options and split them into new rows.
Save this result into new table for your use.
I did it myself and it worked like a charm.
A formula solution:
Delimiter: Can be a real delimiter or an absolute reference to a cell containing only the delimiter.
HelperCol: I have to use a helper column to make it work. You need to give the column letter.
StartCol: The column letter of the first column containing data.
SplitCol: The column letter of the column to be splitted.
Formula1: Used to generate the formula for the first column not to be splitted. You can fill this formula down and then fill to right.
Formula2: Used to generate the formula for the column to be splitted(only support split one column).
Formula3: Used to generate the formula for the Helper column.
(If the title of the column to be splitted contains the delimiter, you must change the first value of the helper column to 1 manually.)
Formula1:=SUBSTITUTE(SUBSTITUTE("=LOOKUP(ROW(1:1),$J:$J,A:A)&""""","$J:$J","$"&B2&":$"&B2),"A:A",B3&":"&B3)
Formula2:=SUBSTITUTE(SUBSTITUTE(SUBSTITUTE("=MID($M$1&LOOKUP(ROW(A1),$J:$J,F:F)&$M$1,FIND(""艹"",SUBSTITUTE($M$1&LOOKUP(ROW(A1),$J:$J,F:F)&$M$1,$M$1,"&"""艹"",ROW(A2)-LOOKUP(ROW(A1),$J:$J)))+1,FIND(""艹"",SUBSTITUTE($M$1&LOOKUP(ROW(A1),$J:$J,F:F)&$M$1,$M$1,""艹"",ROW(A2)-LOOKUP(ROW(A1),$J:$J)+1))-FIND(""艹"",SUBSTITUTE($M$1&LOOKUP(ROW(A1),$J:$J,F:F)&$M$1,$M$1,""艹"",ROW(A2)-LOOKUP(ROW(A1),$J:$J)))-1)&""""","$M$1",IF(ISERROR(INDIRECT(B1)),""""&B1&"""",B1)),"$J:$J","$"&B2&":$"&B2),"F:F",B4&":"&B4)
Formula3:=SUBSTITUTE(SUBSTITUTE(SUBSTITUTE("=SUM(E1,LEN(B1)-LEN(SUBSTITUTE(B1,$H$1,"""")))+1","B1",B4&1),"$H$1",IF(ISERROR(INDIRECT(B1)),""""&B1&"""",B1)),"E1",B2&1)
Helper must filled one row more than the data.
How to use:
Copy the formula generated by the above three formula.
Use Paste Special only paste the value.
Make the formula into effect.
Fill the formula.
Bug:
Numbers will be converted to Text. Of course you can remove the &"" at the end of the formula, but blank cells will be filled with 0.
ps. This method may by very hard to comprehend. But once you master it, it can be very useful to solve relative problems.
Consider the following Excel sheet:
A B C
1 ASX:ANZ ANZ:ASX http://www.site.com/page?id=ANZ:ASX
2 DOW:1234 1234:DOW http://www.site.com/page?id=1234:DOW
3 NASDAQ:EXP EXP:NASDAQ http://www.site.com/page?id=EXP:NASDAQ
I need a formula for the B and the C column. In the B column I need the values of the A column to be split on : and the two resulting parts to be reversed, see the three examples. In the C column, I need the result from B to be added to a (hardcopy) URL (http://www.site.com/page?id=) to form a link.
Who can help me out? Your help is greatly appreciated!
Alright. I don't normally spoon feed answers but here you go.
In B:
=MID(A1, FIND(":", A1, 1)+1, LEN(A1) - FIND(":",A1,1)) & ":"&MID(A1,1,FIND(":",A1,1)-1)
In C:
=HYPERLINK("http://www.site.com/page?id="&B1)
=hyperlink("http://www.site.com/page?id="&B1) *english version *
The loop looks something like his:
Dim row As Integer
Dim snumber As Variant
Dim TestCell As String
Dim lastcell As Integer
Sheets("data").Select
lastcell = Sheets("data").Cells(Rows.Count, "A").End(xlUp).row
For row = 1 To lastcell
TestCell = "A" & row
snumber = Range(TestCell).Value
If snumber <> "" And snumber <> "0" Then
Range(TestCell).Select
ActiveSheet.Hyperlinks.Add Anchor:=Selection, Address:= _
"url goes here", TextToDisplay:=snumber
End If
Next row