Condividi tramite

Macro per importare file CSV

Anonimo
2018-10-14T16:56:29+00:00

Buona sera,

vorrei sapere, se possibile, come fare a creare una macro che mi importi un file CSV su excel dividendo ogni sumero (separato nel file CSV dal ";") in colonne.

I file ha migliaia di numeri e mi piacerebbe creare un codice in modo che il tutto venga in automatico.

Di seguito un parte del file CSV in modo da farvi capire meglio cosa mi servirebbe.

2018-09-26 00:02:43.100;123;3,58462119102478;-0,349906921386719;0;0,0995604395866394;41,9406814575195;0;92;-0,144214287400246;-0,144214287400246;2,35775780677795;4,87863254547119;-0,140170812606812
2018-09-26 00:02:45.100;123;3,58462119102478;-0,362560272216797;0;0,0970007851719856;41,9533348083496;0;92;-0,144486874341965;-0,144486874341965;2,18934655189514;4,87863254547119;-0,140170812606812
2018-09-26 00:02:47.100;123;3,58462119102478;-0,336128234863281;0;0,0994941294193268;41,9269027709961;0;92;-0,144580647349358;-0,144580647349358;2,35775780677795;4,87521362304688;-0,140170812606812
2018-09-26 00:02:49.100;123;3,58462119102478;-0,376461029052734;0;0,1008375659585;41,9672355651855;0;92;-0,145010769367218;-0,145010769367218;2,35775780677795;4,87863254547119;-0,140170812606812
2018-09-26 00:02:51.100;123;3,58462119102478;-0,344810485839844;0;0,100619219243526;41,9355850219727;0;92;-0,14330181479454;-0,14330181479454;2,35775780677795;4,87179470062256;-0,140170812606812
2018-09-26 00:02:53.100;123;3,58462119102478;-0,355358123779297;0;0,102606855332851;41,9461326599121;0;92;-0,144114270806313;-0,144114270806313;2,35775780677795;4,87179470062256;-0,140170812606812
2018-09-26 00:02:55.100;123;3,58462119102478;-0,329635620117188;0;0,101611234247684;41,92041015625;0;92;-0,14364404976368;-0,14364404976368;2,35775780677795;4,87179470062256;-0,140170812606812
2018-09-26 00:02:57.100;123;3,58462119102478;-0,363475799560547;0;0,10114161670208;41,9542503356934;0;92;-0,145281955599785;-0,145281955599785;2,69458031654358;4,87863254547119;-0,140170812606812
2018-09-26 00:02:59.100;123;3,58462119102478;-0,354911804199219;0;0,0998550280928612;41,945686340332;0;92;-0,144641071557999;-0,144641071557999;2,69458031654358;4,87179470062256;-0,140170812606812

L'unica cosa in più che avrei bisogno è dividere la data dall'ora sfruttando due celle.

Infatti i gruppi di valori sono 14 nel file CSV e dovrei trovarli in 15 colonne sul file excel proprio per la divisione tra data ed ora.

Anticipatamente ringrazio

Saluti

Giuseppe

Microsoft 365 e Office | Excel | Per la casa | Windows

Domanda bloccata. Questa domanda è stata eseguita dalla community del supporto tecnico Microsoft. È possibile votare se è utile, ma non è possibile aggiungere commenti o risposte o seguire la domanda.

0 commenti Nessun commento

Risposta accettata dall'autore della domanda

Anonimo
2018-10-14T19:28:02+00:00

Ciao Giuseppe,

tra le varie possibilità prova quanto ti propongo (basata sulla semplice importazione dei dati non conoscendo la struttra del tuo file).

Vedi questo file di esempio: File esempio

Nel Modulo1 del progetto VBA trovi il seguente codice:

'---

Option Explicit

