Finding Missing numbers in a given range - vb.net

So i have a problem with my codings and was wondering if anyone can help me.
Basically i'm using VB.NET and MSSQL to make a program on finding missing numbers in between a given range set by the user. The program will read from the table and give the output on a textbox. And the above codes are so far what i can come up with. But the problem is, i get wrong output and not what i want. Here's an image of the output.
Function FindingMissingNumber() As String
Dim intX As Integer = Nothing
Dim intY As Integer = Nothing
Dim strSting As String = Nothing
Dim strSqlQUery As String = Nothing
Dim cmdSqlCommand As Data.SqlClient.SqlCommand = Nothing
Dim rdrDataReader As Data.SqlClient.SqlDataReader = Nothing
'------------------------------------------------------------------------------------------------------------------------
'-> Process
'------------------------------------------------------------------------------------------------------------------------
strSqlQUery = "Select ExReportPolicyNo From DBReport Order by ExReportPolicyNo"
Dim msSqlConnection As New Data.SqlClient.SqlConnection()
'NOTE - You may need to CHECK your connection string!!! in the line below
msSqlConnection.ConnectionString = "Data Source=SISBSQL\SISBSQL;Initial Catalog=ExceptionReport;User ID=sa;Password=123;"
cmdSqlCommand = New Data.SqlClient.SqlCommand(strSqlQUery, msSqlConnection)
If cmdSqlCommand.Connection.State = Data.ConnectionState.Closed Then cmdSqlCommand.Connection.Open()
rdrDataReader = cmdSqlCommand.ExecuteReader()
If rdrDataReader.HasRows Then
Do While rdrDataReader.Read()
intX = txtRangeLeft.Text
intY = txtRangeRight.Text
'intY = rdrDataReader.GetValue(rdrDataReader.GetOrdinal("ExReportPolicyNo"))
Do While intX <> intY
intX = intX + 1
If intX <> intY Then
strSting = strSting & intX & ", " 'if it is not, then record the non sequential number into the string
Else
Exit Do
End If
Loop
Loop
End If
If cmdSqlCommand.Connection.State = Data.ConnectionState.Open Then cmdSqlCommand.Connection.Close()
'return string
Return strSting
'tidy up
intX = Nothing
intY = Nothing
strSting = Nothing
strSqlQUery = Nothing
cmdSqlCommand = Nothing
rdrDataReader = Nothing
End Function
As you can see the program loops it multiple times, and give out the wrong output. The output should read only "286118, 286120, 286121". Question is where did i went wrong?

Try this (using linq)
Change query to return rows between start and end value
Select distinct ExReportPolicyNo From DBReport
Where ExReportPolicyNo between #start and #end
Order by ExReportPolicyNo
Create List from your query:
Dim originalList as List(Of Integer)
If rdrDataReader.HasRows Then
Do While rdrDataReader.Read()
originalList.Add(rdrDataReader.GetInt(0))
Loop
End If
Create List of range from your start and end number
//Dim rangeList = Enumerable.Range(286117, 286121 - 286117 + 1).ToList()
Dim starti = Int32.Parse(txtRangeLeft.Text)
Dim endi = Int32.Parse(txtRangeRight.Text)
Dim rangeList = Enumerable.Range(starti, endi - starti + 1).ToList()
Find all missing numbers
Dim missingList = originalList.Except(rangelist)
Create CSV string from list above
strString = String.Join(",", missingList.Select(x => x.ToString()).ToArray())

Related

I want to make a maths quiz on vb.net that uses bracket questions

