Trying to build a scale using For, If and Offest loops - vba

I compose a code ,which take "Samples" spreadsheeet with a depth database and displays the numbers in "Log"
Sub Log()
Dim i As Integer
For i = 1 To 4
Sheets("Samples").Select
Sheets("Log").Select
If Value <= 0.2 Then
ActiveSheet.Range("C9").Value = Sheets("Samples").Range("B6").Offset(i - 1)
ElseIf Value < 0.4 And Value > 0.2 Then
ActiveSheet.Range("C10").Value = Sheets("Samples").Range("B6").Offset(i - 1)
ElseIf Value <= 0.5 And Value >= 0.4 Then
ActiveSheet.Range("C11").Value = Sheets("Samples").Range("B6").Offset(i - 1)
ElseIf Value > 0.5 And Value < 0.9 Then
ActiveSheet.Range("C12").Value = Sheets("Samples").Range("B6").Offset(i - 1)
ElseIf Value < 1 And Value >= 0.9 Then
ActiveSheet.Range("C13").Value = Sheets("Samples").Range("B6").Offset(i - 1)
ElseIf Value > 1 And Value < 1.2 Then
ActiveSheet.Range("C14").Value = Sheets("Samples").Range("B6").Offset(i - 1)
ElseIf Value > 1.2 And Value <= 1.5 Then
ActiveSheet.Range("C15").Value = Sheets("Samples").Range("B6").Offset(i - 1)
ElseIf Value > 1.5 And Value < 1.8 Then
ActiveSheet.Range("C16").Value = Sheets("Samples").Range("B6").Offset(i - 1)
ElseIf Value > 1.7 And Value < 1.9 Then
ActiveSheet.Range("C17").Value = Sheets("Samples").Range("B6").Offset(i - 1)
ElseIf Value >= 1.9 And Value < 2 Then
ActiveSheet.Range("C18").Value = Sheets("Samples").Range("B6").Offset(i - 1)
ElseIf Value > 2 And Value < 2.2 Then
ActiveSheet.Range("C19").Value = Sheets("Samples").Range("B6").Offset(i - 1)
ElseIf Value >= 2.2 And Value < 2.4 Then
ActiveSheet.Range("C20").Value = Sheets("Samples").Range("B6").Offset(i - 1)
ElseIf Value >= 2.4 And Value <= 2.5 Then
ActiveSheet.Range("C21").Value = Sheets("Samples").Range("B6").Offset(i - 1)
ElseIf Value > 2.5 And Value < 2.8 Then
ActiveSheet.Range("C22").Value = Sheets("Samples").Range("B6").Offset(i - 1)
ElseIf Value >= 2.8 And Value < 3 Then
ActiveSheet.Range("C23").Value = Sheets("Samples").Range("B6").Offset(i - 1)
ElseIf Value > 3 And Value < 3.2 Then
ActiveSheet.Range("C24").Value = Sheets("Samples").Range("B6").Offset(i - 1)
ElseIf Value >= 3.2 And Value <= 3.5 Then
ActiveSheet.Range("C25").Value = Sheets("Samples").Range("B6").Offset(i - 1)
ElseIf Value > 3.5 And Value < 3.7 Then
ActiveSheet.Range("C26").Value = Sheets("Samples").Range("B6").Offset(i - 1)
ElseIf Value >= 3.7 And Value <= 3.9 Then
ActiveSheet.Range("C27").Value = Sheets("Samples").Range("B6").Offset(i - 1)
ElseIf Value > 3.9 And Value < 4 Then
ActiveSheet.Range("C28").Value = Sheets("Samples").Range("B6").Offset(i - 1)
End If
Next i
End Sub
spreadsheet, a depth scale.
The problem is that i use Offset and the loop does not work on the whole database. The loop stars on B6 until B13 on "Samples" spreadsheet.
Here is what I have done already

Related

Calculating discount in VB.NET

