Why am I getting this If statement problem? - excel

I am getting the error "End If Without Block If" problem in VBA. Followin is my code. Could someone help me find out the mistake I am making?
Function ProjectedProductionPlan(Coverage As Double, Sales As Variant, ProjectedStock As Double) As Double
Dim count As Integer
Dim ResidualBalance As Double
Dim ProjectedPlan As Double
Dim k As Integer
Dim x As Integer
Dim y As Single
Dim s As Single
count = Sales.count
s = 0
ResidualBalance = ProjectedStock
i = 1
If Coverage < 1 Then
ProjectedPlan = (Sales(i) * Coverage) - ResidualBalance
ElseIf Coverage = 1 Then
ProjectedPlan = Sales(i) - ResidualBalance
Else
For k = 1 To count
Do Until k - Coverage > 0
x = k
y = Coverage - x
s = Sales(k) + s
Loop
Exit For
End If
ProjectedPlan = s + (Sales(x + 1) * y)
End Function

As per my comment:
To get rid of the compile error, you'll need to change Exit For into Next to create an actual iteration whereas Exit For is simply a statement within the loop to Exit the loop. Here is MS-documentation on For...Next loops.
However, you also make use of a Do Until...Loop. As I see your code, repairing the above would immediately throw your code in an infinite loop since no variable (neither k nor coverage) get's adjusted. So my suggestion would be to include an IF statement inside your For...Next loop instead. For example like this:
For k = 1 To count
If k - Coverage > 0 Then
Exit For
Else
x = k
y = Coverage - x
s = Sales(k) + s
End If
Next
I've not checked the rest of your code to see if implementing this is actually what you needed.
Small sidenote: using Integer data type variables is only going to bite you at one point. Use Long instead.

Related

Visual Basic create loop for counting even numbers

The program requires input of positive numbers, and counts each even number using a loop function that doesn't count odds and ends if a O is input.
I'm not sure how to go about creating a loop or if I can use an if function within the loop.
Dim Count = 0
While (number mod 2 = 0) do
Count + 1 = Count
I actually didn't understand the question very well but as far as concerned, if you dont want odd numbers to be included I suggest on count add 2 not one , since the count variable starts with zero do:
Dim Count+2
Btw when do you want the count to stop? At 2 And goes back to 0?
If so then use the if statement
var Dim_count = 0;
if(Dim_count == 0){Dim_count+2}
else if(Dim_count ==2){Dim_Count =0;}
It would help if you provide a sample input so we can work with actual code and guide you to the right solution.
If you receive the input as, let's say, array of numbers, you can simply loop trough it using for or foreach and add additional condition to check for 0 if you want to preliminary exit:
For Each number As Integer In numbers
If (number mod 2 = 0) Then
Count = Count + 1
End If
If (number = 0) Then
Exit For
End If
Next
If you have existing code in which somehow number is reinitialized/redefined on each iteration already, then what you have is pretty close to what you need:
While (number <> 0)
If (number mod 2 = 0) Then
Count = Count + 1
End If
End While
Function counts even numbers:
REM function gets input, exits at 0 and adds positive even numbers.
DO
INPUT X
IF X = 0 THEN PRINT Y; " even numbers": END
IF X > 0 THEN
IF X / 2 = X \ 2 THEN Y = Y + 1
END IF
LOOP
I am completely unsure about this. just a guess...
Dim j as Integer
Dim i As integer
j = 0
i = 2
For i = 1 to 100
j = j+i
Print j
Loop
End Sub
Assuming you are getting numbers from some input, this is how you can do it. Have an infinite loop with While True, then for every number given from your input, check if its even using number mod 2 = 0. This will go on forever so you need to add some condition (another if statement) for it to stop the while loop. More information about while loops here: https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/while-end-while-statement
Dim Count = 0
While True do
If (number mod 2 = 0) Then
Count + 1 = Count
End If
End While

Error "Function call on left side of assignment must return Variant or Object"

So here is a code snippet. The error I am getting is "Function call on left side of assignment must return Variant or Object". I changed the function return to a variant data type, but that did not help.
I am trying to generate a random string using function calls. Because it is a large number of sub tables I want to maintain the tables separated like so instead of in a single long series of code for ease of maintainability.
If this is not viable, can anyone suggest an alternative method of doing this?
Private Function GenAstStrategicResouce() As Variant
Dim X As Integer
X = Int((200 * Rnd) + 1)
If X < 10 Then
GenStrategicResouce = "Bose-Einstein Condensates"
ElseIf X < 20 Then
GenStrategicResouce = "Diamonds"
End If
End Function
Declare the function to return a string.
You also have mistyped the function's name on the return as GenStrategicResouce instead of GenAstStrategicResouce.
Private Function GenAstStrategicResouce() As STRING
Dim X As long
X = Int((200 * Rnd) + 1)
If X < 10 Then
GenAstStrategicResouce = "Bose-Einstein Condensates"
ElseIf X < 20 Then
GenAstStrategicResouce = "Diamonds"
End If
End Function
It cannot return anything else so a variant (typically used to possibly return a CVErr or array) is unnecessary.

Access VBA to Excel, add apostrophe [duplicate]

