Android Question Find a line in txt and update it

Mattiaf

Active Member
Licensed User
HI, I already searched on the forum for an answer and it could be this one, but to be honest, I don't know how to implement it on my case...
I'm having around 100 lines on my txt and I'm filtering each of these through a search on edittext6.
Edittext 5 shows all the results with what is being searched on edit6.

Since
B4X:
For Each line As String In File.ReadList(...)
would make the process heavier, I'm creating a List variable and connecting it to the txt file at the b4x page creating.
So I'm having this code
B4X:
On class global
Dim chiavi As List
on B4XPage_Created
    chiavi= File.Readlist(File.DirInternal,"chiavi.txt")

Private Sub EditText6_TextChanged (Old As String, New As String)
  
    EditText5.Text = ""

    For Each line As String In chiavi
        If line.trim.ToUpperCase.Contains(EditText6.Text.trim.ToUpperCase) Or line.trim.ToUpperCase.startswith(EditText6.Text.trim.ToUpperCase) Then
          
            EditText5.Text= EditText5.Text & CRLF & CRLF & line
        End If
    Next
    If EditText6.Text="".Trim Then
        EditText5.Text="".Trim   
  
    End If
End Sub

After I'll filter the results, I will now have only 1 result in edit 5, and i'm going to modify that string by myself by hand ( so not by code..)
So now I have to save all the things
I thought about

B4X:
File.WriteString(File.DirInternal, "chiavi.txt",  edittext5)
, but it wouldn't make sense since in edit6 there aren't all the txt lines but only the result after the search...
Any idea? Much thanks
 
Last edited:
Solution
I assume that you want to edit a text file and that you want to narrow down the relevant lines that need revision.
After you find them, you edit them and replace the lines in the original.

I may be wrong but if that is the case, here is a B4X approach.

B4X:
Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
    Private Button1 As Button
#if B4J
    Private TextArea1 As TextArea
    Private TextField1 As TextField
#Else If B4A
    Private TextArea1 As EditText
    Private TextField1 As EditText
#End IF
    Private RabbitStory As List
    Private FoundIndices As List
End Sub

Public Sub Initialize
End Sub

Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
#if B4J...

endbyte

Member
B4X:
Private Sub EditText6_TextChanged (Old As String, New As String)
    EditText5.Text = ""
    For Each line As String In chiavi
        If line.trim.ToUpperCase.Contains(EditText6.Text.trim.ToUpperCase) Or line.trim.ToUpperCase.startswith(EditText6.Text.trim.ToUpperCase) Then
           
            '****here you get the index of the line to modify
            dim ide as string = chiavi.indexof(line)
           
           
            EditText5.Text= EditText5.Text & CRLF & CRLF & line
           
            '****here you replace in your list exactly the line you modify and that's it
            '****then you just have to write the list to txt
            chiavi.set(ide,edittext5.text)
            '
           
        End If
       
    Next
    If EditText6.Text="".Trim Then
        EditText5.Text="".Trim  
    End If
End Sub
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
B4X:
Private Sub EditText6_TextChanged (Old As String, New As String)
    If New.Length = 0 Then Return

    EditText5.Text = ""

    For Each line As String In chiavi
        If line.trim.ToUpperCase.Contains(EditText6.Text.trim.ToUpperCase) Or line.trim.ToUpperCase.startswith(EditText6.Text.trim.ToUpperCase) Then
            EditText5.Text= EditText5.Text & line & CRLF
        End If
    Next

    File.WriteString(File.DirInternal, "chiavi.txt",  edittext5.Text)
End Sub
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
I assume that you want to edit a text file and that you want to narrow down the relevant lines that need revision.
After you find them, you edit them and replace the lines in the original.

I may be wrong but if that is the case, here is a B4X approach.

B4X:
Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
    Private Button1 As Button
#if B4J
    Private TextArea1 As TextArea
    Private TextField1 As TextField
#Else If B4A
    Private TextArea1 As EditText
    Private TextField1 As EditText
#End IF
    Private RabbitStory As List
    Private FoundIndices As List
End Sub

Public Sub Initialize
End Sub

Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
#if B4J
    RabbitStory = File.ReadList(File.DirApp, "RabbitStory.txt")
#else If B4A
    RabbitStory = File.ReadList(File.DirInternal, "RabbitStory.txt")
#End If
    TextField1.RequestFocus
End Sub