Sub ImportaCsv()

   Const sFoglioDatiImportati As String = "Dati Importati"

   Const sRngDest As String = "A1"

   Dim Wb As Workbook

   Dim Ws As Worksheet

   Dim rngDest As Range

   Dim sFileFullName As String

   Set Wb = ThisWorkbook

   On Error Resume Next

   Set Ws = Wb.Worksheets(sFoglioDatiImportati)

   If Err.Number <> 0 Then

      Set Ws = Wb.Worksheets.Add(After:=Wb.Worksheets(Wb.Worksheets.Count))

      Ws.Name = sFoglioDatiImportati

   End If

   On Error GoTo 0

   Set rngDest = Ws.Range(sRngDest)

   sFileFullName = GetFileCsvFullName

   Ws.Cells.ClearContents

   If sFileFullName <> vbNullString Then

      With Ws.QueryTables.Add(Connection:="TEXT;" & sFileFullName, _

                              Destination:=rngDest)

         .Name = "XXXX"

         .FieldNames = True

         .RowNumbers = False

         .FillAdjacentFormulas = False

         .PreserveFormatting = True

         .RefreshOnFileOpen = False

         .RefreshStyle = xlInsertDeleteCells

         .SavePassword = False

         .SaveData = True

         .AdjustColumnWidth = True

         .RefreshPeriod = 0

         .TextFilePromptOnRefresh = False

         .TextFilePlatform = 1252

         .TextFileStartRow = 1

         .TextFileParseType = xlDelimited

         .TextFileTextQualifier = xlTextQualifierDoubleQuote

         .TextFileConsecutiveDelimiter = False

         .TextFileTabDelimiter = False

         .TextFileSemicolonDelimiter = True

         .TextFileCommaDelimiter = False

         .TextFileSpaceDelimiter = False

         .TextFileColumnDataTypes = Array(4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)

         .TextFileTrailingMinusNumbers = True

         .Refresh BackgroundQuery:=False

         .Delete

      End With

      Ws.Columns("B:B").Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove

      rngDest.EntireColumn.TextToColumns Destination:=Range("A1"), _

                                          DataType:=xlDelimited, _

                                          TextQualifier:=xlDoubleQuote, _

                                          ConsecutiveDelimiter:=True, _

                                          Tab:=False, _

                                          Semicolon:=False, _

                                          Comma:=False, _

                                          Space:=True, _

                                          Other:=False, _

                                          FieldInfo:=Array(4, 4), _

                                          TrailingMinusNumbers:=True

      rngDest.CurrentRegion.Columns.AutoFit

      If ActiveSheet.Name <> Ws.Name Then Ws.Activate

   End If

End Sub

Function GetFileCsvFullName() As String

   With Application

      With .FileDialog(msoFileDialogFilePicker)

         .Title = "Seleziona File csv"

         .ButtonName = "Ok"

         .AllowMultiSelect = False

         .InitialFileName = Environ("UserProfile") & ""

         With .Filters

            .Clear

            .Add "File csv", "*.csv"

         End With

         If .Show = -1 Then

            GetFileCsvFullName = .SelectedItems(1)

         End If

      End With

   End With

End Function

'---