Having a problem with this Error. I am creating a GA and the loop is to assign my fitness value to an array.
some of the variables
Dim Chromolength as integer
Chromolength = varchromolength * aVariables
Dim i as integer, j as integer, counter as integer
Dim Poparr() As Integer
Dim FitValarr() As Integer
the code:
ReDim Poparr(1 To PopSize, 1 To Chromolength)
For i = 1 To PopSize
For j = 1 To Chromolength
If Rnd < 0.5 Then
Poparr(i, j) = 0
Else
Poparr(i, j) = 1
End If
Next j
Next i
For i = 1 To PopSize
j = 1
counter = Chromolength
Do While counter > 0
FitValarr(i) = FitValarr(i) + Poparr(i, counter) * 2 ^ (j - 1)
j = j + 1
counter = counter - 1
Loop
Next i
I am having problems with:
FitValarr(i) = FitValarr(i) + Poparr(i, counter) * 2 ^ (j - 1)
I apologize, I am fairly new to VBA.
An overflow condition arises when you create an integer expression that evaluates to a value larger than can be expressed in a 16-bit signed integer. Given the expression, either the contents of FitValarr(i), or the expression 2^(j-1) could be overflowing. Suggest all the the variables presently declared as Int be changed to Long. Long integers are 32-bit signed values and provide a correspondingly larger range of possible values.
I had the same run time error 6. After much investigation l discovered that mine was a simple 'divide by zero' error.
I set up an integer value to hold Zip codes, and Error 6 events plagued me - until I realized that a zip code of 85338 exceeded the capacity of an int...
While I didn't think of a zip code as a "value" it was nonetheless certainly interpreted as one. I suspect the same could happen with addresses as well as other "non-numeric" numeric values. Changing the variable to a string resolved the problem.
It just didn't occur to me that a zip code was a "numeric value." Lesson learned.

Counting rows in VBA excel

I'm designing a function in VBA of the form myFunction(x,y,z) where z is a table, and x can take the values of the column headings. As part of the function I need to find the number of rows in z.
I'm having problems with this, as everywhere I look suggests using length = z.Rows.Count, but when I try and output this value (as in, set myFunction = length), it produces a VALUE error. However, when I output myFunction = a which doesn't directly use length (it will eventually form part of an IF statement once I get it working), the function works fine. My code is below:
Public Function myFunction(x As String, y As Double, z As Range) As Double
Dim upper_threshold As Double
Dim lower_threshold As Double
Dim a As Double
Dim rates As Variant
Dim u As Byte
Dim l As Byte
Dim r As Byte
Dim length As Byte
a = 0
u = 2
l = 1
rates = Application.WorksheetFunction.Index(z, 1, 0)
r = Application.WorksheetFunction.Match(x, rates, 0)
length = z.rows.Count
upper_threshold = z(u, 1)
Do While y > upper_threshold
u = u + 1
l = l + 1
upper_threshold = z(u, 1)
lower_threshold = z(l, 1)
If y < upper_threshold Then
a = a + z(l, r) * (y - lower_threshold)
Else
a = a + z(l, r) * (upper_threshold - lower_threshold)
End If
Loop
myFunction = a
End Function
To test it out I also created another function:
Public Function myRows(myTable As Range) As Double
myRows = myTable.rows.Count
End Function
This one works fine on its own, but when I try to use it within the other function, I still get a VALUE error. I've tried declaring length as every type I can think of and it doesn't seem to help.
Can anyone see what's going on?
EDIT: I'm obviously not making myself very clear. The function without the two lines referring to length works as I intended. However, I need to add a bit of code to increase its functionality and this involves calculating the number of rows in the table z. When I add the two lines shown here into the function it continues to work, since it doesn't affect the output. However, if I then set the output to show length, i.e. change the penultimate line to myFunction = length it gives me a VALUE error. This leaves me with two options as far as I can see: either something else in the program is impacting on these two lines (some clashes of syntax or something), or I'm making a mistake in just assuming I can output length like that.
Your problem is with:
rates = Application.WorksheetFunction.Index(z, 1, 0)
Index only accepts a single row or column, otherwise you get a VALUE error.

Overflow error with Mod in VBA when value is in the billions or greater

I am trying to find the largest prime divisor of a number x. When x is smaller than 1billion my code works but when it is greater than 1billion it gives an overflow error and debugging highlights the line with Mod in it.
Sub Largest_Divisor()
Dim x As Double
Dim Q As Integer
Q = 0
Dim L() As Double
x = 999999999#
Dim i As Double
For i = 775145 To 3 Step -2
If x Mod i = 0 Then
If IsPrime(i) Then
ReDim Preserve L(Q) As Double
L(Q) = i
Q = Q + 1
End If
End If
Next i
MsgBox (Application.Max(L))
End Sub
I suspect it is when x is larger than about 2 billion, 2,147,483,648 to be precise, that you have trouble.
That is because as per the documentation of mod, at most a long is returned, which ranges in value from -2,147,483,648 to 2,147,483,647 as a 32-bit signed value. It is not explicitly stated in the help documentation, but the arguments of mod are probably coerced to long as well.
A good work around can be to use this function:
Function Modulus(int1 As Double, int2 As Double) As Double
' This function will return int1 Mod int2. It is useful when |int1| exceeds
' 2,147,483,647 as the VBA Mod function will then break.
'
Dim myInt As Integer
myInt = Int(int1 / int2)
Modulus = int1 - (myInt * int2)
Return Modulus
End Function

Resources