Separatori per file csv



  • Separatori per file csv
    di Francesco Tokyo (utente non iscritto) data: 22/10/2012 06:40:00

    Buongiorno a tutti.

    Sono capitato per caso su questo forum mentre cercavo soluzioni al mio problema, quindi ringrazio anticipatamente chiunque volesse darmi una mano.

    Ecco il mio problema: Ho un documento Excel formato da diversi fogli lavoro. Desidero esportare ogni singolo foglio in un documento separato (dandogli come nome il nome del rispettivo foglio) e salvarlo in csv nella stessa directory del file originale. Ho trovato questo codice su un altro forum, che mi permette di scegliere dove salvare i file (cosa che non mi interessa) e quale separatore usare per i file csv. Il problema e' che io voglio mantenere la struttura delle colonne excel nei file csv, e non so proprio quale separatore usare

    In alternativa mi andrebbe anche bene esportare i file in xls, ma desidero copiare i valori delle celle originali, non i riferimenti/formule...

    Uso Excel 2007, di cui conosco molto poco.

    Se qualcuno puo' aiutarmi birra virtuale pagata!

    Grazie a tutti,

    Francesco
     
    ' ---------------------- Directory Choosing Helper Functions -----------------------
    ' Excel and VBA do not provide any convenient directory chooser or file chooser
    ' dialogs, but these functions will provide a reference to a system DLL
    ' with the necessary capabilities
    Private Type BROWSEINFO ' used by the function GetFolderName
        hOwner As Long
        pidlRoot As Long
        pszDisplayName As String
        lpszTitle As String
        ulFlags As Long
        lpfn As Long
        lParam As Long
        iImage As Long
    End Type
    
    Private Declare Function SHGetPathFromIDList Lib "shell32.dll" _
        Alias "SHGetPathFromIDListA" (ByVal pidl As Long, ByVal pszPath As String) As Long
    Private Declare Function SHBrowseForFolder Lib "shell32.dll" _
        Alias "SHBrowseForFolderA" (lpBrowseInfo As BROWSEINFO) As Long
    
    Function GetFolderName(Msg As String) As String
    ' returns the name of the folder selected by the user
    Dim bInfo As BROWSEINFO, path As String, r As Long
    Dim X As Long, pos As Integer
        bInfo.pidlRoot = 0& ' Root folder = Desktop
        If IsMissing(Msg) Then
            bInfo.lpszTitle = "Select a folder."
            ' the dialog title
        Else
            bInfo.lpszTitle = Msg ' the dialog title
        End If
        bInfo.ulFlags = &H1 ' Type of directory to return
        X = SHBrowseForFolder(bInfo) ' display the dialog
        ' Parse the result
        path = Space$(512)
        r = SHGetPathFromIDList(ByVal X, ByVal path)
        If r Then
            pos = InStr(path, Chr$(0))
            GetFolderName = Left(path, pos - 1)
        Else
            GetFolderName = ""
        End If
    End Function
    '---------------------- END Directory Chooser Helper Functions ----------------------
    
    Public Sub DoTheExport()
    Dim FName As Variant
    Dim Sep As String
    Dim wsSheet As Worksheet
    Dim nFileNum As Integer
    Dim csvPath As String
    
    
    Sep = InputBox("Enter a single delimiter character (e.g., comma or semi-colon)", _
    "Export To Text File")
    'csvPath = InputBox("Enter the full path to export CSV files to: ")
    
    csvPath = GetFolderName("Choose the folder to export CSV files to:")
    If csvPath = "" Then
        MsgBox ("You didn't choose an export directory. Nothing will be exported.")
        Exit Sub
    End If
    
    For Each wsSheet In Worksheets
    wsSheet.Activate
    nFileNum = FreeFile
    Open csvPath & "" & _
      wsSheet.Name & ".csv" For Output As #nFileNum
    ExportToTextFile CStr(nFileNum), Sep, False
    Close nFileNum
    Next wsSheet
    
    End Sub
    
    
    
    Public Sub ExportToTextFile(nFileNum As Integer, _
    Sep As String, SelectionOnly As Boolean)
    
    Dim WholeLine As String
    Dim RowNdx As Long
    Dim ColNdx As Integer
    Dim StartRow As Long
    Dim EndRow As Long
    Dim StartCol As Integer
    Dim EndCol As Integer
    Dim CellValue As String
    
    Application.ScreenUpdating = False
    On Error GoTo EndMacro:
    
    If SelectionOnly = True Then
    With Selection
    StartRow = .Cells(1).Row
    StartCol = .Cells(1).Column
    EndRow = .Cells(.Cells.Count).Row
    EndCol = .Cells(.Cells.Count).Column
    End With
    Else
    With ActiveSheet.UsedRange
    StartRow = .Cells(1).Row
    StartCol = .Cells(1).Column
    EndRow = .Cells(.Cells.Count).Row
    EndCol = .Cells(.Cells.Count).Column
    End With
    End If
    
    For RowNdx = StartRow To EndRow
    WholeLine = ""
    For ColNdx = StartCol To EndCol
    If Cells(RowNdx, ColNdx).Value = "" Then
    CellValue = ""
    Else
    CellValue = Cells(RowNdx, ColNdx).Value
    End If
    WholeLine = WholeLine & CellValue & Sep
    Next ColNdx
    WholeLine = Left(WholeLine, Len(WholeLine) - Len(Sep))
    Print #nFileNum, WholeLine
    Next RowNdx
    
    EndMacro:
    On Error GoTo 0
    Application.ScreenUpdating = True
    
    End Sub



  • di Vecchio Frac data: 22/10/2012 09:22:21

    Non ti serve tutto quel po' di codice "Directory Choosing Helper Functions" per poter scegliere una directory, probabilmente l'hai trovato per VB, ma in Excel ci sono istruzioni apposite che lo fanno (FileDialog).
    Per esportare un foglio di Excel - invece di usare un file aperto For Output - a me verrebbe da pensare Worksheet.SaveAs con il parametro FileFormat:=xlCSVWindows.
    Naturalmente occorrono alcune prove anche per capire bene che cosa ti serve (" io voglio mantenere la struttura delle colonne excel nei file csv " penso di sapere cosa intendi ma preferirei un esempio in chiaro: ho questa struttura e voglio quest'altra).





  • di Vecchio Frac data: 22/10/2012 14:06:49

    Comunque guarda, ci ho pensato su un attimo, ma veramente tutto il codice che hai postato si riduce a queste pochissime righe.
    Copia e incolla in un modulo, lancia con Alt-F8 e fai sapere :)
     
    Option Explicit
    
    Sub esporta_fogli()
    Dim sh As Worksheet
    
        For Each sh In ThisWorkbook.Sheets
            sh.SaveAs ThisWorkbook.Path & "" & sh.Name, FileFormat:=xlCSVWindows
        Next
        
    End Sub






  • di Vecchio Frac data: 22/10/2012 14:10:57

    cit. " e non so proprio quale separatore usare "
    --> Di default viene utilizzata la virgola come separatore e a meno di esigenze particolari si può lasciare la virgola. Per esigenze particolari intendo che tu non debba memorizzare numeri con decimali in formato italiano (che usa la virgola come separatore) oppure testo che contiene delle virgole (ad esempio degli indirizzo con i numeri civici separati da virgola dalla toponomastica).
    In tal caso dovremo cambiare strategia :)
    La virgola è il default proprio perché "csv" significa appunto "comma separated values".





  • di Vecchio Frac data: 22/10/2012 14:14:53

    E per darti una risposta del tutto completa, ti dirò che puoi benissimo utilizzare il codice che hai postato, senza tutta la parte della scelta della directory (quindi puoi sfruttare la sola Sub DoTheExport), con l'unica variante che a te interessa: salvare i file nella stessa cartella dell'originale.
    per ottenere questo risultato, cambia la riga

    csvPath = GetFolderName("Choose the folder to export CSV files to:")

    con questa:

    csvPath = ThisWorkbook.Path

    Il resto funzionerà perfettamente (la routine è costruita molto bene, ti permette di specificare un separatore diverso dalla virgola e ti permette di specificare esattamente quale range di celle esportare).





  • di Francesco Tokyo (utente non iscritto) data: 23/10/2012 02:45:08

    Grazie dell'aiuto!

    Ho provato il codice che mi hai passato, molto gentilmente, ma mi esce un errore sul salvataggio del file.

    Runtime error "1004"

    Ho comunque studiato un po' i file csv e VBA, e ho scoperto che il codice che avevo trovato funziona perfettamente. Il problema era sul separatore, che non poteva essere la virgola, in quanto devo esportare delle liste di parole chiave separate da virgole in una stessa cella. E' bastato impostare un separatore diverso e tutto e' andato a posto.

    Comunque, tutto sembra funzionare e il lavoro che devo fare lo riesco a fare, quindi sono piu' che felice

    Ne approfittero' per approfondire lo studio di Excel e delle macro.

    Grazie ancora dell'aiuto!

    Francesco.



  • di Vecchio Frac data: 23/10/2012 08:33:10

    Bene, meglio così alla fine.

    cit. " Runtime error "1004"
    ---> Probabilmente ci sono caratteri che ad Excel non piacciono nei nomi dei fogli :)

    cit. " ho scoperto che il codice che avevo trovato funziona perfettamente. Il problema era sul separatore, che non poteva essere la virgola, in quanto devo esportare delle liste di parole chiave separate da virgole in una stessa cella"
    ---> LOL, l'ho ben detto anch'io che andava bene così, bastava - per i tuoi scopi - impostare direttamente da codice la directory di salvataggio risparmiandoti tutto l'ambaradan sulla scelta della cartella di destinazione.