I'll post below the file I'm given for school. Basically I have a stock amount and a sale price. I have to figure out how to show the value for each
item. The only I would know how to do this is by doing one at a time.
Stock#, Descrip, Sale Price, Iventory
ET001, 1 Drawer End table, 169.99, 10
ET002, 2 Drawer End table, 289.95, 05
ET003, 6 Drawer End table, 129.99, 02
ST001, Stacking Table, 320.75, 20
You will still need to read in the file and parse the contents. I would suggest using a StreamReader inside a Using block to read each line of text and then .Split(",") the line data to get the values. Once you have the values parsed it should be fairly straight forward using this simple console application as a starting point.
Option Strict On
Option Explicit On
Module Module1
Sub Main()
' Create a list to hold the items
Dim slist As New List(Of StockItem)
' Get your file contents and parse out the data then add it to the list. Done manually below
slist.Add(New StockItem With {.StockCode = "ET001", .Description = "1 Drawer End table", .SalePrice = 169.99D, .Inventory = 10I})
slist.Add(New StockItem With {.StockCode = "ET002", .Description = "2 Drawer End table", .SalePrice = 289.99D, .Inventory = 5I})
'Loop Through all Items and get the values.
For Each item As StockItem In slist
'Write it out to the Debug
Debug.WriteLine(item.GetValue())
Next
End Sub
End Module
Public Structure StockItem
Public Property StockCode As String
Public Property Description As String
Public Property SalePrice As Decimal
Public Property Inventory As Integer
Public Function GetValue() As Decimal
Return CDec(Me.SalePrice * Me.Inventory)
End Function
End Structure
Related
I have an 3 array's (Drink, Food, Desert), as well as a multidimensional array named prices that stores prices for 8 items on the menu. I have a sub procedure that deals with transferring the item from the array in the listbox to the textboxes below, but am having trouble with price considering it is multidimensional
You would be better thinking of your menu and each item as objects for example, a menu contains a list of menu items and a menu item is an object that has properties such as a name, a type(Drink/Main Course/Dessert/Side),a description and a price.
So you might be better creating a Menu object that contains a list of all the menu items to be stored in it.
So first of all you want to define what your MenuItems are .. somthing like the code below. You will also want to define what sort of item it is. That is done by the Enum..End Enum block.
Friend Class FoodMenuItem
Enum ItemType
Drink
MainCourse
Dessert
Side
End Enum
Public Property Name As String
Public Property Price As Decimal
Public Property Catagory As ItemType
Public Property Description As String
Public Sub New(newName As String, newPrice As Decimal, newCatagory As ItemType, newDescription As String)
Name = newName
Price = newPrice
Catagory = newCatagory
Description = newDescription
End Sub
End Class
Next you want to create a menu which is simply a list of menu items
Dim FoodItems As New List(Of FoodMenuItem)
To add a food item to the list you need to create it and add it to your list
Dim itemtoAdd1 As New FoodMenuItem("Pasta", 4.95D, FoodMenuItem.ItemType.MainCourse, "Delicious pasta with parmesan cheese")
Dim itemtoadd2 As New FoodMenuItem("Beer", 3D, FoodMenuItem.ItemType.Drink, "Cool and refreshing")
Dim itemtoadd3 As New FoodMenuItem("Red Wine", 3.3D, FoodMenuItem.ItemType.Drink, "Fruity")
Dim itemtoadd4 As New FoodMenuItem("White Wine", 3.5D, FoodMenuItem.ItemType.Drink, "Dry")
Dim itemtoadd5 As New FoodMenuItem("Salad", 4.5D, FoodMenuItem.ItemType.MainCourse, "Crisp Salad with iceberg lettuce, tomatoes and beetroot")
Dim itemtoadd6 As New FoodMenuItem("Chocolate Fudge Cake", 4.25D, FoodMenuItem.ItemType.Dessert, "Indulgent fudge cake with fresh whipped cream")
Dim itemtoadd7 As New FoodMenuItem("Ice Cream", 4.5D, FoodMenuItem.ItemType.Dessert, "In a choice of flavours with the topping of your choice")
FoodItems.Add(itemtoAdd1)
FoodItems.Add(itemtoadd2)
FoodItems.Add(itemtoadd3)
FoodItems.Add(itemtoadd4)
FoodItems.Add(itemtoadd5)
FoodItems.Add(itemtoadd6)
FoodItems.Add(itemtoadd7)
So at some point you want to have these items in their appropriate listboxes. You could use this sub ..
Private Sub UpdateList(listBoxToUpdate As ListBox, category As FoodMenuItem.ItemType)
listBoxToUpdate.Items.Clear()
listBoxToUpdate.Items.AddRange((From item As FoodMenuItem In FoodItems Where item.Category = category Select item).ToArray)
listBoxToUpdate.DisplayMember = "Name"
End Sub
And use it like this, assuming listbox names of ListBoxDrinks,ListBoxMainCourse,ListBoxDessert
UpdateList(ListBoxDrinks, FoodMenuItem.ItemType.Drink)
UpdateList(ListBoxMainCourse, FoodMenuItem.ItemType.MainCourse)
UpdateList(ListBoxDessert, FoodMenuItem.ItemType.Dessert)
When you click an item in say ListBoxDrinks you would get the item and place its name in one textbox and its price in another textbox like this ..
Private Sub ListBoxDrinks_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBoxDrinks.SelectedIndexChanged
Dim selectedDrink As FoodMenuItem = CType(ListBoxDrinks.SelectedItem, FoodMenuItem)
TextBoxItemName.Text = selectedDrink.Name
TextBoxItemPrice.Text = selectedDrink.Price.ToString("C")
End Sub
That should do it. By the way ToString("C") in the last line will format the text to your local currency.
self-taught VBA noob here. If I'm breaching ettiquette or asking something that everyone else knows already I'm sorry. Also, if I'm doing things that appear insane, it's because it is the only way I can either think of or actually make work. There's a department here at my work than can turn my makeshift code into something decent, but I have to give them a workable model first.
I have two programs with native VBA. One is a terminal emulator which I'm using to scrape mainframe data and to construct a custom class object, and then intend to pass it to MS Excel for number crunching. I am stuck with VBA until I can convince the IT folks that I am worthy of a Visual Studio license and scripting access. Also I have to pass the class in memory and not a spreadsheet in case of a program crash; no loose, easily recoverable data in lost files allowed.
The data is an invoice that has up to 99 lines, each line can bill an item or a service. The invoice is a custom invoice class, and each line is a custom line class contained in a collection of lines. I have everything built and working, but I'm stuck trying to set the line objects to their invoice line properties. Something with the effect of this:
For x = 1 To intLines
Invoice.Linex = cLines.Item(x)
Next x
hoping that in Excel I can use the invoice like this:
currTotalChrg = Invoice.Line01.Charge + Invoice.Line02.Charge
I've looked at the CallByName function but couldn't get it to work, and couldn't find an online example to show me how to set it up properly. Without that, I don't know how to make what I've seen others call a wrapper to construct and execute the lines. If I must, I can construct a SelectCasenstein to do the job, but there's got to be a better way. Since I can't post code (proprietary issues and government regulations), I am perfectly fine with vague answers; I can figure out the nuts and bolts if pointed in the right direction.
Thanx for the time and help!
Seems you want an Invoice collection class that holds InvoiceLineItem objects and exposes a TotalAmount property.
You can't edit module/member attributes directly in the VBE, but if you want to be able to iterate the line items of an invoice with a nice For Each loop, you'll have to find a way. One way is to export the class and edit it in your favorite text editor to add the attributes, save it, and then re-import it into your VBA project. Next release of Rubberduck will let you do that with "annotations" (magic comments), which I'm also including here:
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Attribute VB_Name = "Invoice"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit
Public Const MAX_LINE_ITEMS As Long = 99
Private Type TInvoice
InvoiceNumber As String
InvoiceDate As Date
'other members...
LineItems As Collection
End Type
Private this As TInvoice
Private Sub Class_Initialize()
this.LineItems = New Collection
End Sub
'#Description("Adds an InvoiceLineItem to this invoice. Raises an error if maximum capacity is reached.")
Public Sub AddLineItem(ByVal lineItem As InvoiceLineItem)
Attribute AddLineItem.VB_Description = "Adds an InvoiceLineItem to this invoice."
If this.LineItems.Count = MAX_LINE_ITEMS Then
Err.Raise 5, TypeName(Me), "This invoice already contains " & MAX_LINE_ITEMS & " items."
End If
this.LineItems.Add lineItem
End Sub
'#Description("Gets the line item at the specified index.")
'#DefaultMember
Public Property Get Item(ByVal index As Long) As InvoiceLineItem
Attribute Item.VB_Description = "Gets the line item at the specified index."
Attribute Item.VB_UserMemId = 0
Set Item = this.LineItems(index)
End Property
'#Description("Gets an enumerator that iterates through line items.")
'#Enumerator
Public Property Get NewEnum() As IUnknown
Attribute NewEnum.VB_Description = "Gets an enumerator that iterates through line items."
Attribute NewEnum.VB_UserMemId = -4
Set NewEnum = this.LineItems.[_NewEnum]
End Property
'...other members...
You could implement the sum outside the class, but IMO that would be feature envy; an invoice wants to be able to tell you its total amount & quantity.
So I would expose properties for that:
'#Description("Gets the total amount for all line items.")
Public Property Get TotalAmount() As Double
Dim result As Double
Dim lineItem As InvoiceLineItem
For Each lineItem In this.LineItems
result = result + lineItem.Amount
Next
TotalAmount = result
End Property
'#Description("Gets the total quantity for all line items.")
Public Property Get TotalQuantity() As Double
Dim result As Double
Dim lineItem As InvoiceLineItem
For Each lineItem In this.LineItems
result = result + lineItem.Quantity
Next
TotalQuantity = result
End Property
And then you might as well...
'#Description("Gets the total net amount for all line items (including taxes, discounts and surcharges).")
Public Property Get TotalNetAmount() As Double
TotalNetAmount = TotalAmount - TotalDiscounts + TotalSurcharges + TaxAmount
End Property
From your post and the nature of your question I suspect your class has.. what, 99 properties, one for each line on the invoice?
I am stuck with VBA until I can convince the IT folks that I am worthy of a Visual Studio license and scripting access.
VBA is just as object-oriented a language as any other "real" language you could use with Visual Studio. The above solution is fairly similar to how I would have implemented it in C#, or VB.NET. If your VBA class has a member for every single possible invoice line, your thinking is wrong - not the language you're using.
Stop hating VBA for the wrong reasons. The editor sucks, get over it.
I have a partial answer for you: not exactly what you asked for, but it shows you a syntax that can do it.
I have a 'totals' class - a simple wrapper for a dictionary - that allows you to specify named fields and start adding up values. It's trivial, and there isn't much to be gained by doing it... But bear with me:
Dim LoanTotals As clsTotals
Set LoanTotals = New clsTotals
For Each Field In LoanFileReader.Fields
LoanTotals.CreateField Field.Name
Next Field
For Each LineItem In LoanFileReader
LoanTotals.Add "LoanAmount", LineItem!LoanAmount
LoanTotals.Add "OutstandingBalance", LineItem!OutstandingBalance
LoanTotals.Add "Collateral", LineItem!Collateral
Next LineItem
The implementation details in the class aren't terribly interesting - you can work out that it all ends in Debug.Print LoanTotals.Total("LoanAmount")
...But what if I implemented this?
Dim LoanTotals As clsTotals
Set LoanTotals = New clsTotals
For Each Field In LoanFileReader.Fields
LoanTotals.CreateCommand Field.Name, Field.MainframeCommand
Next Field
...With an internal implementation like this:
Public Sub ExecuteCommand(CommandName, ParamArray() Args())
' Wrapper for objMainService, ends a command to the COM interface of the Mainframe client
CallByName objMainService, CommandName, vbMethod, Args
End Sub
Altenatively, you can concatenate Shell commands to execute those mainframe functions.
...And now you've populated a VB class that encapsulates a primitive API for a set of functions supplied at runtime.
As I say: it's not quite what you wanted, but it might get you somewhat closer to the solution you need.
For completeness, here's the code for the 'Totals' class:
A VBA Class for aggregating totals on named fields specified at runtime:
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Attribute VB_Name = "clsTotals"
Attribute VB_Description = "Simple 'Totals' class based on a Scripting.Dictionary object"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit
' Simple 'Totals' class based on a Scripting.Dictionary object
' Nigel Heffernan, Excellerando.Blogspot.com April 2009
' As it's based on a dictionary, the 'Add' and 'Reset' methods
' support implicit key creation: if you use a new name (or you
' mistype an existing name) a new Totals field will be created
' Coding Notes:
' This is a wrapper class: 'Implements' is not appropriate, as
' we are not reimplementing the class. Or not very much. Think
' of it as the 'syntactic sugar' alternative to prefixing all
' our method calls in the extended class with 'Dictionary_'.
Private m_dict As Scripting.Dictionary
Attribute m_dict.VB_MemberFlags = 40
Attribute m_dict.VB_VarDescription = "(Internal variable)"
Public Property Get Sum(FieldName As String) As Double
Attribute Sum.VB_Description = "Returns the current sum of the specified field."
Attribute Sum.VB_UserMemId = 0
' Returns the current sum of the specified field
Sum = m_dict(FieldName)
End Property
Public Sub CreateField(FieldName As String)
Attribute CreateField.VB_Description = "Explicitly create a new named field"
' Explicitly create a new named field
If m_dict.Exists(FieldName) Then
Err.Raise 1004, "Totals.CreateField", "There is already a field named '" & FieldName & "' in this 'Totals' object."
Else
m_dict.Add FieldName, 0#
End If
End Sub
Public Sub Add(FieldName As String, Value As Double)
Attribute Add.VB_Description = "Add a numeric amount to the field's running total \r\n Watch out for implicit field creation."
' Add a numeric amount to the field's running total
' Watch out for implicit field creation.
m_dict(FieldName) = m_dict(FieldName) + Value
End Sub
Public Sub Reset(FieldName As String)
Attribute FieldName.VB_Description = "Reset a named field's total to zero \r\n Watch out for implicit key creation"
' Reset a named field's total to zero
' Watch out for implicit key creation
m_dict(FieldName) = 0#
End Sub
Public Sub ResetAll()
Attribute ResetAll.VB_Description = "Clear all the totals"
' Clear all the totals
m_dict.RemoveAll
Set m_dict = Nothing
End Sub
Public Property Get Fields() As Variant
Attribute Fields.VB_Description = "Return a zero-based vector array of the field names"
'Return a zero-based vector array of the field names
Fields = m_dict.Keys
End Property
Public Property Get Values() As Variant
Attribute Values.VB_Description = "Return a zero-based vector array of the current totals"
'Return a zero-based vector array of the current totals
Fields = m_dict.Items
End Property
Public Property Get Count() As Long
Attribute Count.VB_Description = "Return the number of fields"
'Return the number of fields
Count= m_dict.Count
End Property
Public Property Get Exists(FieldName As String) As Boolean
Attribute Count.VB_Description = "Return a zero-based vector array of the field names"
'Return True if a named field exists in this instance of clsTotals
Exists = m_dict.Exists(FieldName)
End Property
Private Sub Class_Initialize()
Set m_dict = New Scripting.Dictionary
m_dict.CompareMode = TextCompare
End Sub
Private Sub Class_Terminate()
m_dict.RemoveAll
Set m_dict = Nothing
End Sub
Comment out the Attribute statements if you can't import them into your project.
The text file contains lines with the year followed by population like:
2016, 322690000
2015, 320220000
etc.
I separated the lines substrings to get all the years in a list box, and all the population amounts in a separate listbox, using the following code:
Dim strYearPop As String
Dim intYear As Integer
Dim intPop As Integer
strYearPop = popFile.ReadLine()
intYear = CInt(strYearPop.Substring(0, 4))
intPop = CInt(strYearPop.Substring(5))
lstYear.Items.Add(intYear)
lstPop.Items.Add(intPop)
Now I want to add the population amounts together, using the .Items to act as an array.
Dim intPop1 As Integer
intPop1 = lstPop.Items(0) + lstPop.Items(1)
But I get an error on lstPop.Items(1) and any item other than lstPop.Items(0), due to out of range. I understand the concept of out of range, but I thought that I create an index of several items (about 117 lines in the file, so the items indices should go up to 116) when I populated the list box.
How do i populate the list box in a way that creates an index of list box items (similar to an array)?
[I will treat this as an XY problem - please consider reading that after reading this answer.]
What you are missing is the separation of the data from the presentation of the data.
It is not a good idea to use controls to store data: they are meant to show the underlying data.
You could use two arrays for the data, one for the year and one for the population count, or you could use a Class which has properties of the year and the count. The latter is more sensible, as it ties the year and count together in one entity. You can then have a List of that Class to make a collection of the data, like this:
Option Infer On
Option Strict On
Imports System.IO
Public Class Form1
Public Class PopulationDatum
Property Year As Integer
Property Count As Integer
End Class
Function GetData(srcFile As String) As List(Of PopulationDatum)
Dim data As New List(Of PopulationDatum)
Using sr As New StreamReader(srcFile)
While Not sr.EndOfStream
Dim thisLine = sr.ReadLine
Dim parts = thisLine.Split(","c)
If parts.Count = 2 Then
data.Add(New PopulationDatum With {.Year = CInt(parts(0).Trim()), .Count = CInt(parts(1).Trim)})
End If
End While
End Using
Return data
End Function
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim srcFile = "C:\temp\PopulationData.txt"
Dim popData = GetData(srcFile)
Dim popTotal = 0
For Each p In popData
lstYear.Items.Add(p.Year)
lstPop.Items.Add(p.Count)
popTotal = popTotal + p.Count
Next
' popTotal now has the value of the sum of the populations
End Sub
End Class
If using a List(Of T) is too much, then just use the idea of separating the data from the user interface. It makes processing the data much simpler.
I am making a dvd database system in windows form and trying to display the dvd's entered by a user. Then display the Title, Director and Genre in 3 separate listBoxes.
When the user enters the information through 3 separate text boxes, the information is stored in a structure I made called TDvd. This means I can call for example dvd.Title or dvd.Director. I also use the variable index to add this information to an array I made called Dvd(100) (just a random number I used to test).
Here is the code I currently have for adding the items to the ListBox:
For i = 1 To noOfAddedDvds
lstTitle.Items.Add(dvd(i).Title)
lstDirector.Items.Add(dvd(i).Director)
lstGenre.Items.Add(dvd(i).Genre)
Next
The variable NoOfDvdsAdded is just a way of keeping track of the number of dvd's the user has already entered.
I run this and enter the Title, Director and Genre, but when I try and display this information across the 3 listboxes, I get the error:
An unhandled exception of type 'System.ArgumentNullException' occurred in System.Windows.Forms.dll
Public Class Form1
Structure TDvd
Dim Title As String
Dim Director As String
Dim Genre As String
End Structure
Dim dvd(100) As TDvd
Dim index As Integer = 0
Dim noOfAddedDvds As Integer
Private Sub btnAddToDatabase_Click(sender As Object, e As EventArgs) Handles btnAddToDatabase.Click
If txtDirector.Text <> "" Or txtGenre.Text <> "" Or txtTitle.Text <> "" Then
txtTitle.Text = dvd(index).Title
txtDirector.Text = dvd(index).Director
txtGenre.Text = dvd(index).Genre
index += 1
noOfAddedDvds += 1
End If
End Sub
Private Sub btnDisplayDatabase_Click(sender As Object, e As EventArgs) Handles btnDisplayDatabase.Click
Dim i As Integer
For i = 0 To noOfAddedDvds
MessageBox.Show(index & ", " & i)
lstTitle.Items.Add(dvd(i).Title)
lstDirector.Items.Add(dvd(i).Director)
lstGenre.Items.Add(dvd(i).Genre)
MessageBox.Show(index & ", " & i)
Next
End Sub
End Class
According to the documentation, an ArgumentNullException is thrown by the Add() method if the argument passed to it is null. (Or Nothing in VB.) So one of these is Nothing at runtime:
dvd(i).Title
dvd(i).Director
dvd(i).Genre
You'll have to debug to determine which. It would seem that the error is because you're starting your iteration at 1 instead of 0, I would think it should be:
For i = 0 To noOfAddedDvds - 1
So when you get to the index of noOfAddedDvds in your collection, that element will be an uninitialized struct with Nothing strings.
You'll definitely want to fix the iteration (indexes start at 0). Additionally, you may also benefit from initializing the String properties in your struct to String.Empty internally. Depends on whether you want similar errors to manifest as an exception or as an empty record. Sometimes the latter makes the problem more obvious since at runtime you'd see that your output started on the second record.
Just a few pointers...
The Items collection on the ListBox is actually 0 indexed, by which I mean that instead of going "1,2,3", it actually goes (0,1,2).
That's what your problem is.
Hint - think about perhaps using a List instead of an array as well... (for dvd)
Your thing cries out for being rewritten in OO form:
Friend DVDGenres
Undefined
Comedy
Action
Adventure
Sci-Fi
End Enum
Friend Class DVD
Public Property Title As String
Public Property Director As String
Public Property Genre As DVDGenres
Public Sub New
Title = ""
Director = ""
Genre = DVDGenres.Undefined
' other stuff too
End Sub
Public Overrides Function ToString As String
Return Title
End Sub
End Class
Now something to store them in. Arrays went out with Rubik's Cubes, so a List:
Private myDVDs As New List(of DVD)
A list and a class can do what arrays and structures can without the headaches. Add a DVD:
Dim d As New DVD
d.Name = TextBoxName.Text
d.Director = TextBoxDir.Text
d.Genre = comboboxGenre.SelectedItem
' add to the container:
myDVDs.Add(d)
Display all the DVDs in a ListBox to pick from:
AllDVDsLB.DataSource = myDVDs
AllDVDsLB.DisplayMember = "Title"
This will set your list as the datasource for the listbox. Whatever is in the List is automatically displayed without copying data into the Items collection. Then, say from selectedindex changed event, display the selected item details to some labels:
Label1.Text = Ctype(AllDVDsLB.SelectedItem, DVD).Title
Label2.Text = Ctype(AllDVDsLB.SelectedItem, DVD).Director
Label3.Text = Ctype(AllDVDsLB.SelectedItem, DVD).Genre.ToString
Iterate to do something like what is in the Question:
For Each d As DVD in myDVDs ' CANT run out of data
lstTitle.Items.Add(d.Title)
lstDirector.Items.Add(d.Director)
lstGenre.Items.Add(d.Genre.ToString)
Next
Or iterate and reference with an Int32:
For n As Integer = 0 To myDVDs.Count - 1
lstTitle.Items.Add(myDVDs(n).Title)
' etc
Next n
HTH
Dim index As Integer
Dim choice As String
Dim total As Integer
total = 0
index = NumericUpDown1.Value
Dim arr(4) As Integer
arr(0) = 10
arr(1) = 5
arr(2) = 21
arr(3) = 33
If index > 0 Then
choice = (Combobox1.SelectedItem.ToString + " x " + NumericUpDown1.Value.ToString)
ListBox1.Items.Add(choice)
CheckedListBox1.Items.Add(choice)
total += arr(Combobox1.SelectedIndex) * index
TotalLabel.Text = total.ToString()
Else
MsgBox("error.")
End If
I can calculate the total of single choice, but fail to accumulate to sum.
What's wrong of the code?
Current Situation:
Step 1:
choose arr(0), index = 2
total = 20
Step 2:
choose arr(2), index = 1
total = 21
Correct Situation:
Step 1:
choose arr(0), index = 2
total = 20
Step 2:
choose arr(2), index = 1
total = 41
You'll need a either a global variable or a class with a public variable. You should create a Transaction class to store the data about the transaction and probably a Product class to store the data about the product. What you put in it is up to you, but I'd start out with something like this:
Public Class Transaction
Private _productsList As List(of Product)
Private _transationNumber As Integer
'...more stuff...
'you'll want to remember what products are in your "cart" for the transaction
Public Property ProductsList As List(of Product)
'your get/set accessors
End Property
Public Property TransactionNumber As Integer
'your get/set accessors
End Property
Public Property TotalTransactionCost() As Double
Get
'this will sum of the prices of all of the products you have stored in your
'list of products for this transaction
Return _productsList.Sum(product => product.Price)
End Get
End Property
Public Sub New()
'...constructor stuff
End Sub
Public Sub AddProductToTransaction(byval product)
_productsList.Add(product)
End Sub
End Class
Public Class Product
Private _price As Double
Private _productName As String
Private _UPC As String
Public Property Price() As Double
'your get/set accessors
End Property
Public Property ProductName() As String
'your get/set accessors
End Property
Public UPC As String () As String
'your get/set accessors
End Property
Public Sub New()
'constructor stuff
End Sub
End Class
These are a couple class shells to get you started. If you're serious about making a product, this is a step in the right direction. If you're going to write code, write it the right way.
If you're just looking for a quick and dirty solution, you can declare a global variable and just keep a running sum. Just don't forget to clear it out before you start a new transaction.
You'll want to do something like:
Private TransactionCost As Double in your form outside of all your methods.
Again, I would recommend the first way of going about things. You'll need at least those two classes and they'll definitely be more fleshed out for a real product.
I hope this helps and answers your question. If it does, hit me with an upvote and accept the answer. Welcome to SO.