PDA

View Full Version : caricare/modificare una riga precisa di un file in VB6


ErMeglio
30-10-2003, 23:34
Ciao, volevo chiedervi una mano per un probema col vb(6) che non ho saputo risolvere, premetto che di vb so molto poco, anche se qualche programmino sono riuscito a metterlo su, quindi per favore non siate tecnici perché credo che non capirei niente: gli esempi sono la cosa che mi spiega di più!
Comunque il problema è questo: in pratica voglio "aprire" un semplice file .ini col vb e caricare, controllare ed eventualmente modificare una sua riga precisa.
In particolare non sono riuscito a selezionare proprio una specifica riga, il resto credo di saperlo fare da solo.
Non ho idea di come fare, nonostante abbia provato vari modi seguendo la guida del vb o informazioni su internet. . .
Vi ringrazio in anticipo, spero che qualcuno sappia come fare dai ci conto tnx ;)

bsummer
31-10-2003, 13:15
L'esempio che segue può darti un'idea...il problema è che con il metodo descritto, un file di testo lo puoi o aprire in lettura o in scrittura ma non assieme quindi dovresti fare diverse modifiche.
Potresti perciò fare una cosa del tipo:
-rinomini il file che stai analizzando aggiungendo una estensione. es: da prova.ini -> prova.ini.bak
-crei un nuovo prova.ini nel quale vai a scrivere le righe non modificate dell'originale e quelle modificate in base ai tuoi criteri
-una volta salvato il nuovo file puoi cancellare quello di precendete


Esempio di lettura da file di testo e ricerca stringa...

Dim fs, a, retstring
Set fs = CreateObject("Scripting.FileSystemObject")
Set a = fs.OpenTextFile("c:\test.ini", ForReading, False)
Do While a.AtEndOfStream <> True
retstring = a.ReadLine
if instr(retstring,"quello che cerchi",vbTextCompare)<>0 then
' fai quello che devi
end if
Loop
a.Close


Aloha!

cisky
31-10-2003, 13:19
Oppure puoi fare una cosa di questo tipo senza creare l'oggetto Scripting..


' *** sFile = Nome del file (Completo di percorso)
' lRowNumber = Riga da leggere
'
Private Function f_GetFilesRowText(ByVal sFile As String, ByVal lRowNumber As Long) As String

Dim iFile As Integer
Dim bRowFound As Boolean
Dim lRowCounter As Long
Dim sRowText As String
Dim sRet As String

iFile = FreeFile()

Open sFile For Input As #iFile

Do While Not EOF(iFile) ' *** Scorro sequenzialmente il file.
Input #iFile, sRowText
lRowCounter = lRowCounter + 1 ' *** Incremento la posizione della riga corrente

bRowFound = (lRowCounter = lRowNumber) ' *** Se sono sulla riga desiderata
If bRowFound Then
sRet = sRowText
Exit Do
End If
Loop

Close #iFile

f_GetFilesRowText = sRet

End Function

ErMeglio
02-11-2003, 18:55
Grande cisky, funziona alla grande ;)
E se adesso volessi scriverla invece una determinata riga?
Grazie mille x ora:cool:

cisky
03-11-2003, 13:20
Devi utilizzare una funzione simile a quella che ho scritto ma devi aprire il file in scrittura

