Console VB.NET: File Processing - Search file for a specific number and output record - vb.net

Hello I am building a console application in VB.NET that reads a record file and outputs it to the user. I have gotten the program to output all of the records to the console but I cannot seem to get the search function working.
I want the user to input the record number and for the program to search the text file for that specific record and then output it to the console.
I will leave the read record function here for reference.
Read Records function:
Public Function Read_Records()
File_Name = "drecords.txt"
File_num = FreeFile()
Record_Counter = 0
record_no = 999
If File_Name <> "" Then
Try
FileOpen(File_num, File_Name, OpenMode.Input)
Do Until EOF(File_num)
Record_Counter = Record_Counter + 1
record_no = record_no + 1
records(Record_Counter, 0) = record_no
records(Record_Counter, 1) = LineInput(File_num)
records(Record_Counter, 2) = LineInput(File_num)
records(Record_Counter, 3) = LineInput(File_num)
records(Record_Counter, 4) = LineInput(File_num)
records(Record_Counter, 5) = LineInput(File_num)
Loop
record_ID = Record_Counter
Catch ex As Exception
MsgBox("ERROR OPENING FILE")
Finally
FileClose(File_num)
End Try
End If
Last_Record = Record_Counter
Return records
End Function

I'm not sure exactly what you want, but here are a few examples.
To read a record number from the console and output that record, do something like this:
dim i, k as integer
k = val(console.readline())
for i = 1 to 5
console.writeline(records(k, i))
next i
I'm not sure how else you would identify the record, but, for example, you can search the records for a value of "abc" in the first field like this:
For i = 1 to Last_Record
if records(i, 1) = "abc" then
' output the record to the user
end if
next i
Replace records(i, 1) with records(i, 0) to search for a record number.
If you want to search each field, you can add a nested loop:
For i = 1 to Last_Record
for k = 1 to 5
if records(i, k) = "abc" then
' output the record to the user
end if
next k
next i

Related

Understanding the steps in making a counter for each letter when a sentence is inputed

I have an example of a program that shows how to set up a counter for how many times each letter of the alphabet was used. I don't understand the syntax of the middle portion of the program.
LET letter$ = MID$(sentence$, LETTERNUMBER, 1)
I have tried searching on youtube and tutorials online
CLS
REM Make Counters for each Letter!!!
DIM Count(ASC("A") TO ASC("Z"))
REM Get the Sentence
INPUT "Enter Sentence:", sentence$
LET sentence$ = UCASE$(sentence$)
FOR I = ASC("A") TO ASC("Z")
LET Count(I) = 0
NEXT I
FOR LETTERNUMBER = 1 TO LEN(sentence$)
LET letter$ = MID$(sentence$, LETTERNUMBER, 1)
IF (letter$ >= "A") AND (letter$ <= "Z") THEN
LET k = ASC(letter$)
LET Count(k) = Count(k) + 1
END IF
NEXT LETTERNUMBER
PRINT
REM Display These Counts Now
LET letterShown = 0
FOR letternum = ASC("A") TO ASC("Z")
LET letter$ = CHR$(letternum)
IF Count(letternum) > 0 THEN
PRINT USING "\\## "; letter$; Count(letternum);
END IF
LET letterShown = letterShown + 1
IF letterShown = 7 THEN
PRINT
LET letterShown = 0
END IF
NEXT letternum
END
A through Z appears with the count of how many times they appeared.
The MID$ function returns a portion of a STRING's value from any position inside a string.
Syntax:
MID$(stringvalue$, startposition%[, bytes%])
Parameters:
stringvalue$
can be any literal or variable STRING value having a length. See LEN.
startposition%
designates the non-zero position of the first character to be returned by the function.
bytes%
(optional) tells the function how many characters to return including the first character when it is used.
Another method to calculate characters in a string:
REM counts and displays characters in a string
DIM count(255) AS INTEGER
PRINT "Enter string";: INPUT s$
' parse string
FOR s = 1 TO LEN(s$)
x = ASC(MID$(s$, s, 1))
count(x) = count(x) + 1
NEXT
' display string values
FOR s = 1 TO 255
PRINT s; "="; count(s); " ";
IF (s MOD 8) = 0 THEN
PRINT
IF (s MOD 20) = 0 THEN
PRINT "Press key:";
WHILE INKEY$ = "": WEND: PRINT
END IF
END IF
NEXT
END

Update previous row

