Random number guessing game VB - vb.net

OBJECTIVE:
This is a guessing game. The program is to generate a random number between 1 and 500. The user is to guess the number.
The form should include a START button, a listbox to hold all valid guesses, and a label displaying the answer.
Upon clicking the START button, the user will enter a number in response to an InputBox().
If the user’s guess is invalid (not numeric, not a whole number, out of range), display an appropriate message.
If the guess is valid but is not the correct number (high or low), display an appropriate message.
image high quess dialog boximage low quess dialog box
Every time the user guesses a valid numeric guess within range, add the guess to the listbox on the form. Allow the guesses to be shown in multiple columns in the listbox.
If the user successfully guesses the number, display an appropriate message. Include how many guesses they took. Count only valid (in range, integral) numeric guesses as a guess.
Allow the user to quit the game by entering Quit in response to the input box. If the user gives up, tell them the correct number
Important: Display the random number in a label immediately after generating it so that I (and you) know what the number is while I am (and you are) testing it. You can obviously take it out if you really want to play the game.
Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click
'Declare Variables
Dim strGuess As String
Dim random As New Random
Dim answer As Integer
'Start with empty Boxes
lstGuesses.Items.Clear()
answer = random.Next(1, 500)
lblAnswer.Text = CStr(answer)
Do
Try
strGuess = InputBox("Enter a numeric integer between 1 and 500. , Enter 'quit' to Quit.", "Guessing Game")
lstGuesses.Items.Add(strGuess)
If strGuess = CStr("quit") Then
MessageBox.Show("The number was " & answer & ". Click Start Game to play again.")
Exit Do
End If
If CInt(strGuess) < CInt(1) Then
MessageBox.Show("Invalid Guess. Enter an Integer Number between 1 and 500!")
End If
If CInt(strGuess) > CInt(500) Then
MessageBox.Show("Invalid Guess. Enter an Integer Number between 1 and 500!")
End If
If CInt(strGuess) = CInt(answer) Then
MessageBox.Show("Got it! You guessed " & lstGuesses.Items.Add(strGuess) & " times!")
End If
If CInt(strGuess) > CInt(answer) And CInt(strGuess) <= CInt(500) Then
MessageBox.Show("Guess is High")
End If
If CInt(strGuess) < CInt(answer) And CInt(strGuess) >= CInt(1) Then
MessageBox.Show("Guess is Low")
End If
If lstGuesses.Items.Contains("quit") = True Then
MessageBox.Show("The number was " & answer & ". Click Start Game to play again.")
End If
Catch ex As InvalidCastException
'Make user guess
MessageBox.Show("Invlid Guess. Enter a numeric integer between 1 and 500!")
End Try
Loop While CInt(strGuess) <> answer
End Sub
MY PROBLEM:
I have been trying everything and this is the best i have made yet. This homework is due in 4 hours so any help will be appreciated.
I am suppose to type the word "quit" to end the game. But also give an error message when something other than letters are typed. Every time I type a letter and press enter, it gives the warning that i set but then it crashes. It is not supposed to crash. It says the crash is from:
Loop While CInt(strGuess) <> answer
and the problem is because of an InvalidCastException and says convertion from string to type integer is not valid. I tried doing TRYPARSE but still the same problem. Can anyone tell me how to let me type the word "quit" into the box so that it quits the game, but doesn't make it crash.

