I want to create a vba macro that transforms text to columns, but this command is only capable of doing column by column.
Columns("F:F").Select
Selection.TextToColumns Destination:=Range("F1"), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
Semicolon:=False, Comma:=False, Space:=False, Other:=False, FieldInfo _
:=Array(1, 1), TrailingMinusNumbers:=True
This code above works whell for one column, but i would like to do the command for the columns F to BL.
How can i do a For Loop to iterate over all the columns between F and BL?
Some sort of For Columns in Range Do?
Something like this should give you an idea of what you can do.
Note that you don't need to select. And most of those option are probably set to their default value, making the code unecessary verbose. The macro recorder is nice but you might want to rework the result.
Sub quick_and_dirty()
Dim cell As Range
For Each cell In Range("F1:G1")
cell.EntireColumn.TextToColumns Destination:=cell, DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
Semicolon:=False, Comma:=False, Space:=False, Other:=False, FieldInfo _
:=Array(1, 1), TrailingMinusNumbers:=True
Next cell
End Sub
You are going to run into an issue with regard to overwriting existing data, so the route you want to follow is dependent on how you want to address that.
If you use AugustinLopez' method above, you'd want to make a handful of adjustments either way.
If you want to copy each row to a new sheet and then expand it, just add a "cell.EntireColumn copy xxx" step before the TextToColumns step and copy it to a new range.
If you want to add the necessary number of empty columns first, and presuming you have a variable number of commas through out the columns, it gets trickier and you'd need something like this (depending on your table size, some optimization for speed may be needed):
Sub DummyCode()
Dim cell As Range
Dim ColumnCount As Integer
Dim RangeOfInterest As Range
Dim CellStart As Integer
Dim i As Integer
Dim j As Integer
Dim CommaCount As Integer
Set RangeOfInterest = Range("F1:BL1")
ColumnCount = RangeOfInterest.Columns.Count
CellStart = RangeOfInterest.Range("A1").Column
For i = CellStart + ColumnCount - 1 To CellStart Step -1 'you gotta go backwards to not mess up your count
CommaCount = 0
For Each cell In Intersect(Cells(1, i).EntireColumn, ActiveSheet.UsedRange)
If InStr(1, cell.Value, ",") > 0 Then
If CommaCount < (Len(cell.Value) - Len(Replace(cell.Value, ",", ""))) Then
CommaCount = (Len(cell.Value) - Len(Replace(cell.Value, ",", "")))
'credit for the above bit of cleverness goes to here:
'http://www.ozgrid.com/forum/showthread.php?t=45651
'via here
'https://stackoverflow.com/questions/9260982/how-to-find-number-of-occurences-of-slash-from-a-strings
End If
End If
For j = 1 To CommaCount
Cells(1, i).EntireColumn.Insert
Next j
Cells(1, i).EntireColumn.TextToColumns Destination:=Cells(1, i), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
Semicolon:=False, Comma:=False, Space:=False, Other:=False, FieldInfo _
:=Array(1, 1), TrailingMinusNumbers:=True
Next i
End Sub
good luck!
Related
I am trying to perform the "Text to Columns" feature on several columns of data in Excel. How can I modify the VBA script of my macro to do this? Right now, I can only select one column for my macro, but I'd like to select multiple columns, and have this loop through somehow.
Also, is there any way to write script that clicks "okay" for me, when it asks if I can overwrite the data in the next column?
Sub text2col()
'
' text2col Macro
'
' Keyboard Shortcut: Option+Cmd+k
'
Selection.TextToColumns Destination:=Range(ActiveCell.Address), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=False, _
Semicolon:=False, Comma:=False, Space:=False, Other:=True, OtherChar _
:="-", FieldInfo:=Array(Array(1, 1), Array(2, 1))
End Sub
change 1 to the column number of the 1st column you need to change
change 10 to the column number of the last column you need to change
columns are numbered from the left (A) starting with 1
Make sure you pay attention to Mark Wickett's warning in his comment.
Sub text2col()
'
' text2col Macro
'
' Keyboard Shortcut: Option+Cmd+k
'
Dim Col as Integer
Application.DisplayAlerts = False
For Col = 1 to 10
Selection.TextToColumns Destination:=Range(ActiveCell.Address), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=False, _
Semicolon:=False, Comma:=False, Space:=False, Other:=True, OtherChar _
:="-", FieldInfo:=Array(Array(1, 1), Array(2, 1))
Next
Application.DisplayAlerts = True
End Sub
I have tried creating a macro that automatically formats a column value to change date and time just to date, however when the macro is run the cell values dont automatically update.
I currently need to make the following function selection happen using VBA for excel 2010.
Data/Text to Columns/Next button (keep default "Delimited")/Next button (keep default "tab")/Next button (keep default "General"/Finish button
I have tried recording functions but the VBA doesn't work. HELPPPPPPPPPPPPPPPPPPPPP!!!!!
Here is my code so far.
' Autochange_Extractdata_Date_Format Macro
'
Sheets("Data Extract").Select
Columns("AK:AK").Select
Selection.NumberFormat = "m/d/yyyy"
Columns("AK:AK").Select
Selection.TextToColumns Destination:=Range("AK1"), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
Semicolon:=False, Comma:=False, Space:=False, Other:=False, FieldInfo _
:=Array(1, 1), TrailingMinusNumbers:=True
End Sub
From the symptoms you described it sounds like your field is initially in TEXT format, that's why changing it to number format doesn't do anything. When you click into the cell it automatically converts it to a number.
Try this
Columns("AK:AK").NumberFormat = "m/d/yyyy"
Columns("AK:AK").Value = Columns("AK:AK").Value '//This will convert each properly
Columns("AK:AK").Select
Selection.TextToColumns Destination:=Range("AK1"), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
Semicolon:=False, Comma:=False, Space:=False, Other:=False, FieldInfo _
:=Array(1, 1), TrailingMinusNumbers:=True
Because i couldnt work out how to update the cell value i managed to work this code to change the cell value instead from Date time just to Date.
works a treat!!!
' Autochange_Extractdata_Date_Format Macro
Sheets("Data Extract").Select
Columns("AK:AK").Select
Selection.NumberFormat = "m/d/yyyy"
Range("AK4:AK999999").Select
Dim c As Range
For Each c In Selection
Dim v As String
v = c.value
If c.value <> Empty Then
c.value = DateValue(c.value)
Else
Exit For
End If
Next
Range("A1").Select
End Sub
I have this code to split strings. Currently if the counter is equal to the number of rows on which data is present, it will run properly. However, this number of rows is variable. How do I make the for loop run for as long there is data?
Sub SplitToColumns()
Range("A1").Select
For Counter = 0 To 100 Step 1
Selection.TextToColumns Destination:=ActiveCell, DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, _
Tab:=False, Semicolon:=False, Comma:=True, Space:=False, _
Other:=False, _
FieldInfo:=Array(Array(1, 1), Array(2, 1), Array(3, 1)), _
TrailingMinusNumbers:=True
ActiveCell.Offset(1, 0).Select
Next Counter
End Sub
Something like this:
get the row number of the last populated row in column A. (Replace with the column of your choice). Then use that row number in the for-loop, but start with 1, not with zero. Remove the debug.print if no longer required.
Sub SplitToColumns()
Dim rowCount As Long
rowCount = Cells(rows.Count, "A").End(xlUp).Row
Debug.Print rowCount
Range("A1").Select
For Counter = 1 To rowCount Step 1
Selection.TextToColumns Destination:=ActiveCell, DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, _
Tab:=False, Semicolon:=False, Comma:=True, Space:=False, _
Other:=False, _
FieldInfo:=Array(Array(1, 1), Array(2, 1), Array(3, 1)), _
TrailingMinusNumbers:=True
ActiveCell.Offset(1, 0).Select
Next Counter
End Sub
There are several other ways to make this code more efficient. For example, you don't need to select the cell before you do a TextToColumns. In fact, you can do a TextToColumns on a range of cells, you don't need to loop through all the cells in the range.
Use the technique above to get the row number of the last row, and then build a range starting in A1 and extending to column A, last populated row number.
Then perform a TextToColumns on the whole range, all in one go. Much, much faster than looping!!!
Sub SplitToColumns()
Dim rowCount As Long
Dim ws As Worksheet
'~~> Change this to the relevant sheet
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
rowCount = .Cells(.Rows.Count, "A").End(xlUp).Row
.Range("A1:A" & rowCount).TextToColumns _
Destination:=.Range("A1"), _
DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, _
ConsecutiveDelimiter:=False, _
Tab:=False, _
Semicolon:=False, _
Comma:=True, _
Space:=False, _
Other:=False, _
FieldInfo:=Array(Array(1, 1), Array(2, 1), Array(3, 1)), _
TrailingMinusNumbers:=True
End With
End Sub
Is there way to find cell that contains "Date" and run the TextToColumns macro?
instead of referencing column "H" or "J" and/or so on...
Ultimately I am trying to change about 5 columns that contains "~ Date" to TextToColumn.
And it's not always on the "H" column.
Thank you so much for your expertise
Columns("H:H").Select
Selection.TextToColumns Destination:=Range("H1"), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
Semicolon:=False, Comma:=False, Space:=False, Other:=False, FieldInfo _
:=Array(1, 5), TrailingMinusNumbers:=True
Assuming that the "date" values are to be found in the column headers for row 1, the following code should do the trick.
It works as follows:
find the rightmost column header in row 1
loop through the first to last header
search for the string "date" within each header cell
-- if not found, go to the next header cell
-- if found, then convert the text values of the column of date for that header into columns and go to the next header cell
Note that I removed the Selects from the code, which are not necessary to do the conversions.
Your description was not clear on whether there were enough blank columns to the right of a "date"-headed column to hold the split data without overwriting other existing data. This procedure assumes that there is enough room. As a result, if there is data in the cells to the right, Excel will show a dialog box asking if you want to overwrite the adjacent cell. If there is not, and additional columns need to inserted, please modify your question to make that clear.
Sub txttocol()
Dim ws As Sheet1
Dim rng As Range
Dim lastCol As Long
Dim i As Long
Set ws = Worksheets("Sheet1")
With ws
lastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
For i = 1 To lastCol
If InStr(UCase(.Cells(1, i).Value), UCase("date")) <> 0 Then
Set rng = .Range(Columns(i), Columns(i))
rng.TextToColumns Destination:=rng, DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
Semicolon:=False, Comma:=False, Space:=False, Other:=False, FieldInfo _
:=Array(1, 5), TrailingMinusNumbers:=True
End If
Next i
End With
End Sub
basically i am using the TextToColumns function to separate out data separated by a semi colon in the same cell. problem is there are 2 columns of data that needs this function done and i have to insert the data without overwriting.
(go easy, first time with VBA and excel) this is what i currently have:
Sub Button1_Click()
Dim rng As Range
Dim sh As Worksheet
Set sh = Worksheets("Sheet1")
With sh
Set rng = .[Q1]
Set rng = .Range(rng, .Cells(.Rows.Count, rng.Column).End(xlUp))
num = Application.WorksheetFunction.Max(Columns("P"))
rng.Offset(0, 1).Resize(1, num).EntireColumn.Insert
rng.TextToColumns Destination:=rng, DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=False, _
Semicolon:=True, Comma:=False, Space:=False, Other:=False, _
FieldInfo:=Array(Array(1, 1), Array(2, 1), Array(3, 1)), TrailingMinusNumbers:=True
End With
Set sh2 = Worksheets("Sheet1")
With sh2
num2 = Application.WorksheetFunction.Max(Columns("P"))
Dim lastColumn As Integer
lastColumn = ActiveSheet.UsedRange.Column - 1 + ActiveSheet.UsedRange.Columns.Count
MsgBox Replace(Cells(1, lastColumn).Address(False, False), "1", "")
MsgBox lastColumn
Set rng = .[W1]
Set rng = .Range(rng, .Cells(.Rows.Count, rng.Column).End(xlUp))
rng.TextToColumns Destination:=rng, DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=False, _
Semicolon:=True, Comma:=False, Space:=False, Other:=False, _
FieldInfo:=Array(Array(1, 1), Array(2, 1), Array(3, 1)), TrailingMinusNumbers:=True
End With
End Sub
ok so what i am trying to fix is setting the rng manually in the second part to W1. the rng needs to be the next empty column. so lastColumn using the MsgBox DOES return the column "W" but i cannot set that to rng (type mismatch). oh and the num variable is set to the amount of columns i need to insert. my data looks like this:
count | column with ; data need separating | column with ; data need separating
5 | 5 sets of data separated by semi colons | don't care because this is the end of sheet
is there any easier way to do this? am i even close?
... Easiest solution if I understand your question correctly... Why don't you just make a THIRD column that equals Column1 & ";" & Column2, then just do text-to-columns on that single column??
Or am I missing something??
Assuming I'm understanding your setup correctly, the following code should work.
If you process the data columns from right to left, you don't have to worry about the change in address references when the columns are inserted. That means you can use a single block of insertion/conversion code, iterated over the two data address references, which I've assumed are Q1 and R1.
Note also that I added an offset to the TextToColumns destination to avoid overwriting the original data.
Option Explicit
Sub myTextToColumns()
Dim sh As Worksheet
Dim rng As Range
Dim num As Long
Dim arr As Variant
Dim i As Long
Set sh = Worksheets("Sheet1")
arr = Array("R1", "Q1")
num = Application.WorksheetFunction.Max(Columns("P"))
With sh
For i = LBound(arr) To UBound(arr)
Set rng = .Range(arr(i))
Set rng = .Range(rng, .Cells(.Rows.Count, rng.Column).End(xlUp))
rng.Offset(0, 1).Resize(1, num).EntireColumn.Insert
rng.TextToColumns Destination:=rng.Offset(0, 1), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=False, _
Semicolon:=True, Comma:=False, Space:=False, Other:=False, _
FieldInfo:=Array(Array(1, 1), Array(2, 1), Array(3, 1)), TrailingMinusNumbers:=True
Next
End With
End Sub