Link to home
Start Free TrialLog in
Avatar of fruitloopy
fruitloopy

asked on

VB.NET - Problem with If statement and streamreader

This is following on from a previous question where I was helped to move code out of a While loop to prevent errors.
Well now it seems to be causing another problem.
What it should be doing is read a text file with employee badge numbers and matching it to the one that's been scanned. If it finds a match it removes the badge number and writes the name associated with it to another text file.
It seems to have no problem finding the badge number but still produces the message saying "Badge number not found" which would seem to be contrary to the IF statement and the Boolean.
Can anyone help?
If e.KeyData = Keys.Return Then
            Dim _bAddBadge As Boolean = False
            Using _stream As Stream = New FileStream("\\Server\Asset Management\AssetPCSoftware\badge numbers.txt", FileMode.Open, FileAccess.ReadWrite)
                Using _reader As StreamReader = New StreamReader(_stream)
                    While Not _reader.EndOfStream
                        Dim _lineData As String = _reader.ReadLine()
                        If _lineData.Contains(txtAnalyst.Text) Then
                            _bAddBadge = False
                            Dim analyst As String = _lineData.Split("-"c)(1)
                            Dim sendtext As New StreamWriter("\\Server\Asset Management\Automated_Asset.txt", True)
                            sendtext.WriteLine("")
                            sendtext.WriteLine(DateTime.Now.ToLongDateString & " - " & DateTime.Now.ToShortTimeString)
                            sendtext.WriteLine("Computer Name: " & Form1.txtPCno.Text)
                            sendtext.WriteLine("Service Tag: " & Form1.txtServiceTag.Text)
                            sendtext.WriteLine("Computer Model: " & Form1.txtModelShipped.Text)
                            If Form1.ComboBox1.SelectedItem <> "" Or Form1.ComboBox1.Text <> "" Then
                                Dim cbtext1 As String = Form1.ComboBox1.Text
                                sendtext.WriteLine("Booked in reason: " & cbtext1)
                            End If
                            If Form1.ComboBox2.SelectedItem <> "" Or Form1.ComboBox2.Text <> "" Then
                                Dim cbtext2 As String = Form1.ComboBox2.Text
                                sendtext.WriteLine("Booked out reason: " & cbtext2)
                            End If

                            If Form1.txtRetainReason.Text > "" Then
                                sendtext.WriteLine(Form1.lblRetainReason.Text & Form1.txtRetainReason.Text)
                            End If
                            If Form1.txtRetainName.Text > "" Then
                                sendtext.WriteLine(Form1.lblRetainName.Text & Form1.txtRetainName.Text)
                            End If
                            If Form1.txtOutName.Text > "" Then
                                sendtext.WriteLine(Form1.lblOutName.Text & Form1.txtOutName.Text)
                            End If
                            sendtext.WriteLine(analyst)
                            sendtext.Close()

                            Dim ack As New ack_timer()
                            ack.Owner = Form1
                            ack.Show()
                            Me.Close()
                        Else
                            _bAddBadge = True
                        End If

                    End While
                    _reader.Close()

                End Using
                _stream.Close()
            End Using
            If _bAddBadge = True Then
                Dim result = MessageBox.Show("Analyst badge number not found, do you want to add your details?", "Badge number not found", MessageBoxButtons.YesNo)
                If result = Windows.Forms.DialogResult.Yes Then

                    'reader.Close()
                    Dim scan As New Add_Badge
                    scan.ShowDialog()
                    Form1.SendToBack()
                    Me.Close()


                End If
            End If

Open in new window

Avatar of Mr Knackered
Mr Knackered
Flag of United Kingdom of Great Britain and Northern Ireland image

Looking at your code and assuming that the StreamReader is reading multiple lines from the file your _bAddBadge value is going to hold the last iteration as the test containing "If _bAddBadge = True Then" is outside of the loop reading the file. Therefore the last read the "While Not _reader.EndOfStream" is doing doesn't contain txtAnalyst.Text.

Check the file being read to ensure there are no blank lines at the end of the data and put some break points into the code and step through the loop and look at the data being read on each loop and see which one is causing the _bAddBadge = True to be set.
Avatar of fruitloopy
fruitloopy

ASKER

Thanks Mr Kanckered
I've checked the badge number text file and this is the data
c:2554BF00B-Simon
c:70ADD6-Neil
c:2554D18AD-Kyle
c:2554D1853-Gemma
c:2554BF0BB-Jamie
c:2554BF061-Laura
c:70ADD4-Aaron

Open in new window

I used Laura as an example and I think I see what's happening.
I'm not greatly familiar with break points but I put some in at lines 7, 41, 43, 45, 48 and 50
The first time the break point gets to the Else statement at line 41 the _bAddBadge boolean is still false but as soon as it goes to End If at 43 it becomes true for each time it goes through the loop until it finds Laura's badge then it becomes False. It then carries on to Aaron and sets the boolean to True again even though it has found it.
How can I set the Boolean to False as soon as it finds a match and keep it that way until the ReadLine - EndOfStream is done?
Would you not want your logic re adding missing badge numbers to appear at line 44? while looping through the records in the file if a badge number is missing then it does something and then continues on the next loop to check the next person and badge number. Currently you are only going to get the last badge number missing result as the logic is outside of the loop.

