How do I fix this multidimensional array? - vb.net

So I need to make a program that displays the monthly sales and totals of three different areas of a company when I click a button. I've added this code, but can't seem to get it right. Can someone advise me on how to fix it. Also, my headings "province, Percentage, Contribution etc" does not display in the list box when the form is loaded.
So basically the values in my .txt files are as follows:
1,Kwazulu Natal,44,120000
1,Gauteng,33,900000
1,Western Cape,23,65000
2,Kwazulu Natal,56,190000
2,Gauteng,25,85000
2,Western Cape,19,64000
3,Kwazulu Natal,54,175000
3,Gauteng,25,80000
3,Western Cape,21,71000
4,Kwazulu Natal,55,188000
4,Gauteng,25,83000
4,Western Cape,20,67000
5,Kwazulu Natal,46,125000
5,Gauteng,31,87000
5,Western Cape,23,65000
6,Kwazulu Natal,53,163000
6,Gauteng,26,80000
6,Western Cape,21,64000
Now they are supposed to show underneath their headings per month (1 - 6). When I run my code, they do not show headings, just the names of the places. It does not give errors
Imports System.IO
Public Class FormMain
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
resultsBox.Items.Clear()
resultsBox.Columns.Add("Province", 100, HorizontalAlignment.Center)
resultsBox.Columns.Add("Percentage", 100, HorizontalAlignment.Center)
resultsBox.Columns.Add("Contribution", 100, HorizontalAlignment.Center)
resultsBox.Columns.Add("Total Cost", 100, HorizontalAlignment.Center)
End Sub
Private Sub ExitBtn_Click(sender As Object, e As EventArgs) Handles ExitBtn.Click
Me.Close()
End Sub
Private Sub ShowResultsBtn_Click(sender As Object, e As EventArgs) Handles ShowResultsBtn.Click
Dim salesReport As String = MonthlyCBox.Text
Dim filereader As New StreamReader("C:\Users\HP Notebook 15\Desktop\main.txt")
Dim details As Array
Dim provinceFound As String = " "
Dim percentageContribute As Integer = 0
Dim monthlySales As Integer = 0
Dim totalvalue As Integer = 0
While filereader.EndOfStream = False
details = filereader.ReadLine().Split(",")
Dim province As String = details(1)
Dim percentage As Decimal = details(2)
Dim monthlyammount As String = details(3)
Dim totalamm As String = details(3)
If details(0) = salesReport Then
resultsBox.Items.Add(New ListViewItem({province, percentage, FormatCurrency(monthlyammount), FormatCurrency(totalamm)}))
End If
End While
End Sub
End Class

I guess you are using ListView, Not List Box. If so, please add
resultsBox.View = View.Details, in load event. That should visible the header text.

Related

How to remove an item in a two dimensional array with a list box