Maybe this is not the best way but i think it will help.
What you need to do is Make a new if statement at the top just after the user entered something in the inputbox.
If IsNumeric(strGuess) Or strGuess = CStr("quit") Then
Else
MessageBox.Show("Only Numbers")
GoTo Line1
End If
And here you check "If IsNumeric(strGuess) Or strGuess = CStr("quit") Then"
if yes do nothing
If No show a msgbox and use a goto "GoTo Line1" "so above your do you add Line1:"
If somebody types something like "a" he will go to line1 "so start the do" and the user needs to enter something new in the inputbox.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Declare Variables
Dim strGuess As String
Dim random As New Random
Dim answer As Integer
'Start with empty Boxes
lstGuesses.Items.Clear()
answer = random.Next(1, 500)
lblAnswer.Text = CStr(answer)
Line1:
Do
Try
strGuess = InputBox("Enter a numeric integer between 1 and 500. , Enter 'quit' to Quit.", "Guessing Game")
lstGuesses.Items.Add(strGuess)
If IsNumeric(strGuess) Or strGuess = CStr("quit") Then
Else
MessageBox.Show("Only Numbers")
GoTo Line1
End If
If strGuess = CStr("quit") Then
MessageBox.Show("The number was " & answer & ". Click Start Game to play again.")
Exit Do
End If
If CInt(strGuess) < CInt(1) Then
MessageBox.Show("Invalid Guess. Enter an Integer Number between 1 and 500!")
End If
If CInt(strGuess) > CInt(500) Then
MessageBox.Show("Invalid Guess. Enter an Integer Number between 1 and 500!")
End If
If CInt(strGuess) = CInt(answer) Then
MessageBox.Show("Got it! You guessed " & lstGuesses.Items.Add(strGuess) & " times!")
End If
If CInt(strGuess) > CInt(answer) And CInt(strGuess) <= CInt(500) Then
MessageBox.Show("Guess is High")
End If
If CInt(strGuess) < CInt(answer) And CInt(strGuess) >= CInt(1) Then
MessageBox.Show("Guess is Low")
End If
If lstGuesses.Items.Contains("quit") = True Then
MessageBox.Show("The number was " & answer & ". Click Start Game to play again.")
End If
Catch ex As InvalidCastException
'Make user guess
MessageBox.Show("Invlid Guess. Enter a numeric integer between 1 and 500!")
End Try
Loop While CInt(strGuess) <> answer
End Sub

Related

MS Access VBA Code on Form Field with Multiple If's to Prevent / Allow Entry Depending on Value Entered