So I've used visual basics (vb.net) for a bit now and understand some stuff. Right now I want to make a maths quiz that when I click a button it takes me to a new form and starts the quiz. When the quiz starts I want it so it gives the user random numbers and the user needs to answer it in a textbox and if correct it moves on to the next question (Basic, I should be able to do). IMPORTANT - my question is, there's a maths rule called BODMAS (Bracket.Order.Division.Multiply.Add.Subtract) and I want to add this rule into my coding instead of doing regular simple maths...
EXAMPLE question is 2 x (2+3) - 1 = ?
2 x 5 - 1 = ?
10 - 1 = ?
9 = 9
person writes answer to textbox and moves to next similar question
This is my first time using this but I wanted to write in-depth so people can understand. Please help me if you find a video explaining what I'm looking for or if someone has a file with a similar code I could download would be greatly appreciated!
Basically,you need to determine the range of numbers you use, and then match them randomly among '*', '/', '+', '-'. Then randomly insert brackets into it.
Private codeStr As String
Private Function GenerateMathsQuiz() As String
Dim r As Random = New Random()
Dim builder As StringBuilder = New StringBuilder()
'The maximum number of operations is five, and you can increase the number [5] to increase the difficulty
Dim numOfOperand As Integer = r.[Next](1, 5)
Dim numofBrackets As Integer = r.[Next](0, 2)
Dim randomNumber As Integer
For i As Integer = 0 To numOfOperand - 1
'All numbers will be random between 1 and 10
randomNumber = r.[Next](1, 10)
builder.Append(randomNumber)
Dim randomOperand As Integer = r.[Next](1, 4)
Dim operand As String = Nothing
Select Case randomOperand
Case 1
operand = "+"
Case 2
operand = "-"
Case 3
operand = "*"
Case 4
operand = "/"
End Select
builder.Append(operand)
Next
randomNumber = r.[Next](1, 10)
builder.Append(randomNumber)
If numofBrackets = 1 Then
codeStr = InsertBrackets(builder.ToString())
Else
codeStr = builder.ToString()
End If
Return codeStr
End Function
Public Function InsertBrackets(ByVal source As String) As String
Dim rx As Regex = New Regex("\d+", RegexOptions.Compiled Or RegexOptions.IgnoreCase)
Dim matches As MatchCollection = rx.Matches(source)
Dim count As Integer = matches.Count
Dim r As Random = New Random()
Dim numIndexFirst As Integer = r.[Next](0, count - 2)
Dim numIndexLast As Integer = r.[Next](1, count - 1)
While numIndexFirst >= numIndexLast
numIndexLast = r.[Next](1, count - 1)
End While
Dim result As String = source.Insert(matches(numIndexFirst).Index, "(")
result = result.Insert(matches(numIndexLast).Index + matches(numIndexLast).Length + 1, ")")
Return result
End Function
When you finish this, you will get a math quiz, then you need to know how to compile and run code at runtime.
Private Function GetResult(ByVal str As String) As String
Dim sb As StringBuilder = New StringBuilder("")
sb.Append("Namespace calculator" & vbCrLf)
sb.Append("Class calculate " & vbCrLf)
sb.Append("Public Function Main() As Integer " & vbCrLf)
sb.Append("Return " & str & vbCrLf)
sb.Append("End Function " & vbCrLf)
sb.Append("End Class " & vbCrLf)
sb.Append("End Namespace" & vbCrLf)
Dim CompilerParams As CompilerParameters = New CompilerParameters()
CompilerParams.GenerateInMemory = True
CompilerParams.TreatWarningsAsErrors = False
CompilerParams.GenerateExecutable = False
CompilerParams.CompilerOptions = "/optimize"
Dim references As String() = {"System.dll"}
CompilerParams.ReferencedAssemblies.AddRange(references)
Dim provider As VBCodeProvider = New VBCodeProvider()
Dim compile As CompilerResults = provider.CompileAssemblyFromSource(CompilerParams, sb.ToString())
If compile.Errors.HasErrors Then
Dim text As String = "Compile error: "
For Each ce As CompilerError In compile.Errors
text += "rn" & ce.ToString()
Next
Throw New Exception(text)
End If
Dim Instance = compile.CompiledAssembly.CreateInstance("calculator.calculate")
Dim type = Instance.GetType
Dim methodInfo = type.GetMethod("Main")
Return methodInfo.Invoke(Instance, Nothing).ToString()
End Function
Finally, you can use these methods like:
Private Sub GetMathQuizBtn_Click(sender As Object, e As EventArgs) Handles GetMathQuizBtn.Click
Label1.Text = GenerateMathsQuiz()
End Sub
Private Sub ResultBtn_Click(sender As Object, e As EventArgs) Handles ResultBtn.Click
If TextBox1.Text = GetResult(Label1.Text) Then
MessageBox.Show("bingo!")
TextBox1.Text = ""
Label1.Text = GenerateMathsQuiz()
Else
MessageBox.Show("result is wrong")
End If
End Sub
Result:

Adding rows to a DataGridView control causes crash but only on second attempt