Hi I have an assignment for coding and I am having a hard time to figure out how to code it. My teacher wanted us to build a program that uses a list box that holds product names and a 2-D array that holds quantity in stock and price. Then in the one of the buttons in the application, which is the remove button, the item in the list box as well as the data from the array should be removed. When the user deletes an item, not only must the list loose the name of the item but the 2-D array must also be readjusted.
I am sorry. My brain just doesn't want to do what your teacher wants. If you can make sense of the following, maybe you can convince your teacher not to ask you to use 2D arrays in this instance.
Public Class Product
'These are automatic properties
'The compiler provides the getter, setter and backer fields.
Public Property Name As String
Public Property Quantiy As Integer
Public Property Price As Double
'ToString is a method inherited from Object. It will return a fully
'qualified name of the Type, not what we want in a ListBox
'The ListBox will call .ToString on Product and we will get the Name
'property of the Product object.
Public Overrides Function ToString() As String
Return Name
End Function
Public Sub New(prodName As String, prodQuantity As Integer, prodPrice As Double)
'We add a parameterized Constructor to make it easy to add our Product objects
'to the ListBox. Intelisense will help out once we type the New keyword
Name = prodName
Quantiy = prodQuantity
Price = prodPrice
End Sub
End Class
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'The New keyword calls the Constructor of the Product class
'so a Product object is added to the ListBox
ListBox1.Items.Add(New Product("Bell", 30, 2.98))
ListBox1.Items.Add(New Product("Book", 7, 200))
ListBox1.Items.Add(New Product("Candle", 42, 14.99))
End Sub
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
'When a Product is deleted from the ListBoX with the RemoveItem button
'this event will fire. (The index changed) -1 means nothing is selected which is
'what happens after the delete. If Nothing is selected our cast will fail and
'we will get an exception.
If ListBox1.SelectedIndex <> -1 Then
'The ListBox items are objects but underneath the objects are Products
'so we can Cast the object back to a Product
Dim p As Product = CType(ListBox1.SelectedItem, Product)
'All the properties of the Procuct are then available
MessageBox.Show($"Product Name is {p.Name}. There are {p.Quantiy} on hand. The price is {p.Price:N2}")
End If
End Sub
Private Sub btnRemoveItem_Click(sender As Object, e As EventArgs) Handles btnRemoveItem.Click
ListBox1.Items.Remove(ListBox1.SelectedItem)
End Sub
End Class
This should work, though it's really the wrong way to approach this:
LBProducts = Form ListBox
lblQuantity = Form Label
lblPrice = Form Label
btnDelete = Form Button
Public Class Form1
'5 Rows, (Price, Qty)
Private ProductArray(5, 1) As Integer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
LBProducts.Items.Add("Apples")
LBProducts.Items.Add("Bananas")
LBProducts.Items.Add("Grapes")
LBProducts.Items.Add("Oranges")
LBProducts.Items.Add("Peaches")
For x = 0 To 5
ProductArray(x, 0) = x
ProductArray(x, 1) = 1
Next
End Sub
Private Sub LBProducts_SelectedIndexChanged(sender As Object, e As EventArgs) Handles LBProducts.SelectedIndexChanged
Dim Index = LBProducts.SelectedIndex()
If Index >= 0 Then
lblPrice.Text = "Price: " & ProductArray(Index, 0)
lblQuantity.Text = "Qty: " & ProductArray(Index, 1)
End If
End Sub
Private Sub btnDelete_Click(sender As Object, e As EventArgs) Handles btnDelete.Click
Dim Index = LBProducts.SelectedIndex()
If Index >= 0 Then
LBProducts.Items.RemoveAt(Index)
Dim NewArray(UBound(ProductArray) - 1, 1) As Integer
Dim i As Integer = 0
For x = 0 To UBound(ProductArray)
If x <> Index Then
NewArray(i, 0) = ProductArray(x, 0)
NewArray(i, 1) = ProductArray(x, 1)
i += 1
End If
Next
ProductArray = NewArray
End If
End Sub
End Class

How to turn over cards in card game?

