Rudi
  • Home
  • About
  • Contact
  • VB.Net
    • Flippin
    • Calculator
    • Mine Scout
    • Slot Machine
    • Snake
    • Accounting using Child forms
  • Excel
    • Calendar 1
    • Calendar 2
    • Sudoku
    • Mine Scout
    • Tilexcel
    • ExceLudo
    • Alphabet Game
  • C# Child Forms
  • C# Struct Array

Windows within Window
Multi Document Interface

This project will do some basic accounting. Its inspiration is MYOB. My Level 1 version will be much simpler and therefore won't take long to finish. It handles Sales and Purchases for now but later I'll add Inventory and more.
My reason for this project was to learn and teach how to program an MDI application. The advantage with having a parent form is that all its windows close if the parent is minimized.
Let's create the Business is good accounting project. (BIG)

Picture
Picture
As explained above, this project employs a Multi Document Interface. An MDI has a parent form and child forms that stay within the parent form. The advantage is that all the windows close when the parent is closed although there may be free floating forms, or windows, as well.
I'll start with the parent form. Change the filename to frm BIG Parent. Click on the form and change it's Text to BIG Accounting and set its IsMdiContainer property to true.
Add a MenuStrip. For fun and experimenting I've made it unconventional.

The Buy and Sell menus are for switching windows with Alt + B or S. The other 3 will show the appropriate data. Next add 4 more forms and a Module.

Picture
Picture
In the Module declare all the forms and variables for the project.

Module mod_BIG

  Public frmBigSales As New frm_BIG_Sales
  Public frmBigPurchases As New frm_BIG_Purchases
  Public frmShowSales As New frm_Show_Sales
  Public frmShowPurchases As New frm_Show_Purchases

  Public strFileNameSales As String = "BigFileSales.txt"
  Public strFileNamePurchases As String = "BigFilePurchases.txt"

  Public strSales() As String              'Array for sales descriptions
  Public sngSales() As Single            'Array for sales values
  Public sngAllSales As Single          'Value of all sales
  Public intSales As Integer               'The number of sales

  Public strPurchases() As String       'Array for purchases descriptions
  Public sngPurchases() As Single     'Array for purchases values
  Public sngAllPurchases As Single   'Value of all purchases
  Public intPurchases As Integer        'The number of purchases

End Module

Set the ControlBox to False for all the child forms. This prevents them from being closed. The parent can now ask all the children to assemble.

  Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    Me.Size = New Size(810, 500)

    Dim strTemp As String
    Dim sngTotal As Single
    Dim intLength As Integer

    frmBigPurchases.MdiParent = Me
    frmBigPurchases.Show()
    frmBigPurchases.Location = New Point(395, 10)

    frmBigSales.MdiParent = Me
    frmBigSales.Show()
    frmBigSales.Location = New Point(10, 10)

    frmShowPurchases.MdiParent = Me
    frmShowPurchases.Show()
    frmShowPurchases.Location = New Point(395, 165)

    frmShowSales.MdiParent = Me
    frmShowSales.Show()
    frmShowSales.Location = New Point(10, 165)

    'More to come

  End Sub

We'll now design the child forms. Here is the Sell form. Set the MaxLength property of txtName to 25 characters. Name all the items then copy and paste the items to the Buy form.









Next is the Sales form. It only has a ListBox with its font set to Courier New as I want all characters to be the same width. Name the ListBox lstItems then copy it to the Purchases form.

Picture
We are now ready to enter the code to enter some data. Double click the Add button on the Sell form.

  Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click

    If txtName.Text = "" Then
      MsgBox("Need a description")
      txtName.Focus()
      Exit Sub
    End If

    If Val(txtAmount.Text) = 0 Then
      MsgBox("Need an amount")
      txtAmount.Text = ""
      txtAmount.Focus()
      Exit Sub
    End If

    'Add the item to the array
    intSales += 1

    ReDim Preserve strSales(intSales)
    strSales(intSales) = txtName.Text

    ReDim Preserve sngSales(intSales)
    sngSales(intSales) = CSng(txtAmount.Text)

    'Calculate the text length of the item
    Dim intLength As Int16
    intLength = txtName.TextLength + sngSales(intSales).ToString("C").Length

    'Pad and add the item to the ListBox
    frmShowSales.lstItems.Items.Add((txtName.Text) _
      & StrDup(42 - intLength, ".") _
      & sngSales(intSales).ToString("C"))

    'Add transaction to total
    sngAllSales += sngSales(intSales)

    'Show results in the MenuStrip
    My.Forms.Form1.SalesToolStripMenuItem.Text = "Total Sales: " _
      & sngAllSales.ToString("C")

    'Do not change the Balance calculation
    My.Forms.Form1.BalanceToolStripMenuItem.Text = "Balance:  " _
      & (sngAllSales - sngAllPurchases).ToString("C")

    txtAmount.Text = ""
    txtName.Text = ""
    txtName.Focus()

  End Sub