I have a DataGridView (dgvNew) which is populated by a JSON file which is located by a FileSystemWatcher, data is added row by row after being read. It works fine on first file. But if i trigger a new file by copying and pasting the same JSON file it adds the rows again row by row as id expect, but then the whole form crashes with no error.
I've tried TRY..CATCH with WHILE loops for opened the files which works in terms of openning them and adding rows, i just don't understand why it crashes. The code continues to step through regardless even though the form is frozen ? is it Thread related ?
Public Sub subParseJSONs(strFilePath As String, strDesiredField As String)
Dim json As String
Dim strMachine As String
Dim read As New Newtonsoft.Json.Linq.JObject
Dim booErrorJSNOArrRead As Boolean
Dim i As Integer
Dim dgvIndex As Integer
Dim booOpened As Boolean
Dim k As Integer, j As Integer
booOpened = False
k = 1
j = 1
json = Nothing
While json Is Nothing
Try
j = j + 1
If j = 10 Then
MessageBox.Show("J integer reached 10")
Exit While
Exit Try
End If
json = Replace(Replace(System.IO.File.ReadAllText(strFilePath), vbLf, ""), vbTab, "")
read = Newtonsoft.Json.Linq.JObject.Parse(json)
Catch ex As IOException
'MessageBox.Show(ex.Message)
Threading.Thread.Sleep(300)
'GoTo EndOfSUb
Catch ex As Exception
'MessageBox.Show(ex.Message)
Threading.Thread.Sleep(300)
'GoTo EndOfSUb
Finally
booOpened = True
End Try
End While
booErrorJSNOArrRead = False
i = 0
dgvNew.ColumnCount = 6
dgvNew.Columns(0).Name = "TempID"
dgvNew.Columns(1).Name = "DriverName"
dgvNew.Columns(2).Name = "Seat"
dgvNew.Columns(3).Name = "RaceTime"
dgvNew.Columns(4).Name = "ResultTime"
dgvNew.Columns(5).Name = "CarDriven"
dgvNew.RefreshEdit()
dgvNew.Refresh()
Do Until i = read.Item("Result").Count
If Not read.Item("Result")(i)("DriverName") = "" Then
Dim milliseconds As Double = Convert.ToDouble(read.Item("Result")(i)("TotalTime"))
Dim ts As TimeSpan = TimeSpan.FromMilliseconds(milliseconds)
Dim strMMSSmmm As String = ts.Minutes.ToString & ":" & ts.Seconds.ToString & "." & ts.Milliseconds.ToString
Dim row As String() = New String() {i + 1,
read.Item("Result")(i)("DriverName"),
read.Item("Result")(i)("DriverName"),
strMMSSmmm,
DateTime.Now, read.Item("Result")(i)("CarModel")}
dgvNew.Rows.Add(row)
End If
i = i + 1
Loop
read = Nothing
End Sub
I'm expecting new rows to be added to the bottom of dgvNew, which they are, but then it crashes ?

vb.net Splitting string lines into new strings

I want to split a string - which includes multiple lines - into new strings.
As it seems that people dont understand my problem here some further informations:
I read out values into strings from a XML-file. Some of those strings countain multiple lines. Now I need every single value of that string on a new string(variable) so that I can tell Homer to drink a beer and tell Lenny to go to bed and not tell the whole Team to go to bed. (Hopefully this story helps you :D )
To keep this simple I'll define a "static" string for this sample.
I'll put 3 of my tries down below. I'd love to hear what's wrong with them. I also tried it with lists and enums where I could split the string but no define a new one..
But I assume that there is a much easier solution for my problem...
Dim team As String = "Simpson, Homer" & vbCrLf & "Leonard, Lenny" & vbCrLf & "Carlson, Carl"
1.
Dim objReader As New StringReader(team)
Dim tm() As String
Dim i As Integer = 1
Do While objReader.Peek() <> -1
tm(i) = objReader.ReadLine() & vbNewLine
i = i + 1
Loop
Dim i As Integer = 0
For Each Line As String In team.Split(New [Char]() {CChar(vbTab)})
Dim tm(i) As String = ReadLine(team, i)
i = i + 1
Next
3.
Dim tm() As String
Dim i As Integer = 0
Dim objReader As New StringReader(team)
Do While objReader.Peek() <> -1
tm(i) = ReadLine(team, i)
i = i + 1
Loop
And the function used in 2. and 3.
Public Function ReadLine(ByVal sFile As String, Optional ByVal nLine As Long = 1) As String
Dim sLines() As String
Dim oFSO As Object
Dim oFile As Object
On Error GoTo ErrHandler
oFSO = CreateObject("Scripting.FileSystemObject")
If oFSO.FileExists(sFile) Then
oFile = oFSO.OpenTextFile(sFile)
sLines = Split(oFile.ReadAll, vbCrLf)
oFile.Close()
Select Case Math.Sign(nLine)
Case 1
ReadLine = sLines(nLine - 1)
Case -1
ReadLine = sLines(UBound(sLines) + nLine + 1)
End Select
End If
ErrHandler:
oFile = Nothing
oFSO = Nothing
End Function
Thanks in advance for any shared thoughts.
There is in fact an easy solution for my problem. Sorry if I caused confusion.
Module Module1
Dim team As String = "Simpson, Homer" & vbCrLf & "Leonard, Lenny" & vbCrLf & "Carlson, Carl"
Sub Main()
Dim tm As String() = team.Split(vbLf)
'Test
Console.WriteLine(tm(0)) 'Homer
Console.WriteLine(tm(1)) 'Lenny
Console.WriteLine(tm(2)) 'Carl
End Sub
End Module

