i have text content in the first cell of each row. it is basically a paragraph. i want to split this paragraph into different cells, in the same row.
Definition: Photosynthesis is a process used by plants and other organisms to convert light energy, normally from the Sun, into chemical energy that can be later released to fuel the organisms activities. Working: In photosynthetic bacteria, the proteins that gather light for photosynthesis are embedded in cell membranes. In its simplest form, this involves the membrane surrounding the cell itself. Evolution: Early photosynthetic systems, such as those from green and purple sulfur and green and purple nonsulfur bacteria, are thought to have been anoxygenic, using various molecules as electron donors.
this content is present in cell a1. i want to split it into 3 cells
cell a2
"Definition: Photosynthesis is a process used by plants and other organisms to convert light energy, normally from the Sun, into chemical energy that can be later released to fuel the organisms activities."
cell a3
"Working: In photosynthetic bacteria, the proteins that gather light for photosynthesis are embedded in cell membranes. In its simplest form, this involves the membrane surrounding the cell itself."
cell a4
"Evolution: Early photosynthetic systems, such as those from green and purple sulfur and green and purple nonsulfur bacteria, are thought to have been anoxygenic, using various molecules as electron donors."
first cell goes on from text Definition: ---- Working: (this includes the text "Definition:" and does not include "Working:")
second cell goes on from Working: ------- Evolution: (this includes the text "Working:" and does not include "Evolution:")
third cell from Evolution: ------- endof string.
Being that you tagged this as Excel-vba also I thought I would post a VBA solution for you. This UDF hopefully covers your needs.
Function SplitString(MyString As String, PartNum As Long)
Dim MyNewString As String, DefNames As Variant, DefNamesOn As Boolean
DefNamesOn = True
DefNames = Array("Definition: ", "Working: ", "Evolution: ")
MyNewString = Split(MyString, ":")(PartNum)
If DefNamesOn Then
SplitString = DefNames(PartNum - 1)
Else
SplitString = ""
End If
If Right(UCase(MyNewString), 8) = " WORKING" Then
SplitString = SplitString & Trim(Left(MyNewString, Len(MyNewString) - 8))
ElseIf Right(UCase(MyNewString), 10) = " EVOLUTION" Then
SplitString = SplitString & Trim(Left(MyNewString, Len(MyNewString) - 10))
Else
SplitString = SplitString & Trim(MyNewString)
End If
End Function
You can change DefNamesOn = True to False if you don't want "Definition: ", "Working: " or "Evolution: " at the start
Use it like any other formula: =SplitString(A1,1) where A1 has your string and 1 is the number of the part you want (1, 2 or 3)
You can chop a bit out of the code if you always want DefNames on or off but I thought it better to give you the option in the code.
Another VBA solution:
Option Explicit
Public Sub extractPara()
Dim lRow As Long, ur As Variant, arr As Variant
Dim i As Long, j As Long, x2 As Long, x3 As Long
With ActiveSheet
lRow = .Range("A" & .Rows.Count).End(xlUp).Row: j = 1
ur = .Range("A1:A" & lRow).Value2
arr = .Range("A1:A" & lRow * 4).Value2
For i = 1 To lRow
x2 = InStr(1, ur(i, 1), "Working:", vbBinaryCompare)
x3 = InStr(1, ur(i, 1), "Evolution:", vbBinaryCompare)
arr(j + 0, 1) = ur(i, 1)
arr(j + 1, 1) = Left(ur(i, 1), x2)
arr(j + 2, 1) = Mid(ur(i, 1), x2, x3)
arr(j + 3, 1) = Mid(ur(i, 1), x3)
j = j + 4
Next
.Range("A1:A" & lRow * 4) = arr
End With
End Sub
Using FIND() and MID() you should be able to parse this.
Disclaimer: The solution below assumes that you will always have the strings "Definition", "Working", and "Evolution" in each paragraph you wish to parse.
FIND returns a number based on the position of the character starting from the designated position, in this case, the first character, 1.
In A2 use this formula:
=LEFT(A1,FIND("Working:",A1,1)−1)
This searches for "Working:" and returns its position. In this case character number 206. The -1 omits the "W" in working from being returned as it is character #206. We want to end at the character before "W".
In A3 use this formula:
=MID(A1,FIND("Working:",A1,1),FIND("Evolution:",A1,1)-FIND("Working:",A1,1))
Now we are looking for a start and end character position. We have to use subtraction to get the string length.
In A4 use this formula:
=MID(A1,FIND("Evolution:",A1,1),FIND("Working:",A1,1))
Middle requires a start and end character position.
Bonus: to eliminate any extra white space at the beginning or end, wrap the formulas in the TRIM() function. Exampple: =TRIM(MID(A1,FIND("Working:",A1,1),FIND("Evolution:",A1,1)-FIND("Working:",A1,1)))
googled alot about this.
got something that worked for me.
=MID(A1,SEARCH("Definition:",A1),SEARCH("Working:",A1)-SEARCH("Definition:",A1))
this got me the result in cell a2
Working: In photosynthetic bacteria, the proteins that gather light for photosynthesis are embedded in cell membranes. In its simplest form, this involves the membrane surrounding the cell itself.
Related
I have a chart with a text-column with numerous entries per cell.
Entries are separated with “;”.
Entries have the format “xy 00/00” (e.g. “AB 03/18”).
I need Excel to find and give in the next column a specific entry I predefine per row (above the column, example below).
Only the first two and last two characters are defined, the characters in the middle can be whatever (e.g. “AB ??/18”).
A cell can have more than one entry with the definition of “AB ??/18” (e.g. “AB 03/18” & “AB 08/18” etc.).
I need to know, if there are more than 1 of this predefined entries.
If I change the search box to “ZZ ??/12”, it should overwrite the previous defined search and give me back only the ZZ… ones.
For example:
Screenshot Chart
I tried a formula, but it gives me the first AB…, not the rest.
If it is only possible to give back the amount of the searched text in the cell above, that would also be ok.
Your screenshot doesn't seem entirely consistent with your objective, i.e.
the pattern AB ##/18 can be found 3 times in the string
blabla WF 12/23; AB 08/18; AB 09/18; AB 08/18
but your count column registers only 1 result (for AB 08/18)- there is also a match in the 1st row (for AB 12/18), but there you have a count of 0...
The code below assumes that the 4 data cells from your screenshot are in the range A3:A6 and that they are not part of a table
Sub txtMatching()
Dim results As String, cell As Range, incidence As Integer, pattern As String, pos As Integer, temp As String
pattern = "AB ##/18"
For Each cell In Range("A3:A6")
pos = 1
If cell.Value Like "*" & pattern & "*" Then
Do
pos = InStr(pos, cell.Value2, Mid(pattern, 1, InStr(1, pattern, "#") - 1))
If pos = 0 Then Exit Do
temp = Mid(cell.Value2, pos, Len(pattern))
If temp Like pattern Then
results = results & temp & "; "
incidence = incidence + 1
End If
pos = pos + Len(pattern)
Loop While pos < Len(cell.Value2)
cell.Offset(0, 1).Resize(1, 2).Value2 = Array(Mid(results, 1, Len(results) - 2), incidence)
results = vbNullString
incidence = 0
Else
cell.Offset(0, 2).Value2 = 0
End If
Next cell
End Sub
I looked for several hours for a satisfactory answer to this question and couldn't find one, so I rolled my own.
For example, suppose cell A1 = "word1", A2 = "word2", A3 = "word3", and A4 = "word4."
I want B1 to be "word1 word2 word3 word4 "
If none, any, or all the words in column A are bold, I want that reflected in B1. Like this:
partial sheet image
Sub test1()
Dim Row As Integer
Dim Start As Integer
Dim Length As Integer
' concatenate the words with a space between each
Range("B1").Value = ""
For Row = 1 To 4
Range("B1").Value = Range("B1").Value & " " & Cells(Row, "A").Value
Next Row
' match bold formatting
Start = 1
For Row = 1 To 4
Length = Len(Cells(Row, "A").Value)
Range("B1").Characters(Start, Length + 1).Font.Bold = Cells(Row, "A").Font.Bold
Start = Start + Length + 1
Next Row
End Sub
I found I needed two separate loops to make this work. With one loop, Excel made bold all the words following the first bold one, except the last word if it was not bold.
Why did I need (Start, Length + 1) in the code above?
I know this is not an exact answer but maybe can provide you ideas:
With ActiveCell.Characters(Start:=13, Length:=6).Font
.FontStyle = "Bold"
End With
You need to find how to set your Start and Length values using the functions that fit your needs.
The usage of Length + 1 makes that select all the text in your cell before Start.
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
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)))
I have received a worksheet in Excel which contains kids names and video time tags all in one column, and I need to sort this into a logical format so I can use it. However, the list has no separators.. So I am hoping someone could help me out with a VBA Excel macro.
Below is an example (shortened) string, lets say this is in Cell A1.
" Sandy 25:1132:27Giorgio
09:1114:7Anne Marie 32:10David 17:48Marty
04:3506:1010:3613:1014:32Sandy (2) 04:30Brian 13:4714:37"
I would ideally like for the string to be split up into cells as follows
Cell A2 Sandy
Cell A3 25:11
Cell A4 32:27
Cell A5 Giorgio
Cell A6 09:11
Cell A7 14:7
Cell A8 Anne Marie
Cell A9 32:10
Cell A10 David
Cell A11 17:48
Cell A12 Marty
Cell A13 04:35
Cell A14 06:10
Cell A15 10:36
Cell A16 13:10
Cell A17 14:32
Cell A18 Sandy (2)
Cell A19 04:30
Cell A20 Brian
Cell A21 13:47
Cell A22 14:37
I have tried using some basic "find" and "len" formulas but no luck..
Doesn't do exactly what you want - but it may help get you going in a direction... Hopefully it'll turn out to be the right one...
I pasted your string into cell A1 in my worksheet and then wrote this code in a module in the sheet:-
Function parseText(ByVal text As String, ByVal domain As Integer) As String
Dim returnValue As String
Dim colon As Integer
Dim soFar As Integer
soFar = 0
text = Trim(text)
While soFar < domain
colon = InStr(text, ":")
While (Mid(text, colon + 5, 1) = ":")
colon = colon + 5
Wend
returnValue = Mid(text, 1, colon + 2)
While Not (IsNumeric(Right(returnValue, 1)))
returnValue = Left(returnValue, Len(returnValue) - 1)
Wend
text = Replace(text, returnValue, "")
soFar = soFar + 1
Wend
parseText = returnValue
End Function
Function parseDomain(ByVal domain As String) As String
Dim returnValue As String
Dim part As String
While Len(domain) > 0
part = ""
If InStr(domain, ":") > 0 Then
part = Mid(domain, InStrRev(domain, ":") - 2, 5)
returnValue = part & "~" & returnValue
domain = Left(domain, Len(domain) - Len(part))
End If
If part = "" Then
returnValue = Trim(domain) & "~" & Left(returnValue, Len(returnValue) - 1)
domain = ""
End If
Wend
parseDomain = returnValue
End Function
Function pullPiece(ByVal block As String, ByVal piece As Integer) As String
Dim returnValue As String
Dim pieces() As String
pieces = Split(block, "~")
If piece > UBound(pieces) + 1 Then
returnValue = ""
Else
returnValue = pieces(piece - 1)
End If
pullPiece = returnValue
End Function
This bit is complicated to explain...
In the image below the formula in A14 is the content of cell A4. The formula in A15 is the content of cell A5, etc. all the way down to A10. These formulae break out the block of text for each name.
The formula in B14 is the content of B4. This cell can then be copied down the range to B10 so that the references change to A4 thru A10. These formulae reformat the text with tildes so that the text is easier to split up (later).
The formula in C14 is the contents of C4. This cell can be copied down to C10. This pulls the name from the block it relates to. The second parameter is the "piece" number - 1=name, 2=time1, 3=time2, etc.
The formula in D14 is the contents of cells D4 and pulls the first time out of the block it relates to. I haven't put the definition for the other formulae - but hopefully you can see the pattern on how they are used.
Drop me a message if you want any clarification.
The string is difficult to parse due to the timestamps not appearing to follow a similar format. For example most follow the format 00:00, however the value you wish to place in cell A7 only has a single digit following the colon. I have therefore created some code to get you started in the right direction, but this works on the assumption of the format 00.00 and currently doesn't parse text following numbers. But if you perform a bit more research I'm sure you can complete from this point:
Public Sub TestCode()
Dim strTest As String, strModify() As String, strNew() As String, x As Long
strTest = "Sandy 25:1132:27Giorgio 09:1114:7Anne Marie 32:10David 17:48Marty 04:3506:1010:3613:1014:32Sandy (2) 04:30Brian 13:4714:37"
strModify = Split(strTest)
ReDim strNew(0 To 0)
strNew(0) = strModify(0)
For x = 1 To UBound(strModify)
If Left(strModify(x), 1) Like "[A-Z]" Then
ReDim Preserve strNew(0 To (UBound(strNew) + 1))
strNew(UBound(strNew)) = strModify(x)
ElseIf Left(strModify(x), 1) Like "[0-9]" Then
Do Until InStr(1, strModify(x), ":") = 0
ReDim Preserve strNew(0 To (UBound(strNew) + 1))
strNew(UBound(strNew)) = Left(strModify(x), InStr(1, strModify(x), ":") + 2)
strModify(x) = Right(strModify(x), Len(strModify(x)) - (InStr(1, strModify(x), ":") + 2))
Loop
Else
strNew(UBound(strNew)) = strNew(UBound(strNew)) & " " & strModify(x)
End If
Next x
For x = 0 To UBound(strNew)
Range("A1").Offset(0, x).Value = strNew(x)
Next x
End Sub
To help you understand the code in order to modify, this is basically splitting the original string wherever there is a space (result placed in array called strModify). It then checks the first character in the string to see if it is a letter, number or other character. Based on this information it will place the individual components of the string in to a new array variable called strNew. It then simply reads this array and places each item in to the next available cell.
I hope this helps you begin. Once you have a solution please post your final code on here in order to help others who may have a similar problem.