I have created a card game where 2 x 12 different images will be loaded into 24 picture boxes in vb forms. My intention is for the user to turn over two cards at a time, trying to find pairs to match. Each time the game is loaded, there will be different pictures and they will be in different positions. So far I have loaded the image for the back of the card in the game successfully but I can’t turn them over to see if my images have loaded successfully.
I am not concerned about shuffling them yet, I just want to see if the images have loaded and to be able to have two cards turned over at a time. I’m really confused as I’m not used to using VB for such tasks so any help is appreciated. Here is my code:
Imports System.IO
Public Class Board
' as per stackoverflow Terms of Service
' this code comes from
' http://stackoverflow.com/a/40707688
'array of picture boxes
Private pBoxes As PictureBox()
'array of images
Private imgs As String() = {"1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg", "6.jpg", "7.jpg", "8.jpg", "9.jpg", "10.jpg", "11.jpg", "12.jpg", "13.jpg", "14.jpg", "15,jpg", "16.jpg", "17.jpg", "18.jpg", "19.jpg", "20.jpg", "21.jpg", "22.jpg", "23.jpg", "24.jpg"}
'random number generator
Private RNG = New Random
'cover image
Private coverImg As String = "bg.jpg"
'timer
Private dt As DateTime
'turns cards
Private pbFirst As PictureBox
Private pbSecond As PictureBox
Private matches As Int32 = 0
'Folder where images are held
Private ImgFolder As String
Private Sub Board1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
RNG = New Random()
'array of picture boxes
pBoxes = New PictureBox() {PictureBox1, PictureBox2, PictureBox3, PictureBox4,
PictureBox5, PictureBox6, PictureBox7, PictureBox8,
PictureBox9, PictureBox10, PictureBox11, PictureBox12, PictureBox13, PictureBox14, PictureBox15, PictureBox16, PictureBox17, PictureBox18, PictureBox19, PictureBox20, PictureBox21, PictureBox22, PictureBox23, PictureBox24}
'where images are located
ImgFolder = "F: \COMPUTER SCIENCE\Test images"
coverImg = Path.Combine(ImgFolder, coverImg)
For Each p As PictureBox In pBoxes
p.ImageLocation = coverImg
Next
NewGame()
End Sub
'Take images from file
Private Sub PickImages()
Dim nums = Enumerable.Range(1, 12).ToArray()
Dim pool = nums.Concat(nums).OrderBy(Function(r) RNG.Next).ToArray()
End Sub
Private Sub Shuffle()
End Sub
' reset everything
Private Sub NewGame()
matches = 0
pbFirst = Nothing
pbSecond = Nothing
' repick, reshuffle
PickImages()
Shuffle()
dt = DateTime.Now
'tmrMain.Enabled = True
End Sub
End Class
I dont have the points to comments however are you clicking on the pictures to turn them over? If so I think you would just need to have an event such as the below to load the back of the card image.
Private Sub PictureBox1_Click(sender As System.Object, e As System.EventArgs) Handles PictureBox1.Click
PictureBox1.ImageLocation = ("Path to Picture of back of the card")
PictureBox1.Load()
End Sub
Don't try and over-think this - forget about "turning them over" simply change the image:
Private Sub PictureBox1_Click(sender As System.Object, e As System.EventArgs) Handles PictureBox1.Click, PictureBox2.Click 'etc
dim index as short
' to do: get the index of the PictureCard
If sender.Image is coverImg then
sender.Image = imgs(index) ' in stead of 0, use the index of the picture card
Else
sender.Image = coverImage
End if
End Sub

Displaying winner's name in picture box

