How do I correct this vba code? - vba

I am still new to vba.
I am trying to create a new function however, it keeps giving me an output that I am not expecting.
my code is as follows:
Function bonusplanA(a, b, c)
Dim example As Range
Set example = Range("a:c")
Value = Application.WorksheetFunction.CountIf(example, ">=90")
Value1 = Application.WorksheetFunction.CountIf(example, ">=80")
If Value = 3 Then
bonusplanA = "$20,000 bonus"
Else
If Value1 = 3 Then
bonusplanA = "$10,000 bonus"
Else
bonusplanA = "NO BONUS"
End If
End If
End Function

You need to define your function like this:
Function bonusplanA(a, b, c)
If a >= 90 And b >= 90 And c >= 90 Then
bonusplanA = "$20,000 bonus"
Else
If a >= 80 And b >= 80 And c >= 80 Then
bonusplanA = "$10,000 bonus"
Else
bonusplanA = "NO BONUS"
End If
End If
End Function
The problem in your example was that Range("a:c") does not make a range of your a,b,c variables; instead it selects the range composed of columns A, B and C.
You need to use parameters a, b and c directly, not through the Range function.
Otherwise, the logic was sound. :)

Related

If, Then and Select Case

I'm writing VB Code and I see a question below
There are three positive integers A, B, C
If A is greater than B, C is equal to A+B
If A is less than or equal to B, then C is equal to A-B.
Please use IF...Then and Select/Switch Case to write a program, both of which are used in this program, and additional variables can be added by yourself.
I would like to ask how to write this question, as far as I know, the answer just need only IF Then or Select Case can be realized?
Dim A As Double = 3
Dim B As Double = 2
Dim C As Double = 1
Dim D As Double = 0
D = A - B
Select Case D
Case D > 0
C = A + B
Case D < 0
C = A - B
End Select
If D > 0 Then
C = A + B
ElseIf D < 0 Then
C = A - B
End If
In the real world you wouldn't need to use both an If/Then statement and a Select/Case statement. Since this appears to be homework, I believe the exercise is to see if you can use both conditional check.
I would setup two functions that accept two arguments (a and b) that return the value of c. In your first function use an If/Then and in your second function use a Select/Case.
E.g.
Private Function IfThenOption(a As Integer, b As Integer) As Integer
Dim c As Integer
If (a > b) Then
c = a + b
ElseIf (a < b) Then
c = a - b
Else
c = a
End If
Return c
End Function
Private Function SelectCaseOption(a As Integer, b As Integer) As Integer
Dim c As Integer
Select Case True
Case a > b
c = a + b
Case a < b
c = a - b
Case Else
c = a
End Select
Return c
End Function
Example: https://dotnetfiddle.net/kwcyWc

How do I compare values in two columns and then mark true/false in a third?

Can someone please help me create a macro that will search two columns on a worksheet for a list of conditions and mark true/false on the third column. (office 2010)
e.g.
Column A would have the following values: 1111,1,2,3,3,4,...
Column B would have the following values: O,A,Y,A,S,3Y,...
If the following matching conditions are met, the column C would mark as TRUE, otherwise FALSE.
A B
1111 = O
0 = Y
1 = A
2 = S
3 = 3YRY
4 = Q
6 = B
12 = M
13 = V
360 = D
CONDITION RULES:
IF column A = 1111 AND column B = O
OR
IF column A = 0 AND column B = Y
OR
IF column A = 1 AND column B = A
OR
IF column A = 2 AND column B = S
OR
IF column A = 3 AND column B = 3YR
OR
IF column A = 4 AND column B = Q
OR
IF column A = 6 AND column B = B
OR
IF column A = 12 AND column B = M
OR
IF column A = 13 AND column B = V
OR
IF column A = 360 AND column B = D
THEN COLUMN C = "TRUE" ELSE "FALSE"
This should match more closely what you're wanting to accomplish, any questions about what's happening here let me know.
Option Base 1
Sub testCriteria()
'arrays for criteria r, r2. Array for T/F r3
Dim r, r2, r3(10, 1)
'iterators for loop and variable for output column
Dim i As Long, j As Long, c As Long
'column for output of t/f
c = 3
'location of criteria cells h1 through i10
r = [h1:i10]
'location of comparison
r2 = [a1:b10]
'loop through rows of rows to check (r2) and compare with all rows from criteria (r)
For i = LBound(r2) To UBound(r2)
For j = LBound(r) To UBound(r)
If CStr(r(j, 1)) = CStr(r2(i, 1)) _
And CStr(r(j, 2)) = CStr(r2(i, 2)) _
Then r3(i, 1) = "TRUE"
Next j
If Not r3(i, 1) Then r3(i, 1) = "FALSE"
Next i
'reusing iterators for array limits
i = LBound(r3): j = UBound(r3)
'loading t/f array into api
Range(Cells(i, c), Cells(j, c)) = r3
End Sub

