No response on if-elseif function [closed] - vba

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am trying to create a tool using macro so that when few criteria are selected, a certain rating will be shown. There are three criteria that need to be filtered before getting the result.
For example, if the industry (eg. Agriculture) is selected, followed by selection of countries (e.g Indonesia), followed by selection of certain ratio (e.g. 2.5), a rating from 1 to 6 will be given (in this case, 3).
I tried the following code, nothing appears under my rating column but there is no error message. Is there anything missing in my code which causes no result happening?
Private Sub CommandButton1_Click()
If Range("V4").Value = "A.Agriculture,forestry and fishing" Then
If Range("W4").Value = All Or ID Or SG Then
If Range("D4").Value <= 0 Then
Range("X4").Value = 6
ElseIf Range("M4").Value > 4 Then
Range("X4").Value = 5
ElseIf Range("M4").Value <= 4 And Value > 2 Then
Range("X4").Value = 4
ElseIf Range("M4").Value <= 2 And Value > 1 Then
Range("X4").Value = 3
ElseIf Range("M4").Value <= 1 And Value > 0 Then
Range("X4").Value = 2
ElseIf Range("M4").Value <= 0 Then
Range("X4").Value = 1
End If
ElseIf Range("W4").Value = MY Or TH Then
If Range("D4").Value <= 0 Then
Range("X4").Value = 6
ElseIf Range("M4").Value > 4.5 Then
Range("X4").Value = 5
ElseIf Range("M4").Value <= 4.5 And Value > 2 Then
Range("X4").Value = 4
ElseIf Range("M4").Value <= 2 And Value > 1 Then
Range("X4").Value = 3
ElseIf Range("M4").Value <= 1 And Value > 0 Then
Range("X4").Value = 2
ElseIf Range("M4").Value <= 0 Then
Range("X4").Value = 1
End If
End If
End If
End Sub

Your If statements with Or are not properly formed. Additionally, a combination of If and Select Case statements would seem to be best for these multiple, nested conditions. This should also make your code mode readable.
If Range("W4").Value = "All" Or Range("W4").Value = "ID" Or Range("W4").Value = "SG" Then
VBA is case sensitive by default and strings need to be enclosed in quotes; e.g. All <> "All" and "ALL" <> "all". Best to use the LCase and UCase functions to compare "Apples" with "Apples".
Private Sub CommandButton1_Click()
If Range("V4").Value = "A.Agriculture,forestry and fishing" Then
Select Case LCase(Range("W4").Value)
Case "all", "id", "sg"
If Range("D4").Value <= 0 Then
Range("X4").Value = 6
Else
Select Case Range("M4").Value
Case Is > 4
Range("X4").Value = 5
Case 2.01 To 4
Range("X4").Value = 4
Case 1.01 To 2
Range("X4").Value = 3
Case 0.01 To 1
Range("X4").Value = 2
Case Is <= 0
Range("X4").Value = 1
Case Is > 4
Range("X4").Value = 6
End Select
End If
Case "my", "th"
If Range("D4").Value <= 0 Then
Range("X4").Value = 6
Else
Select Case Range("M4").Value
Case Is > 4.5
Range("X4").Value = 5
Case 2.01 To 4.5
Range("X4").Value = 4
Case 1.01 To 2
Range("X4").Value = 3
Case 0.01 To 1
Range("X4").Value = 2
Case Is <= 0
Range("X4").Value = 1
Case Is > 4
Range("X4").Value = 6
End Select
End If
End Select
End If
End Sub
Note that I have added a small decimal value to the between style Case statements in order to achieve the greater than and less than or equal to logic.

Add an Else case at the very end to handle errors. Chances are your If... ElseIf block isn't actually doing anything.
Also, because you are checking so many CASES, this looks like a great opportunity to re-structure your If... Then block to a Select... Case block..
Select [ Case ] testexpression 'stuff here
[ Case expression1 ]
[ statements ] ]
[ Case Else
[ elsestatements ] ]
End Select
more info - https://msdn.microsoft.com/en-us/library/cy37t14y.aspx for info.

