Using Visual Basic, write a menu-driven multiform inventory program for a book store with data saved in a text file. Each record of the text file should consist of five fields–title, author, category, wholesale price, and number in stock. (The two categories are fiction and nonfiction.) At any time, the program should display the titles of the books in stock in a list box. The user should have the option of displaying either all titles or just those in one of the two categories. The user should be able to add a new book, delete a book, or alter any of the fields of a book in stock. The adding and editing processes use the second form, frmDetails. See the figure below for an example. At any time, the user should be able to calculate the total value of all books, or the total value of the books in either category. The menu item File contains the two second-level menu items Save and Exit. The menu items Display and Values each contain the three second-level menu items All, Fiction, and Nonfiction. (Hint: Store the data about the books in an array of structures.)


Type the following text into a .txt file named Books.txt and place it into the bin/Debug folder of your project. Be sure to type it exactly as shown because white space and punctuation are important.

Suggested Control Names and Attributes for frmBooks:
| Name Property | Text Property | Control Type | Notes |
| frmBooks | Book Inventory | Form | Holds Controls |
| mnuFile | &File | Top level menu item | Holds second level menu items |
| mnuFileSave | &Save | File submenu item | Saves changes to text file |
| mnuFileExit | E&xit | File submenu item | Exit the program |
| mnuBook | &Book | Top level menu item | Holds second level menu items |
| mnuBookAdd | &Add | Book submenu item | Add a new book using frmDetails |
| mnuBookDelete | &Delete | Book submenu item | Delete a book from inventory |
| mnuBookUpdate | &Update | Book submenu item | Update an existing book using frmDetails |
| mnuDisplay | &Display | Top level menu item | Holds second level menu items |
| mnuDisplayAll | &All | Display submenu item* | Displays titles of all books in inventory |
| mnuDisplayFiction | &Fiction | Display submenu item | Displays titles of fiction books only |
| mnuDisplayNonfiction | &Nonfiction | Display submenu item | Displays titles of nonfiction books only |
| mnuValues | &Values | Top level menu item | Holds second level menu items |
| mnuValuesAll | &All | Values submenu item* | Displays total value of all books |
| mnuValuesFiction | &Fiction | Values submenu item | Displays value of all fiction books |
| mnuValuesNonfiction | &Nonfiction | Values submenu item | Displays value of all nonfiction books |
| lstBooks | ListBox | Displays all books in inventory |
* Set the checked property to true
Suggested Control Names and Attributes for frmDetails:
| Name Property | Text Property | Container | Control Type | Notes |
| frmDetails | Details | N/A | Form | Holds Controls |
| txtTitle | frmDetails | TextBox | Captures book title | |
| txtAuthor | frmDetails | TextBox | Captures book author | |
| txtStock | frmDetails | TextBox | Captures number in stock | |
| txtPrice | frmDetails | TextBox | Captures book price | |
| grpCategory | Category | frmDetails | GroupBox | Holds radio category controls |
| radFiction | Fiction | grpCategory | RadioButton | Book is fiction when selected |
| radNonFiction | Nonfiction | grpCategory | RadioButton | Book is nonfiction when selected |
| btnRecord | Record Details | grpCategory | Button | Triggers event to record book data |
* Set the checked property to true
Hints:
- Make frmBooks the startup form.
- The menu bar should consist of four drop-down menus, as shown in the figure above.
Write the Code for frmBooks:
' Project: Inventory Control
' Description: Program allows viewer to view and manipulate an inventory list of books.
' Manipulation is performed through menu options. After manipulation, user can save the
' new list into the file, replacing the old data.
Imports System.IO
Public Class frmBooks
' Declare global variables
Structure Book
Dim title As String
Dim author As String
Dim category As String
Dim numInStock As Integer
Dim wholesalePrice As Double
End Structure
Public books(25) As Book
Public lastIndex As Integer ' index of last member of array
Public currentIndex As Integer
Dim totalValue As Double = 0
Public numberOfBooks As Integer = 0
Public addABook As Boolean = False
Private Sub frmBooks_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' Read from file and load into array of structures named books
If IO.File.Exists("Books.txt") Then
Dim line As String
Dim reader As StreamReader = File.OpenText("Books.txt")
Dim data(4) As String
For i As Integer = 0 To 25
If reader.EndOfStream = True Then
lastIndex = i - 1
numberOfBooks = lastIndex + 1
reader.Close()
Exit For
Else
line = reader.ReadLine
data = line.Split(","c)
books(i).title = data(0)
books(i).author = data(1)
books(i).category = data(2)
books(i).numInStock = CInt(data(3))
books(i).wholesalePrice = CDbl(data(4))
End If
Next
Else
MessageBox.Show("File not found.")
End If
End Sub
Private Sub mnuFileExit_Click(sender As Object, e As EventArgs) Handles mnuFileExit.Click
' Ends program if the user chooses Exit from the File menu
End
End Sub
Private Sub mnuDisplayAll_Click(sender As Object, e As EventArgs) Handles mnuDisplayAll.Click
' Displays all of the books in inventory to the list box
lstBooks.Items.Clear()
For j As Integer = 0 To lastIndex
lstBooks.Items.Add(books(j).title)
Next
End Sub
Private Sub mnuDisplayFiction_Click(sender As Object, e As EventArgs) Handles mnuDisplayFiction.Click
' Filters all of the fiction books and displays them to the list box
lstBooks.Items.Clear()
For j As Integer = 0 To lastIndex
If books(j).category = "F" Then
lstBooks.Items.Add(books(j).title)
End If
Next
End Sub
Private Sub mnuDisplayNonfiction_Click(sender As Object, e As EventArgs) Handles mnuDisplayNonfiction.Click
' Filters all of the nonfiction books and displays them to the list box
lstBooks.Items.Clear()
For j As Integer = 0 To lastIndex
If books(j).category = "N" Then
lstBooks.Items.Add(books(j).title)
End If
Next
End Sub
Private Sub mnuValuesAll_Click(sender As Object, e As EventArgs) Handles mnuValuesAll.Click
' Calculates the total value of all of the books in inventory and displays to a message box
totalValue = 0 ' reset value to zero in case of prior value
For k = 0 To lastIndex
totalValue += (books(k).wholesalePrice * books(k).numInStock)
Next
MessageBox.Show("Value: " & totalValue, "All Books")
End Sub
Private Sub mnuValuesFiction_Click(sender As Object, e As EventArgs) Handles mnuValuesFiction.Click
' Calculates the total value of all of the fiction books and displays to a message box
totalValue = 0 ' reset value to zero in case of prior value
For l = 0 To lastIndex
If books(l).category = "F" Then
totalValue += (books(l).wholesalePrice * books(l).numInStock)
End If
Next
MessageBox.Show("Value: " & totalValue, "Fiction Books")
End Sub
Private Sub mnuValuesNonfiction_Click(sender As Object, e As EventArgs) Handles mnuValuesNonfiction.Click
' Calculates the total value of all of the nonfiction books and displays to a message box
totalValue = 0 ' reset value to zero in case of prior value
For m = 0 To lastIndex
If books(m).category = "N" Then
totalValue += (books(m).wholesalePrice * books(m).numInStock)
End If
Next
MessageBox.Show("Value: " & totalValue, "Fiction Books")
End Sub
Private Sub mnuBookAdd_Click(sender As Object, e As EventArgs) Handles mnuBookAdd.Click
' Add a new book record to the array
addABook = True
frmDetails.txtTitle.Clear()
frmDetails.txtAuthor.Clear()
frmDetails.txtNumInStock.Clear()
frmDetails.txtWholesalePrice.Clear()
frmDetails.radFiction.Checked = True
frmDetails.ShowDialog() ' opens second form for input of a new book
End Sub
Private Sub mnuBookDelete_Click(sender As Object, e As EventArgs) Handles mnuBookDelete.Click
' Finds the index of the highlighted book title and deletes that record from the array
Dim currentIndex As Integer
' obtain the value of the index of the book name from the highlighted choice
currentIndex = lstBooks.SelectedIndex
' set up a for loop to reassign the values after the selected record is deleted
For n = currentIndex To lastIndex - 1
books(n) = books(n + 1)
Next
' assign null to the last element of the array
books(lastIndex).title = ""
books(lastIndex).author = ""
books(lastIndex).category = ""
books(lastIndex).numInStock = 0
books(lastIndex).wholesalePrice = 0
' reduce the largest index by 1
lastIndex = lastIndex - 1
End Sub
Private Sub mnuBookUpdate_Click(sender As Object, e As EventArgs) Handles mnuBookUpdate.Click
' Updates the record for a book with new information
' obtain the value of the index of the book name from the highlighted choice
currentIndex = lstBooks.SelectedIndex
If currentIndex >= 0 Then ' make sure a book has been selected
addABook = False
frmDetails.txtTitle.Text = books(currentIndex).title
frmDetails.txtAuthor.Text = books(currentIndex).author
frmDetails.txtNumInStock.Text = CStr(books(currentIndex).numInStock)
frmDetails.txtWholesalePrice.Text = CStr(books(currentIndex).wholesalePrice)
If books(currentIndex).category = "F" Then
frmDetails.radFiction.Checked = True
Else
frmDetails.radNonfiction.Checked = True
End If
frmDetails.ShowDialog() ' opens second form for updating a book record
End If
End Sub
Private Sub mnuFileSave_Click(sender As Object, e As EventArgs) Handles mnuFileSave.Click
' Saves the edited array into the text file by overwriting the existing file
Dim writer As StreamWriter = File.CreateText("Books.txt")
For i = 0 To lastIndex
writer.Write(books(i).title)
writer.Write("," & books(i).author)
writer.Write("," & books(i).category)
writer.Write("," & CStr(books(i).numInStock))
writer.WriteLine("," & CStr(books(i).wholesalePrice))
Next
MessageBox.Show("File saved.")
writer.Close()
End Sub
End Class
Write the Code for frmDetails:
Public Class frmDetails
Private Sub btnRecordDetails_Click(sender As Object, e As EventArgs) Handles btnRecordDetails.Click
If (txtTitle.Text = "") Or (txtAuthor.Text = "") Or (txtNumInStock.Text = "") Or (txtWholesalePrice.Text = "") Then
MessageBox.Show("One or more fields is empty. Please try again.")
Else
If frmBooks.addABook = True Then
frmBooks.numberOfBooks += 1
frmBooks.lastIndex += 1
frmBooks.books(frmBooks.numberOfBooks - 1).title = txtTitle.Text
frmBooks.books(frmBooks.numberOfBooks - 1).author = txtAuthor.Text
frmBooks.books(frmBooks.numberOfBooks - 1).numInStock = CInt(txtNumInStock.Text)
frmBooks.books(frmBooks.numberOfBooks - 1).wholesalePrice = CDbl(txtWholesalePrice.Text)
If radFiction.Checked Then
frmBooks.books(frmBooks.numberOfBooks - 1).category = "F"
Else
frmBooks.books(frmBooks.numberOfBooks - 1).category = "N"
End If
MessageBox.Show("New book saved.")
Else
frmBooks.books(frmBooks.currentIndex).title = txtTitle.Text
frmBooks.books(frmBooks.currentIndex).author = txtAuthor.Text
frmBooks.books(frmBooks.currentIndex).numInStock = CInt(txtNumInStock.Text)
frmBooks.books(frmBooks.currentIndex).wholesalePrice = CDbl(txtWholesalePrice.Text)
If radFiction.Checked Then
frmBooks.books(frmBooks.currentIndex).category = "F"
Else
frmBooks.books(frmBooks.currentIndex).category = "N"
End If
MessageBox.Show("Book information updated.")
End If
End If
End Sub
End Class