Importare TXT delimitato da spazi

di il
34 risposte

Importare TXT delimitato da spazi

Ciao…

Dovrei importare un file TXT delimitato da spazi (non tab) in un dataview, il numero degli spazi però non è fisso..

alla fine dovrei avere una colonna per Area, una per areaelem….

ho provato con questo codice trovato online, ma vede ogni spazio come una colonna…
la chiamo con :

Dim TXT_Datatable As DataTable = txt_to_data(nomeFile, vbYes, Space(1))

Private Function txt_to_data(ByVal filename As String, ByVal header As Boolean, ByVal delimiter As String) As DataTable
    'New datatable
    Dim dt As DataTable = New DataTable

    'Read the contents of the textfile into an array
    Dim sr As IO.StreamReader = New IO.StreamReader(filename)
    Dim txtlines() As String = sr.ReadToEnd.Split({Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)

    'Return nothing if there's nothing in the textfile
    If txtlines.Count = 0 Then
        Return Nothing
    End If

    Dim column_count As Integer = 0
    For Each col As String In txtlines(0).Split({delimiter}, StringSplitOptions.None)
        If header Then
            'If there's a header then add it by it's name
            dt.Columns.Add(col)
            dt.Columns(column_count).Caption = col
        Else
            'If there's no header then add it by the column count
            dt.Columns.Add(String.Format("Column{0}", column_count))
            dt.Columns(column_count).Caption = String.Format("Column{0}", column_count + 1)
        End If

        column_count += 1
    Next

    If header Then
        For rows As Integer = 1 To txtlines.Count - 1 'start at one because there's a header for the first line(0)
            'Declare a new datarow
            Dim dr As DataRow = dt.NewRow

            'Set the column count back to 0, we can reuse this variable ;]
            column_count = 0
            For Each col As String In txtlines(rows).Split({delimiter}, StringSplitOptions.None) 'Each column in the row
                'The column in cue is set for the datarow
                dr(column_count) = col
                column_count += 1
            Next

            'Add the row
            dt.Rows.Add(dr)
        Next
    Else
        For rows As Integer = 0 To txtlines.Count - 1 'start at zero because there's no header
            'Declare a new datarow
            Dim dr As DataRow = dt.NewRow

            'Set the column count back to 0, we can reuse this variable ;]
            column_count = 0
            For Each col As String In txtlines(rows).Split({delimiter}, StringSplitOptions.None) 'Each column in the row
                'The column in cue is set for the datarow
                dr(column_count) = col
                column_count += 1
            Next

            'Add the row
            dt.Rows.Add(dr)
        Next
    End If

    Return dt
End Function

avete altre soluzioni?
dopo averlo importato devo filtrare i valori per colonna Area e poi Outputcase, e fare la media dei vaolri

34 Risposte

  • Re: Importare TXT delimitato da spazi

    …questo codice trovato online…

    male!

    Riesci a sapere il numero massimo di spazi presenti tra una colonna e l'altra?

  • Re: Importare TXT delimitato da spazi

    Guardando l'immagine che hai allegato mi sembra che la cosa sia molto banale, 
    è semplicemente un file TXT con colonne a larghezza fissa.
    Basta contare ogni colonna quanto larga è, estrarre i dati con un semplicissimo string.Substring(x, n).Trim per avere i dati.
    Poi i valori decimali si trasformano in numeri con Double.Parse

    Oppure puoi usare Microsoft.VisualBasic.FileIO.TextFieldParser che ti dà già tutto disposizione

  • Re: Importare TXT delimitato da spazi

    Ciao…hai ragione..ma mi è servito per cominciare…
    ho modificato l'istruzione txtlines(0).Split({delimiter}, StringSplitOptions.None) mettendo StringSplitOptions.RemoveEmptyEntries ed ha funzionato…

    Il numero massimo di spazi dovrei saperlo…

    per calcolare la media, pensavo di:

    Ordinare il dataview per le due colonne che mi interessano

    Trovare i valori univoci delle due colonne

    Creare due for each per filtrare con i dati univoci e poi calcolare la media di ogni colonna,,,

    Per ora ho fatto questo:

           Dim ListaArea As New List(Of Double)
    
           Dim UniqueAREA As System.Collections.Generic.List(Of String) = ((From T In TXT_Datatable.AsEnumerable() Select T.Field(Of String)("Area")).Distinct()).OrderBy(Function(s) s).ToList()
           Dim UniqueCASE As System.Collections.Generic.List(Of String) = ((From T In TXT_Datatable.AsEnumerable() Select T.Field(Of String)("OutputCase")).Distinct()).OrderBy(Function(s) s).ToList()
    
    
           Dim TXTdataview As DataView = TXT_Datatable.AsDataView
    
           TXTdataview.Sort = "Area, OutputCase"
    
           If UniqueAREA.Item(0) Is Nothing Then UniqueAREA.RemoveAt(0)
           If UniqueCASE.Item(0) Is Nothing Then UniqueCASE.RemoveAt(0)
           UniqueAREA.Sort()
           UniqueCASE.Sort()
    
    
           For Each TXT_AREA As String In UniqueAREA
    
        For Each TXT_OUTPUTCASE As String In UniqueCASE
    
    
            Dim filterstr As String = "Area = " & "'" & TXT_AREA & "' " & "AND " & "Outputcase = " & "'" & TXT_OUTPUTCASE & "'"
            '"Area = '23' AND OutputCase '46'"
    
    
    
            TXTdataview.RowFilter = filterstr
    
    
            For k = 8 To 24
    
    
                For Each dataRowTMP As DataRowView In TXTdataview
    
                    F11 += F11
                    F22 += F22
                    F12 += F12
                    FMax += FMax
                    FMin += FMin
                    FAngle += FAngle
                    FVM += FVM
                    M11 += M11
                    M22 += M22
                    M12 += M12
    
    
    'trovo i totali delle colonne filtrate e calcolo la media
    
                    Dim TotTMP As Double = 0
    
    
    
    
                Next
    
    
    
            Next
    
    
    
    
    
    
            dataRowTMP = TXTdataview.Item(0)
    
    
            Me.DataGridView1.DataSource = TXTdataview
    
    
    
        Next
    
            

    c' è un modo più veloce?

  • Re: Importare TXT delimitato da spazi

    Non so se è la maniera più veloce ma funziona.
    ora il problema è fargli scrivere il secondo datatable creato con le media, in un file txt che ha la stessa struttura di quello che aprivo

           Dim nomeFile As String = "E:\_Lavori\_Visual_Basic\07_VarieRFAEM\wetransfer_dirx_slu_zona_unica-txt_2023-09-05_1225\prova_media3.txt"
           Dim TXT_Datatable As DataTable = txt_to_data(nomeFile, True, Space(1))
           Dim TXTMedia_Datatable As DataTable = TXT_Datatable.Clone
    
           'ImpData(nomeFile)
    
           Dim ListaArea As New List(Of Double)
    
           Dim UniqueAREA As System.Collections.Generic.List(Of String) = ((From T In TXT_Datatable.AsEnumerable() Select T.Field(Of String)("Area")).Distinct()).OrderBy(Function(s) s).ToList()
           Dim UniqueCASE As System.Collections.Generic.List(Of String) = ((From T In TXT_Datatable.AsEnumerable() Select T.Field(Of String)("OutputCase")).Distinct()).OrderBy(Function(s) s).ToList()
    
    
           Dim TXTdataview As DataView = TXT_Datatable.AsDataView
    
           Me.DataGridView1.DataSource = TXTdataview
           Me.Update()
           TXTdataview.Sort = "Area, Joint, OutputCase"
           Me.DataGridView1.DataSource = TXTdataview
           Me.Update()
    
           If UniqueAREA.Item(0) Is Nothing Then UniqueAREA.RemoveAt(0)
           If UniqueCASE.Item(0) Is Nothing Then UniqueCASE.RemoveAt(0)
           UniqueAREA.Sort()
           UniqueCASE.Sort()
    
    
           For Each TXT_AREA As String In UniqueAREA
    
               For Each TXT_OUTPUTCASE As String In UniqueCASE
    
    
                   Dim filterstr As String = "Area = " & "'" & TXT_AREA & "' " & "AND " & "Outputcase = " & "'" & TXT_OUTPUTCASE & "'"
                   '"Area = '23' AND OutputCase '46'"
    
    
    
                   TXTdataview.RowFilter = filterstr
                   Me.DataGridView1.DataSource = TXTdataview
                   Me.Update()
    
                   Dim F11 As Double = 0
                   Dim F22 As Double = 0
                   Dim F12 As Double = 0
                   Dim FMax As Double = 0
                   Dim FMin As Double = 0
                   Dim FAngle As Double = 0
                   Dim FVM As Double = 0
                   Dim M11 As Double = 0
                   Dim M22 As Double = 0
                   Dim M12 As Double = 0
                   Dim MMax As Double = 0
                   Dim MMin As Double = 0
                   Dim MAngle As Double = 0
                   Dim V13 As Double = 0
                   Dim V23 As Double = 0
                   Dim VMax As Double = 0
                   Dim VAngle As Double = 0
    
    
    
                   Dim Area_media As String = ""
                   Dim AreaElem_Media As String = ""
                   Dim Shell_Media As String = ""
                   Dim Joint_Media As String = ""
                   Dim OutputCase_Media As String = ""
                   Dim CaseType_Media As String = ""
                   Dim StepType_Media As String = ""
    
    
                   Dim F11_Media As Double = 0
                   Dim F22_Media As Double = 0
                   Dim F12_Media As Double = 0
                   Dim FMax_Media As Double = 0
                   Dim FMin_Media As Double = 0
                   Dim FAngle_Media As Double = 0
                   Dim FVM_Media As Double = 0
                   Dim M11_Media As Double = 0
                   Dim M22_Media As Double = 0
                   Dim M12_Media As Double = 0
                   Dim MMax_Media As Double = 0
                   Dim MMin_Media As Double = 0
                   Dim MAngle_Media As Double = 0
                   Dim V13_Media As Double = 0
                   Dim V23_Media As Double = 0
                   Dim VMax_Media As Double = 0
                   Dim VAngle_Media As Double = 0
    
    
                   For Each dataRowTMP As DataRowView In TXTdataview
    
                       Area_media = dataRowTMP.Item(0)
                       AreaElem_Media = dataRowTMP.Item(1)
                       Shell_Media = dataRowTMP.Item(2)
                       Joint_Media = "CENTER"
                       OutputCase_Media = dataRowTMP.Item(4)
                       CaseType_Media = dataRowTMP.Item(5)
                       StepType_Media = "Min/MAX"
    
                       F11 += Double.Parse(dataRowTMP.Item(7).ToString.Replace(".", ","))
                       F22 += Double.Parse(dataRowTMP.Item(8).ToString.Replace(".", ","))
                       F12 += Double.Parse(dataRowTMP.Item(9).ToString.Replace(".", ","))
                       FMax += Double.Parse(dataRowTMP.Item(10).ToString.Replace(".", ","))
                       FMin += Double.Parse(dataRowTMP.Item(11).ToString.Replace(".", ","))
                       FAngle += Double.Parse(dataRowTMP.Item(12).ToString.Replace(".", ","))
                       FVM += Double.Parse(dataRowTMP.Item(13).ToString.Replace(".", ","))
                       M11 += Double.Parse(dataRowTMP.Item(14).ToString.Replace(".", ","))
                       M22 += Double.Parse(dataRowTMP.Item(15).ToString.Replace(".", ","))
                       M12 += Double.Parse(dataRowTMP.Item(16).ToString.Replace(".", ","))
                       MMax += Double.Parse(dataRowTMP.Item(17).ToString.Replace(".", ","))
                       MMin += Double.Parse(dataRowTMP.Item(18).ToString.Replace(".", ","))
                       MAngle += Double.Parse(dataRowTMP.Item(19).ToString.Replace(".", ","))
                       V13 += Double.Parse(dataRowTMP.Item(20).ToString.Replace(".", ","))
                       V23 += Double.Parse(dataRowTMP.Item(21).ToString.Replace(".", ","))
                       VMax += Double.Parse(dataRowTMP.Item(22).ToString.Replace(".", ","))
                       VAngle += Double.Parse(dataRowTMP.Item(23).ToString.Replace(".", ","))
    
    
                   Next
    
                   F11_Media = Math.Round(F11 / TXTdataview.Count, 2)
                   F22_Media = Math.Round(F22 / TXTdataview.Count, 2)
                   F12_Media = Math.Round(F12 / TXTdataview.Count, 2)
                   FMax_Media = Math.Round(FMax / TXTdataview.Count, 2)
                   FMin_Media = Math.Round(FMin / TXTdataview.Count, 2)
                   FAngle_Media = Math.Round(FAngle / TXTdataview.Count, 2)
                   FVM_Media = Math.Round(FVM / TXTdataview.Count, 2)
                   M11_Media = Math.Round(M11 / TXTdataview.Count, 2)
                   M22_Media = Math.Round(M22 / TXTdataview.Count, 2)
                   M12_Media = Math.Round(M12 / TXTdataview.Count, 2)
                   MMax_Media = Math.Round(MMax / TXTdataview.Count, 2)
                   MMin_Media = Math.Round(MMin / TXTdataview.Count, 2)
                   MAngle_Media = Math.Round(MAngle / TXTdataview.Count, 2)
                   V13_Media = Math.Round(V13 / TXTdataview.Count, 2)
                   V23_Media = Math.Round(V23 / TXTdataview.Count, 2)
                   VMax_Media = Math.Round(VMax / TXTdataview.Count, 2)
                   VAngle_Media = Math.Round(VAngle / TXTdataview.Count, 2)
    
    
                   Dim drNewRow As DataRow = TXTMedia_Datatable.NewRow
    
                   drNewRow(0) = Area_media
                   drNewRow(1) = AreaElem_Media
                   drNewRow(2) = Shell_Media
                   drNewRow(3) = Joint_Media
                   drNewRow(4) = OutputCase_Media
                   drNewRow(5) = CaseType_Media
                   drNewRow(6) = StepType_Media
    
                   drNewRow(7) = F11_Media
                   drNewRow(8) = F22_Media
                   drNewRow(9) = F12_Media
                   drNewRow(10) = FMax_Media
                   drNewRow(11) = FMin_Media
                   drNewRow(12) = FAngle_Media
                   drNewRow(13) = FVM_Media
                   drNewRow(14) = M11_Media
                   drNewRow(15) = M22_Media
                   drNewRow(16) = M12_Media
                   drNewRow(17) = MMax_Media
                   drNewRow(18) = MMin_Media
                   drNewRow(19) = MAngle_Media
                   drNewRow(20) = V13_Media
                   drNewRow(21) = V23_Media
                   drNewRow(22) = VMax_Media
                   drNewRow(23) = VAngle_Media
    
                   TXTMedia_Datatable.Rows.Add(drNewRow)
    
    
                   Me.DataGridView1.DataSource = TXTdataview
                   Me.DataGridView2.DataSource = TXTMedia_Datatable
    
                   Me.Update()
    
    
               Next
    
           Next
  • Re: Importare TXT delimitato da spazi

    Boh, secondo me il tuo approccio è sbagliato.
    Hai un file TXT con le colonne a larghezza fissa eppure continui a fare lo SPLIT con un DELIMITER.
    Ti funziona solo perchè dentro nel file non ci sono dati con lo spazio in mezzo, e quindi diciamo che finora sei solo stato fortunato, ma se ti arriva un file con uno spazio in mezzo cosa fai ??
    Prova ad esempio a modificare il file, sostituendo un qualsiasi “Shell-Thin” con “Shell Thin” e poi vedrai che non funziona più nulla.

  • Re: Importare TXT delimitato da spazi

    In questo caso il file TXT che esce dal programma di calcolo è sempre così e non cambia, ma comunque  hai ragione e provo a sistemare il codice per farlo funzionare sempre.

    Per quanto riguarda invece il calcolo dei valori medi, ho lanciato il programma e per elaborare 1 milione di righe del file txt impiega una vita..dopo 3 ore era ancora al 15%…

    c'è un altro sistema che posso utilizzare più veloce?

    attualmente leggo dalle due colonne che mi interessano i valori univoci, e poi con due for each filtro il dataview e calcolo la media….

  • Re: Importare TXT delimitato da spazi

    Ma devi calcolare la media di sole due colonne ??
    Si può avere questo file ??

  • Re: Importare TXT delimitato da spazi

    Non so come allegare il file….

    comunque studiando ho trovato datatype.compute() è ho scritto questo:
    Funziona e in circa 1 ora calcola tutto considerando che il txt originale è da circa 1645000 righe) prima dopo 3 ore non aveva finito

    poi passo all'importazione del txt fissando il numero di caratteri delle colonne in modo da farlo funzionare sempre

     Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    
    
    
         Dim nomeFile As String = "prova_media.txt"
    
         Dim TXT_Datatable As DataTable = txt_to_data(nomeFile, True, Space(1))
         Dim TXTMedia_Datatable As DataTable = TXT_Datatable.Clone
    
         'ImpData(nomeFile)
    
         Dim ListaArea As New List(Of Double)
    
         Dim UniqueAREA As System.Collections.Generic.List(Of String) = ((From T In TXT_Datatable.AsEnumerable() Select T.Field(Of String)("Area")).Distinct()).OrderBy(Function(s) s).ToList()
         Dim UniqueCASE As System.Collections.Generic.List(Of String) = ((From T In TXT_Datatable.AsEnumerable() Select T.Field(Of String)("OutputCase")).Distinct()).OrderBy(Function(s) s).ToList()
    
         Me.Label3.Text = TimeString
    
    
         Me.TextBox_Aree.Text = UniqueAREA.Count.ToString
    
         Me.TextBox_Combi.Text = UniqueCASE.Count.ToString
    
         Me.TextBox_Aree.ReadOnly = True
         Me.TextBox_Combi.ReadOnly = True
    
         Me.ProgressBar_Area.Maximum = UniqueAREA.Count
         Me.ProgressBar_Combinazioni.Maximum = UniqueCASE.Count
    
         Me.ProgressBar_Area.Minimum = 1
         Me.ProgressBar_Combinazioni.Minimum = 1
    
         Me.ProgressBar_Area.Step = 1
         Me.ProgressBar_Combinazioni.Step = 1
         Dim TXTdataview As DataView = TXT_Datatable.AsDataView
    
         Me.DataGridView1.DataSource = TXTdataview
         Me.Update()
         TXTdataview.Sort = "Area, Joint, OutputCase"
         Me.DataGridView1.DataSource = TXTdataview
         Me.Update()
    
         If UniqueAREA.Item(0) Is Nothing Then UniqueAREA.RemoveAt(0)
         If UniqueCASE.Item(0) Is Nothing Then UniqueCASE.RemoveAt(0)
         UniqueAREA.Sort()
         UniqueCASE.Sort()
    
    
         For Each TXT_AREA As String In UniqueAREA
    
             For Each TXT_OUTPUTCASE As String In UniqueCASE
                 Dim filterstr As String = "Area = " & "'" & TXT_AREA & "' " & "AND " & "Outputcase = " & "'" & TXT_OUTPUTCASE & "'"
    
                 Dim F11_Media As Double = TXT_Datatable.Compute("Avg(F11)", filterstr)
                 Dim F22_Media As Double = TXT_Datatable.Compute("Avg(F22)", filterstr)
                 Dim F12_Media As Double = TXT_Datatable.Compute("Avg(F12)", filterstr)
                 Dim FMax_Media As Double = TXT_Datatable.Compute("Avg(FMax)", filterstr)
                 Dim FMin_Media As Double = TXT_Datatable.Compute("Avg(FMin)", filterstr)
                 Dim FAngle_Media As Double = TXT_Datatable.Compute("Avg(FAngle)", filterstr)
                 Dim FVM_Media As Double = TXT_Datatable.Compute("Avg(FVM)", filterstr)
                 Dim M11_Media As Double = TXT_Datatable.Compute("Avg(M11)", filterstr)
                 Dim M22_Media As Double = TXT_Datatable.Compute("Avg(M22)", filterstr)
                 Dim M12_Media As Double = TXT_Datatable.Compute("Avg(M12)", filterstr)
                 Dim MMax_Media As Double = TXT_Datatable.Compute("Avg(MMax)", filterstr)
                 Dim MMin_Media As Double = TXT_Datatable.Compute("Avg(F11)", filterstr)
                 Dim MAngle_Media As Double = TXT_Datatable.Compute("Avg(MMin)", filterstr)
                 Dim V13_Media As Double = TXT_Datatable.Compute("Avg(V13)", filterstr)
                 Dim V23_Media As Double = TXT_Datatable.Compute("Avg(F11)", filterstr)
                 Dim VMax_Media As Double = TXT_Datatable.Compute("Avg(VMax)", filterstr)
                 Dim VAngle_Media As Double = TXT_Datatable.Compute("Avg(VAngle)", filterstr)
    
    
                 Dim drNewRow As DataRow = TXTMedia_Datatable.NewRow
    
                 drNewRow(0) = TXT_AREA
                 drNewRow(1) = TXT_AREA
                 drNewRow(2) = "Shell-Thin"
                 drNewRow(3) = "CENTER"
                 drNewRow(4) = TXT_OUTPUTCASE
                 drNewRow(5) = "Combination"
                 drNewRow(6) = "Min/Max"
    
                 drNewRow(7) = F11_Media
                 drNewRow(8) = F22_Media
                 drNewRow(9) = F12_Media
                 drNewRow(10) = FMax_Media
                 drNewRow(11) = FMin_Media
                 drNewRow(12) = FAngle_Media
                 drNewRow(13) = FVM_Media
                 drNewRow(14) = M11_Media
                 drNewRow(15) = M22_Media
                 drNewRow(16) = M12_Media
                 drNewRow(17) = MMax_Media
                 drNewRow(18) = MMin_Media
                 drNewRow(19) = MAngle_Media
                 drNewRow(20) = V13_Media
                 drNewRow(21) = V23_Media
                 drNewRow(22) = VMax_Media
                 drNewRow(23) = VAngle_Media
    
                 TXTMedia_Datatable.Rows.Add(drNewRow)
    
    
                 Me.DataGridView1.DataSource = TXTdataview
                 Me.DataGridView2.DataSource = TXTMedia_Datatable
    
                 Me.Update()
    
                 Me.ProgressBar_Combinazioni.PerformStep()
                 Me.Update()
    
    
             Next
             Me.ProgressBar_Area.PerformStep()
             Me.Update()
         Next
    
         Me.Label4.Text = TimeString
    
     End Sub
  • Re: Importare TXT delimitato da spazi

    Riesci a mettere il file su qualche server e/o servizio cloud in modo che posso scaricarlo ??

  • Re: Importare TXT delimitato da spazi

    Eccolo

    https://drive.google.com/file/d/1UxCdNZxn0nXhvqMflhRsWIlDZ9y6NkO1/view?usp=drive_link

    ieri sera alla fine l'ho finito…ma mi interessa vedere se la strada che ho trovato è la migliore..

  • Re: Importare TXT delimitato da spazi

    Ok, provo a dargli un'occhiata e vediamo se i tempi di elaborazione sono gli stessi o se riesco a ridurli.
    Ho la necessità di sapere di quali colonne hai bisogno la media

    Ti sarà arrivata una email di richiesta da google per poter condividere il file TXT altrimenti non riesco a scaricarlo

  • Re: Importare TXT delimitato da spazi

    Le colonne da cui calcolare la media sono dalla F11 all'ultima colonna

    Per ogni elemento della colonna Area, posso avere n combinazioni di carico (Outputcase) la media la calcolo filtrando la colonna area e outputcase

  • Re: Importare TXT delimitato da spazi

    ….. riesci a farmi avere il file TXT ??

  • Re: Importare TXT delimitato da spazi

    Ti dovrebbe arrivare con wetrans….

    comunque il link è questo:

    https://we.tl/t-hGF9eXA0AY 

Devi accedere o registrarti per scrivere nel forum
34 risposte