Below is code for a simple voting system I am coding.
Public Class Form1
Dim winner As String
Dim maxVotes As Integer
Dim votes() As String
Dim index As String
Dim candidates As String
Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click
If Not isValidInput(txtNewCandidate.Text) Then
Exit Sub
End If
lstCandidates.Items.Add(txtNewCandidate.Text)
txtNewCandidate.Clear()
txtNewCandidate.Focus()
ReDim Preserve votes(index)
index += 1
End Sub
Private Function isValidInput(ByRef firstName As String) As Boolean
If IsNumeric(txtNewCandidate.Text) Or txtNewCandidate.Text = "" Then
MsgBox("Please input a valid candidate name.")
txtNewCandidate.Focus()
Return False
Else
Return True
End If
End Function
Private Sub btnTally_Click(sender As Object, e As EventArgs) Handles btnTally.Click
lstTallies.Visible = True
lblTally.Visible = True
For i = 0 To lstCandidates.Items.Count - 1
lstTallies.Items.Add(lstCandidates.Items(i).ToString & " - " & votes(i))
Next
End Sub
Private Sub lstCandidates_DoubleClick(sender As Object, e As EventArgs) Handles lstCandidates.DoubleClick
If lstCandidates.SelectedIndex = -1 Then
MsgBox("Select a candidate by double-clicking")
End If
votes(lstCandidates.SelectedIndex) += 1
MsgBox("Vote Tallied")
End Sub
Private Sub pbxWinner_Click(sender As Object, e As EventArgs) Handles pbxWinner.Click
End Sub
End Class
The voter must double click on their choice of candidate in the first list box. The user then tallies the votes by clicking on a button and a second list box will appear with the votes per candidate.
Now I need to display the winner (or winners, if there is a tie) in a picture box, pbxWinner. I am not sure how to accomplish this. Any clues?
Here is what i am trying to do, though the code below doesn't work.
Private Function candidateWinner(ByRef winner As String) As Boolean
For i As Integer = 0 To lstCandidates.SelectedIndex - 1
If votes(i) > maxVotes Then
maxVotes += 1
End If
Next
g = pbxWinner.CreateGraphics
g.TranslateTransform(10.0F, 0.0F)
g.DrawString(winner, New Font("Arial", 7, FontStyle.Regular), Brushes.DarkBlue, New PointF(0, 0))
Return True
End Function
Your code is actually working fine for an initial paint, but when the picture box image doesn't have its own bitmap set, a number of events can repaint its graphics behind the scenes(even as simple as minimizing/mazimizing the form, and a whole bunch of other ones), so in effect your text seems to never appear at all or disappear almost instantly when in reality it's probable getting repainted. To fix this, use a bitmap for the graphics object's reference, paint the bitmap's graphics, and then assign the bitmap to the picturebox's image property. This will make the image persistent...give this code a try in your candidateWinner function after the for loop:
Dim bmp As New Bitmap(pbxWinner.Width, pbxWinner.Height)
Dim g As Graphics = Graphics.FromImage(bmp)
g.TranslateTransform(10.0F, 0.0F)
g.DrawString(winner, New Font("arial", 7, FontStyle.Regular), Brushes.DarkBlue, 0, 0)
pbxWinner.Image = bmp
...If you still aren't seeing text, make sure the winner string has the correct value set, I tested this code and it showed my test string correctly
Edit for Comment:
That's because of the logic you're using to calculate the winner...you are just checking to see if the currently selected candidate's vote count is higher than maxVotes and then incrementing the max by 1. If you wanted to stick with that sort of logic for picking the winner, you would want to iterate through ALL of the candidates(not just those from index 0 to the currently selected one), and if their vote count is higher than the max, then set the max EQUAL to their vote count. Then the next candidate in the loop will have their count checked against the previous max. However, tracking the winner could be done a lot easier if you just use a dictionary since you are allowing candidates to be added, and you must change your "winner" logic to actually check who has the most votes out of everyone entered. A bare bones example of that would look like this:
Dim dctTally As Dictionary(Of String, Integer)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
dctTally = New Dictionary(Of String, Integer)
End Sub
Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click
dctTally.Add(txtNewCandidate.Text, 0)
lstCandidates.Items.Add(txtNewCandidate.Text)
End Sub
Private Sub lstCandidates_DoubleClick(sender As Object, e As EventArgs) Handles lstCandidates.DoubleClick
dctTally(lstCandidates.text) += 1
End Sub
Private Sub pbxWinner_Click(sender As Object, e As EventArgs) Handles pbxWinner.Click
Dim winner = dctTally.Aggregate(Function(l, r) If(l.Value > r.Value, l, r)).Key
Dim bmp As New Bitmap(pbxWinner.Width, pbxWinner.Height)
Dim g As Graphics = Graphics.FromImage(bmp)
g.TranslateTransform(10.0F, 0.0F)
g.DrawString(winner, New Font("arial", 7, FontStyle.Regular), Brushes.DarkBlue, 0, 0)
pbxWinner.Image = bmp
End Sub
This way, the program allows as many names as you want to be added to the candidates list, and will add a vote count to their name each time their name is double-clicked on. Then, when your winner pixturebox is clicked, it will find the dictionary with the highest vote count and display their name in the winner-box.
You can try this to draw the winners:
Private Sub candidateWinner()
Dim y As Single = 0
maxVotes = votes.Select(Function(x) Convert.ToInt32(x)).Max()
For i = 0 To UBound(votes)
If votes(i) = maxVotes.ToString() Then
g = pbxWinner.CreateGraphics
g.TranslateTransform(10.0F, 0.0F)
g.DrawString(lstCandidates.Items(i).ToString(), New Font("Arial", 7, FontStyle.Regular), Brushes.DarkBlue, New PointF(0, y))
y += 10
g.Dispose()
End If
Next
End Sub

