With the following
DIM a AS INTEGER
a = 10
OPEN "myFile" FOR BINARY AS #1
PUT #1, 1, a
CLOSE #1
I get a file (myFile) with two bytes (using QB64). The first byte is indeed 0A, but there is a second byte 00.
How can I create a file with just one byte?
Snip to write a byte to file:
DIM B AS STRING * 1
x = 10
B = CHR$(x)
OPEN "myfile" FOR BINARY AS #1
PUT #1, 1, B
CLOSE #1
Try this
DIM a AS _UNSIGNED _BYTE
a = 10
OPEN "myFile" FOR BINARY AS #1
PUT #1, 1, a
CLOSE #1
It seems like INTEGER is 2 bytes.
Related
I have a simple code
FileName = "h:\OutStr.txt"
Dim BA(1) As Byte
BA(0) = 99
BA(1) = 100
Open FileName For Binary Access Write As #1
lWritePos = 1
Put #1, lWritePos, BA
Close #1
After saving, OutStr.txt contains two bytes as expected: 99 and 100.
But the result is different in case I am using a function:
Sub BytesToBinaryFile(out_file_name_, vData_)
Open out_file_name_ For Binary Access Write As #1
lWritePos = 1
Put #1, lWritePos, vData_
Close #1
End Sub
FileName = "h:\OutStr.txt"
Dim BA(1) As Byte
BA(0) = 99
BA(1) = 100
Call BytesToBinaryFile(FileName, BA)
In this case the saved file conatins a sequence of bytes, like:
17 32 1 0 2 0 0 0 0 0 0 0 99 100
Could anybody explain me the difference in the results?
Many thanks in advance!
In
Sub BytesToBinaryFile(out_file_name_, vData_)
both variables are of type Variant.
Declare them properly and it works as expected in the function as well
Option Explicit
Public Sub BytesToBinaryFile(ByVal out_file_name_ As String, ByRef vData_() As Byte)
Open out_file_name_ For Binary Access Write As #1
Const lWritePos As Long = 1
Put #1, lWritePos, vData_
Close #1
End Sub
I recommend always to activate Option Explicit: In the VBA editor go to Tools › Options › Require Variable Declaration.
And declare all variables as good as possible and avoid Variant whenever you can.
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.
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
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
I am trying to read file names from source directory and then read a separate file to rename and move files to target directory. Below code reads the file names but the problem is it only reading the contents of app.ini file only once i.e. for first file name. Code is not looping app.ini as soon as for loops switches to second file name.
Dim di As New IO.DirectoryInfo("D:\Transcend")
Dim diar1 As IO.FileInfo() = di.GetFiles()
Dim dra As IO.FileInfo
If (di.GetFiles.Count > 0) Then
Dim a As Integer = 1
Dim b As Integer = 1
For Each dra In diar1
ComboBox1.Items.Add(dra.FullName.ToString)
Using reader2 As New IO.StreamReader("D:\Transcend\test\app.ini")
Do While reader2.Peek() >= 0
Dim line2 = reader2.ReadLine
Do Until line2 Is Nothing
'line2 = reader2.ReadLine()
'ComboBox1.Items.Add(line2.ToString)
'Label1.Text = line2
If line2 <> Nothing Then
If line2.Contains("filename" + a.ToString) Then
Dim values() As String = line2.Split(CChar(":")).ToArray
Dim values2() As String = values(1).Split(CChar(";")).ToArray() 'full filename
Dim values3() As String = values(2).Split(CChar(";")).ToArray() 'keyword to be replaced in filename
Dim values4() As String = values(3).Split(CChar(";")).ToArray() 'fullname in place of keyword
Dim values5() As String = values(4).Split(CChar(";")).ToArray 'destination drive letter
Dim values6() As String = values(5).Split(CChar(";")).ToArray 'destination path after drive letter
ComboBox1.Items.Add(values2(0))
ComboBox1.Items.Add(values3(0))
ComboBox1.Items.Add(values4(0))
ComboBox1.Items.Add(values5(0) + ":" + values6(0))
'Label1.Text = dra.Name.ToString
If dra.Name.ToString.Contains(values2(0)) Then
Dim n As String = dra.Name.Replace(values3(0), values4(0))
File.Copy(dra.FullName, values5(0) + ":" + values6(0) + n)
End If
End If
End If
Exit Do
Loop
a = a + 1
Loop
reader2.Close()
End Using
b = b + 1
Next
Label1.Text = b
Else
MsgBox("No files!")
End
End If
ouput image:
Above image is to show the output and error, first line is the filename1 and the next 8 lines are the output of the app.ini file. As you can see as soon as the filename1 changes to the next file name i.e. Autorun.inf in the 9th line of the above image the same 8 lines of app.ini(line 2nd to 9th in the above image) should be reiterated after Autorun.inf file name but app.ini is not getting to read after file name increments to Autorun.inf and then to FreeSoftware(JF).htm.
The only difference between the first and the second file are the a and b values.
On the first run a will start from 1 and it will be incremented for each line in the app.ini file. After reading 8 lines, the final value of a will be 9.
For the second file, the value a isn't reset so it's value will still be 9. This means that the following condition will never be true because the first run only found value from 1 to 8 *.
If line2.Contains("filename" + a.ToString) Then
To fix your issue, you must set the a variable value back to 1 between each file:
Using reader2 As New IO.StreamReader("D:\Transcend\test\app.ini")
a = 1
Do While reader2.Peek() >= 0
* I'm assuming that the filename in your .ini file are sorted (i.e. line containing filename9 isn't listed before filename2) and that no external process changed the content of your .ini file between the first and the second file.