Italian Scrivere in un file .txt

Luigi S

Active Member
Licensed User
Espongo il mio quesito, e allego innanzitutto il codice funzionante che sto usando scopiazzato come al solito qua e la, e adattato alle mie esigenze (è cosi che si comincia no? :rolleyes:).

B4X:
Sub RegisterDataPlane
   
    Dim ListTemp As List
   
    'controllo se esiste il file di testo
    If File.Exists(File.DirRootExternal, "RCHangar/ListModel.txt") Then
       
        'se il file esiste carico i dati dal file di testo
        ListTemp =File.ReadList(File.DirRootExternal, "RCHangar/ListModel.txt")
       
        Dim Trovato As Boolean
        Trovato = False
       
        For i = 0 To 99
           
            ListModel(i) = ListTemp.Get(i)
           
            If ListModel(i) = "0" And Trovato = False Then
                'Riempio lo slot con i valori da registrare
                ListModel(i) = ModelName.Text &"|"& Component1.text &"|"& Component2.text &"|"& Component3.text &"|"& Component4.text &"|"& Component5.text &"|"& Component6.text
                'imposto la boolean a true
                Trovato = True
            End If
           
        Next
       
       
        File.Writelist(File.DirRootExternal, "RCHangar/ListModel.txt", ListModel)   'Salvo l'array nel file di testo
       
        StartActivity(Main)
       
    Else ' se il file non esiste
           
        For i = 0 To 99
            ListModel(i) = "0"
               
        Next
           
        ListModel(0) = ModelName.Text &"|"& Component1.text &"|"& Component2.text &"|"& Component3.text &"|"& Component4.text &"|"& Component5.text &"|"& Component6.text
           
        File.MakeDir(File.DirRootExternal, "RCHangar")  'creo la directory
   
        File.Writelist(File.DirRootExternal, "RCHangar/ListModel.txt", ListModel)   'Salvo l'array nel file di testo
        StartActivity(Main)
    End If
End Sub

Il problema è che con esso anche se non scrivo nulla nei vari campi, mi inserisce una riga di 6 "|" nel file txt che rimane difficile da interpretare e comunque inutile soprattutto se manca anche primo campo ModelName.
Dovrei fare in modo di verificare se il campo ModelName è stato riempito, altrimenti impedirne la scrittura nel txt e poi non creare gli altri campi o forse meglio scrivere per esempio "null" negli altri campi, in modo da non incorrere in problemi in fase di lettura o modifica (in lettura potrei non far mostrare i campi null)
Cosa mi consigliate, e soprattutto esiste un'alternativa al creare una if per ogni campo?
 

udg

Expert
Licensed User
Longtime User
Ciao,
non vedo perchè tu non possa eseguire un check su ModelName prima di (eventualmente) salvare. Non mi è chiaro però, nella sezione relativa al file non ancora esistente, perchè riempi ListModel(0) con valori che potrebbero ancora essere nulli. Vuoi che il file testo contenga sempre e comunque una prima riga?
Ovviamente nulla ti impedisce di effettuare un check sui valori presenti nella maschera di input; dal più semplice (se sono tutti vuoti) al più complesso (il check ritorna True solo per alcune combinazioni valide di valori). Basta scrivere una breve sub che effettui i test e ritorni un valore boolean in base al quale decidi se inserire o meno la riga nel file testo.
 

sirjo66

Well-Known Member
Licensed User
Longtime User
... mi inserisce una riga di 6 "|" nel file txt che rimane difficile da interpretare e comunque inutile ...

Perchè "difficile da interpretare" ??
Se inserisce i 6 "|" vuol dire che i campi sono vuoti, e quando li rileggi te li ritrovi vuoti, non capisco dove può essere il problema.
Quando rileggi il tutto sicuramente farai uno "split" della stringa, per cui ti ritrovi i campi originali
 

Luigi S

Active Member
Licensed User
Ciao e grazie ad entrambi per le risposte, ma devo ricordarvi che per me niubbo, è ancora piùttosto difficile scrivere del codice, riesco appena a decifrare quello scritto da altri ed adattarlo alle mie esigenze.... Sono solo pochi giorni che ho in mano questa "bestia" :)

Perciò vi sarei molto grato se insieme al consiglio, mi imbeccaste con qualche righetta di codice ;)
 

Sagenut

Expert
Licensed User
Longtime User
Per poterti aiutare anche con del codice abbiamo bisogno di capire la logica di cosa vuoi fare.
Lavori su due liste identiche.
Quando la app parte per la prima volta il file sarà già presente o verrà per forza creato pieno di "0" alla prima esecuzione?
Perchè, se presente, la lista viene caricata in ListTemp e poi ricopiata in ListModel?
La tua routine
B4X:
Dim Trovato As Boolean
        Trovato = False
     
        For i = 0 To 99
         
            ListModel(i) = ListTemp.Get(i)
         
            If ListModel(i) = "0" And Trovato = False Then
                'Riempio lo slot con i valori da registrare
                ListModel(i) = ModelName.Text &"|"& Component1.text &"|"& Component2.text &"|"& Component3.text &"|"& Component4.text &"|"& Component5.text &"|"& Component6.text
                'imposto la boolean a true
                Trovato = True
            End If
         
        Next
