Valutazione 4.87/ 5 (100.00%) 5838 voti

Condividi:        

[Excel 2010] Macro per importare dati da vari file excel

Vuoi potenziare i tuoi documenti Word? Non sai come si fa una macro in Excel? Devi creare una presentazione in PowerPoint?
Oppure sei passato a OpenOffice e non sei sicuro di come lavorare al meglio?

Moderatori: Anthony47, Flash30005

[Excel 2010] Macro per importare dati da vari file excel

Postdi Longo87 » 20/11/13 17:05

Buongiorno a tutti,
mi sono imbattuto nelle macro. La mia esperienza di programmazione si ferma ad un esame in C++ fatto nel 2006 nella facoltà di Ing, quindi sono bello arrugginito e completamente a digiuno di Visual Basic.

Veniamo al dunque:
Ho diversi files excel, tutti salvati in diverse sottocartelle ma all'interno di una medesima cartella principale (E:\danni occulti 2013). In pratica all'interno della cartella danni occulti, ci sono varie cartelle (una per mese) e dentro ogni cartella del mese ci sono altre cartelle, dove all'interno è contenuto un singolo file excel ed una serie di fotografie correlate.

Questi files sono tutti uguali tra di loro, hanno un unico foglio denominato Foglio 1, ma hanno tutti nomi differenti (ovviamente sono tutti .xls)