Alternatively you could add a List into the code so that missing badge numbers are added to the list and at the end you could check for items in the list and then add all missing items in one go. It has been many years since I used Windows Forms or VB but in C# you could create an ObservableCollection<string> objList = new ObservableCollection<string>; and then within the loop if the badge is missing you could add the badge info into the list using objList.Add(badgenumber); and then after the loop has completed check the objList.Count > 0 to identify that you have badges missing that need dealing with.

ObservableCollection<string> objList = new ObservableCollection<string>;

Your Loop Start

  If (_lineData.Contains(txtAnalyst.Text))
  {
      doing some stuff
  }
  else
  {
     objList.Add(badgenumber);
  }
  End

Your Loop End

if (objList.Count > 0)
{
   // Setup a loop and deal with the missing badge numbers
  foreach (string strMissingBadge in objList)
  {
      // deal with the missing badge
      // use strMissingBadge to do whatever you need
  }

}
The quick way to resolve using your current code would be to insert the code between line 51 and 63 into line 44 so the check is being performed on each loop in the file. You will however get messageboxes appearing for each missing badge. If you would prefer this not to happen then go the list route mentioned above and deal with them post loop.

Hope this helps
You gave me another idea Mr Knackered as I may have found an even easier way, by adding
Dim Counter as Integer = 0
Then adding the line If badge is matched
Counter += 1
Which will then process the code
If Counter < 1 then add badge details
It seems to work so far as I have tested with badge numbers in any position in the list and also with an unknown badge number
Dim Counter As Integer = 0
            'Using _stream As Stream = New FileStream("\\Server\Asset Management\AssetPCSoftware\badge numbers.txt", FileMode.Open, FileAccess.ReadWrite)
            Using _reader As New StreamReader("\\Server\Asset Management\AssetPCSoftware\badge numbers.txt")
                While Not _reader.EndOfStream
                    Dim _lineData As String = _reader.ReadLine()
                    If _lineData.Contains(txtAnalyst.Text) Then
                        Counter += 1
                        Dim analyst As String = _lineData.Split("-"c)(1)
                        Dim sendtext As New StreamWriter("\\dxn5200a1.uk.cat.com\os\Desktop\Asset Management\Automated_Asset.txt", True)
                        sendtext.WriteLine("")
                        sendtext.WriteLine(DateTime.Now.ToLongDateString & " - " & DateTime.Now.ToShortTimeString)
                        sendtext.WriteLine("Computer Name: " & Form1.txtPCno.Text)
                        sendtext.WriteLine("Service Tag: " & Form1.txtServiceTag.Text)
                        sendtext.WriteLine("Computer Model: " & Form1.txtModelShipped.Text)
                        If Form1.ComboBox1.SelectedItem <> "" Or Form1.ComboBox1.Text <> "" Then
                            Dim cbtext1 As String = Form1.ComboBox1.Text
                            sendtext.WriteLine("Booked in reason: " & cbtext1)
                        End If
                        If Form1.ComboBox2.SelectedItem <> "" Or Form1.ComboBox2.Text <> "" Then
                            Dim cbtext2 As String = Form1.ComboBox2.Text
                            sendtext.WriteLine("Booked out reason: " & cbtext2)
                        End If

                        If Form1.txtRetainReason.Text > "" Then
                            sendtext.WriteLine(Form1.lblRetainReason.Text & Form1.txtRetainReason.Text)
                        End If
                        If Form1.txtRetainName.Text > "" Then
                            sendtext.WriteLine(Form1.lblRetainName.Text & Form1.txtRetainName.Text)
                        End If
                        If Form1.txtOutName.Text > "" Then
                            sendtext.WriteLine(Form1.lblOutName.Text & Form1.txtOutName.Text)
                        End If
                        sendtext.WriteLine(analyst)
                        sendtext.Close()

                        Dim ack As New ack_timer()
                        ack.Owner = Form1
                        ack.Show()
                        Me.Close()
                    Else
                    End If

                End While
                _reader.Close()

            End Using
            '_stream.Close()
            'End Using
            If Counter < 1 Then
                Dim result = MessageBox.Show("Analyst badge number not found, do you want to add your details?", "Badge number not found", MessageBoxButtons.YesNo)
                If result = Windows.Forms.DialogResult.Yes Then

                    'reader.Close()
                    Dim scan As New Add_Badge
                    scan.ShowDialog()
                    Form1.SendToBack()
                    Me.Close()


                End If
            End If

Open in new window

Can anyone confirm this should be ok?
ASKER CERTIFIED SOLUTION
Avatar of Mr Knackered
Mr Knackered
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Cheers Mr Knackered!
Your most welcome :-)

Have a great day