VB.net Expression does not produce a value error - arrays

I am brand new to vb.net and programming in general so sorry if this is a basic error but im trying to make a x's and o's game in vb.net and it keeps saying that my CheckForWin does not produce a value which makes zero sense to me and when i looked it up the only questions were about converting different code to vb.net and said nothing about the problem i was having
This my code:
Public Class Form1
Dim Board(9) As String
Dim Player1 As String = "X"
Dim Player2 As String = "O"
Public Property X As String
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub ResetBoard()
Do
If CheckForWin() = True Then
Board(0) = 0
Board(1) = 0
Board(2) = 0
Board(3) = 0
Board(4) = 0
Board(5) = 0
Board(6) = 0
Board(7) = 0
Board(8) = 0
End If
Loop Until Board(0) = 0
Board(1) = 0
Board(2) = 0
Board(3) = 0
Board(4) = 0
Board(5) = 0
Board(6) = 0
Board(7) = 0
Board(8) = 0
End Sub
Private Sub CheckForWin()
If "0""3""6" = X Then
ResetBoard()
ElseIf "1""4""7" = X Then
ResetBoard()
ElseIf "2""5""8" = X Then
ResetBoard()
ElseIf "0""1""2" = X Then
ResetBoard()
ElseIf "3""4""5" = X Then
ResetBoard()
ElseIf "6""7""8" = X Then
ResetBoard()
ElseIf "0""4""8" = X Then
ResetBoard()
ElseIf "2""4""6" = X Then
ResetBoard()
ElseIf "0""3""6" = 0 Then
ResetBoard()
ElseIf "1""4""7" = 0 Then
ResetBoard()
ElseIf "2""5""8" = 0 Then
ResetBoard()
ElseIf "0""1""2" = 0 Then
ResetBoard()
ElseIf "3""4""5" = 0 Then
ResetBoard()
ElseIf "6""7""8" = 0 Then
ResetBoard()
ElseIf "0""4""8" = 0 Then
ResetBoard()
ElseIf "2""4""6" = 0 Then
ResetBoard()
End If
End Sub
End Class
The problem lies within this line of code:
If CheckForWin() = True Then

This line of code:
If CheckForWin() = True Then
...
End If
This sets up a conditional check to see if the result of the CheckForWin method is true. The issue is that the method is a Sub routine and not a Function.
A Function represents a block of code that returns a value whereas a Sub also represents a block of code but it does not return a value.
What's more is that it appears as if you have fallen into an infinite loop. ResetBoard calls CheckForWin which calls ResetBoard which calls... and so on.
The simplest thing to do would be to:
Convert the CheckForWin to a Function
Stop calling ResetBoard in the CheckForWin method
Return True when any of your conditional checks in the ResetBoard method is True
Here is an example:
Private Sub ResetBoard()
' check if there is a winner, if not then stop execution of the method early
Dim isWin = CheckForWin()
If (Not isWin) Then
Return
End If
For index = 1 To 8
Board(index) = 0
Next
End Sub
Private Function CheckForWin() As Boolean
Dim winningPatterns = {
"0""3""6",
"1""4""7",
"2""5""8",
' etc...
}
Dim doAnyMatch = winningPatterns.Contains(X)
Return doAnyMatch
End Function

Related

How to delete an element from an Array in userform VBA