In un nuovo file (“Database'13.XLS”) contenuto nella cartella "danni occulti 2013" dovrei importare su ogni riga diversi valori contenuti nei vari fari excel e creare un link alla cartella per reperire il materiale fotografico.

Ho capito che devo realizzare un sottoprogramma da fare girare fino all'esaurimento dei vari file, ma purtroppo le mie conoscenze sono limitate e non riesco a farlo girare, nonostante ci abbia sbattuto sopra la testa per un paio d'ore abbondanti.
Comunque al momento, scopiazzando qui e la e andando a ragionamento sono a questo punto:

Sub importa segnalazioni()
ChDir ("E:\danni occulti 2013")
MyF = Dir("*.xls")
If MyF = "" Then Exit Sub
While MyF <> ""
Call FImp(MyF)
MyF = Dir
Wend
End Sub

Sub FImp(NFile)
Workbooks.Open Filename:=NFile
Sheets("Foglio 1").Activate
If Len(Replace(NFile, "(", "")) = Len(NFile) Then
RNum = 0
Else: RNum = Val(Mid(NFile, InStr(1, NFile, "(") + 1, InStr(1, NFile, ")") - InStr(1, NFile, "(") - 1))
End If

ThisWorkbook.Sheets("Foglio1").Cells(RNum + 1, "A") = Range("A10").Value '<<<
ThisWorkbook.Sheets("Foglio1").Cells(RNum + 1, "B") = Range("D10").Value '<<<
Workbooks(NFile).Close savechanges:=False
End Sub

La parte rossa è quella di codice che non riesco ad interpretare, oltre al fatto che il resto potrebbe essere sbagliato e manca ancora la parte dei link alla cartella da fare.
Un Grazie doveroso a coloro che potranno aiutarmi.
Longo87
Utente Junior
 
Post: 10
Iscritto il: 20/11/13 16:34

Sponsor
 

Re: [Excel 2010] Macro per importare dati da vari file excel

Postdi Anthony47 » 21/11/13 02:23

Si puo' fare, ma e' lungo da collaudare quindi stasera rimani quasi a vuoto.

"Quasi" perche', per cominciare, vedi se riesci a usare la macro runAttrib descritta in questo messaggio: viewtopic.php?t=99260#p571755
Il suo obiettivo e' di creare un elenco di file Excel che dovranno essere aperti.
Il risultato dovrebbe essere un file pippop.txt nella ditectory C:\PROVA\ (che dev esistere), ottenuto tramite il comando dos "Attrib.exe".
Il file va quindi "importato" in excel, in modo da avere l' elenco file in colonna B di un foglio.

La macro successiva si occupera' di aprire uno dopo l' altro questi file e collezionare le celle che ti interessano; ma questo lo vedremo domani.

Ciao
Anthony
Win7 + Office 2010 Ita; Win 7 + Office 2013 Ita
Xp + Office 2003 Ita
E voi cosa usate? (per istruzioni vedere viewtopic.php?f=26&t=97449)
Avatar utente
Anthony47
Moderatore
 
Post: 13899
Iscritto il: 21/03/06 16:03
Località: Ivrea

Re: [Excel 2010] Macro per importare dati da vari file excel

Postdi Longo87 » 21/11/13 12:04

Grazie mille per la risposta Antony.
Dunque al momento ho importato la macro runAttrib e sembrerebbe funzionare almeno in parte. Il file bat lo genera, mentre purtroppo il file di testo no...

EDIT Ok sono riuscito a farlo andare rinominando i file da "danni occulti 2013" a "danni_occulti_2013" Al momento stò lavorando su questo codice. Speriamo di trovare una soluzione.

Quindi al momento la mia runAttrib è così scritta:

Sub runAttrib()
myDir = "E:\danni_occulti_2013\" '<< Drive & directory
Close #1
Open "E:\danni_occulti_2013\myPippoBat.bat" For Output As #1
Print #1, "C:\Windows\System32\attrib.exe " & myDir & "*.xls /s >E:\danni_occulti_2013\pippop.txt" '<<< *.ext
Close #1
myPid = Shell("E:\danni_occulti_2013\myPippoBat.bat")
Application.Wait (Now + TimeValue("0:00:02"))
myTim = Timer
Do While IsProcessRunning("attrib.exe")
DoEvents: DoEvents: Loop
'MsgBox (Timer - myTim)
End Sub

Private Function IsProcessRunning(ByVal ProcName As String) As Boolean
Dim objWMIService, objProcess, colProcess
Dim strComputer, strList
'
strComputer = "."
'
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")

Set colProcess = objWMIService.ExecQuery _
("Select * from Win32_Process")

For Each objProcess In colProcess
If CBool(InStr(1, objProcess.Name, ProcName, vbTextCompare)) Then
IsProcessRunning = True
Exit Function
End If
DoEvents
Next
End Function


Adesso ho aperto ed importato il file di Testo. Cerco di lavorare su questo file per la seconda parte. Ossia, apri il file e copia il contenuto celle. Vediamo cosa riesco a combinare.
Longo87
Utente Junior
 
Post: 10
Iscritto il: 20/11/13 16:34

Re: [Excel 2010] Macro per importare dati da vari file excel

Postdi Anthony47 » 22/11/13 00:45

Nel ".bat" avrei dovuto delimitare il path con due "apostrofo" (oltre alle virgolette), vista la presenza di "spazi" nel nome; va bene la modifica che hai fatto.

Adesso lavorerai in un loop che grosso modo fara':
1)Legge uno dopo l' altro i nomi nel Foglio con l' elenco, con un ciclo For I /Next I
2)Calcoli la prossima riga dove devi scrivere il riepilogo e la memorizzi nella varaibile NextL
3)Apre il file
4)Metti in colonna A del foglio riepilogo il nome del file aperto, con una istruzione tipo
Codice: Seleziona tutto
Thisworkbook.Sheets("IlFoglioDiRiepilogo").Cells(NextL,1).value= ActiveWorkbook.Name

5)Inserisci l' hyperlink che punta alla cartella in cui giace il file, con
Codice: Seleziona tutto
Thisworkbook.Sheets("IlFoglioDiRiepilogo").Cells(NextL,1).Hyperlinks.Add Anchor:= Thisworkbook.Sheets("IlFoglioDiRiepilogo").Cells(NextL,1), Address:= ActiveWorkbook.Path

6)Una dopo l' altra compili le celle sul file di riepilogo con N istruzioni del tipo
Codice: Seleziona tutto
Thisworkbook.Sheets("IlFoglioDiRiepilogo").Cells(NextL,2).value=Cells(Riga, Colonna).value

NB: Thisworkbook punta al file che contiene la macro; dopo "uguale" punti invece al file appena aperto.
7)Chiudi il file senza salvare, con
Codice: Seleziona tutto
ActiveWorkbook.Close savechanges:=False

8)Ripeti per il prossimo nome file

Mi fermo a questo livello perche' mi pare che ti piace scoprire le cose da solo; ma prima di disperarti sai che siamo qui.

Ciao, fai sapere...
Anthony
Win7 + Office 2010 Ita; Win 7 + Office 2013 Ita
Xp + Office 2003 Ita
E voi cosa usate? (per istruzioni vedere viewtopic.php?f=26&t=97449)
Avatar utente
Anthony47
Moderatore
 