Randomly ordering variables

I have 4 strings in variables a,b,c and d. I need to randomly order these variables in such a way so that I can input them into 4 different text boxes but not the same ones every time the program is ran.
I've tried to simplify it for myself by putting the strings into an array. Tell me what I'm doing wrong or if there's a way I could do it much easier.
Private Sub Random()
For i = 1 To 4
If a = 0 Then
a = r.Next(2, 5)
ElseIf b = 0 Then
Do Until b <> a
b = r.Next(2, 5)
Loop
ElseIf c = 0 Then
Do Until c <> a Or c <> b
c = r.Next(2, 5)
Loop
ElseIf d = 0 Then
Do Until d <> a Or d <> b Or d <> c
d = r.Next(2, 5)
Loop
End If
Next
End Sub
Here is one way to do it:
Dim a As String = "a"
Dim b As String = "b"
Dim c As String = "c"
Dim d As String = "d"
Dim all As String() = {a, b, c, d}
Dim random As New Random
Dim allRandom As String() = all.OrderBy(Function() random.Next).ToArray

Output/Print variable, in code, in if statement

I am trying to achieve the following:
The user is shown an excel spread sheet with a list of assumption which they can change.
Title | Value |
Input01 | 10 | =
Input02 | 2 | >=
Input03 | 800 | >=
Input04 | 4 | >=
Input05 | 2 | <=
There is an If .. Then Statement that pulls in data if the assumption are met. However if an assumption is blanc, it should not be included in the If .. Then Statement.
If x = Input01Value And y >= Input02Value _
And z >= Input03Value And a >= Input04Value _
And b <= Input05Value Then
User ommits Input03
If x = Input01Value And y >= Input02Value _
And a >= Input04Value And b <= Input05Value Then
Now I could check to see if each value exist, and then follow it by another If statement with the appropriate variables. But this seems a bit redundant.
I was wondering if something like the following is possible:
Input 01 = ""
If Input01Value != "" Then Input01 = "x = " & Input01Value
'Then use join or something similar to join all of them ..
And Then use this Input01 directly in the If .. Then statement. This way when a variable is empty the And .. are not included and the If statement will not fail.
Eg. (I know this doesn't work, just illustrating the scenario)
VBA: If Input01 Then
Result while compiling: If x = Input01Value Then
Please Note, I know I could do something like the following:
If Boolean And Variable2 > 4 Then and then have Boolean and Variable2 populate with a value in the cell, however the issue with this is that if the user, for example, decides to omit the Variable2 (which is reasonable) it will fail. eg. If (Boolean = True) And > 4 Then.
Hope my question is clear, thanks for the help.
What about using a function which operates on a select case depending on a string operator and two values?
Function conditionalString(condition As String, x As Variant, y As Variant) As Boolean
Select Case condition
Case "="
If (x = y) Then
conditionalString = True
Else
conditionalString = False
End If
Exit Function
Case ">="
conditionalString = (x >= y)
Exit Function
Case "<="
conditionalString = (x <= y)
Exit Function
Case ">"
conditionalString = (x > y)
Exit Function
Case "<"
conditionalString = (x < y)
Exit Function
Case Else
conditionalString = False
End Select
End Function
You could then just have another function, say "check if value isn't blank" before calling all assumptions.
Expanding on my comment, you can use something like this to test each row of input.
Function TestIt(testValue,inputOperator,inputValue) As Boolean
If Len(inputValue)=0 Then
TestIt=True 'ignore this test: no value supplied
Else
TestIt=Application.Evaluate(testValue & inputOperator & inputValue)
End If
End function

do not understand if else block behaviour

I have the following code:
Sub Main()
Dim a As Integer = 8 * 60
Dim b As Integer
Dim c As Integer
If a < (6 * 60) Then
b = 0 And c = 0
ElseIf a >= 6 * 60 And a < 9 * 60 Then
b = 30 And c = 1
Else
b = 45 And
c = 1
End If
MsgBox(b)
End Sub
Thinks i dont understand and where i need someones help:
"c=0" and "c=1" are underlined with the error: Strict on doesnt allow implicit convertation from boolean to integer. WHY? I declared c as integer!
Variable "b" and "c" are always "0" even though in the case above they should be b=30 and c = 1.
can anyone please explain me this behaviour.
You are using the And keyword where it is not allowed. And is a logical operator (along with Or, AndAlso, OrElse.)
The following should work.
Sub Main()
Dim a As Integer = 8 * 60
Dim b As Integer
Dim c As Integer
If a < (6 * 60) Then
b = 0
c = 0
ElseIf a >= 6 * 60 And a < 9 * 60 Then
b = 30
c = 1
Else
b = 45
c = 1
End If
MsgBox(b)
End Sub