Sviluppare funzionalita su Microsoft Office con VBA Macro excel VBA per aprire file con clic sulla cella

LoginRegistrati
Stai vedendo 13 articoli - dal 1 a 13 (di 13 totali)
  • Autore
    Articoli
  • #13809 Risposta

    GnZ_88
    Partecipante

      Buongiorno a tutti,

      Sono nuovo del forum, quindi innanzitutto ne aprofitto per salutare tutti quanti e ringraziarvi in anticipo per la vostra disponibilità.

      Ho scritto una piccola macro in vba per excel che funziona in questo modo:

      Se si fa doppio clic su una delle celle di una determinata colonna, la macro individua il testo contenuto in essa e va a cercare il corrispettivo file (un pdf in questo caso) in un determinato percorso.

      La macro funziona bene ma ha un limite: non è in grado di andare a scansionare le sottocartelle presenti nel percorso che le ho dato. Mi spiego meglio: il percorso che io do alla macro è "C:\\utenti\pippo\" e chiedo di cercarmi un file che si chiama, ad esempio, "prova.pdf", ma dentro quel percorso esistono altre sottocartelle, e il file prova.pdf potrebbe essere dentro una di quelle. Con il codice attuale invece la macro si ferma alla cartella-padre ("pippo", in questo caso) e non va a scansionare le sue cartelle-figli.

      Dato che sono un novizio di vba, potreste per favore darmi qualche dritta per aggiustare il codice?

      Grazie a tutti in anticipo,

      Alex

       

      Di seguito vi allego la mia macro:

      `Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Excel.Range, Cancel As Boolean)
          Dim testo As String
          Dim nomefile As String
          Dim path As String
      
          On Error Resume Next
          
              If Target.Column = 5 Then
              path = "C:\\utenti\pippo\"
              testo = path & Cells(Target.Row, 5)
              nomefile = Dir(Left(testo, Len(testo)) & "*.pdf")
              
              If nomefile = "" Then
                  MsgBox "File non trovato", vbCritical, "ATTENZIONE"
                  Exit Sub
              End If
              
              Do
                  Shell "C:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe " & path & nomefile, vbMaximizedFocus
                  nomefile = Dir
              Loop While nomefile <> ""
          End If
      End Sub
      `
      #13812 Risposta

      vecchio frac
      Senior Moderator
      • Sfida #1
        145 pts

        Mi piace quello slash escapato 🙂

        Come spunto puoi partire a leggerti questa interessante discussione: https://www.excelvba.it/forumexcel/forums/discussione/sfida-numero-1-elenco-di-file-in-cartelle-e-sottocartelle/

        in cui abbiamo trattato, a mo' di sfida, il tema della lettura delle sottocartelle dato un percorso iniziale, senza usare ricorsione (che sarebbe stato troppo facile :D). Scoprirai un mondo 😛

         

        #13816 Risposta

        GnZ_88
        Partecipante

          Ti ringrazio per il link che mi hai inviato!

          Adesso me lo leggerò con attenzione e inizierò a fare un po' di prove. Appena avrò fatto qualche tentativo decente vi farò vedere i risultati e vi chiederò un parere.

           

          #13818 Risposta

          vecchio frac
          Senior Moderator
          • Sfida #1
            145 pts

            Comunque ti do un altro spunto interessante su cui riflettere: se esegui la routine su una macchina che non ha Acrobat Reader, cosa succede? o che ce l'ha ma è installata in un percorso diverso? la shell fallisce... ecco la soluzione: avvia una shell sfruttando l'oggetto WScript e esegui il file pdf direttamente passandolo come argomento al suo metodo Run. In questo modo il file pdf verrà aperto con il lettore impostato in locale, indipendentemente da quale esso sia (per me per esempio è il browser Edge che mi apre i pdf).

            createobject("WScript.Shell").Run "c:\users\franz\desktop\test.pdf"

            E se ci sono spazi nel nome del percorso o del file? beh ti lascio scoprire come risolvere 🙂

            #14205 Risposta

            GnZ_88
            Partecipante

              Ho provatoa buttare giù qualche idea, anche se nella discussione che mi hai citato vengono utilizzati metodi che mi sono ancora poco chiari.

              Comunque ho provato a creare una function che vada a cercarmi il file desiderato, poi tramite la Sub() principale vado ad aprirlo.

              Questo in teoria, ma nella pratica il tutto si arresta sempre su "File non trovato!". Sapete dirmi come mai?

              Considerate che il file in questione è dentro una sottocartella del percorso principale.

               

              Function TrovaFile(FileName As String, MainFolder As Object, ByRef FSO As Object) As String
              DoEvents
              
              If FSO.FileExists(MainFolder & "\" & FileName & "*.pdf*") Then
                  TrovaFile = MainFolder & "\" & FileName & "*.pdf*"
                  Exit Function
              End If
              
              Dim SubFolder As Object
              For Each SubFolder In MainFolder.SubFolders
                  TrovaFile = TrovaFile(FileName, SubFolder, FSO)
              Next
              End Function
              
              
              Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Excel.Range, Cancel As Boolean)
              Dim testo As String
              Dim nomefile As String
              Dim FSO As Object
              Dim Cartella As Object
              
              Set FSO = CreateObject("Scripting.FileSystemObject")
              Set Cartella = FSO.GetFolder("C:\Users\Alex")
              If Target.Column = 5 Then
                  testo = Cells(Target.Row, 5)
                  nomefile = TrovaFile(testo, Cartella, FSO)
              
                  If nomefile = "" Then
                      MsgBox "File non trovato!", vbCritical, "WARNING"
                      Exit Sub
                  End If
              
                  CreateObject("WScript.Shell").Run nomefile
              End If
              End Sub
              
              #14206 Risposta
              albatros54
              albatros54
              Moderatore
                36 pts

                modifica le righe di codiuce cosi

                If FSO.FileExists(MainFolder & "\" & FileName & ".pdf") Then
                TrovaFile = MainFolder & "\" & FileName & ".pdf"
                Exit Function
                End If

                Dim SubFolder As Object
                For Each SubFolder In MainFolder.SubFolders
                TrovaFile = TrovaFile(FileName, SubFolder, FSO)

                exit function
                Next

                nota esplicativa, il codice della funzione va messo in un modulo, mentre il codice dell'evento del foglio va messo nel modulo del foglio  

                 

                 

                 

                 

                Qual è il punto di avere gusti diversi, se non mostrare che i cervelli lavorano diversamente, che pensiamo diversamente? ( Alan Turing)
                Sempre il mare, uomo libero, amerai!
                ( Charles Baudelaire )
                #14212 Risposta

                GnZ_88
                Partecipante

                  Grazie mille!

                  #14246 Risposta

                  GnZ_88
                  Partecipante

                    Ho cantato vittoria troppo presto  .

                    Allora la macro corretta seguendo le tue istruzioni funziona parzialmente. Cerco di spiegarmi:

                    Supponiamo che tutti i file che cerco siano nel percorso "C:\Utenti\Alex\" e siano sparsi in diverse sottocartelle, nominate "A", "B", "C", etc...

                    Con questa macro riesco a trovare e aprire correttamente tutti i file che si trovano direttamente dentro "Alex", cioè non inseriti in sottocartelle, e quelli che si trovano nella sottocartella "A", che è la prima in ordine alfabetico.

                    Se invece il file si trova in un'altra qualsiasi delle sottocartelle che non sia "A", la macro riporta a "File non trovato!"; sembra quindi che non proceda all'iterazione su tutte le sottocartelle ma solo sulla prima, però il codice che ho scritto mi sembra corretto, dato che ho usato un "For Each" su tutte le sottocartelle.

                    Avete idee di quale sia l'errore?

                    `Function TrovaFile(FileName As String, MainFolder As Object, ByRef FSO As Object) As String
                        DoEvents
                    
                        If FSO.FileExists(MainFolder & "\" & FileName & ".pdf") Then
                            FindFile = MainFolder & "\" & FileName & ".pdf"
                            Exit Function
                        End If
                    
                        Dim SubFolder As Object
                        For Each SubFolder In MainFolder.SubFolders
                            TrovaFile = TrovaFile(FileName, SubFolder, FSO)
                            Exit Function
                        Next
                    End Function
                    
                    ------------------------------------------------------
                    
                    Option Explicit
                    
                    Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Excel.Range, Cancel As Boolean)
                    Dim testo As String
                    Dim nomefile As String
                    Dim FSO As Object
                    Dim Cartella As Object
                    
                    Set FSO = CreateObject("Scripting.FileSystemObject")
                    Set Cartella = FSO.GetFolder("C:\Utenti\Alex")
                    If Target.Column = 5 Then
                        testo = Cells(Target.Row, 5)
                        nomefile = TrovaFile(testo, Cartella, FSO)
                    
                        If nomefile = "" Then
                            MsgBox "File non trovato!", vbCritical, "WARNING"
                            Exit Sub
                        End If
                    
                        CreateObject("WScript.Shell").Run nomefile
                    End If
                    End Sub`
                    #14247 Risposta

                    GnZ_88
                    Partecipante

                      Ho cantato vittoria troppo presto.

                      La macro, corretta secondo le tue indicazioni, funziona parzialmente. Cerco di spiegarmi:

                      Il percorso in cui sono contenuti tutti i miei pdf è "C:\Users\Alex", che a sua volta è diviso in sottocartelle denominate "A", "B", "C", ...

                      La macro così scritta lavora bene soltanto con i file contenuti direttamente nel percorso principale e con quelli contenuti nella sottocartella "A", che è la prima dell'elenco.

                      Con tutti gli altri file (quelli contenuti nella sottocartella "B" , nella "C", e così via) non funziona, ritornando a "File non trovato!".

                      Sembra in pratica che l'iterazione si limiti al percorso principale e alla prima delle sottocartelle. Avete idea di quale sia il problema? Ho ricontrollato il codice ma al mio occhio inesperto sembra tutto corretto.

                      Grazie,

                      Alex

                      Function TrovaFile(FileName As String, MainFolder As Object, ByRef FSO As Object) As String
                          DoEvents
                      
                          If FSO.FileExists(MainFolder & "\" & FileName & ".pdf") Then
                              TrovaFile = MainFolder & "\" & FileName & ".pdf"
                              Exit Function
                          End If
                      
                          Dim SubFolder As Object
                          For Each SubFolder In MainFolder.SubFolders
                              TrovaFile = TrovaFile(FileName, SubFolder, FSO)
                              Exit Function
                          Next
                      End Function
                      
                      -------------------------------
                      
                      Option Explicit
                      
                      Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Excel.Range, Cancel As Boolean)
                      Dim testo As String
                      Dim nomefile As String
                      Dim FSO As Object
                      Dim Cartella As Object
                      
                      Set FSO = CreateObject("Scripting.FileSystemObject")
                      Set Cartella = FSO.GetFolder("C:\Users\Alex")
                      If Target.Column = 5 Then
                          testo = Cells(Target.Row, 5)
                          nomefile = TrovaFile(testo, Cartella, FSO)
                      
                          If nomefile = "" Then
                              MsgBox "File non trovato!", vbCritical, "WARNING"
                              Exit Sub
                          End If
                      
                          CreateObject("WScript.Shell").Run nomefile
                      End If
                      End Sub

                       

                      #14264 Risposta
                      patel
                      patel
                      Moderatore
                        31 pts

                        elimina il secondo exit function

                        #14273 Risposta
                        albatros54
                        albatros54
                        Moderatore
                          36 pts

                          Ho modificato un poco il codice della funzione, sostituiscila con quella che ti posto, fai sapere

                          Function TrovaFile(FileName As String, MainFolder As Object, ByRef FSO As Object) As String
                              Dim SubFolder As Object
                              trovato = False
                              Do While FSO.FileExists(MainFolder & "\" & FileName & ".pdf")
                                  TrovaFile = MainFolder & "\" & FileName & ".pdf"
                                  trovato = True
                                  If trovato = True Then
                                      Exit Function
                                  End If
                              Loop
                          
                              trovato = False
                              
                              For Each SubFolder In MainFolder.subfolders
                                  Do While FSO.FileExists(SubFolder & "\" & FileName & ".pdf")
                          
                                      TrovaFile = TrovaFile(FileName, SubFolder, FSO)
                                      trovato = True
                                      If trovato = True Then
                                          Exit Function
                                      End If
                                  Loop
                              Next
                          End Function
                          
                          
                          

                           

                           

                          Qual è il punto di avere gusti diversi, se non mostrare che i cervelli lavorano diversamente, che pensiamo diversamente? ( Alan Turing)
                          Sempre il mare, uomo libero, amerai!
                          ( Charles Baudelaire )
                          #14316 Risposta

                          GnZ_88
                          Partecipante

                            Perfetto, grazie mille! Adesso sembra funzionare.

                            Quindi in pratica hai usato due cicli "Do While ... Loop" anzichè dei semplici "If" come avevo utilizzato io.

                            Una curiosità: a cosa serve quel "trovato = false" che hai inserito all'inizio e prima del "For Each SubFolder"?

                             

                            Grazie ancora,

                            Alex

                            #14327 Risposta
                            albatros54
                            albatros54
                            Moderatore
                              36 pts

                              GnZ_88 ha scritto:

                              prima del "For Each SubFolder"

                              questo è un refuso del codice, lo,puoi anche cancellare  

                              quello dichiarato all'inizio è una variabile Booleana, che puo assumere il valore False o True(vero),che io gli ho assegnato il valore false, se il file esiste, assegno il valore True ed esco dalla Funzione, sia dal primo while che dal secondo while

                               

                              Qual è il punto di avere gusti diversi, se non mostrare che i cervelli lavorano diversamente, che pensiamo diversamente? ( Alan Turing)
                              Sempre il mare, uomo libero, amerai!
                              ( Charles Baudelaire )
                            LoginRegistrati
                            Stai vedendo 13 articoli - dal 1 a 13 (di 13 totali)
                            Rispondi a: Macro excel VBA per aprire file con clic sulla cella
                            Gli allegati sono permessi solo ad utenti REGISTRATI
                            Le tue informazioni:



                            vecchio frac - 2137 risposte

                            albatros54
                            albatros54 - 650 risposte

                            patel
                            patel - 510 risposte

                            Marius44
                            Marius44 - 409 risposte

                            Luca73
                            Luca73 - 373 risposte