Post: 13899
Iscritto il: 21/03/06 16:03
Località: Ivrea

Re: [Excel 2010] Macro per importare dati da vari file excel

Postdi Longo87 » 22/11/13 15:34

Ciao Antony, ti ringrazio molto per la mano che mi stai dando. La questione si è complicata parecchio purtroppo :D
Comunque ho provato a lavorare sulla macro MacroInventory che avevi proposto nella discussione a cui mi rimandi con link nel tuo primo post in questa discussione.

Qui sotto c'è la macro esattamente come l'avevi fatta tu.

Codice: Seleziona tutto
Sub MacroInventory()
'
Dim VBCodeMod
Dim StartLine As Long
Dim Msg As String
Dim ProcName As String
Dim VBComp
Dim ModName As String
Dim FileList As Worksheet, ProcList As Worksheet, myCFile As String
Dim I As Long, myNRow As Long, JJ As Long, myHLine As Long, TotFIles

Set FileList = ThisWorkbook.Sheets("Foglio1")
Set ProcList = ThisWorkbook.Sheets("Foglio2")
aaaa = FileList.Cells(Rows.Count, 2).End(xlUp).Row

'Riga di codice della macro che sara' inserita in Inventario
'   1=prima, 2= seconda, ...
myHLine = 1    '<<< Riga di codice della macro che sara' inserita in Inventario

Application.Calculation = xlManual
TotFIles = FileList.Cells(Rows.Count, 2).End(xlUp).Row
UserForm2.Show vbModeless
DoEvents: DoEvents
UserForm2.TextBox4 = TotFIles
For I = 1 To TotFIles
    UserForm2.TextBox2 = I
    myCFile = FileList.Cells(I, 2)
    UserForm2.TextBox1.Text = myCFile
    myNRow = ProcList.Cells(ProcList.Rows.Count, 7).End(xlUp).Row + 2
    ProcList.Cells(myNRow, 7) = myCFile
    ProcList.Cells(myNRow, 1) = "###_HEAD"     'Scritta che rimane in caso di errore sul  file
    ProcList.Cells(myNRow, 5) = Environ("ComputerName")