La routine ImportaCsv è quella da richiamare (nel file ho messo un pulsante nel foglio1.

In primis se non viene trovato un foglio con il nome impostato con la costante:

Const sFoglioDatiImportati As String = "Dati Importati"

ne crea uno.

Poi viene aperta una finestra di dialogo per selezionare il file csv (il filtro va visualizzare solo i file csv).

Una volta selezionato il file viene importato e i dati vengono riportati nel foglio "Dati Importati" a paritre dalla prima cella impostata con la costante:

 Const sRngDest As String = "A1"

Una volta importati i dati viene inserita una colonna in corrispondenza della colonna B e i dati della colonna A vengono suddivisi tra data e ora.

Infine le colonne vegono "adattate" al contenuto.

Vedi se può andar bene eventualmente adattando al tuo caso specifico.

ciao

La risposta è stata utile?

2 persone hanno trovato utile questa risposta.
0 commenti Nessun commento

Risposta accettata dall'autore della domanda

Anonimo
2018-10-15T16:35:05+00:00

Ciao Giuseppe,

analizzando i valori ho visto che per le colonne diverse dalle 1, 2, 3, 10, i numeri di decimali arrivano fino al massimo di 18.

Ho modificato la procedura per formattare le colonne diverse da quelle in precedenza indicate con un formato numerico composto da 18 decimali.

Ho anche fatto qualche aggiustamento per la eliminazione dei dati nel caso sia già presente un foglio identificiato dalla costante sFoglioDatiImportati.

Riporto la procedura modificata:

Sub ImportaCsv()

   Const sFoglioDatiImportati As String = "Dati Importati"

   Const sRngDest As String = "A1"

   Dim Wb As Workbook

   Dim Ws As Worksheet

   Dim rngDest As Range

   Dim sFileFullName As String

   Dim i As Long

   Dim wsExists As Boolean

   Set Wb = ThisWorkbook

   On Error Resume Next

   Set Ws = Wb.Worksheets(sFoglioDatiImportati)

   If Err.Number <> 0 Then

      Set Ws = Wb.Worksheets.Add(After:=Wb.Worksheets(Wb.Worksheets.Count))

      Ws.Name = sFoglioDatiImportati

Else

Ws.Cells.Delete

End If

   On Error GoTo 0

   Set rngDest = Ws.Range(sRngDest)

   sFileFullName = GetFileCsvFullName

   If sFileFullName <> vbNullString Then

      Application.DisplayAlerts = False

      With Ws.QueryTables.Add(Connection:="TEXT;" & sFileFullName, _

                              Destination:=rngDest)

         .Name = "XXXX"

         .FieldNames = True

         .RowNumbers = False

         .FillAdjacentFormulas = False

         .PreserveFormatting = True

         .RefreshOnFileOpen = False

         .RefreshStyle = xlOverwriteCells

         .SavePassword = False

         .SaveData = True

         .AdjustColumnWidth = False

         .RefreshPeriod = 0

         .TextFilePromptOnRefresh = False

         .TextFilePlatform = 1252

         .TextFileStartRow = 1

         .TextFileParseType = xlDelimited

         .TextFileTextQualifier = xlTextQualifierDoubleQuote

         .TextFileConsecutiveDelimiter = False

         .TextFileTabDelimiter = False

         .TextFileSemicolonDelimiter = True

         .TextFileSpaceDelimiter = True

         .TextFileDecimalSeparator = ","

         .TextFileThousandsSeparator = "."

         .TextFileColumnDataTypes = Array(4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)

         .TextFileTrailingMinusNumbers = True

         .Refresh BackgroundQuery:=False

         .Delete

      End With

      Application.DisplayAlerts = True

With rngDest.CurrentRegion

For i = 1 To .Columns.Count

Select Case i

Case 1, 2, 3, 10

'Do Nothing

Case Else

.Columns(i).NumberFormat = "#0." & String(18, "0")

End Select

Next i

.Columns.AutoFit

End With

      If ActiveSheet.Name <> Ws.Name Then Ws.Activate

   End If

End Sub

Riporto per tua comodità il link al file in questo messaggio: File esempio

La risposta è stata utile?

1 persona ha trovato utile questa risposta.
0 commenti Nessun commento

11 risposte aggiuntive

Ordina per: Più utili
  1. Anonimo
    2018-10-15T07:15:21+00:00

    Ciao Casanmaner,

    penso che il problema sia dovuto alla miriade di record che ho sul file.

    Quando lancio la routine, dopo aver selezionato il file di interesse, mi restituisce questo messaggio prima di dividere la data dall'ora.

    a questo punto, se annullo l'operazione va in debug sul comando della divisione della data dall'ora, se continuo termina la routine e mi trasforma la colonna "C" ove c'è 123 in AM. di seguito come visualizzo io il tutto.

    come puoi vedere oltre alle date anche le virgole sono messe in malo modo.

    ecco il link del file completo:

    https://www.dropbox.com/s/6qm2grmcw069f4x/port.zip?dl=0

    Grazie e buona giornata

    Peppe

    La risposta è stata utile?

    0 commenti Nessun commento
  2. Anonimo
    2018-10-15T06:18:25+00:00

    Ciao Giuseppe,

    durante le mie prove non viene lanciato nessun messaggio sul fatto di applicare le modifiche o meno (utilizzo Excel 2007).

    Inoltre i dati mi vengono importati in questo modo:

    dove per quanto riguarda la parte dell'orario mi viene riportato l'orario per esteso e senza AM.

    sarebbe un problema condividere un file csv reale per verificare che non dipenda dai dati presenti.

    Io il csv l'ho ricostruito copiando e incollando quanto hai riportato nel tuo messaggio iniziale.

    Ma magari c'è qualche elemento che "sfugge".

    ciao

    La risposta è stata utile?

    0 commenti Nessun commento
  3. Anonimo
    2018-10-15T05:19:43+00:00

    Buongiorno Casanmaner,

    felice di risentirti.

    Allora, il codice è perfetto per il mio caso specifico.

    Avrei solo piccole modifiche da fare:

    quando importo i dati, alla fine della processo esce un avviso che mi chiede se applicare le modifiche o meno.

    Se clicco su OK, divide l'ora dalla data ma se clicco su annulla va in debug. questo potrebbe essere un problema perchè se chi opera non sa cosa fare e clicca su annulla non completa il processo della routine.

    Un altro problema che ho notato è proprio la divisione tra data ed ora.

    nel formato originale data ed ora sono scritte per esteso in questo modo:

    2018-09-26 00:00:01.100

    a me servirebbe esattamente come viene estrapolato ma diviso in questo modo:

    2018-09-26        00:00:01.100

    mentre in realtà ora esce così:

    26/09/2018 00:01.0 AM

    come vedi in realtà estrapolazione dei data viene fatta ogni 2 secondi e non ogni due minuti, inoltre la dicitura AM non mi serve ma mi servirebbe l'ora con il .100 al lato che identifica i dati da quale apparato sono estrapolati.

    Spero che si possa aggiustare la routine che a questo punto sarebbe impeccabile.

    Grazie come sempre saluti

    Giuseppe

    La risposta è stata utile?

    0 commenti Nessun commento