This code is supposed to output the number of times a word starts with a letter from the alphabet, but just displays zero for each one

This code is supposed to output the number of times a word starts with a letter from the alphabet, but just displays zero for each one
I get no errors, but just a text file with all of the letters and zero for each one.
When pressing the debug button, it appears to do nothing. Here's the code
Imports System.IO
Module Module1
Sub Main()
Dim myArray As New List(Of String)
Using myReader As StreamReader = New StreamReader(".\myFile.txt")
'telling VB that we're using a StreamREader, read a line at a time
Dim myLine As String
myLine = myReader.ReadLine 'assigns the line to String Variable myLine
Do While (Not myLine Is Nothing)
myArray.Add(myLine) 'adding it to the list of words in the array
Console.WriteLine(myLine)
myLine = myReader.ReadLine
Loop
End Using
SortMyArray(myArray) 'Calls the new SubRoutine => SortMyArray, passing through the parameter myArray,
'created back on line 7 that stores all of the lines read from the text file.
'Console.ReadLine()
wordCount(myArray)
End Sub
Sub SortMyArray(ByVal mySort As List(Of String))
Dim Tmp As String, writePath As String = ".\sorted.txt"
Dim max As Integer = mySort.Count - 1
Dim myWriter As StreamWriter = New StreamWriter(writePath)
For Loop1 = 0 To max - 1
For Loop2 = Loop1 + 1 To max
If mySort(Loop1) > mySort(Loop2) Then
Tmp = mySort(Loop2)
mySort(Loop2) = mySort(Loop1)
mySort(Loop1) = Tmp
End If
Next
myWriter.WriteLine(mySort.Item(Loop1).ToString())
Next
myWriter.Dispose()
End Sub
Sub wordCount(ByVal stringArray As List(Of String))
Dim alphabet As String = "abcdefghijklmnopqrstuvwxyz", myString As String
Dim writePath As String = ".\counted.txt"
Dim myWriter As StreamWriter = New StreamWriter(writePath)
Dim countOf(25) As Integer, Max As Integer = stringArray.Count - 1
For Loop1 = 0 To 25
myString = alphabet.Substring(Loop1, 1)
For Loop2 = 0 To Max
If stringArray(Loop2).Substring(0, 1) = myString Then
countOf(Loop1) += 1
End If
Next
myWriter.WriteLine(myString & " occured " & countOf(Loop1) & " times ")
Next
myWriter.Dispose()
End Sub
End Module
Any help would be appreciated. Thanks

How can I get String values rather than integer

