Reading formatted data from a text file - vba

The following code reads in values (in a loop) from a text file containing two numbers per line into X and Y. The first iteration of the loop gives correct values for X and Y (70, 210). The next iteration onwards, the X and Y values are not what is contained in the file (210, 210 for the second iteration instead of 0, 210). I ust be making a mistake but I can't seem to find it !
Sub main()
Dim X As Double
Dim Y As Double
Open "perforatedcircles.txt" For Input As #1
Do While Not EOF(1)
Input #1, X, Y
Loop
Close #1
End Sub
Sample Contents of "perforatedcircles.txt":
70.000 210.000
0.000 210.000
-70.000 -210.000

How was the input file created? It appears to be in a different format than the Input # directive is expecting.
https://msdn.microsoft.com/en-us/library/aa243386(v=vs.60).aspx
"Data read with Input # is usually written to a file with Write #. Use this statement only with files opened in Input or Binary mode."
"Note To be able to correctly read data from a file into variables using Input #, use the Write # statement instead of the Print # statement to write the data to the files. Using Write # ensures each separate data field is properly delimited."
Given the space delimitation, you'll need to parse the file differently. Here is one example:
Dim iLine As Integer,
Dim sFile As String
Dim sData As String
Dim sLine() As String
Dim sSplitLine() As String
Dim x as Double
Dim y as Double
'read the whole file into 1 string variable
sFile = "perforatedcircles.txt"
Open sFile For Input As #1
sData = Input(LOF(1), 1)
Close #1
sLine = Split(sData, vbCrLf)
For iLine = 0 To UBound(sLine)
sSplitLine = Split(sLine(UBound(sLine)), " ")
x = CDbl(sSplitLine(0))
y = CDbl(sSplitLine(1))
'Do Stuff with your numbers here
Next iLine

Related

Converting .txt file directly into an array with custom delimiter

I am converting a .txt file directly into an array in excel VBA. The default delimiter is a "," (comma) and I need to change it to "vblf". I am having trouble figuring out how to do that with the code I have today.
Please help
Const strFileName As String = [file]
Dim CONFIGTXT(1 To 13000) As String
Dim intFileNum As Integer
Dim intCount As Integer
Dim strRecordData As String
intFileNum = FreeFile
intCount = 1
Open strFileName For Input As #intFileNum
Do Until EOF(intFileNum) Or intCount > 13000
Input #intFileNum, strRecordData
CONFIGTXT(intCount) = strRecordData
intCount = intCount + 1
Loop
Close #intFileNum
Range("Q2:Q" & UBound(CONFIGTXT) + 1) = WorksheetFunction.Transpose(CONFIGTXT)
Change
Input #intFileNum, strRecordData
to
Line Input #intFileNum, strRecordData
Input is intended to read in data that is comma-delimited, one variable at a time. For example, if you had data of
12345,789
and used the statement
Input #intFileNum var1, var2
then var1 would be given the value 12345 and var2 would be given the value 789.
Line Input is intended to read a line at a time, delimited by the new line character (normally CR/LF).
Note: If your data has information separated by line feeds, this will NOT separate those portions into separate entries in the array. So if your data contains
xxx/xxx/xxx
where the / is actually a line feed, that entire record will be placed into one cell in the final output.

Writing Fixed width text files from excel vba

This is the output of a program.
I have specified what shall be width of each cell in the program and my program shows correct output.
What I want to do is cell content shall be written from right to left. E.g highlighted figure 9983.54 has width of 21. Text file has used first 7 columns. But I want it to use last 7 columns of text file.
Please see expected output image.
I am not getting any clue how to do this. I am not a very professional programmer but I love coding. This text file is used as input to some other program and i am trying to automate writing text file from excel VBA.
Can anyone suggest a way to get this output format?
Here is the code which gave me first output
Option Explicit
Sub CreateFixedWidthFile(strFile As String, ws As Worksheet, s() As Integer)
Dim i As Long, j As Long
Dim strLine As String, strCell As String
'get a freefile
Dim fNum As Long
fNum = FreeFile
'open the textfile
Open strFile For Output As fNum
'loop from first to last row
'use 2 rather than 1 to ignore header row
For i = 1 To ws.Range("a65536").End(xlUp).Row
'new line
strLine = ""
'loop through each field
For j = 0 To UBound(s)
'make sure we only take chars up to length of field (may want to output some sort of error if it is longer than field)
strCell = Left$(ws.Cells(i, j + 1).Value, s(j))
'add on string of spaces with length equal to the difference in length between field length and value length
strLine = strLine & strCell & String$(s(j) - Len(strCell), Chr$(32))
Next j
'write the line to the file
Print #fNum, strLine
Next i
'close the file
Close #fNum
End Sub
'for example the code could be called using:
Sub CreateFile()
Dim sPath As String
sPath = Application.GetSaveAsFilename("", "Text Files,*.txt")
If LCase$(sPath) = "false" Then Exit Sub
'specify the widths of our fields
'the number of columns is the number specified in the line below +1
Dim s(6) As Integer
'starting at 0 specify the width of each column
s(0) = 21
s(1) = 9
s(2) = 15
s(3) = 11
s(4) = 12
s(5) = 10
s(6) = 186
'for example to use 3 columns with field of length 5, 10 and 15 you would use:
'dim s(2) as Integer
's(0)=5
's(1)=10
's(2)=15
'write to file the data from the activesheet
CreateFixedWidthFile sPath, ActiveSheet, s
End Sub
Something like this should work:
x = 9983.54
a = Space(21-Len(CStr(x))) & CStr(x)
Then a will be 14 spaces followed by x:
a = " 9983.54"
Here 21 is the desired column width --- change as necessary. CStr may be unnecessary for non-numeric x.
If you're going to right-justify a lot of different data to different width fields you could write a general purpose function:
Function LeftJust(val As String, width As Integer) As String
LeftJust = Space(width - Len(val)) & val
End Function
The you call it with LeftJust(CStr(9983.54), 21).
Also note that VBA's Print # statement has a Spc(n) parameter that you can use to produce fixed-width output, e.g., Print #fNum, Spc(n); a; before this statement you calculate n: n = 21-Len(CStr(a)).
Hope that helps

