Disabling comboboxes after a certain limit has been met - vba

I have 4 comboboxes called:
cboOption1
cboOption2
cboOption3
cboOption4
Each of them can have one of 2 values, either 10 or 20 points, which the user selects from a drop down. However, the user can only select a maximum of 40 points across all drop downs, after which the remaining dropdowns that follow will be disabled.
E.g.1
cboOption1 = 20
cboOption2 = 20
Then
cboOption3.Enabled = False
cboOption3.Enabled = False
E.g.2
cboOption1 = 10
cboOption2 = 20
cboOption3 = 10
Then
cboOption4.Enabled = False
E.g.3
cboOption1 = 10
cboOption2 = 10
cboOption3 = 10
cboOption3 = 40
Then
None disabled
My problem
The difficulty I'm experiencing at the moment is figuring out how to flick the comboboxes on/off in response to user input. This is my code so far, it doesn't seem to be working too well, any idea how I can improve it.
Code so far
Sub checkTotal(var1, var2, var3, var4, total)
so1 = Int(var1)
so2 = Int(var2)
so3 = Int(var3)
so4 = Int(var4)
total = Nz(so1, 0) + Nz(so2, 0) + Nz(so3, 0) + Nz(so4, 0)
If total > 40 And (so1 = "20" Or so2 = "20" Or so3 = "20" Or so4 = "20") Then
cboOption3.Value = ""
cboOption3.Enabled = False
cboOption4.Value = ""
cboOption4.Enabled = False
End If
MsgBox total
End Sub
Private Sub cboOption1_Change()
Call checkTotal(cboOption1.Column(1), cboOption2.Column(1), cboOption3.Column(1), cboOption4.Column(1), so1RunningTotal)
End Sub
Private Sub cboOption2_Change()
Call checkTotal(cboOption1.Column(1), cboOption2.Column(1), cboOption3.Column(1), cboOption4.Column(1), so1RunningTotal)
End Sub
Private Sub cboOption3_Change()
Call checkTotal(cboOption1.Column(1), cboOption2.Column(1), cboOption3.Column(1), cboOption4.Column(1), so1RunningTotal)
End Sub
Private Sub cboOption4_Change()
Call checkTotal(cboOption1.Column(1), cboOption2.Column(1), cboOption3.Column(1), cboOption4.Column(1), so1RunningTotal)
End Sub

Please, read my comments to the question. I'd suggest to do that this way:
cboOption3.Enabled = CBool((cbo1Value + cbo2Value)<40)
cboOption4.Enabled = CBool((cbo1Value + cbo2Value + cbo3Value)<40)
Tip: use proper input parameters data type and remove total from input parameters.
Sub checkTotal(ByVal var1 As Integer, ByVal var2 As Integer, ByVal var3 As Integer, ByVal var4 As Integer)
See: Data Type Summary (Visual Basic)

Related

How can you make random movement?

