Hi Sayre,
….
Thanks a lot Rick! I was just getting ready to post again about this code. I've been playing with and noticed a couple things:………... :D
…..when the MrExcel experts appear it is like an appearance of God and we wonder how quickly they solve difficult problems. But like God they cannot be everywhere all the time. I will try to make a small contribution to bridge the gap.
….
1) When I run this on my actual files I had to change this line of code:
Code:
Lines = Split(TotalFile, vbNewLine)
to this:
Code:
Lines = Split(TotalFile, vblf)
I was getting subscript out of range error in the VbNewLine version.
Now I fear I may have another variable to consider: Different text files could have different line-ending indicators! VbNewline, VbCrLf, VbLf... Is there a way to test for this as well as the delimiter type?
:D
. I could not reproduce your problem with any of the data we have from you. If you could supply a (shortened) sample of the problem data then we may be able to help further on that one.
. In the meantime, I think technically vbNewLine is a combination of VbCr and VbLf (Carriage return and line feed. - Makes sense!. In the practice, however, I have heard that often either does something similar. See here for example.
http://www.mrexcel.com/forum/excel-...ences-between-constants-vbcr-vblf-vbcrlf.html
or try a MrExcel / Google search – there are lots of similar Threads on the difference.
. On your general point of having different separators (delimiters) line-ending indicators etc… and coping with them.
. Rick’s code lends itself I think good to that. I think it is a sort of half way house between my original which relies on a sort of known / formatted input data format, and the sort of streaming ideas of apo’s scripting and my
ADOdb codes.
. Rick’s works on a similar principal to mine, except uses the binary input option which is some sort of very fundamental format which effectively comes out in a very long string. That lends itself nicely to searching for and replacing things like your delimiters, line-ending indicators etc.
To demonstrate with a very simple example. I made up a simple test file here
FileSnack | Easy file sharing
It is a small combination of your Tab and CSV delimitated text files so it has both comas and tabs on the same line. The following code reads that file in one go, by changing all the delimiters to one sort. You could similarly search and replace different line-ending indicators etc. or even combinations with other delimiters.
<font face=Calibri><SPAN style="color:#00007F">Sub</SPAN> ImportFile4() <SPAN style="color:#007F00">'My modified for Sayre</SPAN><br> <SPAN style="color:#00007F">Dim</SPAN> R <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>, C <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>, FileNum <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br> <SPAN style="color:#00007F">Dim</SPAN> TotalFile <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">String</SPAN>, PathAndFileName <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Variant</SPAN>, Delim <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">String</SPAN><br> <SPAN style="color:#00007F">Dim</SPAN> Lines <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Variant</SPAN> <SPAN style="color:#007F00">'Kann not dimension more precisely as it will be created by a Split</SPAN><br> <SPAN style="color:#00007F">Dim</SPAN> Data() <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Variant</SPAN> <SPAN style="color:#007F00">'We know it is an array for our final data, but must be variant values</SPAN><br> <SPAN style="color:#00007F">Dim</SPAN> Fields <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Variant</SPAN><br> <SPAN style="color:#00007F">If</SPAN> Application.CountA(Cells) <SPAN style="color:#00007F">Then</SPAN><br> MsgBox "You have data on the active worksheet... this code can only be run " & _<br> "when the active sheet is empty!", vbCritical, "Worksheet Not Empty"<br> <SPAN style="color:#00007F">Exit</SPAN> <SPAN style="color:#00007F">Sub</SPAN><br> <SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">If</SPAN><br> FileNum = FreeFile <SPAN style="color:#007F00">'Give next "Highway" Number Free for data</SPAN><br> <SPAN style="color:#007F00">'PathAndFileName = Application.GetOpenFilename("CSV Files(*.csv),*.csv,All Files (*.*),*.*", 1, "Open CSV File") '<SPAN style="color:#00007F">Open</SPAN> File Dialogue Box</SPAN><br> <SPAN style="color:#00007F">Let</SPAN> PathAndFileName = ThisWorkbook.Path & "\SayreTextDataTABCSV.txt"<br> Open PathAndFileName <SPAN style="color:#00007F">For</SPAN> <SPAN style="color:#00007F">Binary</SPAN> <SPAN style="color:#00007F">As</SPAN> #FileNum <SPAN style="color:#007F00">' Open allocates a buffer, Binary means a very fundamental format, a long stream.</SPAN><br> <SPAN style="color:#00007F">If</SPAN> PathAndFileName = <SPAN style="color:#00007F">False</SPAN> <SPAN style="color:#00007F">Then</SPAN> <SPAN style="color:#00007F">Exit</SPAN> <SPAN style="color:#00007F">Sub</SPAN><br> TotalFile = Space(LOF(FileNum)) <SPAN style="color:#007F00">'Binary format would said to be unformatted in comparison with other formats. A requirement then is that the accepting string is exactly the same length</SPAN><br> <SPAN style="color:#00007F">Get</SPAN> #FileNum, , TotalFile <SPAN style="color:#007F00">'Put the whole long string in TotalFile string variable</SPAN><br> <SPAN style="color:#00007F">Close</SPAN> #FileNum <SPAN style="color:#007F00">'Always good practice to close / shut everythiung off once finished</SPAN><br> <SPAN style="color:#007F00">'So that is it-we have the entire file and just sort it out as we want it!</SPAN><br> TotalFile = Replace(TotalFile, ",", vbTab)<br> <br> Lines = Split(<SPAN style="color:#00007F">To</SPAN>talFile, vbNewLine) <SPAN style="color:#007F00">'Lines is made an array, values given by those seperated by a vbNewLine. It is a one dimensional array, effectively in the first column.</SPAN><br> <SPAN style="color:#00007F">Let</SPAN> Delim = vbTab<br><br> <SPAN style="color:#00007F">For</SPAN> R = 0 <SPAN style="color:#00007F">To</SPAN> <SPAN style="color:#00007F">UBound</SPAN>(Lines) <SPAN style="color:#007F00">'Go through each row</SPAN><br> Fields = Split(Lines(R), Delim) <SPAN style="color:#007F00">'Fields becomes a 1 dimensional column with the lines split by the seperator. Effectively it is our colum but here as a row, so we call it a filed!</SPAN><br> <SPAN style="color:#00007F">For</SPAN> C = 0 <SPAN style="color:#00007F">To</SPAN> <SPAN style="color:#00007F">UBound</SPAN>(Fields) <SPAN style="color:#007F00">'We are going along the row in the column, but each row is effestibvely wot we want as a column. Hence the Practice of calling it a field, which in everyday language usually translates to a row. for us it is the final column</SPAN><br> <SPAN style="color:#00007F">ReDim</SPAN> <SPAN style="color:#00007F">Preserve</SPAN> Data(1 <SPAN style="color:#00007F">To</SPAN> <SPAN style="color:#00007F">UBound</SPAN>(Lines) + 1, 1 To <SPAN style="color:#00007F">UBound</SPAN>(Fields) + 1) <SPAN style="color:#007F00">'As an alternative to Rick Dimensionong with a guess at column numbers, I do it here as Here all info is available to get the size right. But note as it is continuosly being (unecerssary resize I must include preseve or each time any original data is lost.</SPAN><br> Data(R + 1, C + 1) = Fields(C) <SPAN style="color:#007F00">'This puts the current Field value in the appropriate Rows and Column</SPAN><br> <SPAN style="color:#00007F">Next</SPAN> C <SPAN style="color:#007F00">' a column of our final table is full, so go to next row</SPAN><br> <SPAN style="color:#00007F">Next</SPAN> R <SPAN style="color:#007F00">'Go on to the next line or</SPAN><br> Range("A1").Resize(UBound(Data, 1), UBound(Data, 2)) = Data <SPAN style="color:#007F00">'Wew resize to exactly the same size of Data. Then this will work (Works as long as Data is eqaul to or bigger than the new range)</SPAN><br><SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">Sub</SPAN></FONT>
. In the meantime I have learnt a bit and have another bit better version of my original code. I also modified it to take in that same text file
<font face=Calibri><SPAN style="color:#00007F">Sub</SPAN> DatensaetzeLesenSayre()<br> <SPAN style="color:#00007F">On</SPAN> <SPAN style="color:#00007F">Error</SPAN> <SPAN style="color:#00007F">GoTo</SPAN> Fehler <SPAN style="color:#007F00">'Particularly good idea when playing with open files to stop rather than crash on an error</SPAN><br> <br> <SPAN style="color:#00007F">Open</SPAN> ThisWorkbook.Path & "\SayreTextDataTABCSV.txt" <SPAN style="color:#00007F">For</SPAN> <SPAN style="color:#00007F">Input</SPAN> <SPAN style="color:#00007F">As</SPAN> 3 <SPAN style="color:#007F00">'The Input option prepare the <SPAN style="color:#00007F">Input</SPAN> "Highway" 3 inn a recognisable structured way</SPAN><br> <SPAN style="color:#00007F">Dim</SPAN> FileLine <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">String</SPAN> <SPAN style="color:#007F00">'In this method a line can be diectly accessed and put in a simple string</SPAN><br> <SPAN style="color:#00007F">Dim</SPAN> ExcelRow <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Integer</SPAN>, ExcelColumn <SPAN style="color:#007F00">'In this method we can directly write in Spreadsheet</SPAN><br> <SPAN style="color:#00007F">Let</SPAN> ExcelRow = 1<br> <SPAN style="color:#00007F">Dim</SPAN> Fields() <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">String</SPAN> <SPAN style="color:#007F00">'A Simple Array for the Column Entries for a Row.</SPAN><br> <SPAN style="color:#00007F">Do</SPAN> <SPAN style="color:#00007F">Until</SPAN> EOF(3) <SPAN style="color:#007F00">'We do until the End Of File is reached</SPAN><br> Line Input #3, FileLine <SPAN style="color:#007F00">'A line can be read. (After this the next line for input is automatically set)</SPAN><br> FileLine = Replace(FileLine, vbTab, ",")<br> Fields = Split(FileLine, ",") <SPAN style="color:#007F00">'The line is split by the deliminator to a one dimensional Array in Excel Rows in one Column, but the Fields are actually our Column Entries for a Row (The current line)</SPAN><br> <SPAN style="color:#00007F">For</SPAN> ExcelColumn = 1 <SPAN style="color:#00007F">To</SPAN> <SPAN style="color:#00007F">UBound</SPAN>(Fields) + 1 <SPAN style="color:#007F00">'Going along Spreadsheet Columns</SPAN><br> <SPAN style="color:#00007F">Let</SPAN> ActiveSheet.Cells(ExcelRow, ExcelColumn).Value = Fields(ExcelColumn - 1)<br> <SPAN style="color:#00007F">Next</SPAN> ExcelColumn<br> <SPAN style="color:#00007F">Let</SPAN> ExcelRow = ExcelRow + 1 <SPAN style="color:#007F00">'This selects next excel Row</SPAN><br> <SPAN style="color:#00007F">Loop</SPAN> <SPAN style="color:#007F00">'When row complete go and do again for next row(The file row will have already been set toi next row.</SPAN><br><br> <SPAN style="color:#00007F">Close</SPAN> 3 <SPAN style="color:#007F00">'"Highway" must be closed or some nasty errors can come in.</SPAN><br> <SPAN style="color:#00007F">Exit</SPAN> <SPAN style="color:#00007F">Sub</SPAN><br>Fehler:<br> MsgBox (Err.Description)<br><SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">Sub</SPAN></FONT>
.
. Note for simplicity, both codes do not ask for your file, they simply access directly that text file. So you should put it in the same folder as the file you put the new codes in .
. Alan
I’ll try to look in again soon