I have a user form with the following code. Basically what it does is If the user selects a title, and clicks commandButton2 which inserts the selected movie title into a titlebox and an array. Now i made another button commandButton3 which the user can select from the titlebox for which title to delete, but i am struggling deleting it from the array that i am building as well. Thanks in advance.
Public SelectedTitles As Variant, ArrCount As Long, EnableEvents As Boolean
Private Sub CommandButton1_Click()
'Done Button
Me.Hide
End Sub
Private Sub CommandButton2_Click()
'User has indicated they want to add the currently selected item to the list
If Not EnableEvents Then Exit Sub
If ArrCount = 0 Then 'First item, create the array
SelectedTitles = Array("")
Else
ReDim Preserve SelectedTitles(UBound(SelectedTitles) + 1) 'Next items, add one more space in the array
End If
'Add the selected title to the array
SelectedTitles(ArrCount) = ComboBox1.Value
ListBox1.AddItem (SelectedTitles(ArrCount))
'Increment the counter
ArrCount = ArrCount + 1
'Reset the checkbox and the combobox
EnableEvents = False
CommandButton2.Value = False
ComboBox1.Value = ""
EnableEvents = True
End Sub
Private Sub CommandButton3_Click()
For i = ListBox1.ListCount - 1 To 0 Step -1
If ListBox1.Selected(i) Then
ListBox1.RemoveItem i
If SelectedTitles() = i Then
SelectedTitles() = "n/a"
End If
ArrCount = ArrCount - 1
End If
Next i
EnableEvents = False
CommandButton3.Value = False
ComboBox1.Value = ""
EnableEvents = True
End Sub
Private Sub CommandButton4_Click()
ListBox1.Clear
Erase SelectedTitles
ArrCount = 0
EnableEvents = False
CommandButton4.Value = False
ComboBox1.Value = ""
EnableEvents = True
End Sub
Private Sub ListBox1_Click()
End Sub
Private Sub UserForm_Initialize()
EnableEvents = True
End Sub
Firt of all, using arrays in VBA can be a real pain. You might consider using ArrayLists instead, which are far more convenient to use. Check this:https://excelmacromastery.com/vba-arraylist/
Assuming your array was an arraylist you could just do you could just do :
For i = ListBox1.ListCount - 1 To 0 Step -1
If ListBox1.Selected(i) Then
ListBox1.RemoveItem i
SelectedTitles.RemoveAt i
End If
Next i
But if you wish to stick to your array you'll have to do something like this :
For i = ListBox1.ListCount - 1 To 0 Step -1
If ListBox1.Selected(i) Then
ListBox1.RemoveItem i
For j = 0 to Ubound(SelectedTitles)-1
If SelectedTitles(j) <> SelectedTitles (i) then
ReDim Preserve TempSelectedTitles(UBound(TempSelectedTitles) + 1)
TempSelectedTitles(j) = SelectedTitles(i)
end if
next J
SelectedTitles = TempSelectedTitle
End If
Next i
I didn't try this code but you got the idea, you will need to rebuild your array without including the selected value in you listbox

Linear Search Array Error

I am trying to implement a linear search but whenever i move on to the linearSearch() subroutine, I get the error:
Index was outside the bounds of the array
The line giving this error is the one containing If list(a) = numberToFind Then. How can I fix this?
Module Module1
Sub Main()
Dim list(99) As Integer
Dim x As Integer = 0
Dim answer As Integer
Console.Write("Enter a value, type 9999 to stop.")
answer = Console.ReadLine()
For i = 0 To list.Length
If answer = 9999 Then
linearSearch(list)
Else
list(i) = answer
Console.Write("Enter another")
answer = Console.ReadLine
End If
Next
End Sub
Sub linearSearch(ByVal list)
Dim numberToFind, comparisonNo As Integer
comparisonNo = 0
Console.Write("What number do you want to find?")
numberToFind = Console.ReadLine()
For a = 1 To list.Length
If list(a) = numberToFind Then
Console.Write(comparisonNo)
Else
comparisonNo += 1
End If
Next
Console.ReadLine()
End Sub
End Module
Change the lines "For a = 1 To list.Length" to "For a = 0 To list.Length - 1". Arrays are zero based.

Indexing random Dice Rolls (VBA)