Copy the code to the Buy form Add button. Press Ctrl + h and change all Sales to Purchases except for the Balance calculation.

Picture
Here is the code for the first 2 menu items to enable Alt + B or S to activate the particular form.

  Private Sub BuyToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles BuyToolStripMenuItem.Click
    frmBigPurchases.Activate()
  End Sub

  Private Sub SellToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles SellToolStripMenuItem.Click
    frmBigSales.Activate()
  End Sub

When the program finishes it needs to save the data. At the top of the parent code, before the Class statement, add the code for the Input/Output of our files.

Imports System.IO

  Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
    Dim intLoop As Integer

    'If there are sales then save them
    If intSales > 0 Then
      Dim swStreamWriter As StreamWriter = New StreamWriter(strFileNameSales)

      For intLoop = 1 To intSales
        swStreamWriter.WriteLine(strSales(intLoop))
        swStreamWriter.WriteLine(sngSales(intLoop))
      Next

      swStreamWriter.Close()

    End If

    'If there are purchases then save them
    If intPurchases > 0 Then
      Dim swStreamWriter As StreamWriter = New StreamWriter(strFileNamePurchases)

      For intLoop = 1 To intPurchases
        swStreamWriter.WriteLine(strPurchases(intLoop))
        swStreamWriter.WriteLine(sngPurchases(intLoop))
      Next

      swStreamWriter.Close()

    End If

  End Sub

When the program starts of course it should reload the saved data. Add the following to the Form1_Load procedure.


    'More to come and this is it

    'Copy from here
    'Load sales if they exist


    If File.Exists(strFileNameSales) Then

      Dim srStreamReader As StreamReader = New StreamReader(strFileNameSales)

      Do
        strTemp = srStreamReader.ReadLine
        If strTemp = Nothing Then
          srStreamReader.Close()
          Exit Do
        End If

        intSales += 1

        ReDim Preserve strSales(intSales)
        strSales(intSales) = strTemp

        ReDim Preserve sngSales(intSales)
        sngSales(intSales) = CSng(srStreamReader.ReadLine)

        'Calculate text length of list items
        intLength = strSales(intSales).Length _
          + sngSales(intSales).ToString("C").Length

        'Pad and add list items to the ListBox
        frmShowSales.lstItems.Items.Add(strSales(intSales) _
                        & StrDup(42 - intLength, ".") _
                        & sngSales(intSales).ToString("C"))

        'Add up all sales
        sngAllSales += sngSales(intSales)

      Loop

    'Add transaction to MenuStrip
      SalesToolStripMenuItem.Text = "Total Sales: " & sngAllSales.ToString("C")

    End If

    'Paste here
    'Change Sales to Purchases


    If File.Exists(strFileNamePurchases) Then

      Dim srStreamReader As StreamReader = New StreamReader(strFileNamePurchases)

      Do
        strTemp = srStreamReader.ReadLine
        If strTemp = Nothing Then
          srStreamReader.Close()
          Exit Do
        End If

        intPurchases += 1

        ReDim Preserve strPurchases(intPurchases)
        strPurchases(intPurchases) = strTemp

        ReDim Preserve sngPurchases(intPurchases)
        sngPurchases(intPurchases) = CSng(srStreamReader.ReadLine)

        'Calculate text length of list items
        intLength = strPurchases(intPurchases).Length _
          + sngPurchases(intPurchases).ToString("C").Length

        'Pad and add list items to the ListBox
        frmShowPurchases.lstItems.Items.Add(strPurchases(intPurchases) _
                        & StrDup(42 - intLength, ".") _
                        & sngPurchases(intPurchases).ToString("C"))

        'Add up all purchases
        sngAllPurchases += sngPurchases(intPurchases)

      Loop

    End If

    'Add transaction to MenuStrip
    PurchasesToolStripMenuItem.Text = "Total Purchases: " &
      sngAllPurchases.ToString("C")

    'No change to this
    BalanceToolStripMenuItem.Text = "Balance:  " &
      (sngAllSales - sngAllPurchases).ToString("C")

  End Sub

It may be that you want to be able to handle more than one file. In that case we'd have to change the Save and Load code.

Double click the SaveFileDialog and the OpenFileDialog in the ToolBox. To the MenuStrip add a File Menu with Save and Load sub menus.

I felt in a psychedelic mood with lots of color.

Picture
We'll now have three files for each database. One is a header file with the .big extension. The second file has a .bigp extension for purchases while the third file has a .bigs extension for sales.

Add two global variables just under the Class statement.

  Dim blnOKtoClose As Boolean
  Dim blnNotFirstTime As Boolean

The code to save the files is shifted to the Save menu.