Private Sub searchFor(item As String) As List
    item = item.ToLowerCase.trim
    Dim result As List
    result.Initialize
    For i = 0 To RabbitStory.Size - 1
        Dim line As String = RabbitStory.Get(i)
        If line.ToLowerCase.Contains(item) Then result.Add(i)
    Next
    Return result
End Sub

Private Sub TextField1_TextChanged (Old As String, New As String)
    If New.Trim.length > 2 Then                        'small terms will select all items in source, so ignore
        FoundIndices = searchFor(New)
        If FoundIndices.Size > 0 Then
            Dim sb As StringBuilder
            sb.Initialize
            For Each index As Int In FoundIndices
                sb.Append(RabbitStory.Get(index)).Append(CRLF).Append(CRLF)
            Next
            sb.Remove(sb.Length -1, sb.Length)
            TextArea1.Text = sb.toString
        End If
    End If
End Sub

Private Sub Button1_Click
    Dim lines As List = Regex.Split(CRLF, TextArea1.Text)
    For i = 0 To lines.Size - 1 Step 2
        Dim index As Int = FoundIndices.Get(i / 2)
        RabbitStory.Set(index, lines.Get(i))
    Next
    TextField1.Text = ""
    TextArea1.Text = ""
    TextField1.RequestFocus
   
#if B4J
    File.WriteList(File.DirApp, "RabbitStory.txt", RabbitStory)
#else If B4A
    File.WriteList(File.DirInternal, "RabbitStory.txt", RabbitStory)
#End If

End Sub
 

Attachments

  • Project.zip
    19.4 KB · Views: 58
Upvote 0
Solution

Mattiaf

Active Member
Licensed User
That's some serious coding-under-pressure. ļæ¼



But I like that you've picked up on that string methods can be used on string literals. ļæ¼

lol i m a real noob.

i meant

If i delete the qwery then delete the results..
 
Upvote 0

emexes

Expert
Licensed User
To test for empty(ish) strings, I often use .Trim.Length = 0 eg:

B4X:
If EditText6.Text.Trim.Length = 0 Then
    EditText5.Text = ""    'empty string "" doesn't need .Trim
End If
 
Upvote 0

Mattiaf

Active Member
Licensed User
B4X:
Private Sub EditText6_TextChanged (Old As String, New As String)
    If New.Length = 0 Then Return

    EditText5.Text = ""

    For Each line As String In chiavi
        If line.trim.ToUpperCase.Contains(EditText6.Text.trim.ToUpperCase) Or line.trim.ToUpperCase.startswith(EditText6.Text.trim.ToUpperCase) Then
            EditText5.Text= EditText5.Text & line & CRLF
        End If
    Next

    File.WriteString(File.DirInternal, "chiavi.txt",  edittext5.Text)
End Sub
I might be wrong ( hopefully) but this solution wouldn't work because If I have a txt of 100 lines and when I search on edit6 it will narrow down to a 1 only result, so if I save the file with File.WriteString(File.DirInternal, "chiavi.txt", edittext5.Text) it will write the only line on edit 5 on chiavi.txt..
 
Upvote 0

Mattiaf

Active Member
Licensed User
B4X:
Private Sub EditText6_TextChanged (Old As String, New As String)
    EditText5.Text = ""
    For Each line As String In chiavi
        If line.trim.ToUpperCase.Contains(EditText6.Text.trim.ToUpperCase) Or line.trim.ToUpperCase.startswith(EditText6.Text.trim.ToUpperCase) Then
          
            '****here you get the index of the line to modify
            dim ide as string = chiavi.indexof(line)
          
          
            EditText5.Text= EditText5.Text & CRLF & CRLF & line
          
            '****here you replace in your list exactly the line you modify and that's it
            '****then you just have to write the list to txt
            chiavi.set(ide,edittext5.text)
            '
          
        End If
      
    Next
    If EditText6.Text="".Trim Then
        EditText5.Text="".Trim 
    End If
End Sub
What do you mean with " just have to write the list to txt"?
I need to save file through a button.
If I use
B4X:
File.writeList(File.DirInternal, "chiavi.txt",chiavi)
inside of a button, it doesn't save anything....
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
As shown in #4, you need to index the lines so that when you are finished editing the line of interest, you can replace it in the original text.
 
Upvote 0

Mattiaf

Active Member
Licensed User
I assume that you want to edit a text file and that you want to narrow down the relevant lines that need revision.
After you find them, you edit them and replace the lines in the original.