Hello, please assist with the following:
I am trying to prevent end users from being able to enter a value in the txtPlantUsedGrams (PlantAmountUsed) field that is greater than the amount in the txtExtractionAmountAvailable (ExtractionAvailable) field, but allow entry when the txtPlantUsedGrams value is less than the amount in the txtExtractionAmountAvailable field.
The code is working in the case where PlantAmountUsed is greater than ExtractionAvailable as it triggers the msgbox and then sets the txtPlantAmountUsed field to zero. In the case where PlantAmountUsed is less than ExtractionAvailable it allows the value entered to stick (does not change it to 0), but only after the msgbox is triggered and I click ok. The ‘exit sub’ code I inserted after the first If is not working. Please help me so that the following code does not trigger the msgbox and instead exits the sub in the case where the PlantAmountUsed is less than the ExtractionAvailable. I am open to any / all ways to accomplish this. Thank you for any help:)
Location of VBA Code:
Event is being run in form (frmMedMaking) as an AfterUpdate event in the txtPlantUsedGrams field.
**VBA Code:**
Private Sub txtPlantUsedGrams_AfterUpdate()
Dim PlantAmountUsed As Integer
Dim ExtractionAvailable As Integer
Dim LResponse As Integer
PlantAmountUsed = Me.txtPlantUsedGrams
ExtractionAvailable = Me.txtExtractAmountAvailable.Value
LResponse = MsgBox("Plant Amount Used must be less than Extraction
Available", vbOKOnly + vbCritical, "Available Extraction Amount Exceeded")
If PlantAmountUsed < ExtractionAvailable Then Exit Sub
If PlantAmountUsed > ExtractionAvailable Then
If LResponse = vbOK Then Me.PlantAmountUsed.Value = 0
End If
End Sub
It seems that your problem comes from the fact, that you call the MsgBox before the condition If PlantAmountUsed < ExtractionAvailable Then is checked.
So the code must be restructured a bit.
Resulting Code
That would be the resulting code, based on your given informations:
Private Sub txtPlantUsedGrams_AfterUpdate()
Dim plantAmountUsed As Integer
plantAmountUsed = Me.txtPlantUsedGrams.Value
Dim extractionAvailable As Integer
extractionAvailable = Me.txtExtractAmountAvailable.Value
If plantAmountUsed < extractionAvailable Then Exit Sub
'What if plantAmountUsed = extractionAvailable (see below)?
If plantAmountUsed > extractionAvailable Then
' Why checking the result of the MsgBox when only one button (Ok) can be pressed (see below)?
If MsgBox("Plant Amount Used must be less than Extraction Available", vbOKOnly + vbCritical, "Available Extraction Amount Exceeded") = vbOK Then
Me.txtPlantUsedGrams.Value = 0
End IF
End If
End Sub
Remarks
I changed Me.PlantAmountUsed.Value = 0 to Me.txtPlantUsedGrams.Value = 0. I expect thats what was your intention, right?
Questions / suggestions
What if plantAmountUsed equals extractionAvailable? This is not explicitely handled yet.
You could use If plantAmountUsed <= extractionAvailable Then Exit Sub for example.
In your MsgBox you use vbOKOnly, so the result is always vbOK, what would mean, that you wouldn't really have to check the result of the MsgBox.
So this could be enough:
If plantAmountUsed > extractionAvailable Then
MsgBox "Plant Amount Used must be less than Extraction Available", vbOKOnly + vbCritical, "Available Extraction Amount Exceeded"
Me.txtPlantUsedGrams.Value = 0
End If

VBA in Access. How to require a field if another field has been answered

I am working on an Access DB and need to require that ScrapAmount1 has an answer if they have put data into ScrapCodes1. I want to have an error message pop up that reminds them to make the amount of scrap higher than 0. I'm using VBA and here is what I have that is not working. PS. ScrapCodes1 is a drop down list that they choose from and the ScrapAmount is 0 by default.
Private Sub Form_BeforeUpdate(Cancel As Integer)
If Me.ScrapCodes1 Then
If Nz(Me.ScrapAmount1, "") = "" Then
Cancel = True
MsgBox "If Scrap Code is selected, then Scrap Amount must have a value.", vbExclamation, "Data Required"
End If
End If
End Sub
Thank you for your answers in advance. :)
I don't think you need anything more than:
Private Sub Form_BeforeUpdate(Cancel As Integer)
If Me.ScrapAmount1= 0 Then
Cancel = True
MsgBox "If Scrap Code is selected, then Scrap Amount must have a value.", vbExclamation, "Data Required"
End If
End Sub
Your if is using the Nz to check if ScrapAmount1 is null. ScrapAmount1 defaults to 0, so it's not null.
I'd have a second If condition myself:
'check for null
If Nz(Me.ScrapAmount1, "") = "" Then
Cancel = True
MsgBox "If Scrap Code is selected, then Scrap Amount must have a value.", vbExclamation, "Data Required"
'checks for 0 and negative numbers
ElseIf Me.ScrapAmount1 <= 0 then
Cancel = True
MsgBox "Scrap Amount must be higher than 0"
End If
If Cancel then
'do cancel stuff, I have no idea what you use this var for
end if

How to clear userform textbox without calling the _Change function?