Private Sub SaveToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles SaveToolStripMenuItem.Click

    Dim strFile As String = "BigFile"
    blnOKtoClose = False

    If MsgBox("Save file?", vbYesNo) = MsgBoxResult.No Then
      blnOKtoClose = True
      Exit Sub
    End If

    With SaveFileDialog1
      .Title = "Save the file"
      .Filter = "BIG Files|*.big"
      .FileName = Me.Tag

      If .ShowDialog = DialogResult.OK Then
        blnOKtoClose = True
        My.Computer.FileSystem.WriteAllText(.FileName, strFile, False)

        Me.Tag = .FileName

      'If there are sales then save them
        If intSales > 0 Then
          Dim swStreamWriter As StreamWriter = New StreamWriter(.FileName & "s")

          For intLoop = 1 To intSales
            swStreamWriter.WriteLine(strSales(intLoop))
            swStreamWriter.WriteLine(sngSales(intLoop))
          Next

          swStreamWriter.Close()
        End If

      End If

      'If there are purchases then save them
      If intPurchases > 0 Then
        Dim swStreamWriter As StreamWriter = New StreamWriter(.FileName & "p")

        For intLoop = 1 To intPurchases
          swStreamWriter.WriteLine(strPurchases(intLoop))
          swStreamWriter.WriteLine(sngPurchases(intLoop))
        Next

        swStreamWriter.Close()

      End If

    End With

  End Sub


The Form_Closing procedure will call the above procedure. The following is the code that is left.

    SaveToolStripMenuItem_Click(sender, e)

    If Not blnOKtoClose Then
      e.Cancel = True
    End If

To load the file is also moved to another procedure.

  Private Sub LoadToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles LoadToolStripMenuItem.Click

    blnOKtoClose = False
    If blnNotFirstTime Then
      If MsgBox("Save file?", vbYesNo) = MsgBoxResult.Yes Then
        SaveToolStripMenuItem_Click(sender, e)
        If Not blnOKtoClose Then Exit Sub
      End If
    End If

    Dim strTemp As String
    Dim intLength As Integer

    With OpenFileDialog1

      .Title = "Load a file"
      .Filter = "BIG Files|*.big"
      .FileName = ""

      If .ShowDialog = DialogResult.OK Then

        Me.Tag = .FileName.Substring(.FileName.LastIndexOf("\") + 1)
        Me.Text = "BIG Accounting - " & Me.Tag

        If File.Exists(.FileName & "s") Then

          Dim srStreamReader As StreamReader = New StreamReader(.FileName & "s")

          Do
            strTemp = srStreamReader.ReadLine
            If strTemp = Nothing Then
              srStreamReader.Close()
              Exit Do
            End If

            intSales += 1

            ReDim Preserve strSales(intSales)
            strSales(intSales) = strTemp

            ReDim Preserve sngSales(intSales)
            sngSales(intSales) = CSng(srStreamReader.ReadLine)

            'Calculate length of list items
            intLength = strSales(intSales).Length _
            + sngSales(intSales).ToString("C").Length

            'Pad and add list items
            frmShowSales.lstItems.Items.Add(strSales(intSales) _
                          & StrDup(42 - intLength, ".") _
                          & sngSales(intSales).ToString("C"))

            'Add up all sales
            sngAllSales += sngSales(intSales)

          Loop

          SalesToolStripMenuItem.Text = "Total Sales: " & sngAllSales.ToString("C")

        End If
        'Paste here
        'Change Sales to Purchases


        If File.Exists(.FileName & "p") Then

          Dim srStreamReader As StreamReader = New StreamReader(.FileName & "p")

          Do
            strTemp = srStreamReader.ReadLine
            If strTemp = Nothing Then
              srStreamReader.Close()
              Exit Do
            End If

            intPurchases += 1

            ReDim Preserve strPurchases(intPurchases)
            strPurchases(intPurchases) = strTemp

            ReDim Preserve sngPurchases(intPurchases)
            sngPurchases(intPurchases) = CSng(srStreamReader.ReadLine)

            'Calculate length of list items
            intLength = strPurchases(intPurchases).Length _
            + sngPurchases(intPurchases).ToString("C").Length

            'Pad and add list items to the ListBox
            frmShowPurchases.lstItems.Items.Add(strPurchases(intPurchases) _
                          & StrDup(42 - intLength, ".") _
                          & sngPurchases(intPurchases).ToString("C"))

            'Add up all purchases
            sngAllPurchases += sngPurchases(intPurchases)

          Loop

        End If

        PurchasesToolStripMenuItem.Text = "Total Purchases: " &
        sngAllPurchases.ToString("C")

        'No change to this
        BalanceToolStripMenuItem.Text = "Balance:  " &
        (sngAllSales - sngAllPurchases).ToString("C")

      End If

    End With

  End Sub

The Form1_Load is now shortened to this.

    'More to come and this is it

    LoadToolStripMenuItem_Click(sender, e)
    blnNotFirstTime = True

    Exit Sub
Proudly powered by Weebly