I may be wrong but if that is the case, here is a B4X approach.

B4X:
Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
    Private Button1 As Button
#if B4J
    Private TextArea1 As TextArea
    Private TextField1 As TextField
#Else If B4A
    Private TextArea1 As EditText
    Private TextField1 As EditText
#End IF
    Private RabbitStory As List
    Private FoundIndices As List
End Sub

Public Sub Initialize
End Sub

Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
#if B4J
    RabbitStory = File.ReadList(File.DirApp, "RabbitStory.txt")
#else If B4A
    RabbitStory = File.ReadList(File.DirInternal, "RabbitStory.txt")
#End If
    TextField1.RequestFocus
End Sub

Private Sub searchFor(item As String) As List
    item = item.ToLowerCase.trim
    Dim result As List
    result.Initialize
    For i = 0 To RabbitStory.Size - 1
        Dim line As String = RabbitStory.Get(i)
        If line.ToLowerCase.Contains(item) Then result.Add(i)
    Next
    Return result
End Sub

Private Sub TextField1_TextChanged (Old As String, New As String)
    If New.Trim.length > 2 Then                        'small terms will select all items in source, so ignore
        FoundIndices = searchFor(New)
        If FoundIndices.Size > 0 Then
            Dim sb As StringBuilder
            sb.Initialize
            For Each index As Int In FoundIndices
                sb.Append(RabbitStory.Get(index)).Append(CRLF).Append(CRLF)
            Next
            sb.Remove(sb.Length -1, sb.Length)
            TextArea1.Text = sb.toString
        End If
    End If
End Sub

Private Sub Button1_Click
    Dim lines As List = Regex.Split(CRLF, TextArea1.Text)
    For i = 0 To lines.Size - 1 Step 2
        Dim index As Int = FoundIndices.Get(i / 2)
        RabbitStory.Set(index, lines.Get(i))
    Next
    TextField1.Text = ""
    TextArea1.Text = ""
    TextField1.RequestFocus
 
#if B4J
    File.WriteList(File.DirApp, "RabbitStory.txt", RabbitStory)
#else If B4A
    File.WriteList(File.DirInternal, "RabbitStory.txt", RabbitStory)
#End If

End Sub
hmm it doesn't seems to save it....
look video recorder

Edit!!!! I forgot a rabbit around! Your code works as a charm! Thankssssss
 
Upvote 0

endbyte

Member
What do you mean with " just have to write the list to txt"?
I need to save file through a button.
If I use
B4X:
File.writeList(File.DirInternal, "chiavi.txt",chiavi)
inside of a button, it doesn't save anything....
doesn't understand what you want because in your original question you never mentioned that you wanted to save something inside a button, but still if you need to save some reference inside the button view you can do it in its tag, but be careful I'm not saying a file inside the tag because I think that concept doesn't even exist, maybe you wanted to say the name of the file inside the button, good luck
 
Upvote 0

Mattiaf

Active Member
Licensed User
Can I just ask you one thing?

With my code
B4X:
 EditText5.Text = ""

    For Each line As String In chiavi
        If line.trim.ToUpperCase.Contains(EditText6.Text.trim.ToUpperCase) Or line.trim.ToUpperCase.startswith(EditText6.Text.trim.ToUpperCase) Then
          
            EditText5.Text= EditText5.Text & CRLF & CRLF & line
        End If
    Next
    If EditText6.Text="".Trim Then
        EditText5.Text="".Trim   
 
    End If

if I write a qwery that might find a result and I add other random letters,all the results disappear, like they are supposed to..
With you code instead, If I write for example "ciao" it will find anyway a result and even if i add random letters, all the previous results stay.. It might be because there are results for "ci" [If New.Trim.length > 2 Then], but after that adding "ao" there shouldn't be any result... Do you think it's possible to modify a little your code to have such a solution? Thanks
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
I would encourage you to try various things yourself. That is the best way to learn. The gained knowledge is persistent.
All you have to do add a line when there are no found items.

B4X:
        If FoundIndices.Size > 0 Then
            Dim sb As StringBuilder
            sb.Initialize
            For Each index As Int In FoundIndices
                sb.Append(RabbitStory.Get(index)).Append(CRLF).Append(CRLF)
            Next
            sb.Remove(sb.Length -1, sb.Length)
            TextArea1.Text = sb.toString
        Else
            TextArea1.Text = ""            'Add this
        End If
 
Upvote 0
Top