I'm trying to calculate discount based on a person's age category and amount of visits at a hair salon. It's just not working properly though. It doesn't calculate the proper discount until the second click and then it does some weird stuff if I keep pressing calculate. Just wondering where I am going wrong, thanks.
' Discount
If radAdult.Checked = True Then
discount = 0
ElseIf radChild.Checked = True Then
discount = totalPrice * 0.1
ElseIf radStudent.Checked = True Then
discount = totalPrice * 0.05
ElseIf radSenior.Checked = True Then
discount = totalPrice * 0.15
End If
' Additional discount
If txtClientVisits.Text >= 1 And txtClientVisits.Text <= 3 Then
additionalDiscount = 0
ElseIf txtClientVisits.Text >= 4 And txtClientVisits.Text <= 8 Then
additionalDiscount = totalPrice * 0.05
ElseIf txtClientVisits.Text >= 9 And txtClientVisits.Text <= 13 Then
additionalDiscount = totalPrice * 0.1
ElseIf txtClientVisits.Text >= 14 Then
additionalDiscount = totalPrice * 0.15
End If
totalPrice = baseRate + serviceRate - (discount + additionalDiscount)
The type of the txtClientVisits.Text property is a String. The comparison operators <, >, >=, and <= for strings perform a lexicographic comparison. VB will then convert 14 to the string "14" and so compare each digit one-by-one, which is not what you want.
(This is why I don't like VB.NET - because it performs these implicit conversions without warning you).
You will need to explicitly convert the number in the textbox to an actual number, then compare based on that:
Dim clientVisits As Integer = CInt( txtClientVisits.Text )
If clientVisits >= 1 AndAlso clientVisits < 4 Then
additionalDiscount = 0
ElseIf clientVisits >= 4 AndAlso clientVisits < 9 Then
additionalDiscount = totalPrice * 0.05
ElseIf clientVisits >= 9 AndAlso clientVisits < 14 Then
additionalDiscount = totalPrice * 0.1
ElseIf clientVisits >= 14 Then
additionalDiscount = totalPrice * 0.15
End If
I note you used inclusive boundary values. That works for integer values but will fail for continuous (floating-point) values. Note how I'm using >= and < instead of >= and <= to avoid that case.
Also, note I'm using the AndAlso operator which is short-circuiting (compared to And which is not). This isn't a functional change, it just means the program will run slightly faster.
Also, you don't need to do ElseIf radChild.Checked = True Then because the value of the .Checked property is already a boolean value, you can do this instead:
ElseIf radChild.Checked Then

Conditional ELSEIF does not work

Not sure how to solve this. "a" was meant to start from 1 to NumData, but I have deliberately change the start from 44200 to check the ELSEIF. For NumData = 117,350,
I would expect the 3rd ELSEIF to be activated. Instead throughout the whole run, it only step-into the first ELSEIF even though the "a" value does not meet the conditions.
What should I do?
For a = 44200 To NumData 'Int1
If a > 1 Then
If UCase(Trim(Range1(a, 3))) = UCase(Trim(Range1(a - 1, 3))) Then
GoTo Line1 'Next count loop if next Platform name the same
End If
End If
For b = 1 To NumData
lat1 = Range1(a, 5)
lat2 = Range1(b, 5)
long1 = Range1(a, 6)
long2 = Range1(b, 6)
CompRad = Dist(lat1, lat2, long1, long2)
If (CompRad <= Radius And CompRad >= 0) Then
z = CLng(NumData / 8)
If a <= CLng(NumData / 8) Then
For c = 1 To 6
Range2(d, c) = Range1(b, c)
Next c
Acc_Sum2 = Acc_Sum2 + Range2(d, 4)
d = d + 1
ElseIf CLng(NumData / 8) < a <= 2 * CLng(NumData / 8) Then
z = 2 * CLng(NumData / 8)
For c = 1 To 6
Range3(e, c) = Range1(b, c)
Next c
Acc_Sum3 = Acc_Sum3 + Range3(e, 4)
e = e + 1
ElseIf 2 * CLng(NumData / 8) < a <= 3 * CLng(NumData / 8) Then
For c = 1 To 6
Range4(f, c) = Range1(b, c)
Next c
Acc_Sum4 = Acc_Sum4 + Range4(f, 4)
f = f + 1
ElseIf 3 * CLng(NumData / 8) < a <= 4 * CLng(NumData / 8) Then
z = 3 * CLng(NumData / 8)
For c = 1 To 6
Range5(g, c) = Range1(b, c)
Next c
Acc_Sum5 = Acc_Sum5 + Range5(g, 4)
g = g + 1
ElseIf 4 * CLng(NumData / 8) < a <= 5 * CLng(NumData / 8) Then
For c = 1 To 6
Range6(h, c) = Range1(b, c)
Next c
Acc_Sum6 = Acc_Sum6 + Range6(h, 4)
h = h + 1
ElseIf 5 * CLng(NumData / 8) < a <= 6 * CLng(NumData / 8) Then
For c = 1 To 6
Range7(i, c) = Range1(b, c)
Next c
Acc_Sum7 = Acc_Sum7 + Range7(i, 4)
i = i + 1
ElseIf 6 * CLng(NumData / 8) < a <= 7 * CLng(NumData / 8) Then
For c = 1 To 6
Range8(j, c) = Range1(b, c)
Next c
Acc_Sum8 = Acc_Sum8 + Range8(j, 4)
j = j + 1
ElseIf 7 * CLng(NumData / 8) < a <= NumData Then
For c = 1 To 6
Range9(k, c) = Range1(b, c)
Next c
Acc_Sum9 = Acc_Sum9 + Range9(k, 4)
k = k + 1
End If
End If
Next b
Line1:
Next a
Your conditions like:
1 < a <= 10
are always true. First part (1 < a) evaluates to True or False and then it is converted to integer (True = 1, False = 0). Both values are <=10.
You should change thes conditions to:
(1 < a) And (a <= 10)
Brackets are optional, comparison operators have higher precedence.
user3964075 nailed the core issue. I think making the code a little bit more readable will help to filter out other possible trouble areas. Why do you set the value of 'z' and then not use it?
z = CLng(NumData / 8)
Where are the variables d, e, f...; Range2, Range3, Range4...; Acc_Sum2, Acc_Sum3... assigned, and what are they doing? Can each group be replaced by a single variable?
You may also want to create a simple Between function
to clean up a lot of your conditional statements.
Public Function Between(x As Integer, min As Integer, max As Integer) As Boolean
Between = x <= max And x >= min
End Function
Thanks, user3964075 & Carl for your prompt response. It's worked! Carl, the z variable was slotted in when I was trying to figure out the problem. I thought it would be too much to post the whole code. It does require a lot of cleaning up. Appreciate your tips.

project euler problem17 vb code bug

If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total.
If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?
NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) contains 20 letters. The use of "and" when writing out numbers is in compliance with British usage.
my answer is coming 21148. i cant find the mistake here is my code in vb
the answer should be 21124
Dim length As UInt32 = 11
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For i = 1 To 999
If i / 10 < 1 Then
single_digit(i)
ElseIf i / 10 = 1 Then
ten()
ElseIf i / 10 > 1 And i / 10 < 2 Then
ele_twe_thi(i)
ElseIf i / 10 >= 2 And i / 10 < 10 Then
multiple_10(Math.Floor(i / 10) * 10)
single_digit(i Mod 10)
ElseIf i = 100 Then
single_digit(i / 100)
length += 7
ElseIf i Mod 100 >= 11 And i Mod 100 <= 19 Then
length += 10
single_digit(Math.Floor(i / 100))
ele_twe_thi(i Mod 100)
ElseIf i Mod 100 = 10 Then
length += 3
single_digit(Math.Floor(i / 100))
length += 10
Else
length += 10
single_digit(Math.Floor(i / 100))
multiple_10(Math.Floor((i Mod 100) / 10) * 10)
single_digit(i Mod 10)
End If
Next
MsgBox(length)
End Sub
Private Sub single_digit(num)
If num = 1 Then
length = length + 3
ElseIf num = 2 Then
length = length + 3
ElseIf num = 3 Then
length = length + 5
ElseIf num = 4 Then
length = length + 4
ElseIf num = 5 Then
length = length + 4
ElseIf num = 6 Then
length = length + 3
ElseIf num = 7 Then
length = length + 5
ElseIf num = 8 Then
length = length + 5
ElseIf num = 9 Then
length = length + 4
End If
End Sub
Private Sub ele_twe_thi(num)
If num = 11 Or num = 12 Then
length = length + 6
ElseIf num = 13 Or num = 14 Or num = 18 Or num = 19 Then
length = length + 8
ElseIf num = 17 Then
length = length + 9
ElseIf num = 15 Or num = 16 Then
length = length + 7
End If
End Sub
Private Sub multiple_10(num)
If num = 20 Then
length = length + 6
ElseIf num = 30 Then
length = length + 6
ElseIf num = 40 Then
length = length + 5
ElseIf num = 50 Then
length = length + 5
ElseIf num = 60 Then
length = length + 5
ElseIf num = 70 Then
length = length + 7
ElseIf num = 80 Then
length = length + 6
ElseIf num = 90 Then
length = length + 6
End If
End Sub
Private Sub ten()
length = length + 3
End Sub
every time the program reaches 100, 200, 300 etc. is it adding an "and" unnecessarily?