How To get StartString And EndString
Dim startNumber As Integer
Dim endNumber As Integer
Dim i As Integer
startNumber = 1
endNumber = 4
For i = startNumber To endNumber
MsgBox(i)
Next i
Output: 1,2,3,4
I want mo make this like sample: startString AAA endString AAD
and the output is AAA, AAB, AAC, AAD
This is a simple function that should be easy to understand and use. Every time you call it, it just increments the string by one value. Just be careful to check the values in the text boxes or you can have an endless loop on your hands.
Function AddOneChar(Str As String) As String
AddOneChar = ""
Str = StrReverse(Str)
Dim CharSet As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
Dim Done As Boolean = False
For Each Ltr In Str
If Not Done Then
If InStr(CharSet, Ltr) = CharSet.Length Then
Ltr = CharSet(0)
Else
Ltr = CharSet(InStr(CharSet, Ltr))
Done = True
End If
End If
AddOneChar = Ltr & AddOneChar
Next
If Not Done Then
AddOneChar = CharSet(0) & AddOneChar
End If
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim S = TextBox1.Text
Do Until S = TextBox2.Text
S = AddOneChar(S)
MsgBox(S)
Loop
End Sub
This works as a way to all the codes given an arbitrary alphabet:
Public Function Generate(starting As String, ending As String, alphabet As String) As IEnumerable(Of String)
Dim increment As Func(Of String, String) = _
Function(x)
Dim f As Func(Of IEnumerable(Of Char), IEnumerable(Of Char)) = Nothing
f = _
Function(cs)
If cs.Any() Then
Dim first = cs.First()
Dim rest = cs.Skip(1)
If first = alphabet.Last() Then
rest = f(rest)
first = alphabet(0)
Else
first = alphabet(alphabet.IndexOf(first) + 1)
End If
Return Enumerable.Repeat(first, 1).Concat(rest)
Else
Return Enumerable.Empty(Of Char)()
End If
End Function
Return New String(f(x.ToCharArray().Reverse()).Reverse().ToArray())
End Function
Dim results = New List(Of String)
Dim text = starting
While True
results.Add(text)
If text = ending Then
Exit While
End If
text = increment(text)
End While
Return results
End Function
I used it like this to produce the required result:
Dim alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
Dim results = Generate("S30AB", "S30B1", alphabet)
This gave me 63 values:
S30AB
S30AC
...
S30BY
S30BZ
S30B0
S30B1
It should now be very easy to modify the alphabet as needed and to use the results.
One option would be to put those String values into an array and then use i as an index into that array to get one element each iteration. If you do that though, keep in mind that array indexes start at 0.
You can also use a For Each loop to access each element of the array without the need for an index.
if the default first two string value of your output is AA.
You can have a case or if-else conditioning statement :
and then set 1 == A 2 == B...
the just add or concatenate your default two string and result string of your case.
I have tried to understand that you are looking for a series using range between 2 textboxes. Here is the code which will take the series and will give the output as required.
Dim startingStr As String = Mid(TextBox1.Text, TextBox1.Text.Length, 1)
Dim endStr As String = Mid(TextBox2.Text, TextBox2.Text.Length, 1)
Dim outputstr As String = String.Empty
Dim startNumber As Integer
Dim endNumber As Integer
startNumber = Asc(startingStr)
endNumber = Asc(endStr)
Dim TempStr As String = Mid(TextBox1.Text, 1, TextBox1.Text.Length - 1)
Dim i As Integer
For i = startNumber To endNumber
outputstr = outputstr + ", " + TempStr + Chr(i)
Next i
MsgBox(outputstr)
The First two lines will take out the Last Character of the String in the text box.
So in your case it will get A and D respectively
Then outputstr to create the series which we will use in the loop
StartNumber and EndNumber will be give the Ascii values for the character we fetched.
TempStr to Store the string which is left off of the series string like in our case AAA - AAD Tempstr will have AA
then the simple loop to get all the items fixed and show
in your case to achive goal you may do something like this
Dim S() As String = {"AAA", "AAB", "AAC", "AAD"}
For Each el In S
MsgBox(el.ToString)
Next
FIX FOR PREVIOUS ISSUE
Dim s1 As String = "AAA"
Dim s2 As String = "AAZ"
Dim Last As String = s1.Last
Dim LastS2 As String = s2.Last
Dim StartBase As String = s1.Substring(0, 2)
Dim result As String = String.Empty
For I As Integer = Asc(s1.Last) To Asc(s2.Last)
Dim zz As String = StartBase & Chr(I)
result += zz & vbCrLf
zz = Nothing
MsgBox(result)
Next
**UPDATE CODE VERSION**
Dim BARCODEBASE As String = "SBA0021"
Dim BarCode1 As String = "SBA0021AA1"
Dim BarCode2 As String = "SBA0021CD9"
'return AA1
Dim FirstBarCodeSuffix As String = Replace(BarCode1, BARCODEBASE, "")
'return CD9
Dim SecondBarCodeSuffix As String = Replace(BarCode2, BARCODEBASE, "")
Dim InternalSecondBarCodeSuffix = SecondBarCodeSuffix.Substring(1, 1)
Dim IsTaskCompleted As Boolean = False
For First As Integer = Asc(FirstBarCodeSuffix.First) To Asc(SecondBarCodeSuffix)
If IsTaskCompleted = True Then Exit For
For Second As Integer = Asc(FirstBarCodeSuffix.First) To Asc(InternalSecondBarCodeSuffix)
For Third As Integer = 1 To 9
Dim tmp = Chr(First) & Chr(Second) & Third
Console.WriteLine(BARCODEBASE & tmp)
If tmp = SecondBarCodeSuffix Then
IsTaskCompleted = True
End If
Next
Next
Next
Console.WriteLine("Completed")
Console.Read()
Take a look into this check it and let me know if it can help