Related

Error 16: Expression Too Complex - Nested Select Case

I am getting a "Run-Time Error 16: Expression Too Complex" for the sencond code block. I read online that the maximum allowed number of nested expressions is 8, but if nested statements are defined by every "Select Case," then I haven't yet hit that. Is it possible it's because the Cases are dependent upon a variable? The first code block shows the possible values of egapend, while the second shows the code that is returning the error. Thanks in advance for your help.
First:
Select Case ge1e2
Case Is <= 0
Select Case ge2e3
Case Is <= 0
egap18a = 0
egap18b = 0
Case Is > 0
egap18a = 0
egap18b = ge2e3
egapend = Sheet1.[z1IE]
End Select
Case Is > 0
Select Case ge2e3
Case Is <= 0
egap18a = ge1e2
egap18b = 0
egapend = Sheet1.[z1CZ]
Case Is > 0
Select Case ge1e2
Case Is >= 180
egap18a = ge1e2
egap18b = ge2e3
egapend = Sheet1.[z1CZ]
Case Is < 180
egap18a = ge1e2
egap18b = ge2e3
egapend = Sheet1.[z1IE]
End Select
End Select
End Select
Second:
Dim e1length As Long
Dim e2length As Long
Dim cp121 As Boolean
e1length = DateDiff("d", Sheet1.[z1CZ], Sheet1.[z1DA])
e2length = DateDiff("d", Sheet1.[z1IE], Sheet1.[z1IF])
Select Case extendedgap
Case True
Select Case egapend
Case Sheet1.[z1IE] 'end of egap is start of E2
Select Case e2length 'was borrower employed by E2 for more than 6 months?
Case Is >= 180
cp121 = True
Case Is < 180
Select Case ge1e2 'if not, was there a gap between E1 and E2
Case Is > 1
cp121 = False
Case Else
Select Case DateDiff("d", Sheet1.[z1IE], Sheet1.[z1DA]) 'If not, was employment between E1/E2 6 mos?
Case Is >= 180
cp121 = True
Case Is < 180
cp121 = False
End Select
End Select
End Select
Case Sheet1.[z1CZ] 'end of egap is start of E1
Select Case DateDiff("d", Sheet1.[z1CZ], Sheet1.[z1DA]) 'was borrower employed by E1 for at least 6 mos?
Case Is >= 180
cp121 = True
Case Is < 180
cp121 = False
End Select
End Select
It's really just a big nested conditional structure. Don't use Select...Case for that. Use it e.g. when you're looking at some enum value:
Select Case MsgBox("Yes, no, or cancel?", vbYesNoCancel)
Case vbYes
'stuff
Case vbNo
'stuff
Case vbCancel
'stuff
End Select
Refactoring step 1: Turn all these 2-branch Select...Case blocks into If...Else...End If blocks. That should already take care of the "expression too complex" compile error.
Refactoring step 2: Implement Boolean assignments as such:
For example in one place two places you have:
Select Case DateDiff("d", Sheet1.[z1IE], Sheet1.[z1DA]) 'If not, was employment between E1/E2 6 mos?
Case Is >= 180
cp121 = True
Case Is < 180
cp121 = False
End Select
Replace that with:
cp121 = (DateDiff("d", Sheet1.[z1IE], Sheet1.[z1DA]) >= 180)
Refactoring step 3: Extract functions and procedures out of the If and Else branches where applicable; eliminate the duplicated branches, Don't Repeat Yourself.
Once you have something that works, take it to Code Review for further refactoring and simplification ideas.

how to create an experience / level up system?