I have an Excel file that contains some datas that I want to export into an Access db. In the C column I've got a field called 'Description'. Usually this field occupy just one cell, but it can happens that is more long.
In this case, for example, AP.01 has got 5 rows of description. How can update the first row with the next rows?
Public Sub updateDB(ByVal PathDB As String, str As String, id As Integer)
Dim db As New cDB
Dim v As New cVoce
Dim rs As ADODB.Recordset = db.RecordSet
v.Description = str
db.connetti_DB(PathDB)
db.get_rs("UPDATE Voice SET Description = '" + v.Description + "' WHERE id= '"+id+"'")
End Sub
Public Function get_rs(ByVal query As String) As ADODB.Recordset
If db Is Nothing Then rs = Nothing : Return rs
rs = New ADODB.Recordset
rs.CursorType = ADODB.CursorTypeEnum.adOpenStatic
rs.LockType = ADODB.LockTypeEnum.adLockOptimistic
rs.Open(query, db)
Return rs
End Function
This code doesn't work because I update my current row, for this reason is useless the UPDATE instruction. How can I fix my code?
EDIT I post here the For loop
For r = 2 To grid.RowCount - 1
vett = Split(grid(r, 1).Text)
total = UBound(Split(grid(r, 1).Text, "."))
If grid(r, 1).Text <> "" Then
Select Case total
Case 0
Dim chapter As New cChapter
flag = 1
id = id + 1
chapter.Cod = grid(r, 1).Text.Substring(0, 1)
chapter.Description = grid(r, 3).Text
If Left(vett(0), 1) >= Chr(65) And Left(vett(0), 1) <= Chr(90) Then
chapter.Cod = Left(vett(0), 1)
oldChap = chap.Cod
If chapter.Cod <> oldCap Then
chapters.Add(chapter)
End If
End If
chapters.Add(chapter)
stringChap = chap.Description
Dim par As New cParagraph
If Left(vett(0), 2) >= Chr(65) And Left(vett(0), 2) <= Chr(90) Then
par.Cod = Left(vett(0), 2)
par.Cod_Chapter = Left(vett(0), 1)
oldPar = par.Cod
If par.Cod <> oldPar Then
paragraphs.Add(par)
End If
End If
If grid(r, 3).Text.Length > 255 Then
par.Description = grid(r, 3).Text.ToString.Substring(0, 252) + "..."
Else
par.Description = grid(r, 3).Text.ToString
End If
paragraphs.Add(par)
stringPar = par.Description
Case 1
flag = 2
id = id + 1
c_Voc = voc.Cod_Chapter
p_Voc = voc.Cod_Paragraph
voc.Cod_Chapter = grid(r, 1).Text.Substring(0, 1)
voc.Cod_Paragraph = grid(r, 1).Text.Split(".")(0)
voc.Cod_Voice = Right(vett(0), 2)
If grid(r, 3).Text.Length > 255 Then
voc.Description = grid(r, 3).Text.ToString.Substring(0, 252) + "..."
Else
voc.Description = grid(r, 3).Text.ToString
If voc.Description.EndsWith("-") Then
a = Replace(voc.Description, "-", "")
voc.Description = a
End If
End If
stringVoice = voc.Description
voices.Add(voc)
voices.Save_DB(dbDest)
Case 2
flag = 3
id = id + 1
sVoice = New cVoice
oldSvoice = voice.Cod_SVoice
sVoice.Cod_SVoice = Left(vett(0), 2)
If sVoice.Cod_SVoce <> oldSvoice Then
voices.Add(sVoice)
voices.Save_DB(dbDest)
End If
If grid(r, 3).Text.Length > 255 Then
sVoice.Description = grid(r, 3).Text.ToString.Substring(0, 252) + "..."
Else
sVoice.Description = grid(r, 3).Text
End If
stringSvoice = sVoice.Description
sVoice.Cod_Voce = Left(vett(0), 5)
sVoice.Price1 = grid(r, 12).Text
sVoice.Price2 = sVoice.Price1
sVoice.UniMi = grid(r, 11).Text
sVoce.Sep = "."
voices.Add(sVoce)
voices.Save_DB(dbDest)
End Select
Else
If flag = 1 Then
stringChap = grid(r, 3).Text
chap.Description = stringChap & grid(r, 3).Text
stringPar = grid(r, 3).Text
paragraph.Description = stringPar & grid(r, 3).Text
End If
If flag = 2 Then
stringVoice = grid(r, 3).Text
voc.Description = voc.Description & stringVoice
voices.updateDB(dbDest, stringVoice, id)
voices.Add(voc)
End If
If flag = 3 Then
stringSvoice = grid(r, 3).Text
sVoice.Description = stringSvoice & grid(r, 3).Text
voices.Add(sVoice)
End If
chapter.Save_DB(dbDest)
paragraph.Save_DB(dbDest)
voice.Save_DB(dbDest)
End If
Next
EDIT2 I declared id As Integer and when Code column has a value then id=id+1. In this way I always know which row I have to modify. I modified also updateDB (now I'm using 3 parameters) and I added a WHERE condition into my query. Despite the update, nothing has changed
In database you cannot store records without PrimaryKey (actually you can, but it is bad idea). Since in your solution id is in fact Excel row number (sorry if I'm not correct but it looks like from code) it could be very hard to maintain it in future (in case someone add or remove description row). It would be better to change id column to text and use code as PK.
Storing description then could be solved in 2 ways:
1) Concatenate all rows containing description into 1 variable adding vbNewLine in between and store it in description field.
2) More relational but also more complex - create 2nd table for description with PK as i.e. autonumber, ForeignKey Code referring to main table. Maintenance will be here very complex. Not really worth effort.
Amount of changes in code is quite big, so sorry I'll not provide fixed code but I hope idea is clear.
BTW: The reason why description is not updated is described in your post. You are increasing id only when code is present, so every description field from first group have id = 1. The most simple fix in your code would be to create 2 update statements - One for rows with code
UPDATE Voice SET Description = '" + v.Description + "' WHERE id= '"+id+"'
Second one for rows without code:
UPDATE Voice SET Description = Description + CHAR(13) + CHAR(10) + '" + v.Description + "' WHERE id= '"+id+"'

