I'm trying to send serial data from Arduino and read it on Visual Basic. When I execute the code sometimes works and sometimes doesn't: throwing exception, System.ArgumentOutOfRangeException: 'Index and length must refer to a location within the string. Can you help me?
I'm new to Visual Basic, thanks.
Imports System.IO
Imports System.IO.Ports
Imports System.Threading
Public Class Form1
Dim TWSL, TWAL, THL, AoAL, WAL, PeL, RoilL, RyL, RydL As Integer
Dim TWS, TWA, TH, AoA, WA, Pe, Roil, Ry, Ryd, TWSResult, TWAResult, THResult, AoAResult, WAResult, PeResult, RoilResult, RyResult, RydResult As String
Dim StrSerialIn, StrSerialInRam As String
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.CenterToParent()
SerialPort1.PortName = "COM4"
SerialPort1.BaudRate = 9600
SerialPort1.Open()
Timer1.Start()
SerialPort1.Write(TrackBarAWA.Value & Chr(10))
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Try
StrSerialIn = SerialPort1.ReadExisting
Dim TB As New TextBox
TB.Multiline = True
TB.Text = StrSerialIn
If TB.Lines.Count > 0 Then
If TB.Lines(0) = "Failed to read" Then
Timer1.Stop()
SerialPort1.Close()
Return
End If
StrSerialInRam = TB.Lines(0).Substring(0, 2)
If StrSerialInRam = "A" Then
TWS = TB.Lines(0)
TWSL = TWS.Length
Else
TWS = TWS
End If
StrSerialInRam = TB.Lines(1).Substring(0, 3)
If StrSerialInRam = "B" Then
TWA = TB.Lines(1)
TWAL = TWA.Length
Else
TWA = TWA
End If
StrSerialInRam = TB.Lines(2).Substring(0, 3)
If StrSerialInRam = "C" Then
TH = TB.Lines(2)
THL = TH.Length
Else
TH = TH
End If
StrSerialInRam = TB.Lines(3).Substring(0, 2)
If StrSerialInRam = "D" Then
AoA = TB.Lines(3)
AoAL = AoA.Length
Else
AoA = AoA
End If
StrSerialInRam = TB.Lines(4).Substring(0, 1)
If StrSerialInRam = "E" Then
WA = TB.Lines(4)
WAL = WA.Length
Else
WA = WA
End If
StrSerialInRam = TB.Lines(5).Substring(0, 3)
If StrSerialInRam = "F" Then
Pe = TB.Lines(5)
PeL = Pe.Length
Else
Pe = Pe
End If
StrSerialInRam = TB.Lines(6).Substring(0, 3)
If StrSerialInRam = "G" Then
Roil = TB.Lines(6)
RoilL = Roil.Length
Else
Roil = Roil
End If
StrSerialInRam = TB.Lines(7).Substring(0, 3)
If StrSerialInRam = "H" Then
Ry = TB.Lines(7)
RyL = Ry.Length
Else
Ry = Ry
End If
StrSerialInRam = TB.Lines(8).Substring(0, 3)
If StrSerialInRam = "I" Then
Ryd = TB.Lines(8)
RydL = Ryd.Length
Else
Ryd = Ryd
End If
TWSResult = Mid(TWS, 2, TWSL)
TWAResult = Mid(TWA, 2, TWAL)
THResult = Mid(TH, 2, THL)
AoAResult = Mid(AoA, 2, AoAL)
WAResult = Mid(WA, 2, WAL)
PeResult = Mid(Pe, 2, PeL)
RoilResult = Mid(Roil, 2, RoilL)
RyResult = Mid(Ry, 2, RyL)
RydResult = Mid(Ryd, 2, RydL)
TWSvalue.Text = TWSResult
TWAvalue.Text = TWAResult
THvalue.Text = THResult
AoAvalue.Text = AoAResult
WAvalue.Text = WAResult
PeValue.Text = PeResult
RoilValue.Text = RoilResult
RyValue.Text = RyResult
RydValue.Text = RydResult
From what I gather, you are trying to get characters from specific places in specific lines on a text box. Based on the error message you included in your question, I assume the error occurs on a line of code containing the "String. Substring" method. If the string where you are getting the substring from is too short to cover the range you have specified in the substring method, you will get this error. For instance, if you are getting a substring that's 3 characters long from line 2 starting at character 0 and it has less than 3 characters, you will get this error.
See the documentation on the String.Substring method here
Related
This question already has answers here:
What is an IndexOutOfRangeException / ArgumentOutOfRangeException and how do I fix it?
(5 answers)
Closed 2 years ago.
i've tried the other solution(like changing item that should be shown on data) but i think i've never gotten the point to resolving. Thank you in advance whoever can answer my problem...
Private Sub dgEmp_Click(sender As Object, e As EventArgs) Handles dgEmp.Click
LoadEmployeeInfo(dgEmp.SelectedRows.Item(0).Index)
End Sub
Private Sub LoadEmployee(Optional q As String = "")
list.Query = "Select id,lastname,firstname,middlename,sss,philh,pag,rate,cola,mStatus,free_insurance,mp,mpvalue from tblemployee where (lastname like'%" & q & "%' or firstname like'%" & q & "%' or middlename like'%" & q & "%') and deactive='No' order by lastname,firstname,middlename"
list.datagrid = dgEmp
list.LoadRecords()
If list.RecordCount = Nothing Then Exit Sub
LoadEmployeeInfo(dgEmp.SelectedRows.Item(0).Index)
End Sub
Public Sub LoadEmployeeInfo(index As Integer)
With dgEmp.Rows(index)
id = .Cells(0).Value
lblName.Text = .Cells(1).Value & ", " & .Cells(2).Value & " " & .Cells(3).Value
rpd = .Cells(7).Value
lblRate.Text = Format(rpd, "#,##0.000000000")
cola = .Cells(8).Value
lblAllo.Text = Format(cola, "#,##0.000000000")
otrate = (rpd / 8) * 1.25
lblOTRate.Text = Format(otrate, "#,##0.000000000")
IsSSS = ConvertToBoolean(.Cells(4).Value)
IsPH = ConvertToBoolean(.Cells(5).Value) 'add
IsPAG = ConvertToBoolean(.Cells(6).Value) 'pos
IsMP = ConvertToBoolean(.Cells(11).Value)
IsFI = ConvertToBoolean(.Cells(10).Value)
CStatus = .Cells(9).Value
MPV = .Cells(12).Value
End With
ThisPayroll.Query = "Select * from tblpayroll where payrollperiod=? and empid=?"
ThisPayroll.AddParam("#payrollperiod", GetPeriod)
ThisPayroll.AddParam("#empid", id)
ThisPayroll.ExecQuery()
If ThisPayroll.RecordCount = Nothing Then
isUpdate = False
txtReg_Days.Text = 0
txtReg_OT.Text = 0
txtSP_Days.Text = 0
txtSP_OT.Text = 0
txtHoliday.Text = 0
txtHolidayOT.Text = 0
txtLate.Text = 0
txtAdjustment.Text = 0
txtSSSL.Text = 0
txtHDMFL.Text = 0
txtCA.Text = 0
txtDMA.Text = 0
txtRice.Text = 0
txtCloth.Text = 0
txtEmpMed.Text = 0
txtLaundry.Text = 0
txtMeal.Text = 0
Else
With ThisPayroll.DataSource
isUpdate = True
txtReg_Days.Text = .Rows(0)("regday")
txtReg_OT.Text = .Rows(0)("ot")
txtSP_Days.Text = .Rows(0)("spday")
txtSP_OT.Text = .Rows(0)("spdayot")
txtHoliday.Text = .Rows(0)("lholiday")
txtHolidayOT.Text = .Rows(0)("lhot")
txtLate.Text = .Rows(0)("hlate")
txtAdjustment.Text = .Rows(0)("salary_adj")
txtSSSL.Text = .Rows(0)("sss_loan")
txtHDMFL.Text = .Rows(0)("pag_loan")
txtCA.Text = .Rows(0)("cash_advance")
txtDMA.Text = .Rows(0)("depmed")
txtRice.Text = .Rows(0)("ricesub")
txtCloth.Text = .Rows(0)("clothing")
txtEmpMed.Text = .Rows(0)("empmed")
txtLaundry.Text = .Rows(0)("laundry")
txtMeal.Text = .Rows(0)("meal")
End With
End If
Compute()
End Sub
If you cannot make sure that something is selected elsewhere, you can last-minute check it like this:
Private Sub DataGridView1_SelectionChanged(sender As Object, e As EventArgs) Handles DataGridView1.SelectionChanged
If dgEmp.SelectedRows.Count > 0 Then
LoadEmployeeInfo(dgEmp.SelectedRows.Item(0).Index)
End If
End Sub
It works only because you're using index zero, or else you would have to be careful for your index, too. Of course, this is assuming that dgEmp is not Nothing...
Also, notice that I attached this to the SelectionChanged event, as I don't think that the Click event will give you what you want, but I'll let that part for you to deal with. Have fun!
I have been working on a "WAR" card game in class. I seem to have most of it setup correctly, however, I am having some issues dealing 2 new cards to the image boxes when clicking the deal button.
The exact things I need the draw button to accomplish is
When the draw button is pressed, the first two cards from the shuffled deck
should show up, one on the left and one on the right side. The middle card will be the
“Left win”, “Right Win”, or “Tie” image and is correctly indicate who won (with the higher
card). Furthermore, the winner’s score should increase by 1 point.
I will include a screenshot of my form to give you an idea of what I am working with and where I should go with the deal button. My guess is when I click the deal button a second time it is resetting the values back to 0 and 26 respectively.
enter image description here
Public Class Form1
'WAR
Dim cardarray(52) As Image
Dim valuearray(52) As Integer
Dim cardval1, cardval2 As Integer
Dim card1, card2 As Integer
Dim P1, P2 As Integer
Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
Close()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
pct1.Image = My.Resources.back
pct2.Image = My.Resources.back
pct3.Image = My.Resources.back
'Needed to generate a random number/card
Randomize()
'create 52 card element array
CardArray(0) = My.Resources.twoc
CardArray(1) = My.Resources.twod
CardArray(2) = My.Resources.twoh
CardArray(3) = My.Resources.twos
CardArray(4) = My.Resources.threec
CardArray(5) = My.Resources.threed
CardArray(6) = My.Resources.threeh
CardArray(7) = My.Resources.threes
CardArray(8) = My.Resources.fourc
CardArray(9) = My.Resources.fourd
CardArray(10) = My.Resources.fourh
CardArray(11) = My.Resources.fours
CardArray(12) = My.Resources.fivec
CardArray(13) = My.Resources.fived
CardArray(14) = My.Resources.fiveh
CardArray(15) = My.Resources.fives
CardArray(16) = My.Resources.sixc
CardArray(17) = My.Resources.sixd
CardArray(18) = My.Resources.sixh
CardArray(19) = My.Resources.sixs
CardArray(20) = My.Resources.sevenc
CardArray(21) = My.Resources.sevend
CardArray(22) = My.Resources.sevenh
CardArray(23) = My.Resources.sevens
CardArray(24) = My.Resources.eightc
CardArray(25) = My.Resources.eightd
CardArray(26) = My.Resources.eighth
CardArray(27) = My.Resources.eights
CardArray(28) = My.Resources.ninec
CardArray(29) = My.Resources.nined
CardArray(30) = My.Resources.nineh
CardArray(31) = My.Resources.nines
CardArray(32) = My.Resources.tenc
CardArray(33) = My.Resources.tend
CardArray(34) = My.Resources.tenh
CardArray(35) = My.Resources.tens
CardArray(36) = My.Resources.jackc
CardArray(37) = My.Resources.jackd
CardArray(38) = My.Resources.jackh
CardArray(39) = My.Resources.jacks
CardArray(40) = My.Resources.queenc
CardArray(41) = My.Resources.queend
CardArray(42) = My.Resources.queenh
CardArray(43) = My.Resources.queens
CardArray(44) = My.Resources.kingc
CardArray(45) = My.Resources.kingd
CardArray(46) = My.Resources.kingh
CardArray(47) = My.Resources.kings
CardArray(48) = My.Resources.acec
CardArray(49) = My.Resources.aced
CardArray(50) = My.Resources.aceh
CardArray(51) = My.Resources.aces
'52 integer value array
valueArray(0) = 1
valueArray(1) = 1
valueArray(2) = 1
valueArray(3) = 1
valueArray(4) = 2
valueArray(5) = 2
valueArray(6) = 2
valueArray(7) = 2
valueArray(8) = 3
valueArray(9) = 3
valueArray(10) = 3
valueArray(11) = 3
valueArray(12) = 4
valueArray(13) = 4
valueArray(14) = 4
valueArray(15) = 4
valueArray(16) = 5
valueArray(17) = 5
valueArray(18) = 5
valueArray(19) = 5
valueArray(20) = 6
valueArray(21) = 6
valueArray(22) = 6
valueArray(23) = 6
valueArray(24) = 7
valueArray(25) = 7
valueArray(26) = 7
valueArray(27) = 7
valueArray(28) = 8
valueArray(29) = 8
valueArray(30) = 8
valueArray(31) = 8
valueArray(32) = 9
valueArray(33) = 9
valueArray(34) = 9
valueArray(35) = 9
valueArray(36) = 10
valueArray(37) = 10
valueArray(38) = 10
valueArray(39) = 10
valueArray(40) = 11
valueArray(41) = 11
valueArray(42) = 11
valueArray(43) = 11
valueArray(44) = 12
valueArray(45) = 12
valueArray(46) = 12
valueArray(47) = 12
valueArray(48) = 13
valueArray(49) = 13
valueArray(50) = 13
valueArray(51) = 13
End Sub
Public Sub shuffel()
Dim switch As Integer
Dim tempcard As Image
Dim number_of_cards, tempval As Integer
number_of_cards = 52
'Go through the deck one card at a time:
For i = 0 To number_of_cards - 1
'Get a random card number from the deck
switch = Int(Rnd() * number_of_cards)
'Switch the current card’s value with the random card’s value
tempval = valuearray(i)
valuearray(i) = valuearray(switch)
valuearray(switch) = tempval
'Switch the current card’s image with the random card’s image
tempcard = cardarray(i)
cardarray(i) = cardarray(switch)
cardarray(switch) = tempcard
Next
End Sub
Private Sub BtnClear_Click(sender As Object, e As EventArgs) Handles BtnClear.Click
'shuffle deck and set scores to 0
Call shuffel()
txtP1.Text = 0
txtP2.Text = 0
End Sub
Private Sub TextBox2_TextChanged(sender As Object, e As EventArgs) Handles txtP2.TextChanged
End Sub
Private Sub btnShuffle_Click(sender As Object, e As EventArgs) Handles btnShuffle.Click
'shuffle deck and change card backs
Call shuffel()
pct1.Image = My.Resources.back
pct2.Image = My.Resources.back
pct3.Image = My.Resources.back
End Sub
Private Sub btnDraw_Click(sender As Object, e As EventArgs) Handles btnDraw.Click
'set interger values for starting points
cardval1 = 0
cardval2 = 26
'load those starting points into image boxes
pct1.Image = cardarray(cardval1)
pct3.Image = cardarray(cardval2)
'increase card values by 1
cardval1 = (cardval1 + 1)
cardval2 = (cardval2 + 1)
End Sub
End Class
I would think that you should move the part in btnDraw_Click where you are setting the starting points to btnShuffle_CLick and this would get what you are after?
Essentially, the purpose of this program is for revision. The program will generate a random mathematical expression, convert this into a visual representation of a binary tree and the user will have to traverse the binary tree. However, when I run this code, the initial node is far off centre. How would I go about re-positioning the binary tree to be in the middle of the PictureBox? Here is my code:
Public Class BTT
'VARAIBLES DECLARED CANNOT BE A FAULT
Dim nodes(7) As Object
'maybe try to alter the form so that the user can only get two incorrect answers'
Dim operators(6) As String
Dim actualAnswer As String = ""
Dim ogEquation(11) As String
Dim newLabel As String = "" 'used to store the equation to be stored in the label'
Dim userAnswer As String
Dim myTime As Double
Dim traversal(3) As String
Dim selectedTraversal As String
Dim treeCounter As Integer = 0
Dim draw As Boolean = False
Structure tree
Dim name As String
Dim left As Integer
Dim right As Integer
End Structure
Dim TreeNode(7) As tree
Dim scoreValue As Integer = 0 'stores the user's score for the game just completed'
Dim updating As Boolean = False 'if there are already 10 scores, the first one will need to be removed, so updating = true'
Class node
Public lineColour As Color
Public lineWidth As Integer
Public posX As Integer
Public posY As Integer
Public radius As Integer
Public Sub draw(e As PaintEventArgs)
Dim myPen As New Pen(Me.lineColour, Me.lineWidth)
e.Graphics.DrawEllipse(myPen, Me.posX, Me.posY, Me.radius, Me.radius)
End Sub
End Class
Sub DrawTree()
'these are the coordinates of the top left of the PictureBox
Dim leftX As Integer = 171
Dim rightX As Integer = 171 + PictureBox1.Width 'will be set to the edge of the picturebox
Dim topY As Integer = 138
Dim bottomY As Integer = 138 + PictureBox1.Height 'will be that number of pixels down, WILL NEVER CHANGE
Dim currentNode As Integer = 1 'will initially be the root node
For i = 1 To treeCounter 'loops based on the number of nodes in the array'
'assigns the basic information common to all of the nodes
nodes(i) = New node
nodes(i).radius = 70
nodes(i).lineWidth = 2
nodes(i).lineColour = Color.Black
Next
'need to go through the binary tree and determine x & y positions, with labels inside the ellipses
ConstructTree(currentNode, leftX, rightX, topY, bottomY)
draw = True
PictureBox1.Refresh()
End Sub
Sub ConstructTree(ByRef currentNode As Integer, ByRef leftX As Integer, ByRef rightX As Integer, ByRef topY As Integer, ByRef bottomY As Integer)
'ASK ISABEL ABOUT DYNAMICALLY GENERATING A LABEL'
'e.g. Dim test As New Label
nodes(currentNode).posX = (leftX + rightX) / 2 'gets average of x coordinates'
nodes(currentNode).posY = topY + ((bottomY - topY) * (1 / 3)) 'gets number of pixels down between bottom of form & last node, goes a third of the way down
If TreeNode(currentNode).left <> 0 Then 'if there is a node to the left
ConstructTree(TreeNode(currentNode).left, leftX, (leftX + rightX) / 2, nodes(currentNode).posY, bottomY)
End If
If TreeNode(currentNode).right <> 0 Then 'if there is a node to the right
ConstructTree(TreeNode(currentNode).right, (leftX + rightX) / 2, rightX, nodes(currentNode).posY, bottomY) 'swaps the left and right x-coords which have been changed
End If
End Sub
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
If draw = True Then
For i = 1 To treeCounter
nodes(i).draw(e)
Next
'ALSO need to draw lines between the nodes, but IGNORE FOR NOW
End If
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
TextBox1.Text = myTime - (0.1)
myTime = TextBox1.Text
If myTime = 0 Then
Timer1.Enabled = False
MsgBox("Time is up!")
checkupdate()
resetForm()
End If
'add another if statement checking for two wrong answers, will stop the timer and tell the user that they have got too man questions wrong'
End Sub
Sub resetForm()
Score.Text = "Score:"
Label1.Text = ""
scoreValue = 0
End Sub
Sub writefile()
FileOpen(1, "BTTscores.txt", OpenMode.Output)
Select Case updating
Case True
For i = 2 To 11
WriteLine(1, scores(i))
Next
Case False
For i = 1 To numberOfScores + 1
WriteLine(1, scores(i))
Next
End Select
FileClose()
End Sub
Sub checkupdate()
'need to check whether there are already ten elements in the array. If so, then delete the first score, move all the indices of the other scores 1 to the left and add the new scores on the end'
numberOfScores = 0 'will need to be reset if the user carries on using the program'
FileOpen(1, "BTTscores.txt", OpenMode.Input) 'need to bubble sort values'
Dim line As String
Do Until EOF(1)
line = LineInput(1)
If line <> "" Then
numberOfScores = numberOfScores + 1
scores(numberOfScores) = line 'copies the line to the array'
End If
Loop
If numberOfScores = 10 Then 'if one needs to be updated, need to read all but the first line into the array'
updating = True
scores(11) = scoreValue
Else 'if there are less than 10 scores, the user's current score just needs to be added on the end'
updating = False
scores(numberOfScores + 1) = scoreValue
End If
FileClose(1)
writefile()
End Sub
Private Sub EnterButton_Click(sender As Object, e As EventArgs) Handles EnterButton.Click
userAnswer = Answer.Text
If actualAnswer.Replace(" ", "") = userAnswer.Replace(" ", "") Then
UpdateScore()
End If
Score.Text = ("Score: " & scoreValue)
Answer.Text = ""
InitialSetup()
End Sub
Sub UpdateScore()
Select Case difficulty
Case "Easy"
scoreValue = scoreValue + 10
Case "Medium"
scoreValue = scoreValue + 15
Case "Hard"
scoreValue = scoreValue + 20
End Select
End Sub
Private Sub StartButton_Click(sender As Object, e As EventArgs) Handles StartButton.Click
scoreValue = 0
Initialisation()
InitialSetup()
myTime = 60
Timer1.Enabled = True
End Sub
Sub InitialSetup()
Dim currentNode As Integer = 1 'will be root node'
actualAnswer = ""
GetEquation()
newLabel = ""
selectedTraversal = traversal(CInt(Math.Floor((3 - 1 + 1) * Rnd())) + 1) 'will choose a random traversal'
newLabel = "Traversal: " + selectedTraversal
Label1.Text = newLabel
If selectedTraversal = "Prefix" Then
PrefixConversion(currentNode)
ElseIf selectedTraversal = "Infix" Then
InfixConversion()
Else
RPConversion()
End If
DrawTree()
End Sub
Sub Initialisation()
operators(1) = "("
operators(2) = "-"
operators(3) = "+"
operators(4) = "*"
operators(5) = "/"
operators(6) = ")"
traversal(1) = "Prefix"
traversal(2) = "Infix"
traversal(3) = "Postfix"
End Sub
Sub GetEquation()
Select Case difficulty
'RANDOM NUMBER FORMAT: CInt(Math.Floor((upperbound - lowerbound + 1) * Rnd())) + lowerbound'
Case "Easy"
'FORMAT: 17 * 4'
treeCounter = 3
ogEquation(1) = CInt(Math.Floor((20 - 1 + 1) * Rnd())) + 1
ogEquation(2) = operators(CInt(Math.Floor((5 - 2 + 1) * Rnd())) + 2)
ogEquation(3) = CInt(Math.Floor((20 - 1 + 1) * Rnd())) + 1
'initialising the binary tree iteration'
TreeNode(1).name = ogEquation(2) 'operator is the root'
TreeNode(1).left = 2
TreeNode(1).right = 3
TreeNode(2).name = ogEquation(1)
TreeNode(3).name = ogEquation(3)
'EG: * 17 4
Case "Medium"
treeCounter = 5
'FORMAT: 15 * (17 + 4)'
ogEquation(1) = CInt(Math.Floor((50 - 1 + 1) * Rnd())) + 1
ogEquation(2) = operators(CInt(Math.Floor((5 - 2 + 1) * Rnd())) + 2)
ogEquation(3) = operators(1)
ogEquation(4) = CInt(Math.Floor((50 - 1 + 1) * Rnd())) + 1
ogEquation(5) = operators(CInt(Math.Floor((5 - 2 + 1) * Rnd())) + 2)
ogEquation(6) = CInt(Math.Floor((50 - 1 + 1) * Rnd())) + 1
ogEquation(7) = operators(6)
'initialising the binary tree iteration'
TreeNode(1).name = ogEquation(2) 'root node'
TreeNode(1).left = 2
TreeNode(1).right = 3
TreeNode(2).name = ogEquation(1)
TreeNode(3).name = ogEquation(5)
TreeNode(3).left = 4
TreeNode(3).right = 5
TreeNode(4).name = ogEquation(4)
TreeNode(5).name = ogEquation(6)
'EG: * 15 + 17 4
Case "Hard"
'FORMAT: (17 + 4) * (20 / 10), random numbers are 1-150'
treeCounter = 7
ogEquation(1) = operators(1)
ogEquation(2) = CInt(Math.Floor((150 - 1 + 1) * Rnd())) + 1
ogEquation(3) = operators(CInt(Math.Floor((5 - 2 + 1) * Rnd())) + 2)
ogEquation(4) = CInt(Math.Floor((150 - 1 + 1) * Rnd())) + 1
ogEquation(5) = operators(6)
ogEquation(6) = operators(CInt(Math.Floor((5 - 2 + 1) * Rnd())) + 2)
ogEquation(7) = operators(1)
ogEquation(8) = CInt(Math.Floor((150 - 1 + 1) * Rnd())) + 1
ogEquation(9) = operators(CInt(Math.Floor((5 - 2 + 1) * Rnd())) + 2)
ogEquation(10) = CInt(Math.Floor((150 - 1 + 1) * Rnd())) + 1
ogEquation(11) = operators(6)
'initialising the binary tree iteration'
TreeNode(1).name = ogEquation(6) 'root node'
TreeNode(1).left = 2
TreeNode(1).right = 5
TreeNode(2).name = ogEquation(3)
TreeNode(2).left = 3
TreeNode(2).right = 4
TreeNode(3).name = ogEquation(2)
TreeNode(4).name = ogEquation(4)
TreeNode(5).name = ogEquation(9)
TreeNode(5).left = 6
TreeNode(5).right = 7
TreeNode(6).name = ogEquation(8)
TreeNode(7).name = ogEquation(10)
'EG: * + 17 4 / 20 10
End Select
End Sub
'Traversal Solutions'
'Postfix Conversion'
Sub RPConversion()
Dim myStack As New Stack(15)
Dim empty As Boolean = True
Dim temp As String 'used to store the current part of the original equation'
Dim operatorNum As Integer
Dim peekNum As Integer
Dim stoploop As Boolean = True
For i = 1 To ogEquation.Count - 1 'will iterate through the total number of elements in the array ogEquation'
If myStack.Count = 0 Then empty = True
temp = ogEquation(i)
MatchTempOperation(myStack, temp, operatorNum)
If operatorNum > 1 And operatorNum < 6 Then 'if the value is an operator'
If myStack.Count <> 0 Then 'if the stack contains a value'
CheckPeek(myStack, peekNum)
If operatorNum > peekNum Then
myStack.Push(temp)
ElseIf operatorNum = peekNum Then
actualAnswer = actualAnswer + myStack.Pop()
myStack.Push(temp)
Else 'operatorNum < peekNum'
actualAnswer = actualAnswer + myStack.Pop()
Do
stoploop = True
CheckPeek(myStack, peekNum)
If operatorNum > peekNum Then
myStack.Push(temp)
ElseIf operatorNum = peekNum Then
actualAnswer = actualAnswer + myStack.Pop()
myStack.Push(temp)
Else
actualAnswer = actualAnswer + myStack.Pop()
stoploop = False
End If
Loop Until stoploop Or myStack.Count = 0
End If
Else
myStack.Push(temp)
End If
ElseIf temp = "(" Then
myStack.Push(temp)
ElseIf temp = ")" Then
Do
actualAnswer = actualAnswer + myStack.Pop()
Loop Until myStack.Peek() = "("
myStack.Pop()
Else
actualAnswer = actualAnswer + temp
End If
operatorNum = 0
Next
If myStack.Count > 0 Then
For i = 1 To myStack.Count
actualAnswer = actualAnswer + myStack.Pop()
Next
End If
End Sub
Sub CheckPeek(ByVal myStack As Stack, ByRef peekNum As Integer) 'does the same as MatchTempOperation but for the top of the stack'
For i = 2 To 5 'skip one and six because we know it isn't a left or right bracket'
If myStack.Peek() = operators(i) Then
peekNum = i
End If
Next
End Sub
Sub MatchTempOperation(ByVal myStack As Stack, ByVal temp As String, ByRef operatorNum As Integer) 'wants to look at the stack but not be able to change it'
For i = 1 To 6
If temp = operators(i) Then
operatorNum = i
End If
Next
End Sub
'Infix'
Sub InfixConversion()
For i = 1 To 11
'check each element for empty spaces / brackets'
If ogEquation(i) <> "" And ogEquation(i) <> "(" And ogEquation(i) <> ")" Then
actualAnswer = actualAnswer + ogEquation(i)
End If
Next
End Sub
'Prefix'
Sub PrefixConversion(ByRef currentNode As Integer)
actualAnswer = actualAnswer + TreeNode(currentNode).name
If TreeNode(currentNode).left <> 0 Then
PrefixConversion(TreeNode(currentNode).left)
End If
If TreeNode(currentNode).right <> 0 Then
PrefixConversion(TreeNode(currentNode).right)
End If
End Sub
Private Sub ExitButton_Click(sender As Object, e As EventArgs) Handles ExitButton.Click
Me.Hide()
End Sub
End Class
Apologies for it's inefficiency, please also note that the "difficulty" variable is Public and stored outside of this form. Thanks :)
OUTPUT:
enter image description here
As you can see, the root node is far off centre in the bottom left.
First, I have searched using SO and have not found answer.
Program cannot compile due to this build error in which I attempt to use dynamic label.
Here is the offending part of code (how fix this error message)?
Label(num).text = userchoice(num) Then
Error message:
Label is not a type and cannot be used as an expresssion
All of the code:
Public Class MainForm
Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim foodtype As Decimal
Dim userchoice
For num As Integer = 1 To 7 Step 1
If num <= 4 Then
foodtype = "Main course"
ElseIf num = 5 Then
foodtype = "Bread"
ElseIf num = 6 Then
foodtype = "Drink"
ElseIf num = 7 Then
foodtype = "Dessert"
End If
userchoice(num).to = InputBox(foodtype & num)
Dim lc = userchoice(num).tolower
Dim calories
If lc = "stuffing" Then
calories = 165
ElseIf lc = "turkey" Then
calories = 180
ElseIf lc = "mashed potatoes" Then
calories = 220
ElseIf lc = "carrots" Then
calories = 25
ElseIf lc = "french bread" Then
calories = 224
ElseIf lc = "everclear" OrElse lc = "water" Then
calories = 1
ElseIf lc = "pudding" Then
calories = "170"
End If
Label(num).text = userchoice(num) Then
Next
End Sub
End Class
I am using the below code as a portion of a much larger code to convert a number to its alphanumeric equal i.e 1=A, 2=B, etc. While this does work it is crazy long code and I am sure there is a better way to do this and was hoping you guys could assist.
Sub Convert()
Time = Range("A1")
If Time = 1 Then
E = "A"
Else
If Time = 2 Then
E = "B"
Else
If Time = 3 Then
E = "C"
Else
If Time = 4 Then
E = "D"
Else
If Time = 5 Then
E = "E"
Else
If Time = 6 Then
E = "F"
Else
If Time = 7 Then
E = "G"
Else
If Time = 8 Then
E = "H"
Else
If Time = 9 Then
E = "I"
Else
If Time = 10 Then
E = "J"
Else
If Time = 11 Then
E = "K"
Else
If Time = 12 Then
E = "L"
Else
If Time = 13 Then
E = "M"
Else
If Time = 14 Then
E = "N"
Else
If Time = 15 Then
E = "O"
Else
If Time = 16 Then
E = "P"
Else
If Time = 17 Then
E = "Q"
Else
If Time = 18 Then
E = "R"
Else
If Time = 19 Then
E = "S"
Else
If Time = 20 Then
E = "T"
Else
If Time = 21 Then
E = "U"
Else
If Time = 22 Then
E = "V"
Else
If Time = 23 Then
E = "W"
Else
If Time = 24 Then
E = "X"
Else
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
MsgBox E
End Sub
Easier and more solid way is to use what Excel already offers, which means "every letter is associated to a number in the ranges":
Public Function numberToLetter(ByVal myNumber As Integer) As String
numberToLetter = Split(Cells(1, myNumber).Address, "$")(1)
End Function
This is one way.
Sub numberToLetter()
Dim Time As Integer
Dim E As String
Time = Range("A1")
If Time > 26 Then
E = Chr(Int((Time - 1) / 26) + 64) & Chr(((Time - 1) Mod 26) + 65)
Else
E = Chr(Time + 64)
End If
End Sub
Notes
Chr returns a character based on the ASCII value