I am building a simulation for the game of craps, below is my code to run through the process of rolling, along with a dice Class that executes the random rolls. I want to be able to graph the distribution of the rolls. For that, I believe I need to but the random rolls into an array, can anyone help I have been stuck for awhile.
Sub SetThePoint()
Dim lngRoll As Long
Dim lngNextRoll As Long
Dim lngThePoint As Long
Dim lngCounter As Long
Dim boolPointSet As Boolean
Dim boolResolved As Boolean
Set objDiceDict = CreateObject("Scripting.Dictionary")
Set objDice = New clsDice
'this procedure takes the value the roll dice function and conintiously rolls until a point is set
'StartGame:
Do
objDice.RollDice
lngRoll = objDice.sumDice
'Debug.Print lngRoll
Select Case lngRoll
Case Is = 2
boolPointSet = False
Case Is = 3
boolPointSet = False
Case Is = 4
boolPointSet = True
lngThePoint = 4
Case Is = 5
boolPointSet = True
lngThePoint = 5
Case Is = 6
boolPointSet = True
lngThePoint = 6
Case Is = 7
boolPointSet = False
Case Is = 8
boolPointSet = True
lngThePoint = 8
Case Is = 9
boolPointSet = True
lngThePoint = 9
Case Is = 10
boolPointSet = True
lngThePoint = 10
Case Is = 11
boolPointSet = False
Case Is = 12
boolPointSet = False
Case Else
boolPointSet = False
End Select
'Call PassLineBet(lngRoll)
Loop While boolPointSet = False
If boolPointSet = True Then
Do Until boolResolved = True
Debug.Print "The current point is a " & lngThePoint
objDice.RollDice
lngNextRoll = objDice.sumDice
'Debug.Print lngCounter
Debug.Print "You Rolled a " & lngNextRoll
If lngNextRoll = lngThePoint Then
'boolResolved = True
Debug.Print "You win"
GoTo StartGame:
ElseIf lngNextRoll = 7 Then
boolResolved = True
Debug.Print "You Lose"
'Debug.Print "Roll #: " & lngCounter
Exit Sub
Else
boolResolved = False
End If
Loop
End If
End Sub
Break, Class:
Option Explicit
Public diceOne As Long
Public diceTwo As Long
Public rollNum As Long
Public lngRollCounter As Long
Public sumDice As Long
Public lngPointsMade As Long
Public lSum As Long
Public Sub RollDice()
lngRollCounter = Counter
diceOne = Application.WorksheetFunction.RandBetween(1, 6)
diceTwo = Application.WorksheetFunction.RandBetween(1, 6)
sumDice = diceOne + diceTwo
End Sub
Private Sub Class_Initialize()
End Sub
Public Function Counter() As Long
Dim i As Long
i = i + 1
Counter = i
End Function

Background Worker and ODBC Query