I have a userform in Excel with textboxes meant for numeric data only. I want to clear the textbox when it detects bad entry and gives an error message, but I don't want to have the textbox's _Change function called again or else the message pops up twice because I change the text to "". I didn't see a built in clear function.. is there a better way to do this?
Private Sub txtbox1_Change()
txt = userform.txtbox1.Value
If Not IsNumeric(txt) Then
disp = MsgBox("Please only enter numeric values.", vbOKCancel, "Entry Error")
txtbox1.Text = ""
End If
End Sub
A simple way to achieve this is to use the _Exit() Function:
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
If Not IsNumeric(TextBox1.Value) Then
MsgBox "Please only enter numeric values.", vbCritical, "Error"
End If
End Sub
This triggers as soon as the text box looses Focus.
prevent user from typing Alpha chars:
Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
Select Case KeyAscii
Case Asc("0") To Asc("9")
Case Asc("-")
If Instr(1,Me.TextBox1.Text,"-") > 0 Or Me.TextBox1.SelStart > 0 Then
KeyAscii = 0
End If
Case Asc(".")
If InStr(1, Me.TextBox1.Text, ".") > 0 Then
KeyAscii = 0
End If
Case Else
KeyAscii = 0
End Select
End Sub
Hope this helps!
-Hugues
You can do this way, as shown here
Private Sub TextBox1_Change()
OnlyNumbers
End Sub
Private Sub OnlyNumbers()
If TypeName(Me.ActiveControl) = "TextBox" Then
With Me.ActiveControl
If Not IsNumeric(.Value) And .Value <> vbNullString Then
MsgBox "Sorry, only numbers allowed"
.Value = vbNullString
End If
End With
End If
End Sub
You can add this line at the very beginning
sub txtbox1_Change()
If txtbox1.Text = "" Or txtbox1.Text = "-" Then Exit Sub '<~~~
Alternatively, I found this even shorter and interesting:
Private Sub txtbox1_Change()
If Not IsNumeric(txtbox1.Text & "0") Then
disp = MsgBox("Please only enter numeric values.", vbOKCancel, "Entry Error")
txtbox1.Text = ""
End If
End Sub
The interesting part is that it accepts to enter things like ".2", "-3.2", and also "5e3", the last case being not allowed by the other methods!
Turning it into a while loop can remove only the last bad typed character(s):
Private Sub txtbox1_Change()
t = txtbox1.Text
Do While t <> "" And Not IsNumeric(t) And Not IsNumeric(t & "0")
t = Mid(t, 1, Len(t) - 1)
Loop
txtbox1.Text = t
End Sub
Seems since there is nothing built in that can do what I want, this would be the simplest way to handle the problem:
Private Sub txtbox1_Change()
txt = userform.txtbox1.Value
If (Not IsNumeric(txt)) And (txt <> "") Then
disp = MsgBox("Please only enter numeric values.", vbOKCancel, "Entry Error")
txtbox1.Text = ""
End If
End Sub
Declare a global boolean and at the beginning of each sub, add an if statement which exits the sub if the boolean is true. When you get an error message, set the value to true, and nothing will happen. Then set it to false again.
Dim ufEventsDisabled As Boolean
Private Sub txtbox1_Change()
'repeat the following line everywhere that you don't want to update
if ufeventsdisabled then exit sub
txt = userform.txtbox1.Value
If Not IsNumeric(txt) Then
disp = MsgBox("Please only enter numeric values.", vbOKCancel, "Entry Error")
ufeventsdisabled = true
txtbox1.Text = ""
ufeventsdisabled = false
End If
End Sub
*Credit goes to mikerickson from mrexcel.com
You can't stop the _Changed event from firing. I would advise you to back up a couple of steps in your design and ask if you can get the job done without having to clear it in the first place. In FoxPro we would set the 'format' to 9999.99 and it would automatically prevent users from typing alpha characters, but I think that particular field was unique to FP. You can hook the _Changed event and perform your own validation there. I would suggest not filtering individual key strokes, but validating the whole value each time it's changed.
If Text1.Value <> str(val(Text1.Value)) Then
Text1.Value = previousValue
EndIf
... which will require keeping a backup variable for the previous value, but I'm sure you can figure that out. There may be certain edge cases where VB's string-number conversion functions don't exactly match, like exponential notation as you mentioned, so you may need a more sophisticated check than that. Anyway, this will make it impossible to even enter a bad value. It also provides a better user experience because the feedback is more immediate and intuitive. You may notice that the value is being changed inside the _Changed event, which should raise a knee jerk red flag in your mind about infinite loops. If you do this, make sure that your previous value has already been validated, keeping in mind that the initial value will be an empty string. As such, the recursive call will skip over the If block thus terminating the loop. In any case, what you would consider "better" may differ depending on who you ask, but hopefully I've given you some food for thought.