riempirà solo la prima riga che contiene uno "0" di ListModel con il contenuto da te scritto perchè Trovato poi passerà a True e non cambierà più.
Tutte le altre righe verranno lasciate invariate.
E' questo che volevi?
Facci un esempio di cosa dovrebbe contenere una lista corretta e da dove arrivano i dati che vuoi inserire.
 

Luigi S

Active Member
Licensed User
La logica è questa:
se il file non esiste viene con uno "0" su ogni riga e la riga col primo "0" viene riempita
se il file esiste la riga viene inserita nella prima riga avente lo "0"
Naturalmente avendo creato un file con 100 "0" potro inserire solo 100 righe, ma ampiamente sufficienti per le mie esigenze.

Altre idee?
 
Last edited:

Sagenut

Expert
Licensed User
Longtime User
Dammi un attimo e cerco di proporti qualcosa.
 

Sagenut

Expert
Licensed User
Longtime User
Sperando di non crearti confusione (e di non aver fatto errori) prova così:
B4X:
Sub RegisterDataPlane
       'controllo se esiste il file di testo
    If File.Exists(File.DirRootExternal, "RCHangar/ListModel.txt") Then
        'se il file esiste carico i dati dal file di testo
        ListModel = File.ReadList(File.DirRootExternal, "RCHangar/ListModel.txt")
     
           Dim Trovato As Boolean = False
     
        For i = 0 To 99
               If ListModel(i) = "0"  And Trovato = False Then
                'Riempio lo slot con i valori da registrare
                ListModel.set(i,ModelName.Text &"|"& Component1.text &"|"& Component2.text &"|"& Component3.text &"|"& Component4.text &"|"& Component5.text &"|"& Component6.text)
                'imposto la boolean a true
                Trovato = True
            End If
            'Se la riga è stata aggiunta termina il ciclo anticipatamente perchè non farebbe più nulla
            If Trovato = True Then Exit
        Next
   
        File.Writelist(File.DirRootExternal, "RCHangar/ListModel.txt", ListModel)   'Salvo l'array nel file di testo
   
        StartActivity(Main)
   
    Else ' se il file non esiste
        ListModel.Initialize 'Senza il File.Readlist la lista và Inizializzata
        For i = 0 To 99
            ListModel.Add("0") 'Aggiunge ogni nuovo elemento alla lista che inizialmente è come inesistente
        Next
        'sostituisce il primo elemento con i primi dati
        ListModel.set(0,ModelName.Text &"|"& Component1.text &"|"& Component2.text &"|"& Component3.text &"|"& Component4.text &"|"& Component5.text &"|"& Component6.text)

        File.MakeDir(File.DirRootExternal, "RCHangar")  'creo la directory
        File.Writelist(File.DirRootExternal, "RCHangar/ListModel.txt", ListModel)   'Salvo l'array nel file di testo
        StartActivity(Main)
    End If
End Sub
Ho cercato di farti lavorare con solo una lista.
Controlla se funziona e, sperando che vada tutto bene, chiedi pure cosa non ti è chiaro nel caso.
Il codice si potrebbe pulire ancora però non volevo stravolgere il tuo operato.
Ho ipotizzato che ListModel sia creata prima di chiamare questa routine.
Termina il tuo progetto con calma.
Poi potresti fare modifiche in modo da poter usare liste di lunghezza infinita senza limitarti in anticipo a X elementi.
 
Last edited:

Luigi S

Active Member
Licensed User
Ho sostituito la sub, e ottengo 4 errori Solo La 'Lenght' è supportata dagli array in queste righe


B4X:
        ListModel.set(0,ModelName.Text &"|"& Component1.text &"|"& Component2.text &"|"& Component3.text &"|"& Component4.text &"|"& Component5.text &"|"& Component6.text)
B4X:
            ListModel.Add("0") 'Aggiunge ogni nuovo elemento alla lista che inizialmente è come inesistente
B4X:
        ListModel.Initialize 'Senza il File.Readlist la lista và Inizializzata
B4X:
                ListModel.set(i,ModelName.Text &"|"& Component1.text &"|"& Component2.text &"|"& Component3.text &"|"& Component4.text &"|"& Component5.text &"|"& Component6.text)

che vuol dire?
 

Sagenut

Expert
Licensed User
Longtime User
La ListModel è stata dichiarata in Globals o Process_Globals?
B4X:
dim ListModel as List
 
Last edited:

Sagenut