'
    On Error GoTo myErr
    myDate = FileDateTime(myCFile)
        ProcList.Cells(myNRow, 4) = myDate
    Application.EnableEvents = False
    Application.DisplayAlerts = False
    Application.ScreenUpdating = False
   
    Workbooks.Open myCFile, 0, True
        Application.DisplayAlerts = True
    mySplit = Split(myCFile, "\")
    Workbooks(mySplit(UBound(mySplit, 1))).Activate
    ProcList.Cells(myNRow, 1) = "##_" & mySplit(UBound(mySplit, 1)) 'Replace "##_HEAD"
'
    myWKBook = ActiveWorkbook.Name
    If Right(myWKBook, 5) = ".xlsx" Then GoTo WBClose  'Nessun check sulle macro se ".xlsx"
        For Each VBComp In ActiveWorkbook.VBProject.VBComponents
            ModName = VBComp.Name
            myMod = VBComp.Type   '1=modulo; 100=Foglio /Thisworkbook; 3=Userform; lista non esaustiva
        '
            Set VBCodeMod = ActiveWorkbook.VBProject.VBComponents(ModName).CodeModule
            With VBCodeMod
                StartLine = .CountOfDeclarationLines + 1
                Do Until StartLine >= .Countoflines
                    myProcedure = .ProcOfLine(StartLine, 0)
'cerca prima riga della macro:
                    For JJ = 0 To 20
                        myHead = VBCodeMod.Lines(StartLine + JJ, 1)
                        If myHead <> "" Then Exit For
                        If (StartLine + JJ) > .Countoflines Then JJ = 0: Exit For
                    Next JJ
'
                    myHead = VBCodeMod.Lines(StartLine + JJ + myHLine - 1, 1)
                    StartLine = StartLine + .ProcCountLines(.ProcOfLine(StartLine, 0), 0)
'Salva info di macro in Foglio2:
                    myNRow = ProcList.Cells(ProcList.Rows.Count, 7).End(xlUp).Row + 1
                    ProcList.Cells(myNRow, 1) = ModName                 'Nome Modulo
                    ProcList.Cells(myNRow, 2) = myProcedure             'Nome Macro
                    ProcList.Cells(myNRow, 3) = myMod                   'Tipo di Modulo
                    ProcList.Cells(myNRow, 4) = myDate                  'Data del file
                    ProcList.Cells(myNRow, 5) = Environ("ComputerName") 'Computer name
                    ProcList.Cells(myNRow, 6) = myHead                  'Riga prescelta del codice
                    ProcList.Cells(myNRow, 7) = myCFile                 'Full Path & Name del file
                Loop
            End With
        Next VBComp
WBClose:
    DoEvents
    If ActiveWorkbook.Name <> ThisWorkbook.Name Then
        ActiveWorkbook.Close savechanges:=False
    End If
    On Error GoTo 0
    Application.EnableEvents = True
    Application.ScreenUpdating = True
    Sheets("Foglio2").Select
    Cells(Rows.Count, 7).End(xlUp).Offset(0, -6).Select
    If UserForm2.CBStop = True Then
        MsgBox ("La macro e' stata interrotta; riprenderla manualmente col tasto F5")
   
        UserForm2.CBStop = False
    End If

'Application.ScreenUpdating = True
Next I
'Fine elenco files
Application.Calculation = xlCalculationAutomatic
Calculate
MsgBox ("God willing, abbiamo finito...")    'Completamento job
Unload UserForm2
Exit Sub
myErr:
If Err.Number = 50289 Then
    ProcList.Cells(myNRow, 6) = "VBProject PROTETTO...."
    Resume WBClose
Else
    Msg = "Errore " & Err.Number & vbCrLf & Err.Description
    MsgBox (Msg)
   
    ProcList.Cells(myNRow, 6) = "ERRORE tipo: " & Err.Number
'Resume       'Per vedere dove e' successo l' errore e debuggare
    Resume WBClose
End If
Stop  'Qui non dovremmo mai arrivarci
Application.Calculation = xlCalculationAutomatic
Calculate
End Sub



Penso che devo utilizzare un codice simile a questo

ThisWorkbook.Sheets("Foglio1").Cells(RNum + 1, "A") = Range("A10").Value '<<<
ThisWorkbook.Sheets("Foglio1").Cells(RNum + 1, "B") = Range("D10").Value '<<<


Oltre poi all'integrazione che mi hai proposto tu nel precedente messaggio per gli hyperlink.
Dunque a logica dichiaro
FileList e Proclist
Set FileList = ThisWorkbook.Sheets("Foglio1")
Set ProcList = ThisWorkbook.Sheets("Foglio2")

A questo punto con il ciclo For I / Next I apro ogni file e prendo le informazioni che mi servono per poi richiuderlo. Il fatto è che non riesco a modificare in un modo "funzionale" la tua macro... Non riesco a farla girare, perchè forse non ho ben chiaro la logica di base non avendo mai lavorato con VBA a differenza del C++.
Devo ammettere che è davvero frustrante stare davanti ad un monitor e non sapere cosa fare :(

Comunque è mia intenzione comprendere la logica e poi dopo lavorarci sopra, dove posso eventualmente trovare qualche info sul VBA per capire come lavorare?
Longo87
Utente Junior
 
Post: 10
Iscritto il: 20/11/13 16:34

Re: [Excel 2010] Macro per importare dati da vari file excel

Postdi Longo87 » 22/11/13 16:58

non so se può servire, ma qui qualcosa ho trovato e spiega come funziona un ciclo, così che io possa cominciare a comprendere http://www.excelfacile.it/Macro/2007/Ci ... 20Next.htm
Longo87
Utente Junior
 
Post: 10
Iscritto il: 20/11/13 16:34

Re: [Excel 2010] Macro per importare dati da vari file excel

Postdi Longo87 » 22/11/13 17:17

Longo87 ha scritto:non so se può servire, ma qui qualcosa ho trovato e spiega come funziona un ciclo, così che io possa cominciare a comprendere http://www.excelfacile.it/Macro/2007/Ci ... 20Next.htm


anche questo non è male. https://www.mat.unical.it/didattica/cli ... 0Basic.pdf
Longo87
Utente Junior
 
Post: 10
Iscritto il: 20/11/13 16:34

Re: [Excel 2010] Macro per importare dati da vari file excel

Postdi Anthony47 » 22/11/13 17:55

La MacroInventory non c' entra con quello che devi fare; di quella discussione pendiamo solo la parte che ci consente di creare l' elenco file.

Piu' tardi potro' essere piu' preciso; se fai progressi scrivilo.

Ciao
Anthony
Win7 + Office 2010 Ita; Win 7 + Office 2013 Ita
Xp + Office 2003 Ita
E voi cosa usate? (per istruzioni vedere viewtopic.php?f=26&t=97449)
Avatar utente
Anthony47
Moderatore
 
Post: 13899
Iscritto il: 21/03/06 16:03
Località: Ivrea

Re: [Excel 2010] Macro per importare dati da vari file excel

Postdi Anthony47 » 23/11/13 17:20

Allora...
Immaginiamo che l' elenco files sia in Foglio1, B1 e sottostanti celle, e che vuoi creare il tuo riepilogo in Foglio2.
Codice: Seleziona tutto
Sub longol()
Dim I As Long, LastB As Long, NextL As Long
Dim FileList As Worksheet, DestSh As Worksheet
'
Set FileList = ThisWorkbook.Sheets("Foglio1")    '<< Il foglio con l' elenco dei file
Set DestSh = ThisWorkbook.Sheets("Foglio2")      '<< Il foglio in cui si creera' il riepilogo
'
LastB = FileList.Cells(Rows.Count, "B").End(xlUp).Row
For I = 1 To LastB
    myCFile = FileList.Cells(I, 2)
    Application.EnableEvents = False
    Application.DisplayAlerts = False
    Workbooks.Open myCFile, 0, True
    Application.DisplayAlerts = True
    NextL = DestSh.Cells(DestSh.Rows.Count, "A").End(xlUp).Row + 1
    DestSh.Cells(NextL, 1).Value = ActiveWorkbook.Name
    DestSh.Cells(NextL, 1).Hyperlinks.Add Anchor:=DestSh.Cells(NextL, 1), Address:=ActiveWorkbook.Path
'Mette da col 2 in poi i dati raccolti dal file aperto:
    DestSh.Cells(NextL, 2).Value = Range("X22").Value       '<<< X22 = indirizzo da copiare
    DestSh.Cells(NextL, 3).Value = Range("Y33").Value       '<<< Y33 = indirizzo da copiare
    DestSh.Cells(NextL, 4).Value = Range("Z44").Value       '<<< Z44 = indirizzo da copiare
'altre istruzioni analoghe...
'
'
    If ActiveWorkbook.Name <> ThisWorkbook.Name Then
        ActiveWorkbook.Close savechanges:=False
    End If
Next I
Application.EnableEvents = True
MsgBox ("Completato...")
End Sub
Inserisci la macro in un "Modulo" vuoto e personalizza le istruzioni marcate <<, in particolare quelle che indicano quali celle devono essere prese da ogni file che viene aperto e salvate nel foglio di riepilogo; aggiungi altre righe di codice per salvare tutte le celle che ti interessano.

Poi vai su excel, meglio se con solo il file "corrente" aperto e lancia la macro.
Per cominciare prova solo con una ventina di file, per vedere l' effetto e il risultato; se funziona cancella il foglio di riepilogo e prova con tutto l' elenco dei file.

Ciao
Anthony
Win7 + Office 2010 Ita; Win 7 + Office 2013 Ita
Xp + Office 2003 Ita
E voi cosa usate? (per istruzioni vedere viewtopic.php?f=26&t=97449)
Avatar utente
Anthony47
Moderatore
 
Post: 13899
Iscritto il: 21/03/06 16:03
Località: Ivrea

Re: [Excel 2010] Macro per importare dati da vari file excel

Postdi Longo87 » 25/11/13 14:06

Grazie mille Antony sei stato gentilissimo e finalmente riesco a fare funzionare tutte le macro.
Adesso vedo di personalizzarle un attimo, poi scrivo tutto circa la mia esperienza.
Longo87
Utente Junior
 
Post: 10
Iscritto il: 20/11/13 16:34


Torna a Applicazioni Office Windows


Topic correlati a "[Excel 2010] Macro per importare dati da vari file excel":


Chi c’è in linea

Visitano il forum: Nessuno e 6 ospiti