How to make a "key generator" knowing the formula

I have the formula to check 9 integers,
First digit(d1) must be: 1, 2, 5, 6, 8 or 9
Last digit(d9) must be: 0 or 9
9xd1+8xd2+7xd3+6xd4+5xd5+4xd6+3xd7+2xd8+d9 mod 11 = 0
I can "validate" the key, but how can I generate more of this, knowing the conditions for it to be right?
How can I generate 9 different integers from 0 to 9 and check them under this formula?
Thanks for helping!
Generate the first 7 digits randomly, calculating the formula for those digits.
Set the 9th digit's value to 9, and add it to the formula.
Calculate a value for the 8th digit based on the mod of the result of the formula that causes the result of the formula to be mod 11 = 0.
For the exception case where attempting to do this causes mod 11 = 9, set the 9th digit to 0.
Implementation:
Private randGen As New Random()
Function GenNum() As Integer
Dim digits(0 To 8) As Integer
GenNum = 0
Dim checkSum As Integer
digits(0) = randGen.Next(6) + 1
If digits(0) >= 3 Then digits(0) += 2
If digits(0) >= 7 Then digits(0) += 1
checkSum += digits(0) * 9
For d As Integer = 1 To 6
digits(d) = randGen.Next(10)
checkSum += digits(d) * (9 - d)
Next
digits(8) = 9
checkSum += digits(8)
If (checkSum Mod 11) Mod 2 = 1 Then
digits(7) = (11 - (checkSum Mod 11)) \ 2
Else
digits(7) = ((12 - (checkSum Mod 11)) \ 2 + 4) Mod 10
End If
checkSum += digits(7) * 2
If checkSum Mod 11 = 9 Then digits(8) = 0
Dim pow10 As Integer = 1
For d As Integer = 8 To 0 Step -1
GenNum += pow10 * digits(d)
pow10 *= 10
Next
End Function
I can help you to generate integers from 0 to 9.
here is how your form should look like:
and here is the code:
Public Class Form1
Dim NumRandom As Random = New Random
Dim X, Y, Z As Integer
Private Sub GenerateBUT_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GenerateBUT.Click
Dim a(9), i, j, RN As Integer
Dim flag As Boolean
flag = False
i = 1
a(j) = 1
Do While i <= 9
Randomize()
RN = CInt(Int(9 * Rnd()) + 1)
For j = 1 To i
If (a(j)) = RN Then
flag = True
Exit For
End If
Next
If flag = True Then
flag = False
Else
a(i) = RN
i = i + 1S
End If
Loop
Label1.Text = a(1)
Label2.Text = a(2)
Label3.Text = a(3)
Label4.Text = a(4)
Label5.Text = a(5)
Label6.Text = a(6)
Label7.Text = a(7)
Label8.Text = a(8)
Label9.Text = a(9)
Z = Label4.Text
Y = Label5.Text
X = Z + Y
X = X - Label3.Text
If X > 1 And X < 10 Then
X = NumRandom.Next(1, 7)
If X = 1 Then
Label1.Text = "0"
ElseIf X = 2 Then
Label2.Text = "0"
ElseIf X = 3 Then
Label3.Text = "0"
ElseIf X = 4 Then
Label4.Text = "0"
ElseIf X = 5 Then
Label5.Text = "0"
ElseIf X = 6 Then
Label6.Text = "0"
ElseIf X = 7 Then
Label7.Text = "0"
End If
End If
End Sub
End Class

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