Newsgroup: it.comp.lang.visual-basic
Titolo: [2]conversione file da txt a mdb

Ho due file in formato testo che devo leggere e poi importare in un 
database, il problema è che i files non sono molto strutturati, mi date 
qualche consiglio su come secondo voi è meglio procedere !!!
Esempio anagrafica:
"50001"<0A>"ROSSI PIERO" 012345678901 "VIA XX SETTMBRE 55" "ROMA" "RM" 
no "" ""<0A>"" 17 3 2 .......
Esempio Fatture:
890<0A>50001 30/04/02 89,83 "" 17,97 0 0 107,8 5,16 0 0 30/04/02 "" "" 
"1" <0A>891<0A>50002 30/04/02 99,55 "" 17.50 0 0........
<0A> corrisponde al chr(10) line feed.
Qualsiasi consiglio è ben accetto.
Ciao e grazie  !!!

 Ciao e grazie  !!!
A) Sparati...
B) Attaccati al tubo del gas
C) ....ancora vivo?
allora ti propongo (anche come esercizio di programmazione) una procedura
tutta manuale...
ok allora secondo me potresti far cosě
avevo un problema analogo con  una query uscita fuori da un mainframe di una
industria....nel mio caso era forse un po piů semplice ma visto che sei
parco di info potrebbe essere anche il tuo...
Nel mio caso (e spero nel tuo)
Avevo il tracciato record originario e quindi sapevo che "CAMILLINO       "
era un Char lungo 22 e che il file di testo riempiva di spazi che "12,250"
era un Float con 3 cifre decimali e cosě via "
quando hai ben chiara la struttura record ...ricrea un VB una struttura o
una matrice del record da "digerire" (io preferisco una matrice...tutta di
string visto che leggi testo..le conversioni si fanno quando scrivi nel
db...sempre che non abbia campi memo o blob...ma facciamola semplice eh!)
quindi ad esempio
DIM recordDadigerire(10) as string
al limite anche
DIM NomeCampodaDigerire(10) as string
nel tuo caso verrŕ poi caricato con:
campoDAdigerire(0)="890"
NomeCampodaDigerire(0)="CodiceScheda"
ok allora leggere il record nel file di testo....se finisse con un ritorno a
capo e sei sicuro che ogni riga un record basterebbe una INPUT LINE...ma
siccome son convinto che era come il mio file ossia:
AB001
RONDELLE        12,500   400
AB002
TUBI ZINCO      52,520   300
....etc etc...
mi sa che non va
io credo che il file sia sempre con le righe lunghe uguali (fa un fill di
spazi se vuoto)
devi calcolare quanto č lungo un record (anche su piů righe)...la cosa
meglio č procedere a tentativi!
a questo punto prova sto codice (metti in una form una textbox ed un
pulsante...l'esempio legge sempre il primo record e lo fa lungo 10
caratteri!
Option Explicit
Private Sub cmdLeggi_Click()
Dim t As Integer
Dim BufferLetto As String * 10
t = FreeFile
Open (App.Path & "\test.txt") For Random As t Len = 10
Get t, 1, BufferLetto
Me.Text1.Text = BufferLetto
End Sub
Devi notare e stare attento a 2 cose
1) La VAR BUFFERLETTO deve essere grande ESATTAMENTE quanto il record che
leggi
2) In buffer letto ho tutto il record con operazioni di MID "taglio" la
parte che mi interessa e la piazzo nella matrice alla posizione giusta
caso mai facendo conversioni
da qui con un semplice
(se operi in ado...in dao non ricordo...uguale vero?al limite
rs.field(nomecampo) vero? )
rs(NomeCampodaDigerire(indice))=campoDaDigerire(indice)...lo trasferisci nel
tuo MDB se č testo da trasferire ...se č altro devi fare
rs(NomeCampodaDigerire(indice))=Clng(campoDaDigerire(indice))..se č un long
....e via andare....
 (se non ti incasini puoi anche fare tutto in un unica operazione...basta
fare attenzione e fai anche a meno delle matrici...ma cosě č piů
manutenibile!...metti che ti cambino il tracciato record!)
alla fine con un po di fatica hai fatto tutto da solo....
a me č toccato far cosě perche l'OLEDB solo testo non funzionava sul formato
testo che sparava fuori il mainframe (un "vecchio" IBM..)
Maggiori info sempre premendo F1 nella tua guida!

"Wodka4U"
Integrazione:
Siccome a me cambiavano spesso il tracciato record...l'app era in versione
non definitiva...per rendere il tutto ancora più versatile...
avevo aggiunto una serie di matrici
LenCampo(NumCampo) come long
Tipocampo(tipo) come string
e avevo S= single L=Long etc etc....
della serie...l'idea è quella...complicala come vuoi...ci potresti fare una
classe chiamata ImportaTXT ad esempio!

 Ciao e grazie  !!!