Expert
Licensed User
Longtime User
Un errore sicuro è
B4X:
If ListModel(i) = "0"  And Trovato = False Then
che invece deve diventare
B4X:
If ListModel.Get(i) = "0"  And Trovato = False Then
 

Sagenut

Expert
Licensed User
Longtime User
Per impedire di scrivere nel file se ModelName è vuoto credo che ti convenga fare il controllo prima di chiamare la tua Sub.
B4X:
if ModelName.Text <> "" then
     RegisterDataPlane
else
     Msgbox ("Il Nome del Modello è Obbligatorio!", "ATTENZIONE")
end if
Questo è un esempio.
Poi prova ad adattarlo con i controlli che ritieni necessari sulle varie stringhe.
Era questo il tuo altro dubbio, no?
O mi sono perso qualcosa?
Senza sapere come è strutturato il resto del codice posso solo provare ad immaginare.
Quindi il codice che ti propongo potrebbe non andare bene così come te lo posto.
 
Last edited:

Sagenut

Expert
Licensed User
Longtime User
era dichiarato ma cosi

B4X:
Dim ListModel(100) As String

e aggiungendo il Get gli errori sono scomparsi.

Rimane il fatto che funziona come funzionava prima. Forse cosi è più corretto?
L'importante è che funzioni. Quindi anche il tuo andava bene se faceva quello che ti serviva.
Quello che ti ho postato io può essere Relativamente più corretto in quanto utilizza meno variabili e quindi ottimizza qualcosa.
Ed è ancora migliorabile, ma questo ti verrà con il tempo e l'esperienza.
Il vero problema è che noi possiamo lavorare solo con quello che tu ci passi.
Io ho inteso che ci fossero 2 liste e pensavo di vedere degli errori di sintassi.
Invece erano una lista e un Array.....ma questo lo sò solo ora. ;)
 

Luigi S

Active Member
Licensed User
Se per voi non è un problema e non lo è per gli amministratori del forum, posso passarvi in un file zip il mio intero progetto cosi potremmo andare avanti insieme, vorra dire che in futuro faremo una SpA e divideremo gli utili della App. :):D

Basta che mi ci fate capire qualcosa però....
 

Sagenut

Expert
Licensed User
Longtime User
Così temo che finiamo per farti l'app noi. :D
Piuttosto dimmi se qualcosa di quello che ti ho postato non ti è chiaro così ne parliamo.
Hai la voglia e l'impegno per farcela.
Prova a semplificare le tue idee per ora.
Fai che l'app funzioni e portala a termine anche se bruttina da vedere.
Una volta che sarà funzionante avrai tutto il tempo di abbellirla e raffinarla a mano a mano che imparerai nuove cose.
 

Luigi S

Active Member
Licensed User
Concordo, e per quando riguarda gli abbellimenti mi interessano poco, cerco la praticità e l'essenzialità. App del genere ne esistono (RC Flight and Battery Log), ma oltre il 50 % delle funzioni che hanno riusultano inutili e dispersive per i miei gusti/necessità.
Mettetici poi la mia passione per l'informatica, oltre al modellismo dinamico, ecco che m'è venuta voglia di farmela.
La tua soluzione col message box, può andare ben per me, anzi in realta vabene anche senza, perche io lo so che devo riempire tutti i campi(che saranno molti di più degli attuali 6), ma poi sono sicuro che più di qualche amico del campovolo la vorrà, e se gli crasha dopo che per sbaglio ha cliccato su addModel creando una riga vuota, sicuro mi telefona per insultarmi! :D

Devo fare un controllo al momento dell'invio e se manca il NameModel non deve eseguirlo, mentre per gli altri campi se sono vuoti ci scrivo un bel "Void" cosi quando leggo non crasha, questo per me è il primo passo.
 

Sagenut

Expert
Licensed User
Longtime User
Ma perchè dovrebbe crashare per i campi vuoti?
Semplicemente leggerai i campi vuoti.
Se comunque preferisci sostituire i campi vuoti con una scritta differente lo puoi fare.
Dato che hai già diversi campi su cui devi effettuare delle operazioni ricorsive forse dovresti pensare ad un Array di Edittext in modo da poter effettuare controlli o altro con dei cicli For Next.
Altrimenti dovrai sempre aggiungere tutto manualmente nome per nome delle Edittext e la cosa diventerà presto pesante, visto che hai detto che i campi aumenteranno.
Come ti ho già suggerito inizia a fare piccoli esperimenti isolati in progetti singoli in modo da non perderti nel caos di una applicazione completa.
A mano a mano che avrai imparato ad utilizzare nuove funzioni allora penserai ad integrarle nell'app completa.
Tanto dovrai studiare la XCustomListView per ottenere una fila di Edittext (o qualunque altra cosa) che possa essere scrollabile, o usare la soluzione che @udg ti ha indicato nell'altra discussione.
 
Last edited:
Top