I'm creating a DnD Character Creation program, and I've gotten myself stuck at the "Experience / Level" area. What I want is for every 1000 experience, the level to go up (so 0 to 999 is level 0,
So, I've used the following code to get where I am, but it doesn't change the label (lblLevel) to 1 when experience (txtExperience) is changed to 1000 (or 2 when experience is changed to 2000).
Private Sub txtExperience_textChanged(sender As Object, e As EventArgs) Handles txtExperience.TextChanged
If txtExperience.Text = letters Then
lblLevel.Text = "0"
ElseIf txtExperience.Text >= 10000 Then
lblLevel.Text = "Maxed"
End If
Select Case txtExperience.Text
Case Is <= "999"
lblLevel.Text = "0"
Case "1000" To "1999"
lblLevel.Text = "1"
Case "2000" To "2999"
lblLevel.Text = "2"
Case "3000" To "3999"
lblLevel.Text = "3"
Case "4000" To "4999"
lblLevel.Text = "4"
Case "5000" To "5999"
lblLevel.Text = "5"
Case "6000" To "6999"
lblLevel.Text = "6"
Case "7000" To "7999"
lblLevel.Text = "7"
Case "8000" To "8999"
lblLevel.Text = "8"
Case "9000" To "9999"
lblLevel.Text = "9"
End Select
End Sub
I'll be honest, I'm not sure if I'm using Select Case ... correctly, and when I tried using an If Statement (and Else If in place each of the Case ... to ...) it wouldn't work either. Any help would be greatly appreciated.
You could simplify that even further. Using basic math you can get rid of the long Select Case statement:
Dim Experience As Integer = 0
If Integer.TryParse(txtExperience.Text, Experience) = True Then
If Experience >= 10000 Then
lblLevel.Text = "Maxed"
Return
End If
lblLevel.Text = Math.Floor(Experience / 1000).ToString()
Else
MessageBox.Show("Input must be a whole number between 0 and 10000", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
Here's an online test of my code: https://dotnetfiddle.net/VtGFLx
There is a difference between integer and string
Select Case Integer.Parse(txtExperience.Text)
Case Is <= 999
lblLevel.Text = 0
Case 1000 To 1999
lblLevel.Text = 1
Case 2000 To 2999
lblLevel.Text = 2
Case 3000 To 3999
lblLevel.Text = 3
Case 4000 To 4999
lblLevel.Text = 4
Case 5000 To 5999
lblLevel.Text = 5
Case 6000 To 6999
lblLevel.Text = 6
Case 7000 To 7999
lblLevel.Text = 7
Case 8000 To 8999
lblLevel.Text = 8
Case 9000 To 9999
lblLevel.Text = 9
End Select

Is there an alternative method to using 15 If statements?

I have 15 items in my ComboBox and when the user selects an item I want to present something different in my TextBox.
At the moment I have:
If cb_dropdown.SelectedIndex = 0 Then
RTB_Sql.Text = "update access
set accessdesc = 'Less than 5' where accessID < '5'"
Else
If cb_dropdown.SelectedIndex = 1 Then
RTB_Sql.Text = "update access
set accessdesc = 'More than 5' where accessID > '5' and < '10' "
Else
If cb_dropdown.SelectedIndex = 2 Then
RTB_Sql.Text = ""
etc....
Is there a nicer and more methodical way to approach this as it looks quite scruffy?
Yes, it is called select.
Select Case cb_dropdown.SelectedIndex
Case 0 To 4
RTB_Sql.Text = "update access
set accessdesc = 'Less than 5' where accessID < '5'"
Case 5
RTB_Sql.Text = [...]
Case Else
RTB_Sql.Text = [...]
End Case
Although in your case I think what you are looking for is < (less than) and > (greater than).
If cb_dropdown.SelectedIndex < 5 Then
RTB_Sql.Text = "update access set accessdesc = 'Less than 5' where accessID < '5'"
ElseIf cb_dropdown.SelectedIndex < 10 Then
RTB_Sql.Text = "update access set accessdesc = 'More than 5' where accessID > '5' and < '10' "
End If
Not really sure what you are trying to do though. Maybe if you explain in more detail someone can provide a better answer. So let me take a wild guess:
Dim n As Integer = cb_dropdown.SelectedIndex * 5
RTB_Sql.Text = "update access set accessdesc = 'More than " + n + "' where accessID > '" + n + "' and < '" + (n+6) + "' "
This will give you the following result based on SelectedIndex:
0 = from 1 to including 5
1 = from 6 to including 10
etc...
If you want to shift it down one (include 0 and not 5 in first batch) then just change > to >= and 6 to 5.
You can also use something like this if you want to check range of values:
Sub Main()
Dim i As Integer = 6
Select Case True
Case 0 <= i AndAlso i < 5
Console.WriteLine("i is between 0 and 4")
Case 6 <= i
Console.WriteLine("i is 6 or greater")
End Select
Console.ReadLine()
End Sub
Be aware that it stops in the first true condition.

Converting Check Amount To Words Using Case/Methods

I am working on a project for my Visual Basic class, which is to create a digital check. The assignment requires us to input a check amount, which translates into words. In example, $1,200.00 needs to output "One thousand two hundred dollars"
For the most part, my code works. I'm using a switch statement. The original assignment was to have our check go up to a 9,999 value, but as we continue to build, we need to be able to convert up to 99,999.
As I said, I've been using a series of case statements, but realize that this is a very "hard code" way of doing this and would like create a method that can check these type of things for me, however I'm still new to Visual Basic and don't really have a good idea where to start or what is applicable in this scenario (we don't really have an example to go by.)
Here is my WriteCheck method that does the assigning/converting for the most part.
'Convert check value from a text field to a double'
Try
checkValue = checkInput.Text
Catch ex As InvalidCastException
MessageBox.Show("You must enter a numbers to write a check.")
End Try
'Operation to convert number to String'
thousands = checkValue \ 1000
hundreds = checkValue Mod 1000
hundreds = hundreds \ 100
tens = checkValue Mod 100
tens = tens \ 10
ones = checkValue Mod 10
ones = ones \ 1
'Case for thousands'
Select Case thousands & hundreds & tens
Case 1
tempStringT = "One"
Case 2
tempStringT = "Two"
Case 3
tempStringT = "Three"
Case 4
tempStringT = "Four"
Case 5
tempStringT = "Five"
Case 6
tempStringT = "Six"
Case 7
tempStringT = "Seven"
Case 8
tempStringT = "Eight"
Case 9
tempStringT = "Nine"
End Select
'Case for hundreds'
Select Case hundreds
Case 1
tempStringH = "one"
Case 2
tempStringH = "two"
Case 3
tempStringH = "three"
Case 4
tempStringH = "four"
Case 5
tempStringH = "five"
Case 6
tempStringH = "six"
Case 7
tempStringH = "seven"
Case 8
tempStringH = "eight"
Case 9
tempStringH = "nine"
End Select
'Case for tens'
Select Case tens Or ones
Case 1
tempStringTens = "one"
Case 2
tempStringTens = "twenty"
Case 3
tempStringTens = "thirty"
Case 4
tempStringTens = "fourty"
Case 5
tempStringTens = "fifty"
Case 6
tempStringTens = "sixty"
Case 7
tempStringTens = "seventy"
Case 8
tempStringTens = "eighty"
Case 9
tempStringTens = "ninety"
End Select
If tempStringTens <> "one" Then
'Case for ones'
Select Case ones
Case 1
tempStringO = "one"
Case 2
tempStringO = "two"
Case 3
tempStringO = "three"
Case 4
tempStringO = "four"
Case 5
tempStringO = "five"
Case 6
tempStringO = "six"
Case 7
tempStringO = "seven"
Case 8
tempStringO = "eight"
Case 9
tempStringO = "nine"
End Select
lblConverted.Text = tempStringT & " thousand " & tempStringH & " hundred " & tempStringTens & " " & tempStringO & " dollars " & change & "/100"
End If
If tempStringTens = "one" Then
Select Case ones
Case 1
tempStringO = "eleven"
Case 2
tempStringO = "twelve"
Case 3
tempStringO = "thirteen"
Case 4
tempStringO = "fourteen"
Case 5
tempStringO = "fifteen"
Case 6
tempStringO = "sixteen"
Case 7
tempStringO = "seventeen"
Case 8
tempStringO = "eighteen"
Case 9
tempStringO = "nineteen"
End Select
lblConverted.Text = tempStringT & " thousand " & tempStringH & " hundred " & tempStringO & " dollars"
End If
End Sub
This is my approach to the problem. The solution can be easily scaled up or down by adding or removing items in BigNumbers and upping the scope of num beyond Long if necessary. (As written, it will work for numbers up to 999,999,999,999,999.)
Public Function NumberToText(ByVal num As Long) As String
Dim BigNumbers() As String = {"", " Thousand", " Million", " Billion", " Trillion"}
Dim TextParts() As String = {}
If num < 0 Then
Return "Checks cannot be written for negative amounts."
ElseIf num >= 10 ^ ((BigNumbers.Length) * 3) Then
Return "This number exceeds the current maximum value of " & NumberToText(10 ^ ((BigNumbers.Length) * 3) - 1) & "."
End If
Dim LoopCount As Integer = 0
While num >= 1000
ReDim Preserve TextParts(TextParts.Length)
If num Mod 1000 > 0 Then
TextParts(TextParts.GetUpperBound(0)) = ThreeDigitText(num Mod 1000) & BigNumbers(LoopCount)
End If
num = num \ 1000
LoopCount += 1
End While
ReDim Preserve TextParts(TextParts.Length)
TextParts(TextParts.GetUpperBound(0)) = ThreeDigitText(num) & BigNumbers(LoopCount)
If Array.IndexOf(TextParts, "Error") > -1 Then
Return "An unknown error occurred while converting this number to text."
Else
Array.Reverse(TextParts)
Return Join(TextParts)
End If
End Function
Private Function ThreeDigitText(ByVal num As Integer) As String
If num > 999 Or num < 0 Then
Return "Error"
Else
Dim h As Integer = num \ 100 'Hundreds place
Dim tempText As String = ""
If h > 0 Then
tempText = OneDigitText(h) & " Hundred"
End If
num -= h * 100
If num > 0 And Not tempText = "" Then
tempText &= " "
End If
If num > 9 And num < 20 Then
Dim DoubleDigits() As String = {"Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"}
Return tempText & DoubleDigits(num - 10)
Else
Dim TensPlace() As String = {"Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"}
Dim t As Integer = num \ 10 'Tens place
num -= t * 10
If t > 1 Then
tempText &= TensPlace(t - 2)
If num > 0 Then
tempText &= " "
End If
End If
If num > 0 Then
tempText &= OneDigitText(num)
End If
Return tempText
End If
End If
End Function
Private Function OneDigitText(ByVal num As Integer) As String
If num > 9 Or Num < 0 Then
Return "Error"
Else
Dim SingleDigits() As String = {"Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"}
Return SingleDigits(num)
End If
End Function
Since this is for school, you will probably want to adapt parts of my code to your own rather than copy the whole thing. (Teachers can usually tell when you get code off the internet, especially if you can't explain every line.) If you have any questions about it, send them to the email listed in my profile.

visual basics equal to or greater than

I am trying to write some code that says if textbox1 is equal to 0 between 10 then HandDecimal = 1. Else if textbox1 is equal to 10.1 through 100, then HandDecimal = 3. Else if textbox1 is equal to 100.1 and greater than HandDecimal = 5.
Here is my code, but it does not seem to work for me.
If WeightDecimal = 0 <= 10 Then
HandDecimal = 1
ElseIf WeightTextBox.Text = 10 <= 100 Then
HandDecimal = 3
ElseIf WeightTextBox.Text >= 100.1 Then
HandDecimal = 5
End If
How do I have to change the code to make it work?
Dim weight as Decimal = Decimal.Parse(WeightTextBox.Text)
If weight >= 0 AndAlso weight <= 10 Then
HandDecimal = 1
ElseIf weight > 10 AndAlso weight <= 100 Then
HandDecimal = 3
ElseIf weight > 100 Then
HandDecimal = 5
End If
Select Case statement with To operator
Select Case WeightDecimal
Case 0 To 10
HandDecimal = 1
Case 10.1 To 100
HandDecimal = 3
Case Else
HandDecimal = 5
End Select