split text to rows excel - file

I have a VBA code with which I import a txt file into one cell.
Here's the code (it's not that important):
Sub ReadFile()
' Requires a reference to Microsoft Scripting Runtime (Tools > References)
Dim FSO As FileSystemObject
Dim FSOFile As File
Dim FSOStream As TextStream
Dim Rand
Dim ws As Worksheet
Set ws = Worksheets("Sheet1")
Set FSO = New FileSystemObject
Set FSOFile = FSO.GetFile("C:\Users\sdagfsgedg\Desktop\20121122.log")
Set FSOStream = FSOFile.OpenAsTextStream(ForReading, TristateUseDefault)
Rand = 1
Do While Not FSOStream.AtEndOfStream
ws.Cells(Rand, 1).Value = FSOStream.ReadAll
Loop
End Sub
The text file 20121122.log has about 20.000 lines which are all imported in one cell. How can I split that cell into 20.000 cells (if the log has 20.000 lines). I don't want to read the text file line by line... I want to read it all (it's way more faster) then split every line on a separate row.
LATER EDIT:
Or if there is another solution to read the log file and paste the text as line to row (not everything in one cell as I do right now)

// Code is not tested
Sub ReadFile()
Dim FSO As FileSystemObject
Dim FSOFile As File
Dim FSOStream As TextStream
Dim Rand
Dim row
Dim ws As Worksheet
Set ws = Worksheets("Sheet1")
Set FSO = New FileSystemObject
Set FSOFile = FSO.GetFile("C:\Users\sdagfsgedg\Desktop\20121122.log")
Set FSOStream = FSOFile.OpenAsTextStream(ForReading, TristateUseDefault)
Rand = 1
Dim content As String
Dim lines As Variant
Dim intIndex As Integer
content = FSOStream.ReadAll
lines = split(content, Chr(10))
For intIndex = LBound(lines) To UBound(lines)
ws.Cells(Rand, 1).Value = lines(intIndex)
Rand = Rand + 1
Next
End Sub

Related

Need a VBA code to convert Excel sheet columns into tab in new Excel sheet