(es: Open sFile For Output As #iFile )

e devi utilizzare il metodo Write (es: Write #iFile, "prova").


NOTA: Se hai a che fare con dei file strutturati sempre in uno specifico modo puoi utilizzare le funzioni GET, PUT, SEEK per leggere.scrivere,posizionarsi su un file.

...Prova a dargli un'occhiata.
Se non riesci a creare la funzione x scrivere la singola riga chiedi pure.

ciao!

ErMeglio
03-11-2003, 18:36
Mmh... forse non mi sono spiegato su cosa voglio fare:
Sapevo come scrivere un valore in un file (ho fatto un programmino che legge un valore su una smart card attraverso il programmatore, salva il valore su un file, blocca completamente il pc e lo sblocca solo all'inserimento della stessa smart card).
Io volevo in particolare prendere sto file, fai conto un file con scritto
Ciao
sono
ErMeglio
e cambiare la riga 3 magari scrivendoci un altro nome.
Allora ho studiato a fondo la cosa e avevo fatto così (lasciando la tua funzione nel progetto):

Private Sub f_PutFilesRowText(sFile1 As String, lRowToChange As Long)

Dim iFile1 As Integer
Dim lRowNumber1 As Long
Dim CompleteToWrite As String
Dim a As String
Dim c As String
Dim d As String
Dim wait As Long

iFile1 = FreeFile()
lRowNumber1 = 0
c = "+ Chr(13) +"
Do While Not lRowNumber1 = lRowToChange - 1
a = f_GetFilesRowText("C:\prova.txt", lRowNumber1 + 1) + c
Loop
lRowNumber1 = lRowToChange
Do While Not lRowNumber1 = 7
d = f_GetFilesRowText("C:\prova.txt", lRowNumber1 + 1) + c
Loop
CompleteToWrite = a + RowToBeStored + d

Label2.Caption = CompleteToWrite
Open sFile1 For Output Access Write As #iFile1
Write #iFile1, CompleteToWrite
Close #iFile1

End Sub

Ciò viene richiamato da un timer:

Private Sub Timer1_Timer()
If StoredAtStart <> f_GetFilesRowText("C:\prova.txt", 3) Then GoTo 1 Else GoTo 2
2: If StoredAtStart <> RowToBeStored Then GoTo 1 Else GoTo 3
1: f_PutFilesRowText "C:\prova1.txt", 3
3: End Sub

RowToBeStored (e StoredAtStart) sono stringhe pubbliche e vengono dichiarate nel Form_Load.
StoredAtStart = f_GetFilesRowText("C:\prova.txt", 3)
RowToBeStored è la riga da scrivere.
Tutto ciò sembra aver senso e il vb nn corregge nulla, ma quando apro il programma si blocca sembra quando esegue la scrittura:muro:
Hai qualche idea?
(scusate il post lungo ma almeno mi sono spiegato x bene :D )
Tnx

ErMeglio
03-11-2003, 18:37
Ah Do While Not lRowNumber1 = 7, è 7 facendo conto che le righe del file siano 7.

cisky
04-11-2003, 19:26
Uhm, non ho capito bene come deve funzionare il programma che aggiunge la riga di "blocco" al file.
Deve controllare la presenza della riga di blocco all'avvio della form e se non c'è deve aggiungerla? o deve eseguire questo controllo sempre ogni N secondi obbligatoriamente?
All'uscita della form il blocco andrà rimosso?

... ??? ...

In ogni caso ho dato un'occhiata al tuo codice ed ho notato alcune cose che secondo mè si possono ottimizzare.
Oltre ai consigli ti invio anche il codice "rivisitato".La logica non l'ho capita bene, ma penso che ti potrò servire come spunto.
Se hai qualsiasi dubbio chiedi pure!

P.S: Ti scrivo questi consigli non per fare il "Guru" ma solo per darti delle "dritte".

1) sub f_PutFilesRowText In questa sub ho visto che effettui dei cicli per recuperare le righe precedenti e successive alla riga da scrivere (Utilizzando la funzione f_GetFilesRowText).In questo modo il file viene aperto e chiuso moltissime volte, e se il file è di grosse dimensioni si può impiegare molto tempo.Inoltre se si scatena l'evento del timer, la routine verrà rieseguita ma siccome il file è già aperto darà un errore!

2) La Sub Timer1_Timer() non è molto chiara perchè utilizzi dei goto.Ti converrebbe scriverla per passaggi
Cioè:

passo1:

Private Sub Timer1_Timer()
If StoredAtStart <> f_GetFilesRowText("C:\prova.txt", 3) Then
f_PutFilesRowText "C:\prova1.txt", 3
Else
If StoredAtStart <> RowToBeStored Then
f_PutFilesRowText "C:\prova1.txt", 3
Else
' ***
End If
End If
End Sub


Passo2 (Finale):
Private Sub Timer1_Timer()

Dim bPutFile As Boolean
Dim sRowFile As String

sRowFile = f_GetFilesRowText("C:\prova.txt", 3)
bPutFile = (StoredAtStart <> sRowFile) Or (StoredAtStart <> RowToBeStored)

If bPutFile Then f_PutFilesRowText "C:\prova1.txt", 3

End Sub

... Così non è più chiara?

Questo che segue è l'esempio di codice che ho riscritto.
Ricordati che io non ho capito bene la logica che vuoi utilizzare e non prende per "oro colato" quello che ho scritto (Anche perchè non l'ho provato!)


Option Explicit

Private Const FILE_NAME As String = "W:\Documenti\xxx.txt" ' *** x Prova

Private m_sRowToBeStored As String
Private m_sStoredAtStart As String
Private m_bWriteInProgress As Boolean

Private Sub Form_Load()

m_sStoredAtStart = f_GetFilesRowText(FILE_NAME, 3) ' *** Memorizzo il valore iniziale
m_sRowToBeStored = "ROW KEY CODE" ' *** x Prova

End Sub

Private Sub Timer1_Timer()

Dim bPutFile As Boolean
Dim sRowText As String

' *** (X SICUREZZA) Se questo evento viene scatenato quando sto già eseguendo il codice di scrittura non devo
' fare nulla perchè altrimenti si potrebbero verificare degli errori, in quanto il file risulterebbe già aperto.
'
If m_bWriteInProgress Then Exit Sub

sRowText = f_GetFilesRowText(FILE_NAME, 3) ' *** Leggo la riga del file

' *** Controllo se la riga è diversa dalla riga di "blocco" da aggiungere
'
bPutFile = (sRowText <> m_sRowToBeStored)

If bPutFile Then
' *** Aggiungo la riga di blocco
'
s_PutFilesRowText FILE_NAME, 3, m_sRowToBeStored
End If

Timer1.Enabled = Not bPutFile ' *** Se ho scritto la chiave diabilito il Timer

End Sub

Private Function f_GetFilesRowText(ByVal sFile As String, ByVal lRowNumber As Long) As String

Dim iFile As Integer
Dim bRowFound As Boolean
Dim lRowCounter As Long
Dim sRowText As String
Dim sRet As String

iFile = FreeFile()

Open sFile For Input As #iFile

Do While Not EOF(iFile) ' *** Scorro sequenzialmente il file.
Input #iFile, sRowText
lRowCounter = lRowCounter + 1 ' *** Incremento la posizione della riga corrente

bRowFound = (lRowCounter = lRowNumber) ' *** Se sono sulla riga desiderata
If bRowFound Then
sRet = sRowText
Exit Do
End If
Loop

Close #iFile

f_GetFilesRowText = sRet

End Function

Private Sub s_PutFilesRowText(ByVal sFile As String, ByVal lRowToChange As Long, ByVal sRowToWrite As String)

Dim iFile As Integer
Dim sRowText As String
Dim lRowCounter As Long
Dim sCompleteToWrite As String
Dim bVaiACapo As Boolean

On Error GoTo lError ' *** Gestione di eventuali errori

m_bWriteInProgress = True ' *** Imposto il flag che indica che stò scrivendo sul file

iFile = FreeFile()
Open sFile For Input As #iFile

Do While Not EOF(iFile) ' *** Scorro sequenzialmente il file.

Input #iFile, sRowText ' *** Memorizzo nella variabile sRowText la riga del File

bVaiACapo = (lRowCounter > 0) ' *** Flag che indica se andare a capo
lRowCounter = lRowCounter + 1 ' *** Incremento la posizione della riga corrente

' *** A questo punto devo comporre il testo da scrivere nel file (sCompleteToWrite).
' Per fare ciò, controllo se devo inserire la riga da scrivere, altrimenti compongo il testo
' aggiungendo la riga letta di volta in volta. (se non è laprima riga, devo andare a capo.)
'
If lRowCounter = lRowToChange Then
' *** Aggiungo riga da scrivere
'
sCompleteToWrite = f_AppendTextToString(sCompleteToWrite, sRowToWrite, bVaiACapo)
Else
' *** Aggiungo la riga letta dal file (Input #iFile,sRowText)
'
sCompleteToWrite = f_AppendTextToString(sCompleteToWrite, sRowText, bVaiACapo)
End If

Loop ' *** Ciclo tutto il File

Close #iFile

'Label2.Caption = CompleteToWrite

iFile = FreeFile()
Open sFile For Output Access Write As #iFile

' *** Non uso il comando WRITE perchè aggiunge le " all'inizo e alla fine del testo da scrivare!!!!
'
Print #iFile, sCompleteToWrite
'Write #iFile, sCompleteToWrite

Close #iFile

lExit:
m_bWriteInProgress = False
Exit Sub

lError:
' *** Devo intercettare l'errore per deimpostare il flag di scrittura in corso!
Resume lExit

End Sub

' *** Aggiunge del testo ad una stringa (Se specificato bACapo, aggiunge anche un ritorno a capo)
'
Private Function f_AppendTextToString(ByVal sInitString As String, ByVal sTextToAdd As String, ByVal bACapo As Boolean) As String

If bACapo Then sInitString = sInitString & vbCrLf
sInitString = sInitString & sTextToAdd

f_AppendTextToString = sInitString

End Function


Ciao!;)

a2000
04-11-2003, 19:28
mah .... :confused:

Jamester
11-06-2013, 17:01
E' + o - lo stesso problema che ho io ma visto che non ci ho capito molto, vorrei gentilmente che mi fosse spiegato nel mio caso come fare sapendo che:

C'e' un determinato file chiamato per esempio database.db dove al suo interno ci sono dei dati. Ciascun dato è formato da 5 righe. Ora il problema è che vorrei sovrascrivere questo file ma andando a sostituire solo la quinta riga e lasciando invariate le altre 4 righe precedenti. Usando la funzione replace al 5° rigo riesco a sovrascrivere l'ultimo record come voglio pero' vorrei sapere appunto come sovrascrivere lo stesso file ma lasciando invariate le altre 4 righe. Questa operazione verrà fatta ogni 10 righe in pratica fino alla fine del file. Grazie mille anticipate a chi mi sapra' aiutare!