I'm doing a simple pacman project on vb.net, and I've come across a great difficulty: how can I make a ghost move randomly, without seeming it is trying to move everywhere at once, which looks like it's spasming?
What I wanted was:
To move the ghost in a random direction (up, left, right or down) and keep that direction until it hits a wall;
When it did hit a wall, determin where it could move, and from the possibilities, choose one and keep that movement until it would hit another wall;
So basically, a loop of that. I'm guessing I definitely need a timer and a loop structure.
This is a picture of the "map":
For example, I've tried this and it doesn't work:
Dim direction As movementdirection
Dim ghostlocation As Point
Dim currentLocation As Point
Dim random As New Random
Public Enum Movementdirection
Up = 1
Down = 2
Left = 3
Right = 4
End Enum
Private Sub redtimer_Tick(sender As Object, e As EventArgs) Handles redtimer.Tick
direction = DirectCast(random.Next(1, 5), Movementdirection)
Select Case direction
Case Movementdirection.Down
red.Top += 2
Case Movementdirection.Up
red.Top -= 2
Case Movementdirection.Left
red.Left -= 2
Case Movementdirection.Right
red.Left += 2
End Select
direction = DirectCast(random.Next(1, 5), Movementdirection
End Sub
Public Function DetectCollection(ByVal red As PictureBox) As Boolean
For Each wall As PictureBox In WallList
If red.Bounds.IntersectsWith(wall.Bounds) Then
direction = DirectCast(random.Next(1, 5), Movementdirection)
End If
Next
ghostlocation = red.Location
Return False
End Function
I've also tried this and didn't work that well, he also spasms.
Private Sub redtimer_Tick(sender As Object, e As EventArgs) Handles redtimer.Tick
Select Case direction
Case Movementdirection.Down
red.Top += 2
Case Movementdirection.Up
red.Top -= 2
Case Movementdirection.Left
red.Left -= 2
Case Movementdirection.Right
red.Left += 2
End Select
num = Int((4 * Rnd()) + 1)
If num = 1 Then
direction = Movementdirection.Down
End If
If num = 2 Then
direction = Movementdirection.Left
End If
If num = 3 Then
direction = Movementdirection.Right
End If
If num = 4 Then
direction = Movementdirection.Up
End If
If Not WallList.Any(Function(wall) wall.Bounds.IntersectsWith(New Rectangle(location:=New Point(red.Location.X, (red.Location.Y + 2)), size:=red.Size))) Then
red.Location = New Point(red.Location.X, (red.Location.Y + 2))
Else
End If
If Not WallList.Any(Function(wall) wall.Bounds.IntersectsWith(New Rectangle(location:=New Point(red.Location.X, (red.Location.Y - 2)), size:=red.Size))) Then
red.Location = New Point(red.Location.X, (red.Location.Y - 2))
End If
If Not WallList.Any(Function(wall) wall.Bounds.IntersectsWith(New Rectangle(location:=New Point((red.Location.X + 2), red.Location.Y), size:=red.Size))) Then
red.Location = New Point(red.Location.X + 2, red.Location.Y)
End If
If Not WallList.Any(Function(wall) wall.Bounds.IntersectsWith(New Rectangle(location:=New Point(red.Location.X - 2, red.Location.Y), size:=red.Size))) Then
red.Location = New Point((red.Location.X - 2), red.Location.Y)
End If
End Sub

VB.Net War Game

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?

getting a return value from a function into another sub routine

I have the below code which returns the premium amount but i am not sure how to get this to display in another function. The sub routine i want to get the value into just displays text about the options selected then i need to display the value calculated based on those results.
Function ProcessClaims(ClaimsList As claimsList, PremiumIn As Decimal) As Decimal
Dim adjustedPremium, originalPremium As Decimal
Dim declined As Decimal
originalPremium = ClaimsList.claimValue * 100 \ 5
If ClaimsList.claimValue <= 5000 And ClaimsList.isPersonalInjury = False Then
adjustedPremium = originalPremium
ElseIf ClaimsList.claimValue > 5000 And ClaimsList.claimValue <= 10000 And ClaimsList.isPersonalInjury = False Then
adjustedPremium = originalPremium * 100 / 10
ElseIf ClaimsList.claimValue > 10000 Or ClaimsList.isPersonalInjury = False Then
adjustedPremium = -1.0
declined = -1.0
End If
If adjustedPremium = -1.0 Then
PremiumIn = declined
Else
PremiumIn = adjustedPremium
End If
Return PremiumIn
End Function
Any help would be appreciated, thank you
It's pretty straightforward ..
Your sub/function that displays the result should be defined as something like
Private Sub DisplayStuff(premiumInResult as decimal)
'display the value premiumInResult in here
End Sub
You can then either do this which is clearer
Dim result As Decimal = ProcessClaims(yourClaimsList , yourPremiumIn)
DisplayStuff(result)
or
Displaystuff(ProcessClaims(yourClaimsList , yourPremiumIn))
which is shorter but less clear, and makes debugging more difficult

Upper Case in VB 6 text box

How to make first letter in upper case while pressing tab or space in vb 6.0 ?
My code is as follows
txtFirstName.Text = UCase$(txtFirstName.Text)
but it doesn't change after tab or space
It's just simple just do this in the text box keypress events...
Private sub textbox_keypress(KeyAscii As Integer)
KeyAscii = Asc(UCase(Chr(KeyAscii)))
End Sub
Use the LostFocus event
Private Sub yourTextBox_LostFocus()
With yourTextBox
'first letter in upper case, the rest, untouched.
.Text = UCase(Mid(.Text, 1, 1)) & Mid(.Text, 2, Len(.Text))
End With
End Sub
Apply the same logic to the KeyDown event and check if the pressed key is the space key.
Private Sub yourTextBox_KeyDown(KeyCode As Integer, Shift As Integer)
If KeyCode = 32 Then
With yourTextBox
'first letter in upper case, the rest, untouched.
.Text = UCase(Mid(.Text, 1, 1)) & Mid(.Text, 2, Len(.Text))
.SelStart = Len(.Text) 'put the cursor at the end of the textbox...
End With
End If
End Sub
StrConv Function
Returns a Variant (String) converted as specified.
Syntax
StrConv(string, conversion, LCID)
The StrConv function syntax has these named arguments:
Part Description
string Required. String expression to be converted.
conversion Required. Integer. The sum of values specifying the type of conversion to perform.
LCID Optional. The LocaleID, if different than the system LocaleID. (The system LocaleID is the default.)
Settings
The conversion argument settings are:
Constant Value Description
vbUpperCase 1 Converts the string to uppercase characters.
vbLowerCase 2 Converts the string to lowercase characters.
vbProperCase 3 Converts the first letter of every word in string to uppercase.
AND THERE IS MORE ...
TO GSERGE
$ means nothing when applied to a function name as opposed to a variable name. VBA uses $ AND B as a suffix to denote similar functionality.
VB6 IS VBA the person who said maybe in VB6 but not in VBA. VB6 program host VBA as their programming language. VB6 on it's own are some app objects and the forms package only - no programming language. It's best to think of VB6 as a VBA host like Office.
If you want to proper case see this WORDBASIC Ver 6 code, (which word 2003 helpfully converted to vba).
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
Public Sub MAIN()
Select Case WordBasic.Int(GetModifer)
Case 0
WordBasic.ChangeCase
Case 1
WordBasic.ChangeCase 4
Case 2
WordBasic.ChangeCase 2
Case 3
ProperCase
Case Else
WordBasic.ChangeCase
End Select
End Sub
Private Sub ProperCase()
Dim F
Dim z
Dim a$
Dim P
F = 1
WordBasic.ChangeCase 2
WordBasic.EditBookmark Name:="SerenityChangeCase", SortBy:=0, Add:=1
z = WordBasic.GetSelEndPos()
WordBasic.CharLeft 1
While WordBasic.GetSelEndPos() < z And Not WordBasic.AtEndOfDocument()
WordBasic.SelectCurWord
a$ = WordBasic.[Selection$]()
P = 0
If LCase(a$) = "a" Then
P = 1
ElseIf LCase(a$) = "an" Then
P = 1
ElseIf LCase(a$) = "as" Then
P = 1
ElseIf LCase(a$) = "at" Then
P = 1
ElseIf LCase(a$) = "be" Then
P = 1
ElseIf LCase(a$) = "by" Then
P = 1
ElseIf LCase(a$) = "in" Then
P = 1
ElseIf LCase(a$) = "is" Then
P = 1
ElseIf LCase(a$) = "of" Then
P = 1
ElseIf LCase(a$) = "on" Then
P = 1
ElseIf LCase(a$) = "or" Then
P = 1
ElseIf LCase(a$) = "to" Then
P = 1
ElseIf LCase(a$) = "and" Then
P = 1
ElseIf LCase(a$) = "are" Then
P = 1
ElseIf LCase(a$) = "for" Then
P = 1
ElseIf LCase(a$) = "the" Then
P = 1
ElseIf LCase(a$) = "from" Then
P = 1
ElseIf LCase(a$) = "what" Then
P = 1
ElseIf LCase(a$) = "with" Then
P = 1
End If
If P = 1 And F = 0 Then WordBasic.Insert LCase(a$)
WordBasic.WordRight 1
F = 0
Wend
WordBasic.WW7_EditGoTo Destination:="SerenityChangeCase"
WordBasic.EditBookmark Name:="SerenityChangeCase", SortBy:=0, Delete:=1
End Sub
Private Function GetModifer()
Dim a
Dim B
Dim c
Dim X
a = GetAsyncKeyState(16)
B = GetAsyncKeyState(17)
c = GetAsyncKeyState(18)
X = 0
If a < 0 Then X = X + 1
If B < 0 Then X = X + 2
If c < 0 Then X = X + 4
GetModifer = X
End Function
OK. Yeah txtFirstName is a good indicator of usage here.. So I'd use (sort of) Title Caps And I'd do it on the Validate event.. So
Private Sub txtFirstName_Validate(Cancel As Boolean)
Dim p As Integer ' i doubt we'll use more than 32K for a name....
Dim mName As String
p = 1
' first off lets trim any leading blanks.. assume NOTHING and make sure its all lower case..
mName = LCase(LTrim(txtFirstName))
Do While p > 0 And p <= Len(txtFirstName) ' start with the first non-blank
Mid(mName, p, 1) = UCase(Mid(mName, p, 1))
p = InStr(p, mName, " ")
If p > 0 And p < Len(mName) Then p = p + 1
Loop
Cancel = False
txtFirstName = mName
End Sub
Works every time, and capitalizes each word.. Didn't add any code to to do TRUE title caps but this is close, and short & easy...

Why is my Select Case not working

Okay my question goes as follows; I think i coded everything right execpt for the part where i do my select case, I want the first 3 Flavours to only cost 55 cents but when I do my code it always makes the scoops 65 cents no matter what icecream type i select and i dont know how to make it change, i thought i had it right but it isnt working
Public Class frmJoeyIceCreamParlour
Const MIN_SCOOPS = 1
Const MAX_SCOOPS = 9
Const BASIC_FLAVOUR = 0.55
Const PREMIUM_FLAVOUR = 0.65
Const TOPPING = 0.6
Const DEEZ_NUTS = 0.5
Const WHIPPED_CREAM = 0.65
Public scoopEntry As Single
Public scoopType As Double
Public runningTotal As Double
Private Sub frmJoeyIceCreamParlour_Load(sender As Object, e As EventArgs) Handles MyBase.Load
lstFlavours.Items.Add("Vanilla")
lstFlavours.Items.Add("Chocolate")
lstFlavours.Items.Add("Strawberry")
lstFlavours.Items.Add("Mango")
lstFlavours.Items.Add("Bananna")
lstFlavours.Items.Add("Grape")
lstFlavours.Items.Add("Mint Chocolate Chip")
End Sub
Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
If txtScoops.Text = Nothing Then
MessageBox.Show("Please enter a value in the scoops category.")
txtScoops.Focus()
ElseIf Not IsNumeric(txtScoops.Text) Then
MessageBox.Show("Entry must be numeric! Please try again.")
txtScoops.Focus()
ElseIf txtScoops.Text < MIN_SCOOPS Or txtScoops.Text > MAX_SCOOPS Then
MessageBox.Show("Please enter a number between 1 and 9 scoops.")
txtScoops.Focus()
ElseIf lstFlavours.SelectedItem = Nothing Then
MessageBox.Show("Please select a flavour.")
ElseIf rdoNoTopping.Checked = False And rdoOneTopping.Checked = False And rdoTwoTopping.Checked = False And rdoThreeTopping.Checked = False Then
MessageBox.Show("Please select the amount of toppings you would like.")
Else
Dim number As Integer = 7
Select Case number
Case 1 To 3
scoopType = BASIC_FLAVOUR
Case 4 To 7
scoopType = PREMIUM_FLAVOUR
runningTotal = scoopType * Double.Parse(txtScoops.Text)
End Select
If rdoOneTopping.Checked = True Then
runningTotal = runningTotal + TOPPING
ElseIf rdoTwoTopping.Checked = True Then
runningTotal = runningTotal + (TOPPING * 2)
ElseIf rdoThreeTopping.Checked = True Then
runningTotal = runningTotal + (TOPPING * 3)
End If
If chkWhippedCream.Checked = True Then
runningTotal = runningTotal + WHIPPED_CREAM
End If
If chkNuts.Checked = True Then
runningTotal = runningTotal + DEEZ_NUTS
End If
lblOutputTotal.Text = (FormatCurrency(runningTotal))
End If
End Sub
End Class
You have it hard coded to use 7 via the line just above your Select case number statement: Dim number As Integer = 7. You should instead be looking up the selected index by doing something like Dim number As Integer = lstFlavours.SelectedIndex
Dim number As Integer = lstFlavours.SelectedIndex
Select Case number
Case 1 To 3
scoopType = BASIC_FLAVOUR
Case 4 To 7
scoopType = PREMIUM_FLAVOUR
End Select
runningTotal = scoopType * Double.Parse(txtScoops.Text)