I want to run the fetching of a Database into a background worker but it seems to be crashing without Visual Studio returning me an error in my code.
Here's the code in the DoWork:
Private Sub ITSM_Fetch_BW_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles ITSM_Fetch_BW.DoWork
Dim sql As String = "xxxx"
Dim ConnString As String = "DRIVER={AR System ODBC Driver};ARServer=xxxx;ARServerPort=xxxx;ARPrivateRpcSocket=xxxx;UID=xxxx;PWD=xxxx;ARAuthentication=;ARUseUnderscores=1;SERVER=NotTheServer"
Dim connection As New Odbc.OdbcConnection(ConnString)
connection.Open()
Dim ODBC_Command As New Odbc.OdbcCommand(sql, connection)
Dim ODBC_reader As Odbc.OdbcDataReader
'Load the Data into the local Memory
ODBC_reader = ODBC_Command.ExecuteReader
e.Result = ODBC_reader
ODBC_reader.Close()
End Sub
Private Sub ITSM_Fetch_BW_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles ITSM_Fetch_BW.RunWorkerCompleted
Data = New DataTable
Data.Load(e.Result)
Dim Count_ToDo(5) As String
Count_ToDo(0) = "Product_Name"
Count_ToDo(1) = "Status"
Count_ToDo(2) = "Language"
Count_ToDo(3) = "Assigned_Group"
Count_ToDo(4) = "Priority"
Count_ToDo(5) = "Company"
For Each Item As String In Count_ToDo
Dim i As Integer = 0
Dim ITEM_Count(0, 1) As String
For Each Ticket As DataRow In Data.Rows
'PART FOR THE CI
If IsDBNull(Ticket.Item(Item)) = False Then
Dim IsInIndex As Integer = -1
If i = 0 Then
ITEM_Count(0, 0) = Ticket.Item(Item)
ITEM_Count(0, 1) = 1
Else
For x As Integer = 0 To ITEM_Count.GetLength(0) - 1
If ITEM_Count(x, 0) = Ticket.Item(Item) Then
IsInIndex = x
End If
Next
If IsInIndex = -1 Then
Dim ITEM_Count_Temp(ITEM_Count.GetLength(0), ITEM_Count.GetLength(0)) As String
ITEM_Count_Temp = ITEM_Count
ReDim ITEM_Count(ITEM_Count.GetLength(0), 1)
For x As Integer = 0 To ITEM_Count_Temp.GetLength(0) - 1
For y As Integer = 0 To ITEM_Count_Temp.GetLength(1) - 1
ITEM_Count(x, y) = ITEM_Count_Temp(x, y)
Next
Next
ITEM_Count(ITEM_Count.GetLength(0) - 1, 0) = Ticket.Item(Item)
ITEM_Count(ITEM_Count.GetLength(0) - 1, 1) = 1
Else
ITEM_Count(IsInIndex, 1) = ITEM_Count(IsInIndex, 1) + 1
End If
End If
Else
'IF NULL
End If
i = i + 1
Next
'CI_COUNT FILLING
'ORDERING BY COUNT
Dim ITEM_obj = New List(Of obj)
Dim ITEM_ToObj As String = ""
Dim ITEMCount_ToObj As String = ""
For x As Integer = 0 To ITEM_Count.GetLength(0) - 1
ITEM_ToObj = ITEM_Count(x, 0)
ITEMCount_ToObj = ITEM_Count(x, 1)
ITEM_obj.Add(New obj(ITEM_ToObj, ITEMCount_ToObj))
Next
ITEM_obj = OrderItem(ITEM_obj)
Dim Item_Count_listview As ListViewItem
For Each Itemobj As obj In ITEM_obj
Dim Transfer_Array(2) As String
Transfer_Array(0) = Itemobj.Item
Transfer_Array(1) = Itemobj.Item_Count
Item_Count_listview = New ListViewItem(Transfer_Array)
Select Case Item
Case "Product_Name"
CI_Count_Table.Items.Add(Item_Count_listview)
Case "Status"
Status_Count_Table.Items.Add(Item_Count_listview)
Case "Language"
Language_Count_Table.Items.Add(Item_Count_listview)
Case "Assigned_Group"
AssignedGroup_Count_Table.Items.Add(Item_Count_listview)
Case "Priority"
Priority_Count_Table.Items.Add(Item_Count_listview)
Case "Company"
LOB_Count_Table.Items.Add(Item_Count_listview)
Case Else
MsgBox("No Category Of this type exist. Programming Issue. Item is: " & Item)
End Select
Next
Next
End Sub
What is not possible to run into a background worker like this?
regards,

How to call all members of a picture box array?

I'm making space invaders, and I'm using arrays for the first time, I have yet to learn them in class so I'm kind of free-balling it.
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FireTimer.Tick
Fire.Top = Fire.Top - 7
For index = 0 To 26
If Me.Fire.Bounds.IntersectsWith(pbxMyEnemies(index).Bounds) Then
pbxMyEnemies(index).Visible = False
pbxMyEnemies(index).Enabled = False
pbxMyEnemies(index).Left = 732
pbxMyEnemies(index).Top = 55
FireTimer.Enabled = False
Fire.Visible = False
z = 0
ElseIf Me.Fire.Bounds.IntersectsWith(stopper.Bounds) Then
z = 0
End If
Next
If pbxMyEnemies().Visible = False Then
MessageBox.Show("gotem")
End If
End Sub
Where 'If pbxMyEnemies().visible = false then
Messagebox.Show("gottem")
end if
is where I want it to check if all of the picture boxes in the array are visible false. Can I do that?
Change your code as follows
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FireTimer.Tick
Dim Test As Boolean = True
Fire.Top = Fire.Top - 7
For index = 0 To 26
If Me.Fire.Bounds.IntersectsWith(pbxMyEnemies(index).Bounds) Then
pbxMyEnemies(index).Visible = False
pbxMyEnemies(index).Enabled = False
pbxMyEnemies(index).Left = 732
pbxMyEnemies(index).Top = 55
FireTimer.Enabled = False
Fire.Visible = False
z = 0
ElseIf Me.Fire.Bounds.IntersectsWith(stopper.Bounds) Then
z = 0
Test = False
End If
Next
If Test Then
MessageBox.Show("gotem")
End If
End Sub

Resources