If NUD_Pepperoni.Value > 0 Then
txtSummary.AppendText(vbNewLine + "Pepperoni" + vbTab & vbTab & NUD_Pepperoni.Text + vbTab & price.ToString("c1") + vbTab + vbTab & (NUD_Pepperoni.Value * price).ToString("c1") + vbNewLine)
End If
If NUD_Hawaiian.Value > 0 Then
txtSummary.AppendText(vbNewLine + "Hawaiian" + vbTab & vbTab & vbTab & NUD_Hawaiian.Text + vbTab & price.ToString("c1") + vbTab + vbTab & (NUD_Hawaiian.Value * price).ToString("c1") + vbNewLine)
End If
If NUD_Americano.Value > 0 Then
txtSummary.AppendText(vbNewLine + "Americano" + vbTab & vbTab & NUD_Americano.Text + vbTab & price.ToString("c1") + vbTab + vbTab & (NUD_Americano.Value * price).ToString("c1") + vbNewLine)
End If
there are 12 of them the same
And the code below is the value I store
Dim Pizzalist(11, 1) As Single
================================================================
For p = 0 To 5
Pizzalist(p, 0) = 8.5 'store the regular pizza Price
Next
For p = 6 To 11
Pizzalist(p, 0) = 13.5 'store the gourmet pizza price
Next
================================================================
Pizzalist(0, 1) = NUD_Pepperoni.Value
Pizzalist(1, 1) = NUD_Hawaiian.Value
Pizzalist(2, 1) = NUD_Americano.Value
Pizzalist(3, 1) = NUD_TacoFiesta.Value
Pizzalist(4, 1) = NUD_Margherita.Value
Pizzalist(5, 1) = NUD_BeefOnion.Value
Pizzalist(6, 1) = NUD_BNY.Value
Pizzalist(7, 1) = NUD_MML.Value
Pizzalist(8, 1) = NUD_IL.Value
Pizzalist(9, 1) = NUD_GSS.Value
Pizzalist(10, 1) = NUD_AC.Value
Pizzalist(11, 1) = NUD_TMC.Value'store the amount of specific pizza
I looked up so many examples to try to figure out how to do this, but I couldn't. Thank you!
If you had a class which contained the information related to a pizza, let's call it Pizza, you could create a List(Of Pizza). That list can be iterated over once its data has been entered, for example if the user clicked a button to calculate the price.
Public Class Form1
Dim pizzas As New List(Of Pizza)
Public Class Pizza
Public Property QuantitySelector As NumericUpDown
Public Property UnitPrice As Decimal
Public Property Name As String
Public ReadOnly Property Quantity As Integer
Get
Return Convert.ToInt32(QuantitySelector.Value)
End Get
End Property
Sub New()
' Empty constructor
End Sub
Sub New(name As String, quantitySelector As NumericUpDown, unitPrice As Decimal)
Me.QuantitySelector = quantitySelector
Me.UnitPrice = unitPrice
Me.Name = name
End Sub
End Class
Private Sub bnCalcPrice_Click(sender As Object, e As EventArgs) Handles bnCalcPrice.Click
Dim sb As New Text.StringBuilder
For Each pz In pizzas
If pz.Quantity > 0 Then
sb.Append(vbNewLine & pz.Name & vbTab & vbTab & pz.Quantity & vbTab & pz.UnitPrice.ToString("c1") & vbTab & vbTab & (pz.Quantity * pz.UnitPrice).ToString("c1") & vbNewLine)
End If
Next
txtSummary.Text = sb.ToString()
End Sub
Private Sub InitPizzas()
Dim regularPrice = 8.5D ' Use Decimal values for money.
Dim premiumPrice = 13.5D
pizzas.Add(New Pizza("Hawaiian", NUD_Hawaiian, premiumPrice))
pizzas.Add(New Pizza("Americano", NUD_Americano, premiumPrice))
' etc.
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
InitPizzas()
End Sub
End Class
You could add code to add up the individual prices for each type of pizza too.
I also created a solution for you. Andrew has replied in the meantime while I was busy but I don't want to withhold that from you.
Like Andrew said, I would change the whole concept. I wrote a class with the most important properties of a pizza. You can change the amount in your restaurant kitchen. The data is saved in a List(of ClassPizza). As Andrew said, you can then iterate over this list and take advantage of the properties. For example sort by property xy. Maybe by best-before dates?
You can save the data in a text file. (Of course, it can be done better / differently but we don't want to exaggerate today). These data are read in when the program starts. (The very first time there is of course no data, just click on ‘cancel’ in the OpenfileDialog).
When new goods arrive, you can click on the button "bring new pizzas in store" and enter everything. A second form opens for this. Care is taken to ensure that no input errors are made (for example, quantity 0 makes no sense – the text then turns red).
The current stock is displayed in the 12 text boxes.
This is Form1.vb:
Imports Microsoft.VisualBasic.ControlChars
Imports Microsoft.WindowsAPICodePack.Dialogs
Public NotInheritable Class FormMain
Private ReadOnly Deu As New System.Globalization.CultureInfo("de-DE") ' change this to your language, for example "en-GB"
Private ReadOnly All_my_pizzas_List As New List(Of ClassPizza)
Private Sub FormMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For Each tb As TextBox In Me.Controls.OfType(Of TextBox)
tb.Text = "0"
Next
End Sub
Private Sub FormMain_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
Dim Path As String
Using OFD1 As New CommonOpenFileDialog
OFD1.Title = "pick file to open"
OFD1.Filters.Add(New CommonFileDialogFilter("Text file", ".txt"))
OFD1.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
If OFD1.ShowDialog() = CommonFileDialogResult.Ok Then
Path = OFD1.FileName
Else
Return
End If
End Using
'read all Text
Dim RAT() As String = System.IO.File.ReadAllLines(Path, System.Text.Encoding.UTF8)
If RAT.Length = 0 Then Return
For i As Integer = 1 To RAT.Length - 3 Step 1
If RAT(i) = "#" Then
All_my_pizzas_List.Add(New ClassPizza(CType(RAT(i + 1), ClassPizza.Types_of_pizza), CUShort(RAT(i + 2)), CDec(RAT(i + 3))))
End If
Next
Update_Textboxes()
End Sub
Private Sub Update_Textboxes()
Dim NUD_Pepperoni, NUD_Hawaiian, NUD_Americano, NUD_TacoFiesta, NUD_Margherita, NUD_BeefOnion, NUD_BNY, NUD_MML, NUD_IL, NUD_GSS, NUD_AC, NUD_TMC As Integer
For Each piz As ClassPizza In All_my_pizzas_List
Select Case piz.Type_of_pizza
Case ClassPizza.Types_of_pizza.NUD_Pepperoni
NUD_Pepperoni += 1
Case ClassPizza.Types_of_pizza.NUD_Hawaiian
NUD_Hawaiian += 1
Case ClassPizza.Types_of_pizza.NUD_Americano
NUD_Americano += 1
Case ClassPizza.Types_of_pizza.NUD_TacoFiesta
NUD_TacoFiesta += 1
Case ClassPizza.Types_of_pizza.NUD_Margherita
NUD_Margherita += 1
Case ClassPizza.Types_of_pizza.NUD_BeefOnion
NUD_BeefOnion += 1
Case ClassPizza.Types_of_pizza.NUD_BNY
NUD_BNY += 1
Case ClassPizza.Types_of_pizza.NUD_MML
NUD_MML += 1
Case ClassPizza.Types_of_pizza.NUD_IL
NUD_IL += 1
Case ClassPizza.Types_of_pizza.NUD_GSS
NUD_GSS += 1
Case ClassPizza.Types_of_pizza.NUD_AC
NUD_AC += 1
Case ClassPizza.Types_of_pizza.NUD_TMC
NUD_TMC += 1
Case Else
Exit Select
End Select
Next
TextBox_Pepperoni.Text = NUD_Pepperoni.ToString(Deu)
TextBox_Hawaiian.Text = NUD_Hawaiian.ToString(Deu)
TextBox_Americano.Text = NUD_Americano.ToString(Deu)
TextBox_TacoFiesta.Text = NUD_TacoFiesta.ToString(Deu)
TextBox_Margherita.Text = NUD_Margherita.ToString(Deu)
TextBox_BeefOnion.Text = NUD_BeefOnion.ToString(Deu)
TextBox_BNY.Text = NUD_BNY.ToString(Deu)
TextBox_MML.Text = NUD_MML.ToString(Deu)
TextBox_IL.Text = NUD_IL.ToString(Deu)
TextBox_GSS.Text = NUD_GSS.ToString(Deu)
TextBox_AC.Text = NUD_AC.ToString(Deu)
TextBox_TMC.Text = NUD_TMC.ToString(Deu)
End Sub
Private Sub Button_toStore_Click(sender As Object, e As EventArgs) Handles Button_toStore.Click
Using FNP As New Form_new_pizza
FNP.GetData()
If FNP.ShowDialog = DialogResult.Yes Then
For i As UInt16 = 0US To FNP.Amount - 1US Step 1US
All_my_pizzas_List.Add(New ClassPizza(CType(FNP.SI, ClassPizza.Types_of_pizza), 1US, FNP.price))
Next
End If
End Using
Update_Textboxes()
End Sub
Private Sub Button_change_values_Click(sender As Object, e As EventArgs) Handles Button_change_values.Click
' this is still empty
End Sub
Private Sub Button_Save_Click(sender As Object, e As EventArgs) Handles Button_Save.Click
'-------------------------------------------------------------------------------------------------------------
' User can choose where to save the database text file and the program will save it.
'-------------------------------------------------------------------------------------------------------------
Dim Path As String
Using SFD1 As New CommonSaveFileDialog
SFD1.Title = "write data into text file"
SFD1.Filters.Add(New CommonFileDialogFilter("Text file", ".txt"))
SFD1.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
If SFD1.ShowDialog() = CommonFileDialogResult.Ok Then
Path = SFD1.FileName & ".txt"
Else
Return
End If
End Using
Using textfile As System.IO.StreamWriter = My.Computer.FileSystem.OpenTextFileWriter(Path, True, System.Text.Encoding.UTF8)
textfile.WriteLine("Status of this file [dd.mm.yyyy hh:mm:ss]: " & Date.Now.ToString("G", Deu))
For Each pizza As ClassPizza In All_my_pizzas_List
textfile.WriteLine("#") ' Marker
textfile.WriteLine(pizza.Type_of_pizza)
textfile.WriteLine(pizza.stored_amount)
textfile.WriteLine(pizza.price)
Next
textfile.Close()
End Using
End Sub
End Class
This is the code of the ClassPizza.vb
Public NotInheritable Class ClassPizza
Public Enum Types_of_pizza
NUD_Pepperoni
NUD_Hawaiian
NUD_Americano
NUD_TacoFiesta
NUD_Margherita
NUD_BeefOnion
NUD_BNY
NUD_MML
NUD_IL
NUD_GSS
NUD_AC
NUD_TMC
End Enum
Public Type_of_pizza As Types_of_pizza
Public stored_amount As UInt16 = 0US
''' <summary>
''' in $
''' </summary>
Public price As Decimal
Public Sub New(ByVal type As Types_of_pizza, ByVal storedAmount As UInt16, price As Decimal)
Me.Type_of_pizza = type
Me.stored_amount = storedAmount
Me.price = price
End Sub
End Class
And this is the code of that second Form (Form_new_pizza.vb)
Public NotInheritable Class Form_new_pizza
Public Amount As UInt16
Public price As Decimal
Public SI As Integer
Public Sub GetData()
For Each _item As Object In [Enum].GetValues(GetType(ClassPizza.Types_of_pizza))
ListBox1.Items.Add(_item)
Next
End Sub
Private Sub Form_new_pizza_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub TextBox_Amount_TextChanged(sender As Object, e As EventArgs) Handles TextBox_Amount.TextChanged
Dim success As Boolean = UInt16.TryParse(TextBox_Amount.Text, Amount)
If success AndAlso Amount > 0US Then
TextBox_Amount.ForeColor = Color.FromArgb(0, 200, 0) 'Green
Else
TextBox_Amount.ForeColor = Color.Red
End If
End Sub
Private Sub TextBox_price_TextChanged(sender As Object, e As EventArgs) Handles TextBox_price.TextChanged
Dim success As Boolean = Decimal.TryParse(TextBox_price.Text, price)
If success Then
TextBox_price.ForeColor = Color.FromArgb(0, 200, 0) 'Green
Else
TextBox_price.ForeColor = Color.Red
End If
End Sub
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
If ListBox1.SelectedIndex <> (-1) Then
SI = ListBox1.SelectedIndex
End If
End Sub
Private Sub Button_OK_Click(sender As Object, e As EventArgs) Handles Button_OK.Click
If SI <> (-1) AndAlso Amount > 0US Then
Me.DialogResult = DialogResult.Yes
Else
Me.DialogResult = DialogResult.No
End If
End Sub
End Class
Of course, one can expand everything and do it better than me, but you can start, and understand the concept. 😉
By the way
You should set ‘Option Strict’ to On in the project properties so that you are advised to convert data types. Also set ‘Option Infer’ to Off so that you always have to write down the data type ("As Integer", "As Double", ...). The latter, however, is a matter of taste.
Also, you should remove the VB6 namespace as VB6 features are deprecated.
If you need control characters (such as NewLine), you can write Imports Microsoft.VisualBasic.ControlChars
.
====================================
Please note that I am using a FileDialog that I downloaded from Visual Studios' own Nuget Package Manager. See image. You don't have to do that, but I prefer this FileDialog because it offers more options than the one that is already included.
Related
I am working on a side project in VB, it is a network monitoring tool to pings a number of devices which should come back as successful or failed. I have extreme limits in programming so forgive me.
I am using buttons, a total of 34 for each device that I want to ping that returns a success or fail which will color code green(success) and red(failed) but I am sure there is a better way? Right now, my code is stuck on one button, I cant figure out how to step to the next one on the list. In my code, I have it commented out of the results I want produced which is where I am stuck on.
The text file contains all my IP addresses I want to ping separated by a comma.
Basically, when the form is running, it will display each button as green or red, depending on if the device is online or not. I want the code to loop every 2 minutes as well to keep the devices up to date. Literally a device monitoring tool. I was able to get it to work using 34 different End If statements but that is messy and a lot of work to maintain. Any assistance would be helpful.
Using MyReader As New Microsoft.VisualBasic.FileIO.TextFieldParser("\\txt file location\device.txt")
MyReader.TextFieldType = FileIO.FieldType.Delimited
MyReader.SetDelimiters(",")
Dim currentRow As String()
Dim MyLen() As String = {"Button1", "Button2", "Button3", "Button4", "Button5", "Button6", "Button7", "Button8", "Button9", "Button10", "Button11", "Button12", "Button13", "Button14", "Button15", "Button16", "Button17", "Button18", "Button19", "Button20", "Button21", "Button22", "Button23", "Button24", "Button25", "Button26", "Button27", "Button28", "Button29", "Button30", "Button31", "Button32", "Button33", "Button34"}
While Not MyReader.EndOfData
Try
currentRow = MyReader.ReadFields()
Dim currentField As String
For Each currentField In currentRow
If My.Computer.Network.Ping(currentField) Then
MsgBox(MyLen)
'MyLen = Color.LimeGreen
Else
MsgBox(MyLen)
'MyLen.Text = "Failed"
'MyLen.BackColor = Color.Red
End If
Next
Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
MsgBox("Line " & ex.Message & "is not valid and will be skipped.")
End Try
End While
End Using
enter image description here
Here is some code that takes a different approach. To try it create a new Form app with only a FlowLayoutPanel and Timer on it. Use the default names. It might be above your skill level but using the debugger you might learn something. Or not.
Public Class Form1
Private MyButtons As New List(Of Button)
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
Timer1.Enabled = False 'started later
Timer1.Interval = CInt(TimeSpan.FromMinutes(2).TotalMilliseconds) '<<<< Change >>>>
Dim path As String = "\\txt file location\device.txt"
Dim text As String = IO.File.ReadAllText(path) 'use this
''for testing >>>>>
'Dim text As String = "10.88.0.70, 10.88.0.122,192.168.0.15, 10.88.0.254, 1.2.3.4" ''for testing
''for testing <<<<<
Dim spltCHs() As Char = {","c, " "c, ControlChars.Tab, ControlChars.Cr, ControlChars.Lf}
Dim IPs() As String = text.Split(spltCHs, StringSplitOptions.RemoveEmptyEntries)
For Each addr As String In IPs
Dim b As New Button
Dim p As New MyPinger(addr)
p.MyButton = b
b.Tag = p 'set tag to the MyPinger for this address
b.AutoSize = True
b.Font = New Font("Lucida Console", 10, FontStyle.Bold)
b.BackColor = Drawing.Color.LightSkyBlue
'center text in button
Dim lAddr As String = p.Address
Dim t As String = New String(" "c, (16 - lAddr.Length) \ 2)
Dim txt As String = t & lAddr & t
b.Text = txt.PadRight(16, " "c)
b.Name = "btn" & lAddr.Replace("."c, "_"c)
AddHandler b.Click, AddressOf SomeButton_Click 'handler for button
MyButtons.Add(b) 'add button to list
Next
'sort by IP
MyButtons = (From b In MyButtons
Select b Order By DirectCast(b.Tag, MyPinger).Address(True)).ToList
For Each b As Button In MyButtons
FlowLayoutPanel1.Controls.Add(b) 'add button to panel
Next
FlowLayoutPanel1.Anchor = AnchorStyles.Bottom Or AnchorStyles.Left Or AnchorStyles.Right Or AnchorStyles.Top
Timer1.Enabled = True 'start the timer
End Sub
Private Sub SomeButton_Click(sender As Object, e As EventArgs)
'if button clicked ping it
Dim b As Button = DirectCast(sender, Button) 'which button
b.BackColor = MyPinger.UnknownColor
Dim myP As MyPinger = DirectCast(b.Tag, MyPinger) ''get the MyPinger for this
myP.DoPing() 'do the ping
End Sub
Private Async Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Timer1.Enabled = False
Dim myPs As New List(Of MyPinger)
For Each b As Button In MyButtons
b.BackColor = MyPinger.UnknownColor
Dim myP As MyPinger = DirectCast(b.Tag, MyPinger)
myPs.Add(myP)
Next
Dim t As Task
t = Task.Run(Sub()
Threading.Thread.Sleep(25)
For Each myP As MyPinger In myPs
myP.DoPing()
Next
End Sub)
Await t
Timer1.Enabled = True
End Sub
End Class
Public Class MyPinger
Public Shared ReadOnly UpColor As Drawing.Color = Drawing.Color.LightGreen
Public Shared ReadOnly DownColor As Drawing.Color = Drawing.Color.Red
Public Shared ReadOnly UnknownColor As Drawing.Color = Drawing.Color.Yellow
Private _ip As Net.IPAddress
Private _ping As Net.NetworkInformation.Ping
Public LastReply As Net.NetworkInformation.PingReply
Private Shared ReadOnly PingTMO As Integer = 2500
Private _waiter As New Threading.AutoResetEvent(True)
Public MyButton As Button
Public Sub New(IPAddr As String)
Me._ip = Net.IPAddress.Parse(IPAddr) 'will throw exception if IP invalid <<<<<
Me._ping = New Net.NetworkInformation.Ping 'create the ping
'do initial ping
Dim t As Task = Task.Run(Sub()
Threading.Thread.Sleep(25) 'so init has time
Me.DoPingAsync()
End Sub)
End Sub
Private Async Sub DoPingAsync()
If Me._waiter.WaitOne(0) Then 'only one at a time for this IP
Me.LastReply = Await Me._ping.SendPingAsync(Me._ip, PingTMO)
Dim c As Drawing.Color
Select Case Me.LastReply.Status
Case Net.NetworkInformation.IPStatus.Success
c = UpColor
Case Else
c = DownColor
End Select
Me.SetButColor(c)
Me._waiter.Set()
End If
End Sub
Public Sub DoPing()
Me.DoPingAsync()
End Sub
Private Sub SetButColor(c As Drawing.Color)
If Me.MyButton IsNot Nothing Then
If Me.MyButton.InvokeRequired Then
Me.MyButton.BeginInvoke(Sub()
Me.SetButColor(c)
End Sub)
Else
Me.MyButton.BackColor = c
End If
End If
End Sub
Public Function TheIP() As Net.IPAddress
Return Me._ip
End Function
Public Function Address(Optional LeadingZeros As Boolean = False) As String
Dim rv As String = ""
If LeadingZeros Then
Dim byts() As Byte = Me._ip.GetAddressBytes
For Each b As Byte In byts
rv &= b.ToString.PadLeft(3, "0"c)
rv &= "."
Next
Else
rv = Me._ip.ToString
End If
Return rv.Trim("."c)
End Function
End Class
I made a jeopardy game in VB.Net
I know I am missing some codes but I don't know what should I use.
I need to save in a txt file and load it to a listbox.
here is my code:
Private Sub SummaryMenu_Load (sender As Object, e As EventArgs) Handles MyBase.Load
highscoreFile = FreeFile()
FileOpen(highscoreFile,
"jeeperdeyData.txt",
OpenMode.Input)
FileClose()
If totalScore > highscoreFile Then
highscore = totalScore
FileOpen(highscoreFile,
"jeeperdeyData.txt",
OpenMode.Output)
WriteLine(highscoreFile, username & " " & highscore)
FileClose(highscoreFile)
End If
End Sub
i have the variables in modules
'files
Public highscoreFile As Integer
Thanks
This replicates the work from the existing method with APIs that are actually under active use, though it seems odd to do all of this in a method named "SummaryMenu_Load()":
Private Class ScoreData
Public Property Name As String
Public Property Score as Integer
Public Shared Function FromFileLine(line As String) As ScoreData
Dim data = line.Split(vbTab)
Return New ScoreData With {Name = data(0), Score = Integer.Parse(data(1))}
End Function
Public Overrides Function ToString()
Return $"{Name}{vbTab}{Score}"
End Function
Public Shared ReadOnly Property MaxScores As Integer = 10
End Class
Private Sub SummaryMenu_Load (sender As Object, e As EventArgs) Handles MyBase.Load
var scores = File.ReadLines("jeeperdeyData.txt").
Select(AddressOf ScoreData.FromFileLine).
OrderByDescending(Function(s) s.Score).
ToList()
If scores.Count < ScoreData.MaxScores Then
scores.Add(new ScoreData With {Name = username, Score = highscore})
Else
Dim i As Integer = 0
While i < scores.Count AndAlso highscore <= scores(i).Score
i++
End While
If i < scores.Count Then 'Greater than at least one existing entry
Dim current As ScoreData = scores(i)
scores(i) = New ScoreData With {Name = username, Score = highscore}
i+=1
While i < scores.Count
Dim temp As ScoreData = scores(i)
scores(i) = current
current = temp
i+=1
End While
End If
End IF
File.WriteAllLines("jeeperdeyData.txt", scores.Select(Function(s) s.ToString()))
End Sub
I'm trying to get data from a DGV grid onto specific tags, and so far it has been working great. But an update moved the tags positions in the DGV so Rows(x) does not equal the tags I'm moving data into anymore.
Is it possible to do a search like the one I'm doing in Cells("Val") but in the Rows("") instead?
Actually I want it to be something like this Rows("TagIndex = 5") etc.
A full line of code would then be:
HopperStatus = dgvDataFlt.Rows("TagIndex = 5").Cells("Val").Value
but is this possible.
Row 12 & 13 are switched when logging
dgvDataFLT = dgvDataFloating
If dgvDataFlt.Rows(0).Cells("TagIndex").Value = 12 Then
'DGVDataFlt.AutoResizeColumns()
'--------------------------------------Floating TAGS fra database------------------------------------------
ProdRecCnt = dgvDataFlt.Rows(10).Cells("Val").Value
ProdTotCnt = dgvDataFlt.Rows(9).Cells("Val").Value
FrontFree = dgvDataFlt.Rows(8).Cells("Val").Value
CurrAutoMode = dgvDataFlt.Rows(7).Cells("Val").Value
PalletStatus = dgvDataFlt.Rows(6).Cells("Val").Value
HopperStatus = dgvDataFlt.Rows(5).Cells("Val").Value
PowerStatus = dgvDataFlt.Rows(4).Cells("Val").Value
CurrRecNo = dgvDataFlt.Rows(3).Cells("Val").Value
NomCycTime = dgvDataFlt.Rows(2).Cells("Val").Value
AutoStart = dgvDataFlt.Rows(1).Cells("Val").Value
MachineNo = dgvDataFlt.Rows(0).Cells("Val").Value
LOGTimeStamp = dgvDataFlt.Rows(0).Cells("DateAndTime").Value 'for aktuelle lognings tidstempel
LOGDateStamp = Microsoft.VisualBasic.Left(LOGTimeStamp, 10)
LOGClockStamp = Microsoft.VisualBasic.Mid(LOGTimeStamp, 12, 5)
End If
I want the code to look/work something like this:
If dgvDataFlt.Rows(0).Cells("TagIndex").Value = 12 Then
'DGVDataFlt.AutoResizeColumns()
'--------------------------------------Floating TAGS fra database------------------------------------------
ProdRecCnt = dgvDataFlt.Rows("TagIndex = 10").Cells("Val").Value
ProdTotCnt = dgvDataFlt.Rows("TagIndex = 9").Cells("Val").Value
FrontFree = dgvDataFlt.Rows("TagIndex = 8").Cells("Val").Value
CurrAutoMode = dgvDataFlt.Rows("TagIndex = 7").Cells("Val").Value
PalletStatus = dgvDataFlt.Rows("TagIndex = 6").Cells("Val").Value
HopperStatus = dgvDataFlt.Rows("TagIndex = 5").Cells("Val").Value
PowerStatus = dgvDataFlt.Rows("TagIndex = 4").Cells("Val").Value
CurrRecNo = dgvDataFlt.Rows("TagIndex = 3").Cells("Val").Value
NomCycTime = dgvDataFlt.Rows("TagIndex = 2").Cells("Val").Value
AutoStart = dgvDataFlt.Rows("TagIndex = 1").Cells("Val").Value
MachineNo = dgvDataFlt.Rows("TagIndex = 0").Cells("Val").Value
LOGTimeStamp = dgvDataFlt.Rows(0).Cells("DateAndTime").Value 'for aktuelle lognings tidstempel
LOGDateStamp = Microsoft.VisualBasic.Left(LOGTimeStamp, 10)
LOGClockStamp = Microsoft.VisualBasic.Mid(LOGTimeStamp, 12, 5)
End If
I would suggest adding a class and then inheriting the DataGridView control into that class. I have made a quick little example of this and the code works, but to get it to work you will have to perform a few steps:
(1) If you don't already have a windows forms application to test this then,
make a new one.
(2) Create class named KeyedDataGridView
(3) Copy and Paste the following Code into KeyedDataGridView class
(4) Rebuild your Project
(5) Drag and Drop new component onto your windows Form.
NOTE: This class is limited, but should still be able to do what you require of it.
Finally, if you need any help then, please leave a comment and will try to get to it when I can.
Option Explicit On
Public Class KeyedDataGridView
Inherits Windows.Forms.DataGridView
Dim _Rows As KeyedDataRows
Public Shadows Property Rows As KeyedDataRows
Get
Return _Rows
End Get
Set(value As KeyedDataRows)
_Rows = value
End Set
End Property
Public Sub New()
Dim strName As String
strName = Me.Name
strName = MyBase.Name
_Rows = New KeyedDataRows(Me)
_Rows.Rows = MyBase.Rows
End Sub
Protected Overrides Sub Finalize()
_Rows = Nothing
MyBase.Finalize()
End Sub
End Class
Public Class KeyedDataRows
Inherits Windows.Forms.DataGridViewRowCollection
Dim _TagNames As Dictionary(Of String, Integer)
Dim _Rows As DataGridViewRowCollection
Dim _Cells As Dictionary(Of String, DataGridViewCellCollection)
Dim dgv As DataGridView
Default Public Overloads ReadOnly Property Item(strTagName As String) As DataGridViewRow
Get
Return _Rows.Item(Me.IndexFromName(strTagName))
End Get
End Property
Protected Friend Property Rows As DataGridViewRowCollection
Get
Return _Rows
End Get
Set(value As DataGridViewRowCollection)
_Rows = value
End Set
End Property
Public Property TagName(index As Integer) As String
Get
Return CStr(_TagNames.Item(index))
End Get
Set(value As String)
_TagNames.Item(index) = value
End Set
End Property
Public Sub New(tmp As DataGridView)
MyBase.New(tmp)
dgv = tmp
_TagNames = New Dictionary(Of String, Integer)
_Cells = New Dictionary(Of String, DataGridViewCellCollection)
End Sub
Public Shadows Sub Add(strTagName As String)
Dim intCurRow As Integer
If dgv.AllowUserToAddRows Then
intCurRow = _Rows.Count - 1
Else
intCurRow = _Rows.Count
End If
_TagNames.Add(strTagName, intCurRow)
_Rows.Add()
End Sub
Public Shadows Sub Add(strTagName As String, dataGridViewRow As DataGridViewRow)
Dim intCurRow As Integer
If dgv.AllowUserToAddRows Then
intCurRow = _Rows.Count - 1
Else
intCurRow = _Rows.Count
End If
_TagNames.Add(strTagName, intCurRow)
_Rows.Add(dataGridViewRow)
End Sub
Public Shadows Sub Add(count As Integer, strTagNames() As String)
Dim intI As Integer
Dim intCurRow As Integer
If dgv.AllowUserToAddRows Then
intCurRow = _Rows.Count - 1
Else
intCurRow = _Rows.Count
End If
For intI = 0 To (count - 1)
_TagNames.Add(strTagNames(intI), intCurRow)
_Rows.Add()
intCurRow = _Rows.Count - 1
Next intI
End Sub
Public Property IndexFromName(strTagName As String) As Integer
Get
If _TagNames.Count > 0 Then
If _TagNames.ContainsKey(strTagName) Then
Return _TagNames.Item(strTagName)
Else
Return -1
End If
Else
Return -1
End If
End Get
Set(value As Integer)
_TagNames.Add(strTagName, value)
End Set
End Property
Public Overloads Sub RemoveAt(strTagName As String)
_Cells.Remove(strTagName)
_Rows.RemoveAt(IndexFromName(strTagName))
_TagNames.Remove(strTagName)
End Sub
Protected Overrides Sub Finalize()
_TagNames.Clear()
_TagNames = Nothing
_Cells.Clear()
_Rows.Clear()
_Cells = Nothing
_Rows = Nothing
MyBase.Finalize()
End Sub
End Class
I also, added the following buttons to a windows form to test the code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
With KeyedDataGridView1
.Rows.Add("Tag Test 1")
.Rows.Add("Tag Test 2")
.Rows.Add("Tag Test 3")
.Rows.Add("Tag Test 4")
End With
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
MsgBox(KeyedDataGridView1.Rows("Tag Test 3").Cells(0).Value & vbCrLf &
KeyedDataGridView1.Rows("Tag Test 3").Cells(1).Value & vbCrLf &
KeyedDataGridView1.Rows("Tag Test 3").Cells(2).Value)
MsgBox(KeyedDataGridView1.Rows("Tag Test 2").Cells(0).Value & vbCrLf &
KeyedDataGridView1.Rows("Tag Test 2").Cells(1).Value & vbCrLf &
KeyedDataGridView1.Rows("Tag Test 2").Cells(2).Value)
MsgBox(KeyedDataGridView1.Rows("Tag Test 1").Cells(0).Value & vbCrLf &
KeyedDataGridView1.Rows("Tag Test 1").Cells(1).Value & vbCrLf &
KeyedDataGridView1.Rows("Tag Test 1").Cells(2).Value)
End Sub
So my problem is:
I have a List of a custom Type {Id as Integer, Tag() as String},
and i want to perform a multiple-criteria search on it; eg:
SearchTags={"Document","HelloWorld"}
Results of the Search will be placed a ListBox (ListBox1) in this format:
resultItem.id & " - " & resultItem.tags
I already tried everything i could find on forums, but it didn't work for me (It was for db's or for string datatypes)
Now, i really need your help. Thanks in advance.
For Each MEntry As EntryType In MainList
For Each Entry In MEntry.getTags
For Each item As String In Split(TextBox1.Text, " ")
If Entry.Contains(item) Then
If TestIfItemExistsInListBox2(item) = False Then
ListBox1.Items.Add(item & " - " & Entry.getId)
End If
End If
Next
Next
Next
Example Custom Array:
(24,{"snippet","vb"})
(32,{"console","cpp","helloworld"})
and so on...
I searched for ("Snippet vb test"):
snippet vb helloWorld - 2
snippet vb tcpchatEx - 16
cs something
test
So, i'll get everything that contains one of my search phrases.
I expected following:
snippet vb tcp test
snippet vb dll test
snippet vb test metroui
So, i want to get everything that contains all my search phrases.
My entire, code-likely class
Imports Newtonsoft.Json
Public Class Form2
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Dim MainList As New List(Of EntryType)
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
MainList.Clear()
Dim thr As New Threading.Thread(AddressOf thr1)
thr.SetApartmentState(Threading.ApartmentState.MTA)
thr.Start()
End Sub
Delegate Sub SetTextCallback([text] As String)
Private Sub SetTitle(ByVal [text] As String) ' source <> mine
If Me.TextBox1.InvokeRequired Then
Dim d As New SetTextCallback(AddressOf SetTitle)
Me.Invoke(d, New Object() {[text]})
Else
Me.Text = [text]
End If
End Sub
Sub thr1()
Dim linez As Integer = 1
Dim linex As Integer = 1
For Each line As String In System.IO.File.ReadAllLines("index.db")
linez += 1
Next
For Each line As String In System.IO.File.ReadAllLines("index.db")
Try
Application.DoEvents()
Dim a As saLoginResponse = JsonConvert.DeserializeObject(Of saLoginResponse)(line) ' source <> mine
Application.DoEvents()
MainList.Add(New EntryType(a.id, Split(a.tags, " ")))
linex += 1
SetTitle("Search (loading, " & linex & " of " & linez & ")")
Catch ex As Exception
End Try
Next
SetTitle("Search")
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim searchTags() As String = TextBox1.Text.Split(" ")
Dim query = MainList.Where(Function(et) et.Tags.Any(Function(tag) searchTags.Contains(tag))).ToList
For Each et In query
ListBox1.Items.Add(et.Id)
Next
End Sub
Private Sub Button4_Click(sender As Object, e As EventArgs) ' test
MsgBox(Mid(ListBox1.SelectedItem.ToString, 1, 6)) ' test
End Sub 'test, removeonrelease
End Class
Public Class EntryType
Public Property Id As Integer
Public Property Tags() As String
Public Sub New(ByVal _id As Integer, ByVal _tags() As String)
Me.Id = Id
Me.Tags = Tags
End Sub
Public Function GetTags() As String
'to tell the Listbox what to display
Return Tags
End Function
Public Function GetId() As Integer
'to tell the Listbox what to display
Return Id
End Function
End Class
I also edited your EntryType class; I added a constructor, removed toString and added GetTags and GetID.
Example "DB" im working with ("db" as "index.db" in exec dir):
{"tags":"vb.net lol test qwikscopeZ","id":123456}
{"tags":"vb.net lol test","id":12345}
{"tags":"vb.net lol","id":1234}
{"tags":"vb.net","id":123}
{"tags":"cpp","id":1}
{"tags":"cpp graphical","id":2}
{"tags":"cpp graphical fractals","id":3}
{"tags":"cpp graphical fractals m4th","id":500123}
Error:
Debugger:Exception Intercepted: _Lambda$__1, Form2.vb line 44
An exception was intercepted and the call stack unwound to the point before the call from user code where the exception occurred. "Unwind the call stack on unhandled exceptions" is selected in the debugger options.
Time: 13.11.2014 03:46:10
Thread:<No Name>[5856]
Here is a Lambda query. The Where filters on a predicate, since Tags is an Array you can use the Any function to perform a search based on another Array-SearchTags. You can store each class object in the Listbox since it stores Objects, you just need to tell it what to display(see below).
Public Class EntryType
Public Property Id As Integer
Public Property Tags() As As String
Public Overrides Function ToString() As String
'to tell the Listbox what to display
Return String.Format("{0} - {1}", Me.Id, String.Join(Me.Tags, " "))
End Function
End Class
Dim searchTags = textbox1.Text.Split(" "c)
Dim query = mainlist.Where(Function(et) et.Tags.Any(Function(tag) searchTags.Contains(tag))).ToList
For Each et In query
Listbox1.Items.Add(et)
Next
I have a text file format:
*******************************************************************************
* Mitecs Test Plan *
*******************************************************************************
[PRODUCTN]
FQA=3F.4.W0,41,1
RSC=3F.5.W4,36,1
CFG=3F.9.2J,234,1
[MASTERREV]
MTP=3F.R.WM
[FQA 13]
FQA=3F.4.W0,41,1
CFG=3F.9.2J,263,1
[FQA 14]
FQA=3F.4.W0,160,1
CFG=3F.9.2J,315,1
I want to read text and display it in the list box, something like the below:
[PRODUCTN]
[MASTERREV]
[FQA 13]
[FQA 14]
From the above image, when I the select [FQA 14] item in list box 1 and click on the swap button, it should display in the below format in listbox 2 as
Code Name Version
160 FQA 3F.4.W0
315 CFG 3F.9.2J
One option is to use a class to hold each entry and override the ToString function to return the heading. Now you can add each entry directly to listbox1 and it will show the title to represent the item. Since each listbox item actually is an object you can cast the selected item as your entry class and read the data from the object. Here's one way to do it:
Public Class Entry
Public Property Title As String = ""
Public Property Data As New List(Of String)
Public Overrides Function ToString() As String
Return Title
End Function
End Class
Private Sub Form4_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim sr As New StreamReader("textfile1.txt")
Do Until (sr.EndOfStream)
Dim line As String = sr.ReadLine.Trim
If line.StartsWith("[") Then
Dim newentry As New Entry
newentry.Title = line
Do Until (line = "" OrElse sr.EndOfStream)
line = sr.ReadLine.Trim
If Not line = "" Then
newentry.Data.Add(line)
End If
Loop
ListBox1.Items.Add(newentry)
End If
Loop
End Sub
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
Dim selectedentry As Entry = DirectCast(DirectCast(sender, ListBox).SelectedItem, Entry)
ListBox2.Items.Clear()
For Each datum In selectedentry.Data
Dim line As String() = datum.Split("=,".ToCharArray, StringSplitOptions.RemoveEmptyEntries)
If line.Count > 2 Then
ListBox2.Items.Add(line(2) + vbTab + line(0) + vbTab + line(1))
Else
ListBox2.Items.Add(" " + vbTab + line(0) + vbTab + line(1))
End If
Next
End Sub