-
Nov 19th, 2021, 12:24 PM
#1
Thread Starter
New Member
Bad Record Num Error
Originally Posted by TnTinMN
I can not back this up with any references as I derived it by inspecting the resultant file, but the following formula will compute the record length for your structure.
Code:
Dim reclen As Int32 = Len(Employee) + 6 * (2 * Employee.YearlyRating.Length)
Len(Employee) returns 28; this is the same value for a similar VBA UDT. So it appears as though the array declaration itself is 4 bytes (chars). The file contains the 24 characters from FName and LName followed by a sequence of 10 non-printable characters (hence the 6 = (10 - 4), in the above formula) that are then followed by the two character array elements.
Edit: The reason that setting reclen = -1 works in this case is that internally, a record length of 128 characters is applied that is more than sufficient for writing the record.
hello,
i have some problem with error 'bad record number' in Fileput(nnnn,DB_ores,XXXX) in my code:
Code:
Structure didaktiriaRec
Public tm1 As Integer
Public tm2 As Integer
Public tm3 As Integer
Public tm4 As Integer
Public tm5 As Integer
Public tm6 As Integer
Public tm7 As Integer
Public tm8 As Integer
Public tm9 As Integer
Public tm10 As Integer
Public tm11 As Integer
Public tm12 As Integer
Public tm13 As Integer
Public tm14 As Integer
Public tm15 As Integer
Public tm16 As Integer
Public tm17 As Integer
Public tm18 As Integer
Public tm19 As Integer
Public tm20 As Integer
End Structure
Structure apousiesRec
Public tm1 As Integer
Public tm2 As Integer
Public tm3 As Integer
Public tm4 As Integer
Public tm5 As Integer
Public tm6 As Integer
Public tm7 As Integer
Public tm8 As Integer
Public tm9 As Integer
Public tm10 As Integer
Public tm11 As Integer
Public tm12 As Integer
Public tm13 As Integer
Public tm14 As Integer
Public tm15 As Integer
Public tm16 As Integer
Public tm17 As Integer
Public tm18 As Integer
Public tm19 As Integer
Public tm20 As Integer
End Structure
Structure RecAgoraOresNew
Public ID As Integer
<VBFixedString(10)> Public DateKataxorisis As String
Public ID_kathigiti As Integer
Public ID_mathimatos As Integer
<VBFixedString(2)> Public minasEtousAgorasOrwn As String
<VBFixedString(4)> Public EtosAgorasOrwn As String
<VBFixedString(20)> Public EkpedeutikaEth As String
<VBFixedArray(31)> Public didaktiriaOrTmimata() As didaktiriaRec
<VBFixedArray(31)> Public apousiesDidaktiriwn() As apousiesRec
<VBFixedString(40)> Public paratiriseis As String
<VBFixedString(20)> Public allo1 As String
<VBFixedString(40)> Public allo2 As String
<VBFixedString(40)> Public allo3 As String
Public del As Boolean
End Structure
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
dim nnnn a integer
nnnn = FreeFile()
FileOpen(nnnn, "ores.dat", OpenMode.Random, , , Len(DB_Ores))
plithos_max = LOF(nnnn) / Len(DB_Ores)
For XXXX = 1 To DataGridView1.Rows.Count
DB_Ores.ID = stoxosRealRec
DB_Ores.DateKataxorisis = str
DB_Ores.ID_kathigiti = Val(mTextKathigitisID)
DB_Ores.ID_mathimatos = Val(mText2MathimaID)
DB_Ores.minasEtousAgorasOrwn = Microsoft.VisualBasic.Left(ComboBox11.SelectedItem.ToString, 2)
DB_Ores.EtosAgorasOrwn = ComboBox10.SelectedItem.ToString
DB_Ores.EkpedeutikaEth = DataGridView1.Rows(XXXX - 1).Cells(3).Value
For jhh = 1 To 31
DB_Ores.didaktiriaOrTmimata(jhh).tm1 = 0
DB_Ores.didaktiriaOrTmimata(jhh).tm2 = 0
DB_Ores.didaktiriaOrTmimata(jhh).tm3 = 0
DB_Ores.didaktiriaOrTmimata(jhh).tm4 = 0
DB_Ores.didaktiriaOrTmimata(jhh).tm5 = 0
DB_Ores.didaktiriaOrTmimata(jhh).tm6 = 0
DB_Ores.didaktiriaOrTmimata(jhh).tm7 = 0
DB_Ores.didaktiriaOrTmimata(jhh).tm8 = 0
DB_Ores.didaktiriaOrTmimata(jhh).tm9 = 0
DB_Ores.didaktiriaOrTmimata(jhh).tm10 = 0
DB_Ores.didaktiriaOrTmimata(jhh).tm11 = 0
DB_Ores.didaktiriaOrTmimata(jhh).tm12 = 0
DB_Ores.didaktiriaOrTmimata(jhh).tm13 = 0
DB_Ores.didaktiriaOrTmimata(jhh).tm14 = 0
DB_Ores.didaktiriaOrTmimata(jhh).tm15 = 0
DB_Ores.didaktiriaOrTmimata(jhh).tm16 = 0
DB_Ores.didaktiriaOrTmimata(jhh).tm17 = 0
DB_Ores.didaktiriaOrTmimata(jhh).tm18 = 0
DB_Ores.didaktiriaOrTmimata(jhh).tm19 = 0
DB_Ores.didaktiriaOrTmimata(jhh).tm20 = 0
next jhh
DB_Ores.del = False
DB_Ores.paratiriseis = ""
DB_Ores.allo1 = ""
DB_Ores.allo2 = ""
DB_Ores.allo3 = ""
FilePut(nnnn, DB_Ores, XXXX)
Next XXXX
FileClose(nnnn)
End Sub
Last edited by dday9; Nov 19th, 2021 at 12:41 PM.
-
Nov 19th, 2021, 12:30 PM
#2
Re: Solved - Bad record length vb.net 2008
Please do not resurrect old threads. Is your question Visual Basic .NET or VB6 (or earlier)?
-
Nov 19th, 2021, 12:38 PM
#3
Thread Starter
New Member
Re: Error - Bad record length vb.net 2010
sorry, I have put these following commands in the code of my previous post (at the beginning in 'Sub Button4_Click'):
Code:
ReDim DB_Ores.didaktiriaOrTmimata(31)
ReDim DB_Ores.apousiesDidaktiriwn(31)
Last edited by dday9; Nov 19th, 2021 at 12:42 PM.
-
Nov 19th, 2021, 12:38 PM
#4
Thread Starter
New Member
Re: Solved - Bad record length vb.net 2008
Originally Posted by dday9
Please do not resurrect old threads. Is your question Visual Basic .NET or VB6 (or earlier)?
aaaa OK
-
Nov 19th, 2021, 12:39 PM
#5
Thread Starter
New Member
Re: Solved - Bad record length vb.net 2008
Originally Posted by dday9
Please do not resurrect old threads. Is your question Visual Basic .NET or VB6 (or earlier)?
Visual Basic 2010
-
Nov 19th, 2021, 12:44 PM
#6
Re: Bad Record Num Error
No offense, but it looks like your code was written in 1995.
Could you explain what it is that you're actually trying to do? Is it just reading a dat file and populating the results in a DataGridView?
-
Nov 19th, 2021, 12:53 PM
#7
Thread Starter
New Member
Re: Bad Record Num Error
Originally Posted by dday9
No offense, but it looks like your code was written in 1995.
Could you explain what it is that you're actually trying to do? Is it just reading a dat file and populating the results in a DataGridView?
I want you to tell me why when I put a array in my structure RecAgoraOresNew it gets an error in the 'fileput'
or
give an example of writing to a random access file of a structure (with array inside)
-
Nov 19th, 2021, 12:56 PM
#8
Re: Bad Record Num Error
I still don't understand what it is that you are trying to accomplish. Could you, in plain English, explain what it is that you're trying to do?
If it is writing the contents of an array to a file then that could be as simple as:
Code:
IO.File.WriteAllLines("my-file", myarray)
But depending on what you're actually trying to do, that may or may not be the solution.
-
Nov 19th, 2021, 01:07 PM
#9
Thread Starter
New Member
Re: Bad Record Num Error
Originally Posted by dday9
I still don't understand what it is that you are trying to accomplish. Could you, in plain English, explain what it is that you're trying to do?
If it is writing the contents of an array to a file then that could be as simple as:
Code:
IO.File.WriteAllLines("my-file", myarray)
But depending on what you're actually trying to do, that may or may not be the solution.
i use random files (with fileopen , fileget, fileput ..) . i need one basic Stucture with array() inside like: RecAgoraOresNew but when write that structure with 'Fileput ' get me fault: Bad record length . Why ?
(sorry my english)
-
Nov 19th, 2021, 01:08 PM
#10
Re: Bad Record Num Error
FilePut? Redim? Don't use that VB6 rubbish in VB.Net.
If you want a resizable collection of items, use a List(Of T) and of course dday9 has already shown you one possible way to write to a file.
-
Nov 19th, 2021, 02:37 PM
#11
Re: Bad Record Num Error
If you're writing the file from scratch and not trying to read in something existing or from another system, the easiest thing to do is create a class that has the properties that you want. So let's say you want to store "A" and "B" plus an array or list of strings:
Code:
Public Class SomeData
Public Property A as Integer
Public Property B as Integer
Public Property SomeStrings as new List(Of String)
End Class
Once you have that, you can use serialization to write the data to a file. Then use deserializaiton to read it back.
Code:
Dim s As New FileStream("SomeStuff", FileMode.Create)
Dim f As New BinaryFormatter
f.Serialize(s, my_someData) ' where my_someData is an instance of SomeData
s.Close()
You can also serialize to XML or JSON if you want a resulting file that's more readable.
-tg
-
Nov 19th, 2021, 03:48 PM
#12
Thread Starter
New Member
Re: Bad Record Num Error
Originally Posted by techgnome
If you're writing the file from scratch and not trying to read in something existing or from another system, the easiest thing to do is create a class that has the properties that you want. So let's say you want to store "A" and "B" plus an array or list of strings:
Code:
Public Class SomeData
Public Property A as Integer
Public Property B as Integer
Public Property SomeStrings as new List(Of String)
End Class
Once you have that, you can use serialization to write the data to a file. Then use deserializaiton to read it back.
Code:
Dim s As New FileStream("SomeStuff", FileMode.Create)
Dim f As New BinaryFormatter
f.Serialize(s, my_someData) ' where my_someData is an instance of SomeData
s.Close()
You can also serialize to XML or JSON if you want a resulting file that's more readable.
-tg
Thanks , i need save with recordnumber because after i read again for find my records
I want like as:
Dim reclen As Int32 = Len(Employee) + 6 * (2 * Employee.YearlyRating.Length) from old previous post to calculate my record length because this is problem. My two arrays in structure its the problem. Without arrays alls is Ok
Last edited by sakissoft@gmail.com; Nov 19th, 2021 at 03:56 PM.
-
Nov 19th, 2021, 05:41 PM
#13
Re: Bad Record Num Error
If you're not opposed to reading all the records into memory at once, you can do something like this for both reading and writing records:-
Code:
Imports System.IO
Imports System.Runtime.Serialization.Formatters.Binary
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim data As New List(Of DataClass)
Dim fileName As String = Application.StartupPath & "\myrecs.bin"
data.Add(New DataClass("Hello", 90001, {"Day", "Night"}))
data.Add(New DataClass("Training Day", 2, {"Hunter", "Moon", "DXT5"}))
data.Add(New DataClass("Test String4", 25, {"Gallery"}))
data.Add(New DataClass("Boo", 671123, {"Deaf", "Blind", "Dumb", "Crazy", "Hello", "Goodbye"}))
data.Add(New DataClass("Boo7070", 7070, {}))
data.Add(New DataClass("Pidgeon", 212, {"Blinded", "T1", "T2", "T3", "T4"}))
'Save records to file
SaveRecords(data, fileName)
'Read the data from file
Dim dataFromFile = ReadRecords(fileName)
'Print the 4rd record loaded from file
Debug.WriteLine(dataFromFile.Item(3).ToString)
End Sub
Private Sub SaveRecords(ByVal records As IEnumerable(Of DataClass), ByVal fileName As String)
Using fs As New FileStream(fileName, FileMode.Create, FileAccess.Write)
Dim bw As New BinaryFormatter
bw.Serialize(fs, records)
End Using
End Sub
Private Function ReadRecords(ByVal fileName As String) As List(Of DataClass)
Using fs As New FileStream(fileName, FileMode.Open, FileAccess.Read)
Dim bw As New BinaryFormatter
Return DirectCast(bw.Deserialize(fs), IEnumerable(Of DataClass)).ToList
End Using
End Function
End Class
<Serializable>
Public Class DataClass
Public Sub New(ByVal sdata As String, idata As Integer, ByVal sldata As String())
Me.StringData = sdata
Me.IntegerData = idata
Me.StringListData = sldata.ToList
End Sub
Public Property StringData As String
Public Property IntegerData As Integer
Public Property StringListData As List(Of String)
Public Overrides Function ToString() As String
Return $"String Data = {Me.StringData}, Integer Data = {Me.IntegerData.ToString}, StringList = {String.Join(", ", Me.StringListData)}"
End Function
End Class
The above is an example of the easiest way to save and read structured data in a binary file in .Net.
-
Nov 19th, 2021, 06:33 PM
#14
Re: Bad Record Num Error
I haven't used the old Random Record Access method with .Net, but the problem is essentially that a structure is not really a fully compatible replacement for the VB6 User Defined Type.
The problem is that your record length is too short.
You can't get an accurate length of the structure by using the Len function on the structure. Since you have structures in your structures, and even though a structure is treated like a value type, I believe it still uses a "pointer" to reference the structure so your nested structure arrays are probably counted as an array of pointers (32 4-byte pointers = 128 bytes) instead of the actual data storage of (32 * 80 {80 = 20 * 4-byte integers in your structure} = 2560 bytes. You have two similar structures with the same number of fields so that would be 5120 bytes just for those two arrays. Your original length probably reported something like 190, so if you add 200 to 5120 you get 5320.
Your record size has to be big enough to hold the serialized data, but can be bigger. It will just have some unused bytes at the end of each record. So, if you specify a larger amount than you actually need, you have some waste, but not necessarily a lot if you calculate it correctly.
I might even go to 5500 or 6000 to make the amount of disk storage easier to calculate based on the number of records without using a calculator.
Be aware that record size just indicates where each record will start, not where it finishes.
If you say the record size is 500, but it really only requires 400 bytes to serialize, the start of each record will be on a 500 byte boundary and you can "randomly" jump to any 500 byte modulus offset in your file to get to a particular record, but the record itself will be written to the first 400 bytes, and you have 100 unused bytes at the end of each record.
The file length will thus be (Number of records - 1) * 500 + 400 in size as the last record written doesn't pad out to 500.
I don't know if you will have other issues, but you can try changing the two lines in your code to see if you get past the current problem.
Code:
FileOpen(nnnn, "C:\c\ores.dat", OpenMode.Random, , , 5320) 'Len(DB_Ores))
' plithos_max = CInt(LOF(nnnn) / Len(DB_Ores))
plithos_max = CInt(LOF(nnnn) / 5320) + 1 'Len(DB_Ores))
Back in my VB1 to VB6 days when I used Random access records, I didn't store the UDT defined for the record in the first record. I actually just wrote the number of valid records that were in the file, in the first (0) "slot" of the file.
That way I could open the file, read the Long value (call it X) from the file at the first record of the file, then know I had 1 to X records in the file, and the next record to be written would be X + 1.
This would be particularly handy since I could "delete" records and shuffle the data down to keep the records packed, but the size of the file would remain the same length, so using the length of the file to determine the number of records would be incorrect.
Last edited by passel; Nov 19th, 2021 at 06:49 PM.
"Anyone can do any amount of work, provided it isn't the work he is supposed to be doing at that moment" Robert Benchley, 1930
-
Nov 19th, 2021, 07:02 PM
#15
Re: Bad Record Num Error
I'll just straight, I don't think people should still be reading/writing records like this in .Net. Not because it's bad but because there are so many better ways to go about it now and .Net provides a lot of infrastructure to support them. This kind of low level random access IO with structures is a very outdated way of implementing a database.
-
Nov 19th, 2021, 07:22 PM
#16
Thread Starter
New Member
Re: Bad Record Num Error
Originally Posted by passel
I haven't used the old Random Record Access method with .Net, but the problem is essentially that a structure is not really a fully compatible replacement for the VB6 User Defined Type.
The problem is that your record length is too short.
You can't get an accurate length of the structure by using the Len function on the structure. Since you have structures in your structures, and even though a structure is treated like a value type, I believe it still uses a "pointer" to reference the structure so your nested structure arrays are probably counted as an array of pointers (32 4-byte pointers = 128 bytes) instead of the actual data storage of (32 * 80 {80 = 20 * 4-byte integers in your structure} = 2560 bytes. You have two similar structures with the same number of fields so that would be 5120 bytes just for those two arrays. Your original length probably reported something like 190, so if you add 200 to 5120 you get 5320.
Your record size has to be big enough to hold the serialized data, but can be bigger. It will just have some unused bytes at the end of each record. So, if you specify a larger amount than you actually need, you have some waste, but not necessarily a lot if you calculate it correctly.
I might even go to 5500 or 6000 to make the amount of disk storage easier to calculate based on the number of records without using a calculator.
Be aware that record size just indicates where each record will start, not where it finishes.
If you say the record size is 500, but it really only requires 400 bytes to serialize, the start of each record will be on a 500 byte boundary and you can "randomly" jump to any 500 byte modulus offset in your file to get to a particular record, but the record itself will be written to the first 400 bytes, and you have 100 unused bytes at the end of each record.
The file length will thus be (Number of records - 1) * 500 + 400 in size as the last record written doesn't pad out to 500.
I don't know if you will have other issues, but you can try changing the two lines in your code to see if you get past the current problem.
Code:
FileOpen(nnnn, "C:\c\ores.dat", OpenMode.Random, , , 5320) 'Len(DB_Ores))
' plithos_max = CInt(LOF(nnnn) / Len(DB_Ores))
plithos_max = CInt(LOF(nnnn) / 5320) + 1 'Len(DB_Ores))
Back in my VB1 to VB6 days when I used Random access records, I didn't store the UDT defined for the record in the first record. I actually just wrote the number of valid records that were in the file, in the first (0) "slot" of the file.
That way I could open the file, read the Long value (call it X) from the file at the first record of the file, then know I had 1 to X records in the file, and the next record to be written would be X + 1.
This would be particularly handy since I could "delete" records and shuffle the data down to keep the records packed, but the size of the file would remain the same length, so using the length of the file to determine the number of records would be incorrect.
You are the BEST. this is exactly what I wanted. there was no other way to solve this code. Thank you very much.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|