Moving textbox output into a different textbox

I am trying to output text into another text box once the first has 5 entries in it. Example; i give the scores 100,200,300,200,200. Now when I try to enter a new score it should place it in the next textbox, but doesent.
Dim Testint As Integer ' define an Integer for testing
Dim sampleTextBox(3) As TextBox
sampleTextBox(0) = txtPlayer1Scores
sampleTextBox(1) = txtPlayer2Scores
sampleTextBox(2) = txtPlayer3Scores
sampleTextBox(3) = txtPlayer4Scores
Dim sampleLabel(3) As Label
sampleLabel(0) = lblPlayer1Average
sampleLabel(1) = lblPlayer2Average
sampleLabel(2) = lblPlayer3Average
sampleLabel(3) = lblPlayer4Average
scoreArray(textCount, gameNumber - 1) = CInt(txtScoreInput.Text) ' subtracting 1 from the score array
sampleTextBox(textCount).Text &= " Score:" & scoreArray(textCount, gameNumber - 1) & vbCrLf
'output statement
gameNumber = gameNumber + 1 'increment the counter
If gameNumber > MAX_SCORE_LENGTH Then
sampleTextBox(textCount).Focus()
sampleTextBox(textCount).Enabled = False
For i As Integer = 0 To 4 'Add the array values up
scoreTotal += scoreArray(textCount, i)
Next
playerAverage = scoreTotal / MAX_SCORE_LENGTH
sampleLabel(labelCount).Text = playerAverage
' I need the textbox switch here
textCount = textCount + 1
labelCount = labelCount + 1 ' and labels
ElseIf textCount > MAX_PLAYERS Then
'calculate team average
btnEnterScore.Enabled = False
Else
lblEnterScore.Text = "Enter Score for game #" & gameNumber ' 5 scores have not be inputted,
txtScoreInput.Text = "" 'ask for more
txtScoreInput.Focus() 'refocus the input textbox
End If
Fixed it...setting the max length to 15 forces it to move on after 15 digits, it also works when there are less than 15 digits
txtscore1.MaxLength = 15

VB.NET nested for loops

