trovaapri filecopia e incolla



  • trova,apri file,copia e incolla
    di lucippo (utente non iscritto) data: 09/01/2014 16:07:45

    ciao ragazzi,
    devo fare un piccolo programmino in excel-VBA che faccia il seguente compito:
    - chiede di selezionare una directory in cui ci sono excel files
    - per ogni file all'interno della directory, lo apre, va al primo foglio e copia tutti i dati (un solo foglio per ogni file)
    - incolla i dati in un nuovo file/foglio che si chiama MAIN
    - nella prima colonna del foglio MAIN, inserisca il nome del file su ogni cella della prima colonna a seconda del file da cui i dati sono stati copiati;
    - ripeta la stessa operazione per tutti i files presenti nella directory.

    sapete darmi consigli utili in modo che possa iniziare con il piede gisuto?
    grazie!!



  • di Grograman (utente non iscritto) data: 09/01/2014 16:45:19

    Gnomme gnomme... avevo già scritto un codice che faceva esattamente quanto descritto... solo non ricordo quando!



  • di Grograman (utente non iscritto) data: 09/01/2014 16:49:34

    Trovato!
    Non è proprio lui, la versoine generica.
    Se riesco domani lo implemento, intanto magari serve di spunto:
     
    Option Explicit
    
    Private Sub Sfoglia_Files()
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ''''' ATTENZIONE RICHIEDE L'ATTIVAZIONE DELLA LIBRERIA MICROSOFT SCRIPTING RUNTIME '''''
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        Dim strPath As String
       
        Dim objFSY As FileSystemObject
        Dim objFOL As Folder
        Dim objFIL As File
        
        Dim wbFrom As Workbook, wbTo As Workbook
        Dim wsFrom As Worksheet, wsTo As Worksheet
        Dim x As Long, i As Long
        Dim rngCopy As Range
        
        Set wbTo = ThisWorkbook
        Set wsTo = wbTo.Sheets(1)
         
        strPath = "C:ProveFiles" '''QUI IL PERCORSO
        
        Set objFSY = New FileSystemObject
        Set objFOL = objFSY.GetFolder(strPath)
    
        For Each objFIL In objFOL.Files
          x = wsTo.Range("B" & wsTo.Rows.Count).End(xlUp).Row + 1
          
          Set wbFrom = Application.Workbooks.Open(objFIL)
          Set wsFrom = wbFrom.Sheets(1)
            With wsFrom
              i = .Range("B" & .Rows.Count).End(xlUp).Row
              Set rngCopy = .Range("B3:Q" & i)
              rngCopy.Copy wsTo.Cells(x, 2)
              Set rngCopy = Nothing
            End With
          wbFrom.Close 0
          Set wbFrom = Nothing
          Set wsFrom = Nothing
        Next
    
        Set objFSY = Nothing
        Set objFOL = Nothing
        Set wbTo = ThisWorkbook
        Set wsTo = Nothing
    End Sub
    



  • di mb data: 09/01/2014 17:48:50

    ciao prova se questo fa al caso tuo
    devi crearti una cartella dove sono inseriti i file che si chiama moduli ricevuti e una sottocartella che si chiama storico.
    oppure puoi modificarti la procedura con la richiesta di aprire la cartella manualmente ecc.......

    buon prova

    p.s sicuramente la soluzione Grograman che saluto sarà migliore

    ciao





     
    Sub unionefile()
    '
    ' unionefile Macro
    '
    ' Scelta rapida da tastiera: CTRL+h
    'Sub Copia_Dati_da_più_File()
        Dim File_El As String, MiaDir As String, Perc_Stor  As String, File_Cop As Integer
        Dim Nome_Iniziale As String, Nome_Attuale As String, RR As Integer, I As Integer, J As Integer, Righe As Integer
        Dim WS_In As String, WS_Out As String
        
        Application.ScreenUpdating = False
        Nome_Iniziale = ActiveWorkbook.Name
        WS_Out = ActiveSheet.Name
        
    ' attenzione a mettere le "" finali !!!
        MiaDir = "C:Moduli_Ricevuti" ' ----->> ADATTA i nomi
        Perc_Stor = "Storico" ' ----->> ADATTA i nomi
        File_El = Dir(MiaDir & "*.xls")
        If File_El = "" Then
            MsgBox "ATTENZIONE: nel percorso   '" & MiaDir & "'   non sono stati trovati file"
            Exit Sub
        End If
        
        I = Workbooks(Nome_Iniziale).Sheets(WS_Out).Range("A" & Rows.Count).End(xlUp).Row + 1
        Righe = I
        File_Cop = 0
        While File_El <> ""
            Nome_Attuale = File_El
            Workbooks.Open Filename:=MiaDir & Nome_Attuale
            WS_In = Workbooks(Nome_Attuale).ActiveSheet.Name
            RR = Workbooks(Nome_Attuale).Sheets(WS_In).Range("A" & Rows.Count).End(xlUp).Row
            For J = 2 To RR
                Workbooks(Nome_Iniziale).Sheets(WS_Out).Cells(I, 1) = File_El
                Workbooks(Nome_Iniziale).Sheets(WS_Out).Cells(I, 2) = Date
                
    '....................................................................................................................
    ' QUI vanno inserite le istruzioni per copiare i dati
    ' Nell'esempio vengono copiate le colonne A, B, C e D ---->> ADATTARE in base alle esigenze
                Workbooks(Nome_Iniziale).Sheets(WS_Out).Cells(I, 3) = Workbooks(Nome_Attuale).Sheets(WS_In).Cells(J, 1)
                Workbooks(Nome_Iniziale).Sheets(WS_Out).Cells(I, 4) = Workbooks(Nome_Attuale).Sheets(WS_In).Cells(J, 2)
                Workbooks(Nome_Iniziale).Sheets(WS_Out).Cells(I, 5) = Workbooks(Nome_Attuale).Sheets(WS_In).Cells(J, 3)
                Workbooks(Nome_Iniziale).Sheets(WS_Out).Cells(I, 6) = Workbooks(Nome_Attuale).Sheets(WS_In).Cells(J, 4)
    '           ...
    '....................................................................................................................
                
                I = I + 1
            Next J
            File_Cop = File_Cop + 1
            Windows(Nome_Attuale).Close
            On Error GoTo Errore
            Name MiaDir & Nome_Attuale As MiaDir & Perc_Stor & Nome_Attuale
            
            File_El = Dir
        Wend
        Application.ScreenUpdating = True
        MsgBox "Sono state copiate:  '" & I - Righe & "'  righe di dati" & vbCrLf & _
            "Presenti in:   '" & File_Cop & "'   File"
        Exit Sub
        
    Errore:
        MsgBox "ATTENZIONE !!!" & vbCrLf & "Il File:   '" & Nome_Attuale & _
            "'" & vbCrLf & "E' stato già elaborato e storicizzato" & vbCrLf & vbCrLf & _
            "L'elaborazione viene interrotta !!!", vbCritical
    
    End Sub
    



  • di nichicanta (utente non iscritto) data: 09/01/2014 19:40:53

    Ciao lucippo, prova a questo indirizzo e vedi se riesci a trovare la risposta giusta, il grande gamberini sicuramente ha la soluzione anche per te.
    www.maurogsc.eu/comefareperexcel/comefare.aspx‎



  • di Grograman data: 10/01/2014 09:27:50

    Ariciao!

    Eccolo revisionato, è ancora da adattare, ma l'ho commentato più possibile (sperando di non fare confusione ) sulla base delle indicazioni ricevute:
     
    Private Sub Sfoglia_Files()
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ''''' ATTENZIONE RICHIEDE L'ATTIVAZIONE DELLA LIBRERIA MICROSOFT SCRIPTING RUNTIME '''''
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
      Application.DisplayAlerts = False
      Dim strPath As String
     
      Dim oFSY As FileSystemObject 'variabile oggetto della libreria indicata
      'h t t p: /  /msdn .m ic roso ft.com/ it-it/l ibrary/a a711216(v= vs.71).aspx
      
      Dim oFOL As Folder 'come sopra
      Dim oFIL As File 'idem con patate
      Dim oFD As FileDialog 'variabile oggetto, da guida in linea "un'istanza della finestra di dialogo dei file."
      'trattasi di proprietà dell'oggetto "application"
      Dim oScelta As Variant 'qui non so se sia la scelta migliore, serve per "catturare" la scelta fatta sul filedialog"
      
      Dim wbFrom As Workbook, wbTo As Workbook
      'due variabili workbook, una la istanzieremo su quello dove importare
      'l'altra diverrà di volta in volta il file che apriremo
      
      Dim wsFrom As Worksheet, wsTo As Worksheet
      'come sopra, ma due worksheet
      
      
      Dim x As Long, i As Long
      'serviranno per determinare da che riga a che riga copiare e dove incollare
      
      Dim rngCopy As Range
      
     
      '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
      '- chiede di selezionare una directory in cui ci sono excel files '
      '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
      Set oFD = Application.FileDialog(msoFileDialogFolderPicker)
      With oFD
        .InitialFileName = "C:" 'qui modificare eventuale cartella di default
        .Title = "Sfoglia cartelle"
        .ButtonName = "Ok"
        .AllowMultiSelect = False
        .InitialView = msoFileDialogViewDetails
        .Show
        For Each oScelta In .SelectedItems
          strPath = oScelta 'la variabile stringa diventa il percorso della cartella selezionata
        Next oScelta
      End With
      
      If strPath = "" Then GoTo Uscita
      
      Set wbTo = ThisWorkbook
      
      'istanziamo il foglio dove incollare i dati come il foglio "MAIN" come indicato
      Set wsTo = wbTo.Sheets("MAIN")
      
      Set oFSY = New FileSystemObject
      
      'sempre grazie alla libreria di cui a inizio routine, applicahiamo il metodo "Getfolder" all'oggetto "oFSY"
      'Guida Microsoft per dettagli: ht t p: // m s d n . m i c r o s o ft.com/en- u s / l i b r ary/off i c e/gg278492.aspx
      Set oFOL = oFSY.GetFolder(strPath)
       
      '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
      '- per ogni file all'interno della directory, lo apre, va al primo foglio e copia tutti i dati (un solo foglio per ogni file) '
      '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
      For Each oFIL In oFOL.Files 'per ogni file
        
        'troviamo la prima riga libera di colonna "B" del foglio dove andremo ad incollare i dati
        'questo perchè in colonna A dobbiamo scrivere il nome del file
        x = wsTo.Range("B" & wsTo.Rows.Count).End(xlUp).Row + 1
        
        'istanziamo l'oggetto workbook sul file da cui vogliamo copiare
        Set wbFrom = Application.Workbooks.Open(oFIL)
        
        'idem per il foglio da cui copiare, arbitrariamente il primo (1)
        Set wsFrom = wbFrom.Sheets(1)
        
          With wsFrom
          
            'troviamo ultima riga di colonna A, supponendo di dover copiare da lì in mancanza di maggiori informazioni
            i = .Range("B" & .Rows.Count).End(xlUp).Row
            
            'stabiliamo che range copiare, sempre arbitrariamente da seconda riga a colonna Q in mancanza di maggiori dettagli
            Set rngCopy = .Range("A2:Q" & i)
            
            'copiamo il range
            rngCopy.Copy 'wsTo.Cells(x, 2)
            
            '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
            ' incolla i dati in un nuovo file/foglio che si chiama MAIN     '
            ''hai detto dati duindi procediamo con copia e incolla speciale '
            '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
            wsTo.Cells(x, 2).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
            
            
            '''''''''''''''''''''''''''''''''''''''''''''''''''''''''
            'nella prima colonna del foglio MAIN, inserisca il nome '
            'del file su ogni cella della prima colonna a seconda   '
            'del file da cui i dati sono stati copiati              '
            '''''''''''''''''''''''''''''''''''''''''''''''''''''''''
            wsTo.Range("A" & x & ":A" & x + rngCopy.Rows.Count - 1) = wbFrom.Name
            'qui il "-1" è perchè copiamo da riga 2 occhio!
            
            'distruggiamo oggetto range
            Set rngCopy = Nothing
          End With
        
        
        
        'chiudiamo senza salvare il file aperto
        wbFrom.Close 0
        
        'distruggiamo gli oggetti istanziati poco sopra
        Set wbFrom = Nothing
        Set wsFrom = Nothing
        
      '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
      'ripeta la stessa operazione per tutti i files presenti nella directory '
      '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
      Next oFIL
    
    Uscita:
      Set oFSY = Nothing
      Set oFOL = Nothing
      Set wbTo = ThisWorkbook
      Set wsTo = Nothing
      Application.DisplayAlerts = False
    End Sub
    



  • di mb data: 10/01/2014 10:54:47

    ciao
    volevo complimentarmi con Grograman, come sempre ha migliorato.
    molto più flessibile la sua Sub




  • di lucippo (utente non iscritto) data: 10/01/2014 11:12:47

    ciao ragazzi,
    siete assolutamente fantastici!
    ho provato ad implementare la prima soluzione, con qualche ritocco sul range da copiare che ho sostituito con "region" che fa piu' al caso mio. non appena ho il codice finito, lo pubblico.
    grazie di nuovo a tutti!



  • di lucippo (utente non iscritto) data: 10/01/2014 15:12:37

    ha funzionato alla grande!!!
    davvero poco o nulla da cambiare, solo il range!
    solo una domanda: circa la LIBRERIA MICROSOFT SCRIPTING RUNTIME, c'e' un modo per installarla all'inizio ovvero prima che l'utente vado ad utlizzare la macro? se non e' installata, la macro da errore ovviamente.
    vorrei evitare che questo accada e fare in modo che la library venga utlizzata sempre...non so se e' possibile...

    grazie immensamente Grograman!!!!



  • di Grograman data: 10/01/2014 15:25:35

    E di che ho fatto poco o niente, ho infilato due commenti in un codice che tengo sempre pronto all''uso tra gli appunti

    La libreria va attivata a livello di progetto VBA. Quindi la prima volta che incolli quel codice nel file/modello/componente aggiuntivo, ma poi non c'è più bisogno di fare nulla.
    Quindi anche inviando via mail il file dove hai attivato la libreria il progetto funzionerà.



  • di Grograman data: 10/01/2014 15:27:28

    P.s. il povero Emmebi non si senta messo in disparte se non abbiamo proseguito sul suo codice! Come dicevo, io ho tra gli appunti un sacco di codici, perchè sovente mi capita di dover fare lavori ripetitivi o simili da qualcosa di già fatto tra i files.



  • di lucippo (utente non iscritto) data: 10/01/2014 15:34:51

    ah ottimo allora! l'utente che lo riceve non deve fare nulla quindi.
    benissimo, pensavo che anche chi lo riceve dovesse installare la library!
    sorry e grazie ancora!
    ti auguro un fantastico weekend!



  • di mb data: 10/01/2014 16:10:10

    ciao Gro
    non ti preoccupare, anzi rti ringrazio perchè come sempre in questo e altri firum hai permesso a molti come me di togliere le patate dal fuoco senza bruciarle.
    ti dirò di più ti rigrazio perche hai semplificato il passaggio rispetto alla versione che avevo, non obbligandomi più a dover inserire sempre nella stessa cartella i file da unire.
    anch'io come te ho archiviato nelle cose utilissime le tue info
    alla prossima ..



  • di scossa data: 10/01/2014 16:38:35

    @mb: attenzione con la dichiarazione dell variabili:

    Dim Nome_Iniziale As String, Nome_Attuale As String, RR As Integer, I As Integer, J As Integer, Righe As Integer


    RR = Workbooks(Nome_Attuale).Sheets(WS_In).Range("A" & Rows.Count).End(xlUp).Row

    nelle versioni successive alla 2003 le righe di un foglio vanno ben oltre il limite di Integer, quindi le variabili destinate a ricevere il valore della proprietà .Row / .Column (e anche .Rows.Count / .Columns.Count) devono essere dichiarate Long.



  • di mb data: 10/01/2014 16:45:42

    Grazie Scossa per la preziosa segnalazione
    buona serata