How to Split text and loop to next row - excel

I'm using the split function to split text using spaces. I have gotten my macro to split the text but I am having difficulties getting the loop to move to the next row below to split.
Sub Split_Text_Test1()
Dim Txt As String
Dim i As Integer
Dim FullName As Variant
Range("A1").Select
Txt = ActiveCell.Value
FullName = Split(Txt, " ")
For i = 0 To UBound(FullName)
Cells(1, i + 1).Value = FullName(i)
Next i
End Sub

You probably need to change the bit inside your loop thus as you are starting at A1. This assumes you want the entries in A2 and down. Not generally advisable to use Select/Activate, not very robust.
Edited to move across columns rather than down rows.
For i = 0 To UBound(FullName)
Range("A1").Offset(,i + 1).Value = FullName(i)
Next i
That said, you can avoid a loop altogether and use
Range("B1").Resize(, UBound(FullName) + 1).Value = FullName

In this case I would use a loop (and your solution was not that far from this):
Dim Txt As String
Dim i As Integer
Dim FullName As Variant
Dim R As Integer, C As Integer, MaxR as Integer
C = 1 ' can be another loop as well
For R = 1 to 1000
Txt = Trim(Cells(r,1).Value) ' will remove space from start and end
FullName = Split(Txt, " ")
For i = 0 To UBound(FullName)
Cells(R , C + 1 + i ).Value = FullName(i)
Next i
Next R

Sub Split_Text_Test1()
Dim Txt As String
Dim i As Integer
Dim FullName As Variant
Dim R As Integer, C As Integer
Range("A1").Select ' assumes that the cells below that are empty
Txt = ActiveCell.Value
FullName = Split(Txt, " ")
R = ActiveCell.Row
C = ActiveCell.Column
For i = 0 To UBound(FullName)
Cells(R + 1 + i, C).Value = FullName(i)
Next i
End Sub

I added few thing to your code, see if that serves your purpose. However, as SJR said Text to columns option in Data menu would do the same with less effort.
Sub Split_Text_Test1()
Dim Txt As String
Dim i As Integer
Dim FullName As Variant
Dim lastRow As Long
Dim myRange As Range
With ActiveSheet.UsedRange
lastRow = .Rows(.Rows.Count).Row
End With
Debug.Print lastRow
'Range("A1").Select
Set myRange = ActiveSheet.Range("A1", "A" & lastRow)
For Each cell In myRange
Txt = cell.Value
FullName = Split(Txt, " ")
For i = 0 To UBound(FullName)
Cells(cell.Row, i + 1).Value = FullName(i)
Next i
Next cell
End Sub

Related

VBA Code: How would you split a string in a cell into sections and displaying those section in a new column using offset function

I am trying to find a way that takes a player's name from cell A2 which in that cell reads (Name, Position, School) and splitting their name, position, and school in a different columns using the offset command. The problem I am having is when I split the cell it also splits the name and I need the name to stay together. For example, Jaylen Coleman RB Duke It splits it into "Jaylen" "Coleman" "RB" "Duke" when I need it to split into "Jaylen Coleman" "RB" "Duke" and then offset those splits 12 columns over.
Sub ParseName()
Dim ACC As Worksheet
Dim lastRow As Long
Dim PlayerPosition As Range
Dim dataList As Range
Dim arrData As Variant
Dim i As Variant
Set ACC = ThisWorkbook.Worksheets("ACC Statistics")
lastRow = ACC.Cells(ACC.Rows.count, "A").End(xlUp).Row
Set dataList = ACC.Range("A1").Resize(lastRow, 1)
For Each PlayerPosition In dataList
arrData = Split(PlayerPosition.Value)
For i = LBound(arrData) To UBound(arrData)
ACC.Cells(PlayerPosition.Row, i + 12).Value = arrData(i)
Next
Next
End Sub
Try this I've added random positions RR and ZZ, just use | as an "or"
Sub rege()
With CreateObject("vbscript.regexp")
.Pattern = "(.+) (RB|RR|ZZ) (.+)"
With .Execute("Jaylen X. Coleman RB Duke")
If .Count > 0 Then
If .Item(0).Submatches.Count = 3 Then
MsgBox .Item(0).Submatches(0) & vblf & _
.Item(0).Submatches(1) & vblf & _
.Item(0).Submatches(2)
End If
End If
End With
End With
End Sub
Your code should look like this (If you are not a mac user :)
Sub ParseName()
Dim ACC As Worksheet
Dim lastRow As Long
Dim PlayerPosition As Range
Dim dataList As Range
Dim arrData As Variant
Dim i As Variant
Set ACC = ThisWorkbook.Worksheets("ACC Statistics")
lastRow = ACC.Cells(ACC.Rows.Count, "A").End(xlUp).Row
Set dataList = ACC.Range("A1").Resize(lastRow, 1)
With CreateObject("vbscript.regexp")
.Pattern = "(.*) (RB|QB|WR) (.*)"
For Each PlayerPosition In dataList
With .Execute(" " & PlayerPosition.Value & " ")
If .Count > 0 Then
If .Item(0).Submatches.Count > 0 Then
For i = 0 To .Item(0).Submatches.Count - 1
ACC.Cells(PlayerPosition.Row, i + 12).Value = Trim(.Item(0).Submatches(i))
Next i
End If
End If
End With
Next
End With
End Sub
Add all your positions in Pattern string in RB|QB|WR part just use | as a separator