I have an Excel sheet having 3000 columns and I need to convert this sheet in such a way that one tab will contain 254 columns only and remaining will go to the next tab. So I need a VBA code (Macro) which can perform the same.
As of now I wrote the following code only which is creating 3000 tabs with one column in each, also it is going to infinite loop as I did not put any condition there for blank column.
Sub SpliteIntoMultipleTab()
'
' createtemplates Macro
Dim WS As Worksheet
Dim SS As Worksheet
Dim TemplateName As String
Dim tempstr As String
'
Dim CurCol As String
Dim Template As String
Dim xColIndex As Integer
Dim xRowIndex As Integer
Dim WSCount As Integer
'==========================================================================
'Declarations
CurCol = 1
Template = "Sheet1"
'==========================================================================
Set SS = Worksheets(Template)
If WS Is Nothing Then
Start:
With ActiveWorkbook
Set WS = .Sheets.Add(After:=ActiveSheet)
WSCount = Sheets.Add(After:=Sheets(Worksheets.Count))
On Error Resume Next
Set WS = Worksheets("temp")
WS.Name = SS.Range("A1").Value
End With
Else
End If
SS.Activate
xIndex = Application.ActiveCell.Column
xRowIndex = Application.ActiveSheet.Cells(Rows.Count, xIndex).End(xlUp).Row
Range(Cells(1, xIndex), Cells(xRowIndex, xIndex)).Select
Selection.Copy
WS.Select
WS.Range("A1").Select
ActiveSheet.Paste
SS.Columns(1).EntireColumn.Delete
CurCol = CurCol + 1
GoTo Start
End Sub
Use integer division and modulus, so for example taking the 1000th column
1000 \ 254 = 3
1000 mod 254 = 238
gives the 3rd sheet and the 238th column.
So loop through from 1 to 3000 using \ and mod.
You code is very non-standard and I cannot get my head around it, I suggest you start from my code, this is an illustrative example of breaking a block of data into separate sheets. Copy the code into a new workbook then
Run CreateSheetAndPopulateWithBlockOfData once only to create a block of data.
Run Test to run the BreakBlockIntoChunks routine, you can experiment with the chunk size.
Option Explicit
Private Const csSHEETNAME As String = "Source"
Sub TestCreateSheetAndPopualteWithBlockOfData()
Dim wsSource As Excel.Worksheet
Set wsSource = CreateSheetAndPopulateWithBlockOfData(ThisWorkbook, csSHEETNAME, 20, 100)
End Sub
Sub Test()
Dim wsSource As Excel.Worksheet
Set wsSource = ThisWorkbook.Worksheets.Item(csSHEETNAME)
'Stop
Dim wbResults As Excel.Workbook
Set wbResults = Workbooks.Add
BreakBlockIntoChunks wsSource, 5, wbResults
End Sub
Function BreakBlockIntoChunks(ByVal wsSource As Excel.Worksheet, ByVal lColumnChunkSize As Long, ByVal wbDestinationWorkbook As Excel.Workbook)
Dim rngDataBlock As Excel.Range
Set rngDataBlock = wsSource.Cells(1, 1).CurrentRegion
Dim lSourceColumnCount As Long
lSourceColumnCount = rngDataBlock.Columns.Count
Dim lSourceRowCount As Long
lSourceRowCount = rngDataBlock.Rows.Count
Dim lColumnLoop As Long
For lColumnLoop = 1 To lSourceColumnCount
Dim lCurrentSheet As Long
lCurrentSheet = ((lColumnLoop - 1) \ lColumnChunkSize) + 1
Dim wsCurrentSheet As Excel.Worksheet
If lCurrentSheet > wbDestinationWorkbook.Worksheets.Count Then Set wsCurrentSheet = wbDestinationWorkbook.Worksheets.Add
If wsCurrentSheet Is Nothing Then Set wsCurrentSheet = wbDestinationWorkbook.Worksheets.Item(lCurrentSheet) '* runs first loop
'**ADD your sheet naming logic here perhaps
Dim lCurrentColumn As Long
lCurrentColumn = ((lColumnLoop - 1) Mod lColumnChunkSize) + 1
Dim rngSource As Excel.Range
Set rngSource = wsSource.Range(wsSource.Cells(1, lColumnLoop), wsSource.Cells(lSourceRowCount, lColumnLoop))
Dim rngDestination As Excel.Range
Set rngDestination = wsCurrentSheet.Range(wsCurrentSheet.Cells(1, lCurrentColumn), wsCurrentSheet.Cells(lSourceRowCount, lCurrentColumn))
rngDestination.Value2 = rngSource.Value2 '* <---Copies without using clipboard
Next lColumnLoop
End Function
Function CreateSheetAndPopulateWithBlockOfData(ByVal wb As Excel.Workbook, ByVal sSheetName As String, ByVal lRowsDeep As Long, ByVal lColumnsWide As Long) As Excel.Worksheet
Dim ws As Excel.Worksheet
Set ws = wb.Worksheets.Add
ws.Name = sSheetName
Dim rngBlock As Excel.Range
Set rngBlock = ws.Range(ws.Cells(1, 1), ws.Cells(lRowsDeep, lColumnsWide))
rngBlock.Formula = "=RANDBETWEEN(1,100000)"
rngBlock.Value2 = rngBlock.Value2
Set CreateSheetAndPopulateWithBlockOfData = ws
End Function
you could try this:
Sub SpliteIntoMultipleTab()
Dim colNum As Long, iCol As Long
With Worksheets("Sheet1").UsedRange
colNum = .Columns.count
Do
Worksheets.Add(After:=Worksheets(Worksheets.count)).Range("A1:IT1").Resize(.Rows.count).Value = .Columns(iCol + 1).Resize(, 254).Value
iCol = iCol + 254
colNum = colNum - 254
Loop While colNum > 0
End With
End Sub
which copies values only and speed up things considerably

How Can I Make Sure I Only Open Text Files When Working With FSO - VBA