1. capire la struttura del record: numero e tipo dei campi. qui su ne vedo
alcuni alfanumerici, altri interi, altri con virgola.
2. preparare due strutture di tabelle sugli schemi ricavati. io d'abitudine
i numerici non frazionari li metto tutti a long e i txt tutti a 255, ma non
e' molto corretto, e se il db cresce molto ti puo' impallare il disco. al
tempo stesso se metti nome=txt(20) e poi ti trovi uno che si chiama come
l'antispam di wodka4u (una bella sfiga :), il tuo prog crolla. in casi
d'emergenza dopo l'importazione mi sono andato a leggere quanto occupava il
nome piu' lungo e ho ristrutturato il db di conseguenza, compattandolo. idem
per i long: su 4 mln di righe, dieci campi a byte o a long influiscono.
d'altra parte un controllo simile sui txt, preliminare, lo puoi fare solo a
occhio...
3. leggere i txt in una stringa ognuno. se non sbaglio cosi' come sono i txt
non puoi usare line input perche' accetta solo crlf come separatore.
dovresti prima fare un
    s=txt
    s=replace(s,vblf,vbcrlf)
    txt2=s
cioe' salvare in un nuovo file la stringa e poi leggere quello. per esempi
di input e lineinput c'e' un mio post della settimana scorsa:
    Sent: Thursday, June 27, 2002 11:00 AM
    Subject: Re: Righe di un file senza aprirlo -- timing (lungo)
scusa se sono cose che conosci, ma non dici molto di te :)
4. con instr(), pos(), mid() fai un ciclo nella stringa. a naso,
nell'anagrafica col vblf dovresti poter chiudere un record, mentre nelle
fatture completi prima un campo poi il record
    890 - 50001 - 30/04/02 - 89,83 - "" - 17,97...
    891 - 50002 - 30/04/02 - 99,55 - "" - 17.50...
a parte lo 0a dopo il progressivo (ovviamente non usare un contatore ma un
normale long), gli altri campi sembrano separati da " " (chr(32)), e su
quello ti basi nella scansione della stringa.
l'anagrafica dovrebbe essere simile, ma mi resta il dubbio sulla struttura
record.
5. inglobi la scansone della stringa in un ciclo di append. se i record
fossero semplicemente su una riga, qc come:
    leggi file
        finche' non eof
            scansione stringa (se vblf) linea (se vbcrlf)
                finche' non vb(cr)lf
                    spazio -> la roba prima e' un campo
                    spazio -> la roba prima e' un campo
                    spazio -> la roba prima e' un campo
                vb(cr)lf -> tutti i campi prima fanno un record
                addnew
            fine stringa
        eof
     ciao
per il tracciato record ti prepari un type apposta o tante wNome, wData wEcc
quante te ne servono e poi quando fai addnew le assegni ai campi, previe
conversioni del caso tipo cstr, cdate, clng _e loro svuotamento a ogni
nuovo record_. nb: non ho mai usato un type in vita mia e finora non ho mai
incontrato particolari problemi. ma non dirlo a nessunoop :)
--
ciao, hth, j.
www.sundaysw.com

> "Xenod" [...]:

    Qual e' la regola? Che i campi di tipo testo terminano con Chr$(34) &
Chr$(32) e gli altri campi con Chr$(32) ?
    Se le cose stanno cosi'...
' ------------------------------------------------------------
  Option Explicit
' ------------------------------------------------------------
' ------------------------------------------------------------
  Public Const gc_sMsgErrTitle = "ERRORE#"
' ------------------------------------------------------------
' ************************************************************
  Private Sub Main()
' ------------------------------------------------------------
  On Error GoTo errh
' ------------------------------------------------------------
  Const c_sFile = "D:\TEMP\PIPPO.TXT"
  Const c_lRecs = 2
' ------------------------------------------------------------
  Dim sSepStr   As String
  Dim sSepNum   As String
  Dim iFile     As Integer
  Dim sBuffer   As String
  Dim lRec      As Long
  Dim a_sLine() As String
  Dim lPos      As Long
  Dim lFld      As Long
  Dim lFlds     As Long
  Dim sSep      As String
  Dim lLen      As Long
  Dim sFld      As String
