theheard User Defined Type


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 2 of 2

Thread: theheard User Defined Type

  1. #1
    mIKE Guest

    theheard User Defined Type


    Private Type Cattle
    tag As String
    wgt As Integer
    amt As Currency
    End Type



    Dim filesys, txtStream As Object

    Private Sub Form_Load()
    Dim i As Integer
    Dim theHeard(1 To 500) As Cattle
    For i = 1 To 500
    theHeard(i).tag = "tag #" & i
    theHeard(i).wgt = i
    theHeard(i).amt = 0.5 * i
    Next
    Set filesys = CreateObject("Scripting.FileSystemObject")
    Set txtStream = filesys.CreateTextFile("C:\Windows\Desktop\cattle.txt")
    For i = 1 To 500
    txtStream.WriteLine theHeard(i).tag & " : " & _
    theHeard(i).wgt & " : " & theHeard(i).wgt
    Next
    End Sub

    how do i individually give theHeard
    theHeard.amt, theHeard.wtg, theHeard.tag

    individual values. Let me explain :
    each Beast will need me to put in it's own tag string like A1 or G6 and different
    weights eg. thHeard.wtg and what the beast was sold for theHeard.amt.

    HERE IS A SUGGESTION I RECIEVIED, THOUGH NOW i'M GETTING MORE CONFUSED,
    i JUST WANT TO RECORD MY **** CATTLE DETAILS THEN WHEN I GOT THAT MASTERED
    i KEEP ON EXPANDING THE APPLICATION
    Open "file.dat" for binary as #1
    Put #1, , udtvariable
    Close #1

    Use of the filesys object is overkill.

    In general a simple application can be created by just putting 3 text boxes
    (ID, weight, $$) on a window,
    with a single scroll bar. The .value property of the scroll bar determines
    the information shown.

    One button for Save using the code above.

    To read the file, another 3 lines:

    Open "file.dat" for binary as #1
    Get #1, , udtvariable
    Close #1

    There are several ways to have the information entered in the text boxes
    saved, but the simple approach is just a command button labeled "Apply" with
    the code to store the values in the click event.




  2. #2
    Tony Smith Guest

    Re: theheard User Defined Type

    mIKE wrote:
    >
    > Private Type Cattle
    > tag As String
    > wgt As Integer
    > amt As Currency
    > End Type
    >
    > Dim filesys, txtStream As Object
    >
    > Private Sub Form_Load()
    > Dim i As Integer
    > Dim theHeard(1 To 500) As Cattle
    > For i = 1 To 500
    > theHeard(i).tag = "tag #" & i
    > theHeard(i).wgt = i
    > theHeard(i).amt = 0.5 * i
    > Next
    > Set filesys = CreateObject("Scripting.FileSystemObject")
    > Set txtStream = filesys.CreateTextFile("C:\Windows\Desktop\cattle.txt")
    > For i = 1 To 500
    > txtStream.WriteLine theHeard(i).tag & " : " & _
    > theHeard(i).wgt & " : " & theHeard(i).wgt
    > Next
    > End Sub
    >
    > how do i individually give theHeard
    > theHeard.amt, theHeard.wtg, theHeard.tag
    >
    > individual values. Let me explain :
    > each Beast will need me to put in it's own tag string like A1 or G6 and different
    > weights eg. thHeard.wtg and what the beast was sold for theHeard.amt.
    >
    > HERE IS A SUGGESTION I RECIEVIED, THOUGH NOW i'M GETTING MORE CONFUSED,
    > i JUST WANT TO RECORD MY **** CATTLE DETAILS THEN WHEN I GOT THAT MASTERED
    > i KEEP ON EXPANDING THE APPLICATION
    > Open "file.dat" for binary as #1
    > Put #1, , udtvariable
    > Close #1
    >
    > Use of the filesys object is overkill.
    >
    > In general a simple application can be created by just putting 3 text boxes
    > (ID, weight, $$) on a window,
    > with a single scroll bar. The .value property of the scroll bar determines
    > the information shown.
    >
    > One button for Save using the code above.
    >
    > To read the file, another 3 lines:
    >
    > Open "file.dat" for binary as #1
    > Get #1, , udtvariable
    > Close #1
    >
    > There are several ways to have the information entered in the text boxes
    > saved, but the simple approach is just a command button labeled "Apply" with
    > the code to store the values in the click event.




    Ok, try this. Save the next bit as cattle.frm, and load it into VB.
    A few long lines might get mangled, so you'll need to fix them.

    --Cut here--

    VERSION 5.00
    Begin VB.Form Form1
    Caption = "Form1"
    ClientHeight = 1920
    ClientLeft = 75
    ClientTop = 360
    ClientWidth = 4680
    LinkTopic = "Form1"
    ScaleHeight = 1920
    ScaleWidth = 4680
    StartUpPosition = 3 'Windows Default
    Begin VB.CommandButton Apply
    Caption = "Apply"
    Height = 300
    Left = 3240
    TabIndex = 5
    Top = 1350
    Width = 1200
    End
    Begin VB.CommandButton Next
    Caption = "Next"
    Height = 300
    Left = 1800
    TabIndex = 4
    Top = 1350
    Width = 1200
    End
    Begin VB.CommandButton Prev
    Caption = "Prev"
    Height = 300
    Left = 270
    TabIndex = 3
    Top = 1350
    Width = 1200
    End
    Begin VB.TextBox Amt
    Height = 300
    Left = 3210
    TabIndex = 2
    Top = 720
    Width = 1200
    End
    Begin VB.TextBox wgt
    Height = 300
    Left = 1740
    TabIndex = 1
    Top = 690
    Width = 1200
    End
    Begin VB.TextBox Tagg
    Height = 300
    Left = 210
    TabIndex = 0
    Top = 690
    Width = 1200
    End
    Begin VB.Label Number
    BorderStyle = 1 'Fixed Single
    Height = 300
    Left = 180
    TabIndex = 6
    Top = 150
    Width = 1200
    End
    End
    Attribute VB_Name = "Form1"
    Attribute VB_GlobalNameSpace = False
    Attribute VB_Creatable = False
    Attribute VB_PredeclaredId = True
    Attribute VB_Exposed = False
    Option Explicit



    Const FileName = "C:\Windows\Desktop\cattle.txt"

    Dim CurrentCow As Integer

    Private Type Cattle
    Tag As String
    wgt As Integer
    Amt As Currency
    End Type

    Dim theHeard(1 To 500) As Cattle

    Private Sub Form_Load()

    Dim FileNumber As Long
    Dim ReadCow As Long

    FileNumber = FreeFile
    On Error Resume Next
    Open FileName For Input As #FileNumber
    If Err = 0 Then
    For ReadCow = 1 To 500
    If EOF(FileNumber) Then
    Exit For
    End If
    Input #FileNumber, theHeard(ReadCow).Tag,
    theHeard(ReadCow).wgt, theHeard(ReadCow).Amt
    Next ReadCow
    End If
    Close #FileNumber
    On Error GoTo 0

    ' ReadCow = 1
    ' FileNumber = FreeFile
    ' On Error Resume Next
    ' Open FileName For Input As #FileNumber
    ' If Err = 0 Then
    ' Do Until EOF(FileNumber)
    ' Input #FileNumber, theHeard(ReadCow).Tag,
    theHeard(ReadCow).wgt, theHeard(ReadCow).Amt
    ' ReadCow = ReadCow + 1
    ' Loop
    ' End If
    ' Close #FileNumber
    ' On Error GoTo 0

    CurrentCow = 1
    Call UpdateScreen

    End Sub

    Private Sub UpdateScreen()

    Number.Caption = CurrentCow
    Tagg.Text = theHeard(CurrentCow).Tag
    wgt.Text = theHeard(CurrentCow).wgt
    Amt.Text = theHeard(CurrentCow).Amt

    End Sub

    Private Sub UpdateCow()

    theHeard(CurrentCow).Tag = Tagg.Text
    theHeard(CurrentCow).wgt = Val(wgt.Text)
    theHeard(CurrentCow).Amt = Val(Amt.Text)

    End Sub

    Private Sub Prev_Click()

    Call UpdateCow

    CurrentCow = CurrentCow - 1
    If CurrentCow < 1 Then
    CurrentCow = 500
    End If

    Call UpdateScreen

    End Sub

    Private Sub Next_Click()

    Call UpdateCow

    CurrentCow = CurrentCow + 1
    If CurrentCow > 500 Then
    CurrentCow = 1
    End If

    Call UpdateScreen

    End Sub

    Private Sub Apply_Click()

    Call UpdateCow

    Dim FileNumber As Long
    Dim WriteCow As Long

    FileNumber = FreeFile
    Open FileName For Output As #FileNumber
    For WriteCow = 1 To 500
    Write #FileNumber, theHeard(WriteCow).Tag,
    theHeard(WriteCow).wgt, theHeard(WriteCow).Amt
    Next WriteCow
    Close #FileNumber

    End Sub

    --Cut here--


    Now to explain. I assume the problem is that you have 500 cows, and
    you want to keep 3 pieces of information on each cow in a text file,
    and be able to modify it.

    The form is basically a label, 3 text boxes, and 3 buttons. The label
    has the current cow number (1-500), the text boxes let you edit Tag,
    Weight & Amount. The buttons Prev & Next move thru the array, and
    Apply saves the file to disk.

    First, in Form.Load, we load the file from disk to the array. Note
    the crude error handling, in case the file doesn't exist. See how I
    did...

    Input #FileNumber, theHeard(ReadCow).Tag, theHeard(ReadCow).wgt,
    theHeard(ReadCow).Amt

    ....and not ...

    Input #FileNumber, theHeard(ReadCow)

    ....as you might expect. This is because VB did a major change in how
    UDTs worked. In the olden days, strings in a UDT needed to be fixed
    length. So you UDT might have looked like this:

    Private Type Cattle
    Tag As String * 10 'Tag is always 10 characters!
    wgt As Integer
    Amt As Currency
    End Type

    Now, this existed in memory as a continuous chunk, 20 bytes in all.
    When you created an array, say of 500 elements, you got one big block
    of 500 * 20 bytes. Because VB knew how big it was, you could write
    either one particular element to disk in one write (I'm doing it piece
    by piece), or the entire array (I have to loop).

    This is what this suggestion is referring to.

    > Open "file.dat" for binary as #1
    > Put #1, , udtvariable
    > Close #1


    Well folks, it don't work no more! This, I suspect, is you problem.
    Because you didn't declare a length for the Tag element, VB can't set
    aside a nice neat block of memory for it. What it does is store the
    actual string somewhere else, and in the UDT keep a reference (a
    pointer, basically a number) to where the string is really kept. So
    now when you write the array to disk, you write the pointer to the
    string, not the string itself, to disk. Instead of the string, you
    get garbage write to disk. When you read it back, the once valid
    pointer now pointer to something else entirely. Not fun!

    You'll see that I didn't use the FSO to read & write. I could have,
    there's no reason not to. It's not really 'overkill'. Also, there's
    an alternate method to load the file remmed out. You there for you to
    compare the difference.

    When Apply is clicked, that's just the opposite of loading the file.
    The reest is fairly obvious. Prev & Next alter the CurrentCow
    variable, and update the array and refresh the screen accordingly.

    About Tagg. I couldn't call the TextBox Tag as VB would think I was
    referring to Form.Tag. VB is a bit thick sometimes. It let me create
    the TextBox called Tag, then did weird things...

    Tony

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center