How to Split Cells and Display Only Worksheet Name?

Is there a clean and tidy way to get cells split ONLY by sheet name? I have a bunch of cells that look something like this.
=(Xlookup($A2,Staff!A:A,Client!K:K)*E2
=B3*(Xlookup(E3,Auto!1:1,Desc!3:3)
And, all kinds of other stuff. Basically, I am trying to parse out only the sheet names from each cell. Each sheet name ends with a '!' character. So, I am trying to split one cell into multiple columns, based on the '!' character, and ignore any text that is not a sheet name. I tested the script below, but all it does is a basic split from one cell into multiple columns, which includes the sheet name, but all kinds of superfluous text, which I don't want.
Sub SplitData()
Const SrcCol = 1 ' A
Const TrgCol = 2 ' B
Const FirstRow = 1
Dim LastRow As Long
Dim SrcRow As Long
Dim TrgRow As Long
Dim TheVal As String
Dim TheArr As Variant
Dim Num As Long
Application.ScreenUpdating = False
TrgRow = 1
LastRow = Cells(Rows.Count, SrcCol).End(xlUp).Row
For SrcRow = FirstRow To LastRow
TheVal = Cells(SrcRow, SrcCol).Value
TheArr = Split(TheVal, ",")
Num = UBound(TheArr) + 1
Cells(TrgRow, TrgCol).Resize(ColumnSize:=Num).Value = TheArr
TrgRow = TrgRow + 1
Next SrcRow
Application.ScreenUpdating = True
End Sub
Now:
Desired:
If you have O365, this will work for you ...
=LET(x, TRANSPOSE(FILTERXML("<d><r>" & SUBSTITUTE(A1, ",", "</r><r>") & "</r></d>", "//r[contains(text(),""!"")]")), MID(x, 1, FIND("!", x)))
... here's hoping you do, a lot easier.
Alternatively, I created my own VBA routine with the assumption that everything to the right of the formula is free to load into, just adjust for errors, names, performance, etc. as required ...
Public Sub GetWorksheets()
Dim lngRow As Long, lngColumn As Long, strFormula As String
Dim arrFormula() As String, i As Long, arrSubFormula() As String
With Sheet1
For lngRow = 1 To .Cells(.Rows.Count, 1).End(xlUp).Row
strFormula = Trim(.Cells(lngRow, 1))
lngColumn = 2
If strFormula <> "" Then
arrFormula = Split(strFormula, "!")
For i = 0 To UBound(arrFormula) - 1
arrSubFormula = Split(arrFormula(i), ",")
strFormula = arrSubFormula(UBound(arrSubFormula)) & "!"
.Cells(lngRow, lngColumn) = strFormula
lngColumn = lngColumn + 1
Next
End If
Next
End With
End Sub

How to put into a cell a product of another cell with a variable?

I'm new to vba and I've been trying to make the following code work:
convert = WorksheetFunction.SumIfs(Sheets("Convert").Range("C:C"), _
Sheets("Convert").Range("A:A"), Sheets("Vista").Range("L8"), _
Sheets("Convert").Range("D:D"), Sheets("Vista").Range("C2"), _
Sheets("Convert").Range("E:E"), Sheets("Vista").Range("AC4"))
Sheets("series").Range("L2").FormulaR1C1 = _
"=RC[-8]*"&convert&"
What I'm trying to do, is to put into a variable the result of a SUMIF formula, and use that same value to multiply it with the value of another cell.
It gives me an error of "Application-defined or object-defined error".
Thank you
Arrays Again
The Eliminator
Sub Eliminator()
Dim convert As Long
'Convert = WorksheetFunction.SumIfs(Sheets("Convert").Range("C:C"), _
Sheets("Convert").Range("A:A"), Sheets("Vista").Range("L8"), _
Sheets("Convert").Range("D:D"), Sheets("Vista").Range("C2"), _
Sheets("Convert").Range("E:E"), Sheets("Vista").Range("AC4"))
'e.g.
convert = 1000
Sheets("series").Range("L2").FormulaR1C1 = "=RC[-8]*" & convert
End Sub
Blah, Blah...
Now that we have concluded that the 'Convert' line is causing the error...
Since I use Excel 2003 and you have written the formula correctly, I can only guess that since SumIfs is something like an array formula it can't always be used successfully in VBA, or maybe never!? if you have error values in cells, there might be the solution, because VBA treats them as 'VBA Errors'.
The 'SumIfsless' Solution
So I provided another solution without using SumIfs. You can run it from VBA or any other worksheet. The 'str1' commented lines are for debugging purposes. You can uncomment them and see some 'subtotals' in the Immediate window.
Sub SumIfsArray()
'Variables
'Objects
Dim oRng As Range 'Range of the Sum Column (To Calculate First and Last Row)
'Arrays
Dim arrRngAddress As Variant 'Compare Addresses
Dim arrWs As Variant 'Worksheet Names
Dim arrCol As Variant 'Three Lookup Columns and the Sum Column
Dim arrRng As Variant 'Values of the Compare Addresses
Dim arrRanges As Variant 'The Ranges of the Four Columns
Dim arrArrays As Variant 'The Values of the Four Columns
'Other
Dim iCol As Integer 'Columns Counter
Dim lngFirst As Long 'First Usable Row of Data
Dim lngLast As Long 'Last Usable Row of Data
Dim lngRows As Long 'Number of Rows of Usable Data
Dim lngRow As Long 'Rows Counter
Dim lngSum As Long 'Sum of Values
Dim blnArr As Boolean 'True if all three conditions are met.
' 'Debug Variables
' Const c1 As String = "," 'Debug String Column Separator
' Const r1 As String = vbCr 'Debug String Row Separator
' Dim i1 As Integer 'Debug String Column Counter
' Dim lo1 As Long 'Debug String Rows Counter
' Dim str1 As String 'Debug String Concatenator
'Initialize
arrRngAddress = Array("L8", "C2", "AC4")
arrWs = Array("Convert", "Vista", "series")
arrCol = Array("A:A", "D:D", "E:E", "C:C")
'Program
ReDim arrRng(1 To 3)
With Worksheets(arrWs(1)) 'Worksheet "Vista"
For iCol = 1 To 3
arrRng(iCol) = .Range(arrRngAddress(iCol - 1)).Value
Next
End With
' str1 = "The Values"
' For i1 = 1 To 3: str1 = str1 & r1 & Space(1) & arrRng(i1)
' Next: Debug.Print str1
With Worksheets(arrWs(0)) 'Worksheet "Convert"
'Number of 'usable' rows of data
Set oRng = .Range(arrCol(3))
With oRng
If .Cells(1, 1) <> "" Then
lngFirst = 1
Else
lngFirst = .Cells(1, 1).End(xlDown).Row
End If
lngLast = .Cells(.Rows.Count, .Column).End(xlUp).Row
End With
Set oRng = Nothing
lngRows = lngLast - lngFirst + 1
'Array of Ranges
ReDim arrRanges(1 To 4)
For iCol = 1 To 4
arrRanges(iCol) = Range(Cells(lngFirst, Range(arrCol(iCol - 1)).Column), _
Cells(lngLast, Range(arrCol(iCol - 1)).Column)).Address
Next
' str1 = "The Ranges"
' For i1 = 1 To 4: str1 = str1 & r1 & Space(1) & arrRanges(i1)
' Next: Debug.Print str1
'Array of Arrays
ReDim arrArrays(1 To 4)
For iCol = 1 To 4
arrArrays(iCol) = .Range(arrRanges(iCol)).Value
Next
End With
' str1 = "Values of Ranges" & r1 & Space(1) & "A,D,E,C"
' For lo1 = 1 To lngRows: str1 = str1 & r1 & Space(1): For i1 = 1 To 4
' If i1 <> 1 Then
' str1 = str1 & c1 & arrArrays(i1)(lo1, 1)
' Else: str1 = str1 & arrArrays(i1)(lo1, 1)
' End If: Next: Next: Debug.Print str1
'Sum of Values
For lngRow = 1 To lngRows
For iCol = 1 To 3
If arrArrays(iCol)(lngRow, 1) = arrRng(iCol) Then
blnArr = True
Else
blnArr = False
Exit For
End If
Next
If blnArr = True Then
lngSum = lngSum + arrArrays(4)(lngRow, 1)
End If
Next
' str1 = "The Sum": str1 = str1 & r1 & Space(1) & lngSum
'Output
'Worksheet "series"
Worksheets(arrWs(2)).Range("L2").FormulaR1C1 = "=RC[-8]*" & lngSum
End Sub
P.S. I never ever use variable names with the same name as a worksheet name in the same workbook.

VBA Split String Loop

I am trying to split a string and create a loop for going through the cells in the column.There are a few challenges:
Split works for ActiveCell only.
Loop goes through all cells until LastRow but populates all cells
with split string values from ActiveCell only.
Split of Array starts with i = 0 even though there is Option Base 1
at the beginning of the Module.
How can I change the location of destination (e.g. instead of
splitting string next to existing data, is there an option to manage
column numbers)?
Thank you
Option Explicit
Option Base 1
Sub SplitStringLoop()
Dim txt As String
Dim i As Integer
Dim y As Integer
Dim FullName As Variant
Dim LastRow As Single
ReDim FullName(3)
LastRow = Cells(Rows.Count, "A").End(xlUp).Row
txt = ActiveCell.Value
FullName = Split(txt, "-")
For y = 2 To LastRow
For i = 1 To UBound(FullName)
Cells(y, i + 1).Value = FullName(i)
Next i
Next y
End Sub
Chris Nelisen outlined the reasons, I had this code written before he posted, so I'll post it anyway.
Option Explicit
Sub SplitStringLoop()
Dim txt As String
Dim i As Integer
Dim y As Integer
Dim FullName As Variant
Dim LastRow As Single
ReDim FullName(3)
LastRow = Cells(Rows.Count, "A").End(xlUp).Row
For y = 2 To LastRow
Cells(y, 1).Select
txt = ActiveCell.Value
FullName = Split(txt, "-")
For i = 0 To UBound(FullName)
Cells(y, i + 2).Value = FullName(i)
Next i
Next
End Sub
To address the issues you list
Split acts on the string you pass to it. You are passing the active cell value to it.
You don't update the result of split (FullName) inside the loop. So what else do you expect?
Split Returns a zero-based, one-dimensional array. It says so right there in the help. Option Base 1 specifies the default lower bound, for when you don't specify it in a Dim statement.
You are specifying the column in your code Cells(y, i + 1) (i + 1 in this case). If you want it somewhere else, specify a different column.
this is my sulotion
Public Function CheckEmailsValid(EmailAddresses As String) As Boolean
On Error GoTo Err_1
Dim V_Tempi As Integer
Dim V_Email As Variant
For Each V_Email In Split(EmailAddresses, ";")
V_Tempi = V_Tempi + 1
If CheckEmailValid(V_Email) = False Then
MyMsgBox 2, "Email " & V_Tempi & " Is invalid"
CheckEmailValidFew = False
Exit Function
End If
Next
CheckEmailValidFew = True
Exit_1:
Exit Function
Err_1:
MyMsgBox 2, "Error !!" & vbCr & Err.Number & vbCr & Err.Description
End Function

Loop through listboxes in excel vba

Is there an apparent problem with the following codes? I want to loop through all listboxes and populate selected items.
Dim lRw As Integer
Dim iX As Integer, iY As Integer
Dim i As Integer
For i = 1 To 10
With ActiveSheet
.Columns(i + 10).ClearContents
End With
For iX = 0 To ListBox(i).ListCount - 1
If ListBox(i).Selected(iX) = True Then
With Sheet1
lRw = .Cells(.Rows.Count, i + 11).End(xlUp).Row + 1
For iY = 0 To ListBox(i).ColumnCount - 1
.Cells(lRw, iY + i).Value = ListBox(i).List(iX, iY)
Next iY
End With
End If
Next iX
Next i
With an unkown number of listboxes and an unknown number of selected items each, I would build a string with the results, then split the string on carriage returns Chr(10) for each line (each selected item in a listbox) and then use a text to columns to get everything in the correct cells. It would look like this:
Sub tgr()
Dim wsLists As Worksheet
Dim wsDest As Worksheet
Dim ctrl As OLEObject
Dim strOutput As String
Dim arrOutput() As String
Dim i As Long, j As Long
Set wsLists = Sheets("Sheet1") 'The sheet containing the listboxes
Set wsDest = Sheets("Sheet2") 'The sheet where the output will go
For Each ctrl In wsLists.OLEObjects
If TypeName(ctrl.Object) = "ListBox" Then
For i = 0 To ctrl.Object.ListCount - 1
If ctrl.Object.Selected(i) Then
If Len(strOutput) > 0 Then strOutput = strOutput & Chr(10)
For j = 0 To ctrl.Object.ColumnCount - 1
strOutput = strOutput & ctrl.Object.List(i, j) & vbTab
Next j
End If
Next i
End If
Next ctrl
If Len(strOutput) > 0 Then
wsDest.Range("K:T").ClearContents
arrOutput = Split(strOutput, Chr(10))
With wsDest.Cells(Rows.Count, "K").End(xlUp).Offset(1).Resize(UBound(arrOutput) - LBound(arrOutput) + 1)
.Value = Application.Transpose(arrOutput)
.TextToColumns Tab:=True
End With
Erase arrOutput
End If
End Sub

Resources