Why wont my code go back to the main menu?

I'm creating a guess the number game in VB.Net. I've got to the point where I'm asking the player if they would like to play again after they have won. When I try and send them back to the main menu if they select that they would like to play again it just exits out of the program.
Sub MainMenu()
Console.WriteLine("Main Menu")
Console.WriteLine("1) Play Game")
Console.WriteLine("2) Instructions")
Console.WriteLine("3) View Score")
Console.WriteLine("4) Exit")
Console.WriteLine()
End Sub
If UserGuess = CorrectNumber Then
PlayerScore = PlayerScore + 1
Console.WriteLine("...CORRECT!!! You win!")
Console.WriteLine("You took " & NOfGuesses & " guesses!")
Console.WriteLine("Press Enter to Continue")
Console.ReadLine()
Console.Clear()
PlayAgainSub()
End If
Sub PlayAgainSub()
Dim PlayAgain As Char
Console.Clear()
Console.WriteLine("Would you like to play again? (Y/N)")
PlayAgain = Console.ReadLine.ToUpper
If PlayAgain = "Y" Then
MainMenu()
ElseIf PlayAgain = "N" Then
Quit()
Else
Console.WriteLine("Option not valid!")
REM Next line waits for 0.5 seconds so the user has time to see the error message.
Threading.Thread.Sleep(500)
Console.Clear()
PlayAgainSub()
End If
End Sub
This isn't all of the code, just what I considered relevant, if you need the rest of it I will update the post.
set a variable for recursion example
Dim recur As Char
then use Do .. loop while

VB compile error when trying to use String.Compare

I am trying to check if the password is the same or not (in terms of caps too) using vb.net. But the line
result = String.Compare(actPassword,userPassword)
keep giving error "Compile Error: Expected:("
Private Sub Login_Click()
'Check to see if data is entered into the UserName combo box
If IsNull(Me.cmbLoginID) Or Me.cmbLoginID = "" Then
MsgBox "You must enter a User Name.", vbOKOnly, "Required Data"
Me.cmbLoginID.SetFocus
Exit Sub
End If
'Check to see if data is entered into the password box
If IsNull(Me.txtPW) Or Me.txtPW = "" Then
MsgBox "You must enter a Password.", vbOKOnly, "Required Data"
Me.txtPW.SetFocus
Exit Sub
End If
'Check value of password in tblEmployees to see if this matches value chosen in combo box
Dim userPassword As String
Dim actPassword As String
Dim result As Integer
userPassword = txtPW.Text
actPassword = DLookup("EmpPassword", "Employee", "EmployeeID='" + Me.cmbLoginID.Value + "'")
result = String.Compare(actPassword,userPassword)
If result = -1 Then
'Close logon form and open splash screen
DoCmd.Close acForm, "Login", acSaveNo
DoCmd.OpenForm "HomePage"
Else
MsgBox "Password Invalid. Please Try Again", vbCritical + vbOKOnly, "Invalid Entry!"
Me.txtPW.SetFocus
End If
'If User Enters incorrect password 3 times database will shutdown
intLogonAttempts = intLogonAttempts + 1
If intLogonAttempts > 3 Then
MsgBox "You do not have access to this database. Please contact your system administrator.", vbCritical, "Restricted Access!"
Application.Quit
End If
End Sub
That's because there is no String.Compare() in VBA (There is in VB.NET)
Also, please note VB.NET is not VBA
Use StrComp
Use StrComp
result = StrComp(actPassword, userPassword, vbTextCompare)
While String.Compare() exists in VB.Net, I don't think it does in VBA. In any case, what you're doing is wrong anyway.
String.Compare can return any integer and it will only return zero if they match. Your particular test (comparing against -1) is only checking one possibility, that the actual password is less than the desired one, and it's only checking for one of the possible negative values.
You would be better off in that case with something like:
if result <> 0 Then
However, if you just want to compare two strings for equality in VBA (rather than figure out the relative ordering), you can just use:
if actPassword = userPassword Then