Text File Column Data Extraction with Excel VBA

I have code below that extracts data from a text file and sends to a worksheet. Data sends to the worksheet but its a mess. I aim to extract certain columns of data in the text file. Data columns are space delimited and spacing differs between column but ea column has a heading. How can I complete my code to search text file by column header name and send data under that header to the worksheet? A typical header and columns of data underneath is shown below the code. Header blocks and associated data are repeated throughout the text file but are space delimited by rows. Above ea header band is an identifier for that block.
Sub test()
Dim Path As String
Dim textline As String
Dim arr() As String
Dim i As Long, j As Long
Path = whatever...
Open Path For Input As #1
i = 1
While EOF(1) = False
Line Input #1, textline
arr = Split(CStr(textline), " ")
For j = 1 To UBound(arr)
ActiveSheet.Cells(i, j).Value = arr(j - 1)
Next j
i = i + 1
Wend
Close #1
End Sub
Identifier 1.1
Heave /
Wave Ampl.
/--------------/
Ampl. Phase
0.123 42
0.131 72
0.433 55

Reading csv file with strange line deliminter in VBA

I have a input file which I am struggling to read in line by line, The file can be found here and is also shown below:
I would like to add the first value as key and the third value as item in a dictonary
Then later I can do this: a = myDictonary("CREATED_BY") and this will then return "Eigil..." (Order and number of lines my vary from time to time..)
But somehow I can not get the split to work:
Dim hf As Integer: hf = FreeFile
Dim lines() As String, i As Long
Open FileName For Input As #hf
Line Input #hf, dataLine
lines = Split(dataLine, vbNewLine)
lines = Split(dataLine, "\n")
lines = Split(dataLine, "CR")
lines = Split(dataLine, "LF")
Close #hf
I also tried to follow this thread
For people who like to use dictinary here is my code for that:
Set getProjectDictionary = CreateObject("Scripting.Dictionary")
Dim item As String
Dim key As String
Dim dataLine As String
Open FileName For Input As 1
While Not EOF(1)
On Error Resume Next
Line Input #1, dataLine
temp = Split(dataLine, ",")
If Not temp(0) = "" Then
getProjectDictionary.Add temp(0), temp(3)
End If
Wend
Close 1
I added some debug output below:
The screenshot you attached shows that the file uses CR LF as linebreaks but the file I downloaded from your Google Drive link actually uses LF only, so you might want to use:
lines = Split(dataLine, vbLf)
Also, the file uses Little Endian UCS-2 encoding with BOM. If you simply open the file using the Open statement, you are likely to run into corrupt characters and other encoding related problems. I would suggest using Filesystem object instead.
I think this has the answer - split on vbcrlf?
CRLF in VBScript
Of the 4 examples you gave, "CR" and "LF" would look for the literal strings "CR" and "LF", which is not what you want. VB doesn't recognize "\n" like most C-like languages, so that's out. vbnewline was the closest to working, but I think this might help you:
http://www.jaypm.com/2012/08/the-difference-between-vbcrlf-vbnewline-and-environment-newline/
Here is my code that currently seems to work well:
Option Explicit
Sub test()
Dim a As Object
Set a = getPropertiesDictionary("c:\Temp\Creo\param_table.csv")
Debug.Print a.item("PTC_WM_CREATED_BY")
End Sub
' populate dictinoary with document types based on input file
Function getPropertiesDictionary(FileName As String) As Object
Set getPropertiesDictionary = CreateObject("Scripting.Dictionary")
Dim temp() As String
Dim dataLine As String
Dim hf As Integer: hf = FreeFile
Dim lines() As String, i As Long
Open FileName For Input As #hf
Line Input #hf, dataLine
lines = Split(dataLine, vbLf)
Close #hf
For i = 0 To UBound(lines) - 1
temp = Split(lines(i), ",")
If Not temp(0) = "" Then
getPropertiesDictionary.Add temp(0), temp(2)
End If
Next
End Function

Is it possible to rename the files after copying from source folder?

I copy some test images from source folder.. but i want to make their image name become "001,002" .. and so on.
For Each path As ListViewItem In listbat1.Items
For Each Ftif As String In Directory.GetFiles(path.SubItems(0).Text, "*.tif")
'For n As Integer = 0 To listbat1.Items.Count - 1
Dim Finfo As New FileInfo(Ftif)
My.Computer.FileSystem.CopyFile(Ftif, txtdirectory.Text & imgdir & Finfo.Name & ".tif")
'Next
Next
Next
Is it possible ? if so, can you help me? pls ..
If you want to rename your file using a progressive counter, then you could easily do it using the ToString with a formatting expression. In this example D3 means convert the input number to a string using three numbers and padding with zero if the number is not converted to enough character.
Dim counter as Integer = 0
For Each path As ListViewItem In listbat1.Items
For Each Ftif As String In Directory.GetFiles(path.SubItems(0).Text, "*.tif")
Dim Finfo As New FileInfo(Ftif)
Dim destFile = Path.Combine(txtDirectory.Text, imgdir, counter.ToString("D3") + ".tif")
My.Computer.FileSystem.CopyFile(Ftif, destFile)
Counter = Counter + 1
Next
Next
Notice also that building a path should always be done using the Path class