Currently have a working script that uses FSO, but it also opens .xlsm files within my working directory. I would like to to only open .txt files.
I found this code that should work, however I can't figure out how to apply it to my situation:
Sub test()
' Loop thru all files in the folder
folder = ActiveWorkbook.path
path = folder & "\*.txt"
Filename = Dir(path)
Do While Filename <> ""
'insert other functions here
Loop
End Sub
My Code (Works, but also opens .xlsm files, which I don't want it to do):
Option Explicit
Sub Initialize_barcode_lookup_Array_test()
Dim fso As FileSystemObject
Dim folder As String, path As String, count_txt_files As Long, Filename As String
Dim folder2 As folder
Dim file As file
Dim FileText As TextStream
Dim TextLine As String
Dim Items() As String
Dim ShippingPlanArray() As String
Dim i As Long, j As Long, k As Long
Dim cl As Range
Dim fName
Dim row As Long, column As Long
Dim shipping_plan As Long 'Number of shipping plans text files imported
Dim barcode_Lookup() As String
Dim lastRow As Long
Dim longest_lastRow As Long
Dim counter As Long
Dim FNSKU_Input As String
'<<<< Creating FSO Object >>>>>
'Define longest_lastRow
longest_lastRow = 0
'Define i (References the text file open)
i = 0
' Get a FileSystem object
Set fso = New FileSystemObject
' get the directory you want
Set folder2 = fso.GetFolder(ActiveWorkbook.path)
' Loop only while the files being opened are .txt files:
For Each file In folder2.Files
row = 0
column = 0
Set FileText = file.OpenAsTextStream(ForReading)
Do Until FileText.AtEndOfStream
fName = FileText.ReadLine
'Parse data by tabs (text-tab delimited) into Items() array
Items() = Split(fName, vbTab)
' Redimension Preserve the ShippingPlanArray()
' NOTE: You can only Redimension preserve the last dimension of a multi-dimensional array
' (In this case: row)
ReDim Preserve ShippingPlanArray(9, row)
'Read Data into an Array Variable
For column = LBound(Items) To UBound(Items)
'MsgBox Items(column)
ShippingPlanArray(column, row) = Items(column)
Next column
row = row + 1
Loop
Next file
End Sub
I don't know if fso support an overloaded method for GetFolder where you can specify the pattern. If it does, use that i.e. GetFolder(Path, "*.txt"). If it doesn't, can you not just add a simple condition to check the file extension in your 'for each' loop and only process the ones that ends in '.txt'.
Update:
Try this:
For Each file In folder2.Files
Dim extension As String
extension = LCase(Mid$(file, InStrRev(file, ".")))
If extension = ".txt" Then
Debug.Print "TEST"
End If
Next
I've tested it and it works as expected.

vba powerpoint populating an array from excel range

I´m trying to set a array with data from a MS Excel range.
My VBA Macro replaces the text from an array with text from another array.
It works fine with arrays, but now I´m trying to fill these arrays with data from a Excel file. I´m using range and I´ve tried thousands of ways of making itwork, unsuccessfuly. I´m not a VBA coder, so maybe I´m missing some basic concepts.... :|
Heres the code. Thanks in advance for any help!
Sub ReplacePT2ES()
Dim oSld As Slide
Dim oShp As Shape
Dim oTxtRng As TextRange
Dim oTmpRng As TextRange
Dim strWhatReplace As String, strReplaceText As String
Dim x As Long
Dim xlApp As Excel.Application
Dim xlBook As Excel.Workbook
Dim rng As range
Set xlApp = CreateObject("Excel.Application")
Set xlBook = xlApp.Workbooks.Open("D:\DOCS\DiccionarioPT2ES.xlsx")
xlBook.Application.Visible = False
xlBook.Application.WindowState = xlMinimized
Dim findList As Variant
Dim replaceList As Variant
Set findList = range("A1:A3").Value
Set replaceList = range("B1:B3").Value
'-- works fine with array
'findList = Array("falha", "lei", "projeto", "falhas", "leis", "projetos", "falham", "os", "as", "gestor")
'replaceList = Array("falla", "ley", "proyecto", "fallas", "leyes", "proyectos", "fallan", "los", "las", "gerente")
'MsgBox "Iniciando!"
For x = findList.Count To replaceList.Count
' go during each slides
For Each oSld In ActivePresentation.Slides
' go during each shapes and textRanges
For Each oShp In oSld.Shapes
' replace in TextFrame
'If oShp.HasTextFrame And UBound(findList) And UBound(replaceList) > 0 Then
If oShp.HasTextFrame Then
Set oTxtRng = oShp.TextFrame.TextRange
Set oTmpRng = oTxtRng.Replace(FindWhat:=findList(x), Replacewhat:=replaceList(x), WholeWords:=True)
Do While Not oTmpRng Is Nothing
Set oTxtRng = oTxtRng.Characters(oTmpRng.Start + oTmpRng.Length, oTxtRng.Length)
Set oTmpRng = oTxtRng.Replace(FindWhat:=findList(x), Replacewhat:=replaceList(x), WholeWords:=True)
Loop
End If
Next oShp
Next oSld
Next x
xlBook.Close SaveChanges:=False
Set xlApp = Nothing
Set xlBook = Nothing
'MsgBox "Listo!"
End Sub
Finaly I found a solution: stop using Array and swith to Dictionary.
Here the code wich worked:
Set findList = range("A1:A10")
Dim MyDictionary As Object
Set MyDictionary = CreateObject("Scripting.Dictionary")
With MyDictionary
For Each RefElem In findList
If Not .Exists(RefElem) And Not IsEmpty(RefElem) Then
.Add RefElem.Value, RefElem.Offset(0, 1).Value
End If
Next RefElem
End With
Moral of the history: use the right datatype for the job ;)
You can speed up your code significantly by:
Looping through a variant array rather than a range
Splitting your IF test into two parts (VBA doesn't shortcircuit so will evaluate both parts of an AND even if the first part is False).
code
Sub Recut()
Dim X
Dim MyDictionary As Object
Dim lngRow As Long
Set MyDictionary = CreateObject("Scripting.Dictionary")
X = Range("A1:B10").Value2
With MyDictionary
For lngRow = 1 To UBound(X)
If Len(X(lngRow, 1)) > 0 Then
If Not .Exists(X(lngRow, 1)) Then .Add X(lngRow, 1), X(lngRow, 2)
End If
Next
End With
End Sub

Copy and paste with array macro excel

Can anybody help me edit? I want to copy from column to another workbook column using array.
The range inside the array is the Alphabet of the column i want to copy/paste.
Sub setting2()
Dim wb As ThisWorkbook
Dim here As Workbook
Dim there As Workbook
Dim source() As Variant
Dim log() As Variant
Dim LastRowHere() As Integer
Dim LastRowThere() As Integer
'Open both workbooks first:
Set here = Workbooks.Open("C:\Users\jesslynn\Desktop\macro\Setting2.xlsm")
Set there =Workbooks.Open("C:\Users\jesslynn\Desktop\macro\Setting3.xlsm")
Windows("Setting.xlsm").Activate
source() = Array(Sheets("Sheet1").Range("E11"), Range("E12"), Range("E13"), Range("E14"), Range("E15"), Range("E16"),Range("E17").Value)
Windows("Setting.xlsm").Activate
log() = Array(Sheets("Sheet1").Range("J11"), Range("J12"),Range("J13"),Range("J14"), Range("J15"), Range("J16"), Range("J17").Value)
Windows("Setting2.xlsm").Activate
LastRowHere() = Array(Sheets("Sheet1").Rows.Count, source().End(xlUp).Row)
Windows("Setting3.xlsm").Activate
LastRowThere() = Array(Sheets("Sheet1").Rows.Count, log()).End(xlUp).Row
For i = 1 To LastRowHere()
LastRowThere(1) = there.Sheets("Sheet1").Cells(Sheets("Sheet1").Rows.Count.log(1)).End(xlUp).Row
For k = 1 To LastRowThere()
'here.Sheets("Sheet1").Cells(i, k).Copy Destination:=there.Sheets("Sheet1").Cells(i, k)
here.Sheets("Sheet1").Rows(i).Columns(source(1)).Copy Destination:=there.Sheets("Sheet1").Rows(k + 1).Columns(log(1))
Next k
Next i
End Sub
Your problem is source().End(xlUp).Row. You're trying to use it as a range - which it's not. That is giving you the error.
You'd be better to populate your array by using a loop. And, unless you really want to carry the cell formatting across to the destination sheet, better not to use Copy since then you don't have to activate the destination sheet.
Not sure if the code below exactly fits your need. I wasn't sure of the purpose of log() array so I've left it out. The below copies the values of a single column from Source sheet to Destination sheet.
'Open both workbooks first:
Set here = Workbooks.Open("C:\Users\jesslynn\Desktop\macro\Setting2.xlsm")
Set there =Workbooks.Open("C:\Users\jesslynn\Desktop\macro\Setting3.xlsm")
SourceCol = 5 'Column E from your example
Set SourceSht = here.Sheets(1)
Set DestnSht = there.Sheets(1)
With SourceSht
'Get last cell in the column
LastRow = .Cells(.Rows.Count, SourceCol).End(xlUp).row
End With
With DestnSht
'Get last cell in the column
DestnLastRow = .Cells(.Rows.Count, SourceCol).End(xlUp).row
End With
'Loop through all cells (assumes row 1 is header)
For r = 2 to LastRow
'Assign value from Source to Destination sheet
i = i + 1
DestnSht.Cells(DestnLastRow + i, SourceCol) = SourceSht.Cells(r, SourceCol)
Next
Try this.
I assume you need copy the value from range E11 to E17 and J11 to J17
Option Explicit
Dim CurrentWorkbook As Workbook
Dim SourceWorkbook As Workbook
Dim DestWorkbook As Workbook
Dim CurrentWorksheet As Worksheet
Dim SourceWorksheet As Worksheet
Dim DestWorksheet As Worksheet
Sub setting2()
Dim SourceLastRow As Long
Dim DestLastRow As Long
Set CurrentWorkbook = ActiveWorkbook
Set CurrentWorksheet = CurrentWorkbook.ActiveSheet
Set SourceWorkbook = Workbooks.Open("C:\Users\lengkgan\Desktop\Testing\MyData1.xlsx") 'change to your path
Set DestWorkbook = Workbooks.Open("C:\Users\lengkgan\Desktop\Testing\MyTemplate.xlsx") 'change to your path
Set SourceWorksheet = SourceWorkbook.Sheets(1)
Set DestWorksheet = DestWorkbook.Sheets(1)
SourceLastRow = SourceWorksheet.Cells(Rows.Count, "E").End(xlUp).Row
DestLastRow = DestWorksheet.Cells(Rows.Count, "J").End(xlUp).Row + 1
SourceWorksheet.Range("E11:E17").Copy Destination:=DestWorksheet.Range("E" & DestLastRow + 1) 'Change to the column you want
SourceWorksheet.Range("J11:J17").Copy Destination:=DestWorksheet.Range("J" & DestLastRow + 1) 'Change to the column you want
End Sub

Excel VBA Extract Specified Start & Length from Txt file

I have a code for Excel 2007 that runs without failing.
But it is extremely & unusually slow - making my computer unresponsive for the 1-2 minutes it runs.
The files are about 14,000 kb's - so not too large.
If possible I'd like someone to tell me what I could do to make it run without causing my computer to hang. Thanks in advance.
Sub ReadFileIntoExcel()
Dim fPath As String
Const fsoForReading = 1
Dim readlength As Integer
Dim readstart As Integer
readlength = Worksheets("READFILE").Cells(1, "E").Value
readstart = Worksheets("READFILE").Cells(1, "D").Value
fPath = Worksheets("READFILE").Cells(1, "C").Value
Dim objFSO As Object
Dim objTextStream As Object, txt, allread, rw
Set objFSO = CreateObject("scripting.filesystemobject")
If objFSO.FileExists(fPath) Then
Set objTextStream = objFSO.OpenTextFile(fPath, fsoForReading)
rw = 1
Do Until objTextStream.AtEndOfStream
txt = objTextStream.ReadLine
allread = Trim(Mid(txt, readstart, readlength))
With ActiveWorkbook.Sheets("READFILE").Cells(rw, 7).Resize(1, 1)
.NumberFormat = "#" 'format cells as text
.Value = Array(allread)
End With
rw = rw + 1
Loop
objTextStream.Close
Set objTextStream = Nothing
Set objFSO = Nothing
Exit Sub
I updated your code to use an array rather than cell by cell wrote and it ran instantly
Optimisations made
Avoid cell range loops, especially writing cell by cell. Use arrays instead. This is the big one
Resize(1,1) does nothing as it keeps the cell as a single cell
Long is more efficient than Integer
Use the string functions Mid$ rather than their slower variant alternatives Mid
The allread variable was an un-necessary intermediate step
Using variable names for objects (ie ws for the worksheet), prevents longer references
code
Sub ReadFileIntoExcel()
Dim fPath As String
Dim ws As Worksheet
Const fsoForReading = 1
Dim readlength As Long
Dim readstart As Long
Dim rw as Long
Dim X()
Set ws = Worksheets("READFILE")
readlength = ws.Cells(1, "E").Value
readstart = ws.Cells(1, "D").Value
fPath = ws.Cells(1, "C").Value
Dim objFSO As Object
Dim objTextStream As Object
Set objFSO = CreateObject("scripting.filesystemobject")
If objFSO.FileExists(fPath) Then
Set objTextStream = objFSO.OpenTextFile(fPath, fsoForReading)
rw = 1
ReDim X(1 To 1, 1 To 1000)
Do Until objTextStream.AtEndOfStream
txt = objTextStream.ReadLine
If rw Mod 1000 = 0 Then ReDim Preserve X(1 To 1, 1 To UBound(X, 2) + 1000)
X(1, rw) = Trim$(Mid$(txt, readstart, readlength))
rw = rw + 1
Loop
ws.[G1].Resize(UBound(X, 2), 1) = Application.Transpose(X)
ws.Columns("G").NumberFormat = "#"
objTextStream.Close
Set objTextStream = Nothing
Set objFSO = Nothing
Exit Sub
End If
End Sub
You might try turning off screen updating while the cells are being updated. If you are touching a great many cells, this will definitely speed things up.
Application.ScreenUpdating = False
...update cells...
Application.ScreenUpdating = True
There are other things you can do as well, such as turning off calculations, but it doesn't sound like you have formulas trying to evaluate the cells your setting.

Resources