' ------------------------------------------------------------
  sSepStr = Chr$(34) & Chr$(32)
  sSepNum = Chr$(32)
  'On Error Resume Next
  'Kill c_sFile
  'On Error GoTo errh
  'iFile = FreeFile(0)
  'Open c_sFile For Binary Access Write As #iFile
  'sBuffer _
  '  = "50001" & vbLf
  'Put #iFile, , sBuffer
  'sBuffer _
  '  = """ROSSI PIERO""" & " " _
  '  & "012345678901" & " " _
  '  & """VIA XX SETTMBRE 55""" & " " _
  '  & """ROMA""" & " " _
  '  & """RM""" & " " _
  '  & "4/7/2002" & " " _
  '  & """""" & " " _
  '  & """"""
  'Put #iFile, , sBuffer
  'Close iFile
  iFile = FreeFile(0)
  Open c_sFile For Input As #iFile
  Do Until EOF(iFile)
    Line Input #iFile, sBuffer
    'Debug.Print sBuffer
    a_sLine = Split(sBuffer, vbLf)
    For lRec = LBound(a_sLine) To UBound(a_sLine)
      a_sLine(lRec) = a_sLine(lRec) & " "
      'Debug.Print a_sLine(lRec)
      Select Case lRec
      Case 0
        lFlds = 1
      Case 1
        lFlds = 8
      Case Else
      End Select
      lPos = 1
      For lFld = 1 To lFlds
        Select Case lRec
        Case 0
          Select Case lFld
          Case 1
            sSep = sSepNum
          Case Else
            sSep = sSepStr
          End Select
        Case 1
          Select Case lFld
          Case 2, 6
            sSep = sSepNum
          Case Else
            sSep = sSepStr
          End Select
        Case Else
        End Select
        lLen = InStr(lPos, a_sLine(lRec), sSep) - lPos
        sFld = Mid$(a_sLine(lRec), lPos, lLen + Len(sSep) - 1)
        lPos = lPos + lLen + Len(sSep)
        Select Case lRec
        Case 0
          Select Case lFld
          Case 1
          Case Else
            sFld = Mid$(sFld, 2, Len(sFld) - 2)
          End Select
        Case 1
          Select Case lFld
          Case 2
          Case 6
            sFld = CDate(sFld)
          Case Else
            sFld = Mid$(sFld, 2, Len(sFld) - 2)
          End Select
        Case Else
        End Select
        Debug.Print sFld
      Next
    Next
  Loop
  Close iFile
ext:
  Exit Sub
errh:
  With Err
    MsgBox .Description, vbCritical, gc_sMsgErrTitle & .Number
  End With
  Resume ext
  End Sub
' ************************************************************
--
Ciao.
Maurizio
--------
?SPQR(C)
 X
--------

 "RM" no "" ""<0A>"" 17 3 2 .......
Non mi sembra così mal messo!
E riconoscerne le parti è più semplice di quanto possa sembrare.
Ormai sono giorni che mi sto ammazzando di parser e questo è una banalità :)
ci provo anch'io vediamo... (sostituisco " con ' per comodità)
Private Sub Command1_Click()
    Dim s As String
    Dim i As Long
    Dim ch As String
    Dim in_string As Boolean
    Dim i_campo As Long
    Dim campi(0 To 255) As String
    s = "'50001'<0A>'ROSSI PIERO' 012345678901 'VIA XX SETTMBRE 55' 'ROMA'"
    in_string = False
    i_campo = 0
    For i = 1 To Len(s)
        ch = Mid$(s, i, 1)
        If (in_string) Then
            If (ch = "'") Then
                i_campo = i_campo + 1
                in_string = Not in_string
            Else
                campi(i_campo) = campi(i_campo) & ch
            End If
        Else
            Select Case ch
            Case " "
                ' skip blanks
            Case "'"
                in_string = Not in_string
            Case "<"
                Do While (ch <> ">")
                  ch = Mid$(s, i, 1)
                  campi(i_campo) = campi(i_campo) & ch
                  i = i + 1
                Loop
                campi(i_campo) = Chr$(Val("&H" & Mid$(campi(i_campo), 2,
2)))
                i_campo = i_campo + 1
                i = i - 1
            Case "0" To "9", "."
                Do While (InStr("0123456789.", ch) > 0)
                  ch = Mid$(s, i, 1)
                  campi(i_campo) = campi(i_campo) & ch
                  i = i + 1
                Loop
                i_campo = i_campo + 1
                i = i - 1
            Case Else
                campi(i_campo) = campi(i_campo) & ch
            End Select
        End If
    Next i
End Sub
Ovviamente occorre gestire separatori o caratteri speciali se esistessero
(es. le virgolette nelle stringhe)
Ciao

 ha scritto nel messaggio
news:ag146j$i22m5$1...@ID-52090.news.dfncis.de...


in pratica ti abbiamo fatto il 90% del programma!!!
ma non deve essere una scusa per non imparare eh!
....e sopratutto non è una regola!
:-)

Scusate se non ho partecipato al dibattito, ma sono rientrato ora e sono 
un pň cotto.
Domani vaglierň le vs. idee, cmq ringrazio tutti anche per i consigli 
non proprio tecnici (ne terro di conto) !!!
Se va importo varo un debito con tutti, a me non resterŕ nulla :-(
Ciao e grazie !!!

 Ciao e grazie !!!
Giuro che ho capito solo "Ciao e grazie"