How to copy selected item style to another item in Solid Edge?

I'm developing a macro for Solid Edge which is stores values of things like font size, width etc. and applies them to another object. Both functions are executable by button click. First button is saving the property values and second applies them to another object. The problem is that I have no clue which methods or functions should I use to store the values.
Public Class Form1
Dim solidedge As SolidEdge.Framework.Interop.Application
Dim line As SolidEdge.Framework.Interop.SelectSet
Dim item As SolidEdge.FrameworkSupport.Interop.Line2d
Dim style As SolidEdge.FrameworkSupport.Interop.GeometryStyle2d
Dim breite As Double
Dim dashname As String
Dim autophase As Boolean
Dim dashgapcount As Integer
Dim dashstrokepercent As Double
Dim color As Integer
Dim linearname As String
Dim units As Integer
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
solidedge = GetObject(, "SolidEdge.Application")
line = solidedge.ActiveSelectSet
item = line.Item(1)
style = item.Style
breite = style.Width
autophase = style.AutoPhase
dashgapcount = style.DashGapCount
dashstrokepercent = style.DashStrokePercent
color = style.LinearColor
linearname = style.LinearName
units = style.Units
dashname = style.DashName
End Sub
End Class
Example: I want make the black line look like the pink line by copying format:
I am not familiar with Solid Edge, but based on the code you posted, you could try something like this:
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
solidedge = GetObject(, "SolidEdge.Application")
line = solidedge.ActiveSelectSet
item = line.Item(2)
item.Style = style
End Sub

multiple inputs in text box not totaling

I got another super basic question, im trying to total the subtotals of every entry in the txtPrice.Text the user enters, and then refresh the other lables with the updated tax, shipping, and grand total. Its not totaling the subTotal, everything else works fine. Whats up with that?
Private Sub btnCalc_Click(sender As Object, e As EventArgs) Handles btnCalc.Click
Dim sglSub As Single
Dim sglTotal As Single
Dim sglSalesTax As Single
Const TAX_RATE As Single = 0.02
Dim bytShippingCharge As SByte = 10
Dim sglCompTotal As Single
Single.TryParse(txtPrice.Text, sglSub)
sglTotal += sglSub
lblSubTotal.Text = sglTotal.ToString("C2")
sglSalesTax = (sglTotal * TAX_RATE)
lblTax.Text = sglSalesTax.ToString("C2")
If sglTotal >= 100 Then
bytShippingCharge = 0
End If
lblShipping.Text = bytShippingCharge.ToString("C2")
sglCompTotal = (sglTotal + sglSalesTax + bytShippingCharge)
lblTotal.Text = sglCompTotal.ToString("C2")
End Sub
Tips
In this line:
sglTotal += sglSub
-Every time you work with a total initialize it to zero before adding a value to it. If not it can leads to undesired result.
-When working with currency is better to use a decimal type instead.
If you want a variable keeps its value declare it shared.
This a little example of how you can use a shared field
Public Class Form1
Shared total As Decimal = 0D
Shared Sub calc()
total += 2
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
calc()
Label1.Text = total.ToString
End Sub
End Class