I am having two datasets,I have to check if plant code is 1st dataset and 2nd dataset then i have to set some value for a variable.If plant code is in 1st dataset and not in second dataset then have to set some value.I have try this with following code,but i m not getting output as i want
If Not dsCheckForBOM Is Nothing AndAlso dsCheckForBOM.Tables.Count > 0 Then
If dsCheckForBOM.Tables(0).Rows.Count > 0 Then
For count1 As Int32 = 0 To dsCheckForBOM.Tables(0).Rows.Count - 1
For count2 As Int32 = 0 To dsTmpMat.Tables(0).Rows.Count - 1
If dsTmpMat.Tables(0).Rows(count2)("PLANT_CODE").ToString() = dsCheckForBOM.Tables(0).Rows(count1)("PLANT_CODE").ToString() Then
dsTmpMat.Tables(0).Rows(count2)("BOM_IND") = 1
dsTmpMat.Tables(0).Rows(count2)("BOM_DESC") = "BOM CREATED"
If count2 < dsTmpMat.Tables(0).Rows.Count - 1 AndAlso count1 < dsCheckForBOM.Tables(0).Rows.Count - 1 Then
count2 = count2 + 1
count1 = count1 + 1
End If
Else
dsTmpMat.Tables(0).Rows(count2)("BOM_IND") = 0
dsTmpMat.Tables(0).Rows(count2)("BOM_DESC") = "BOM NOT CREATED"
If count2 < dsTmpMat.Tables(0).Rows.Count - 1 Then
count2 = count2 + 1
End If
End If
Next
Next
Else
For i As Int32 = 0 To dsTmpMat.Tables(0).Rows.Count - 1
dsTmpMat.Tables(0).Rows(i)("BOM_IND") = 0
dsTmpMat.Tables(0).Rows(i)("BOM_DESC") = "BOM NOT CREATED"
Next
End If
End If
I can't test this, but I think you need to use a different approach.
First, there is no need to have two loop nested. Use the Select method to find the rows in the temporary table.
Second, if you don't find the row in the temporary table then I think you need to create it, not to set the last row of the temporary table to zero
If Not dsCheckForBOM Is Nothing AndAlso dsCheckForBOM.Tables.Count > 0 Then
' To remove the clutter, assign the two tables
' to two local variables and work with them
Dim tempTable = dsTmpMat.Tables(0)
Dim checkTable = dsCheckForBOM.Tables(0)
If checkTable.Rows.Count > 0 Then
' Loop on the primary table
For count1 As Int32 = 0 To checkTable.Rows.Count - 1
' Get the key to search for in the temporary table
Dim plantCode = checkTable.Rows(count1)("PLANT_CODE").ToString()
' Use Select to return an array of rows that match the condition.
' I suppose that PLANT_CODE is a primary key value here, so just one
' row should be returned
Dim foundRows = tempTable.Select("PLANT_CODE = '" plantCode + "'")
if foundRows.Count > 0
foundRows(0)("BOM_IND") = 1
foundRows(0)("BOM_DESC") = "BOM CREATED"
Else
' No row found, so create a new row and add it to the temporary table
Dim newRow = tempTable.NewRow()
newRow("BOM_IND") = 0
newRow("BOM_DESC") = "BOM NOT CREATED"
tempTable.Rows.Add(newRow)
End If
Next
Else
For i As Int32 = 0 To dsTmpMat.Tables(0).Rows.Count - 1
dsTmpMat.Tables(0).Rows(i)("BOM_IND") = 0
dsTmpMat.Tables(0).Rows(i)("BOM_DESC") = "BOM NOT CREATED"
Next
End If
End If

Issues with For Loop in VB

For i = 1 To 5
If i = 0 Then
i = i + 1
ElseIf i Mod 2 = 0 Then
LabelEvens.Text = i
i = i + 1
Else
LabelOdds.Text = i
i = i + 1
End If
Next i
I'm making a program in VB where I have to use a for loop to sort between 2 numbers(loop limit 1 and 2) and find if they are even or odd, Then output the results to 2 labels. This loop makes sense to me, but for example when I put in 1 and 4 all it outputs is a 5 in the odd label. I guess my question is can anyone see the issue with my loop?
You don't need to add 1 to your loop variable i manually, the for loop itself does that for you behind the scenes:
For i = 1 To 5
If i Mod 2 = 0 Then
LabelEvens.Text = i
Else
LabelOdds.Text = i
End If
Next i
You'll noticed I've also removed the If i = 0 bit since i can never be zero within that loop. It ranges from one to five inclusive.
One other thing you'll need to do is to append the value to your text box. What you have at the moment is a replacement so that it'll only be set to the last value processed. Something like this should suffice:
' Initialise to empty strings '
LabelEvens.Text = ""
LabelOdds.Text = ""
' Append the values '
For i = 1 To 5
If i Mod 2 = 0 Then
LabelEvens.Text = LabelEvens.Text & "," & CStr(i)
Else
LabelOdds.Text = LabelOdds.Text & "," & CStr(i)
End If
Next i
' Remove initial comma from both '
LabelEvens.Text = Mid(LabelEvens.Text,2)
LabelOdds.Text = Mid(LabelOdds.Text,2)
Some issues in your code:
For i = 1 To 5
If i = 0 Then <-- 'I' will never be 0 since you start from 1
i = i + 1 <-- Don't manually increment since you are using a for
ElseIf i Mod 2 = 0 Then
LabelEvens.Text = i
i = i + 1 <-- Don't manually increment since you are using a for
Else
LabelOdds.Text = i
i = i + 1 <-- Don't manually increment since you are using a for
End If
Next i
Another issue you have is that if you have more than one odd number in the for range (say in a range of 1 to 10) you will only get the last number. What do you want to do in this case? Concatenate all odd numbers in a string or stop after the first one is found? Do you really need a FOR loop at all?
you can Also state
LabelEvens.Text="" 'Clear contents of the label before assigning new values
LabelOdds.Text=""
For i As Integer = 1 To 5
If i Mod 2 = 0 Then
LabelEvens.Text = LabelEvens.Text & i
Else
LabelOdds.Text = LabelOdds.Text & i
End If
Next
From Above you can replace '&' with '+' if you want the Total.