Applicazione Access non chiude file Excel aperto per importazione di alcuni dati

di il
15 risposte

Applicazione Access non chiude file Excel aperto per importazione di alcuni dati

Buongiorno.

Devo importare alcuni valori da alcune celle in foglio Excel.
Uso Office 365, di conseguenza dovrebbero essere Access e Excel 2016.

Non è la prima volta che realizzo un'applicazione del genere e non ho mai avuto problemi.
Evidentemente c'è un errore, ma non riesco a trovare l'istruzione errata.
In sostanza da un form apro un file excel e collego un foglio come tabella;
Importo i dati che mi servono;
scollego il foglio, ed in effetti non è più elencato come tabella;
chiudo il file.
Apparentemente si conclude tutto normalmente, ma nella gestione della attività, il file excel risulta aperto.
Per chiudere il file excel non è sufficiente eseguire il quit dell'applicazione, ma devo necessariamente chiudere il file Access.
Se non chiudo e cerco di eseguire una nuova importazione, ottengo l'errore
"462 - il computer server remoto non esiste o non è disponibile"

Di seguito il codice


Dim strPath As String
Dim objXL As New Excel.Application
Dim xlWB As Excel.Workbook
Dim xlWS As Excel.Worksheet
Dim strFileName As String
Dim strSheetName As String

Dim rFoundCell As Range
Dim rFoundCellNext As Range
Dim rLastCell As Range

Dim lngCol As Long
Dim lngRow As Long
Dim lngColNextVal As Long
Dim lngRowNextVal As Long
Dim I As Integer
Dim strValue As String





        'importa ordine
       
        Set objXL = CreateObject("Excel.Application")
        strSheetName = "Preventivo"
        Set xlWB = objXL.Workbooks.Open(strPath)
        Set xlWS = xlWB.Worksheets(strSheetName)
        
        'collega foglio excel
        strFileName = "ImpExcel_" & strSheetName
        If Not IsNull(DLookup("Name", "MSysObjects", "Name='" & strFileName & "'")) Then CurrentDb.TableDefs.Delete strFileName
        DoCmd.TransferSpreadsheet acLink, acSpreadsheetTypeExcel12, strFileName, strPath, False, strSheetName & "!"
                
        Set rLastCell = xlWS.Cells.Find(What:="*", After:=xlWS.Cells(1, 1), LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False)
        
        'Numero Ordine 
        Set rFoundCell = Range("A1:" & rLastCell.Address).Find("Numero")
        If Not IsEmpty(rFoundCell) Then
            lngCol = Range(rFoundCell.Address).Column
            lngRow = Range(rFoundCell.Address).Row
            Set rFoundCellNext = Range(xlWS.Cells(lngRow, lngCol + 1).Address(False, False))
            Me!NrOrdine = ExtractNumber(rFoundCellNext.Value)
        End If
  
  ' Importazione di altre celle      
  .      
  .    
  .    
  . 
        
        'scollega foglio excel
        CurrentDb.TableDefs.Delete strFileName
        Set xlWS = Nothing
        xlWB.Close
        Set xlWB = Nothing
        objXL.Quit
        Set objXL = Nothing
        

Grazie
Ciao

15 Risposte

  • Re: Applicazione Access non chiude file Excel aperto per importazione di alcuni dati

    Devi fare debug verso la fine quando chiudi l'oggetto XLWB e objXL aiutandoti con il TaskManager e devi controllare appunto prima la chiusura dell'applicativo xls e poi il processo Excel.exe..
    Se così non avviene devi capire perché falliscono...
    Quello che accade poi è normale, il processo è bloccato dal tuo applicativo.
  • Re: Applicazione Access non chiude file Excel aperto per importazione di alcuni dati

    Le istruzioni di chiusura funzionano.
    Come test ho eliminato tutto il blocco
    
            'Numero Ordine 
            Set rFoundCell = Range("A1:" & rLastCell.Address).Find("Numero")
            If Not IsEmpty(rFoundCell) Then
                lngCol = Range(rFoundCell.Address).Column
                lngRow = Range(rFoundCell.Address).Row
                Set rFoundCellNext = Range(xlWS.Cells(lngRow, lngCol + 1).Address(False, False))
                Me!NrOrdine = ExtractNumber(rFoundCellNext.Value)
            End If
    
    e il file Excel di chiude regolarmente.
    Anche ripetendo apertura e chiusura più volte, non si verifica nessun problema.
    Il problema si verifica se eseguo "Set rFoundCell" anche con l'indirizzo "A1:Z1).
    Ho messo anche a nothing rFoundCell, ma il problema permane.
  • Re: Applicazione Access non chiude file Excel aperto per importazione di alcuni dati

    epiworld ha scritto:


    ...
    Apparentemente si conclude tutto normalmente, ma nella gestione della attività, il file excel risulta aperto.
    ...
    ...
    Dim objXL As New Excel.Application
    ...        
    
    Non ho letto il resto del codice, forse c'è qualche altro "errore" perso qua e là.
    Nonostante nelle pagine Microsoft si vedano dichiarazioni fatte così, non è mai una buona abitudine dichiarare gli oggetti As New "qualcosa", ma sempre due righe distinte
    Dim objXL As Excel.Application
    ...
    Set objXL = New Excel.Application
    ...
  • Re: Applicazione Access non chiude file Excel aperto per importazione di alcuni dati

    Philcattivocarattere ha scritto:


    epiworld ha scritto:


    ...
    Apparentemente si conclude tutto normalmente, ma nella gestione della attività, il file excel risulta aperto.
    ...
    ...
    Dim objXL As New Excel.Application
    ...        
    
    Nonostante nelle pagine Microsoft si vedano dichiarazioni fatte così, non è mai una buona abitudine dichiarare gli oggetti As New "qualcosa", ma sempre due righe distinte: una di dichiarazione e una di assegnazione.
    Poi c'è un errore "gravissimo" che secondo me è proprio la causa del tuo problema (Gibra docet): l'uso dell'earlybinding e latebinding mescolati.
    Leggi questo recentissimo intervento: https://www.iprogrammatori.it/forum-programmazione/access/aggiornare-tabelle-excel-t35538.html#p8603575
  • Re: Applicazione Access non chiude file Excel aperto per importazione di alcuni dati

    Philcattivocarattere ha scritto:


    Nonostante nelle pagine Microsoft si vedano dichiarazioni fatte così, non è mai una buona abitudine dichiarare gli oggetti As New "qualcosa", ma sempre due righe distinte: una di dichiarazione e una di assegnazione.
    Poi c'è un errore "gravissimo" che secondo me è proprio la causa del tuo problema (Gibra docet): l'uso dell'earlybinding e latebinding mescolati.
    Leggi questo recentissimo intervento: https://www.iprogrammatori.it/forum-programmazione/access/aggiornare-tabelle-excel-t35538.html#p8603575
    Grazie per il consiglio riguardo la dichiarazione.
    Purtroppo il problema non si è risolto con la dichiarazione consigliata.

    Riguardo all'earlybinding e latebinding mescolati, ammetto la mia ignoranzia in merito ai due metodi, ma ho letto in questo link
    https://support.microsoft.com/it-it/help/245115/using-early-binding-and-late-binding-in-automation
    e salvo essere smentito e non averci capito nulla, non credo di averli mescolati.
    Però se mi smentisci e mi mostri dove sbaglio, ti ringrazio anticipatamente.

    Nel frattempo ho osservato meglio l'istruzione che provocava l'errore.
    Semplicemente non avevo specificato objWS all'oggetto Range
    Set rFoundCell = Range("A1:" & rLastCell.Address).Find("Numero")
    così è corretta
    Set rFoundCell = objWS.Range("A1:" & rLastCell.Address).Find("Numero")
    Ora funziona.

    Grazie
  • Re: Applicazione Access non chiude file Excel aperto per importazione di alcuni dati

    Bene, ora se devi distribuire il tuo applicativo è indispensabile tu valuti l'approccio LATEBINDING... se lo usi solo sul tuo pc no ovviamente.

    P.s. hai pensato anche di usare una buona gestione errori... lo avresti trovato magari prima...
  • Re: Applicazione Access non chiude file Excel aperto per importazione di alcuni dati

    epiworld ha scritto:


    ...
    Riguardo all'earlybinding e latebinding mescolati, ammetto la mia ignoranzia in merito ai due metodi, ma ho letto in questo link
    https://support.microsoft.com/it-it/help/245115/using-early-binding-and-late-binding-in-automation
    e salvo essere smentito e non averci capito nulla, non credo di averli mescolati.
    Però se mi smentisci e mi mostri dove sbaglio, ti ringrazio anticipatamente.
    Infatti non è da quel link che imparerai ad usare correttamente l'earlybinding e il latebinding.
    Se proprio vuoi restare in ambito internet qui trovi qualcosa di meglio
    LATEBINDING Vs EARLYBINDING
    In quella pagina troverai alcuni interventi di Gibra. I suoi post riportano sempre alcuni link ed uno in particolare cade a fagiolo
    Early-Late Binding con Excel e Outlook. E' per VB6, quindi occhio che la parte grafica della compilazione condizionale deve essere adattata a VBA: non ci sono le stesse finestre e gli stessi segni di spunta ma il codice è lo stesso.
    Prendendo quindi il tuo codice, per la parte che qui interessa:
    1) Earlybinding
    Dim objXL As Excel.Application 'senza il New
    Dim xlWB As Excel.Workbook
    Dim xlWS As Excel.Worksheet
    Dim rFoundCell As Range
    Dim rFoundCellNext As Range
    Dim rLastCell As Range
    ...
    Set objXL = New Excel.Application
    ... 
    2) Latebinding
    Dim objXL As Object
    Dim xlWB As Object
    Dim xlWS As Object
    Dim rFoundCell As Object
    Dim rFoundCellNext As Object
    Dim rLastCell As Object
    ...
    Set objXL = CreateObject("Excel.Application")
    ... 
    Ricordando di togliere il riferimento alla libreria di Excel, quando si distribuisce in latebinding, altrimenti si vanifica il beneficio di non essere legati alla versione: un riferimento mancante di una libreria causa errori anche se non viene "chiamato in causa".
  • Re: Applicazione Access non chiude file Excel aperto per importazione di alcuni dati

    Grazie innanzitutto per le spiegazioni e il link interessante.
    Però mi sorge un dubbio. Se il vantaggio del Latebinding è la possibilità di utilizzare l'applicazione con versioni diverse di Excel,
    l'istruzione
    
    DoCmd.TransferSpreadsheet acLink, acSpreadsheetTypeExcel12, strFileName, strPath, False, strSheetName & "!"
    
    dove con acSpreadsheetTypeExcel12 si specifica la versione excel 2010 e successive, come se la caverebbe se trovassi qualcuno con la versione 2003?
    Io finora ho sempre utilizzato versioni identiche alla versione Access.
    Non sarebbe comunque un problema?

    Grazie
    Ciao


    p.s.: riguardo il forum di Masterdrive, ho cercato di iscrivermi tempo fa, ma non posso registrarmi a causa del reCaptcha che non viene visualizzato. Sapete se è bloccata la registrazione?
    Ho provato anche ora, ma è impossibile.
    Ho cercato anche un contatto, ma sempre il reCaptcha "invisibile", mi impedisce il contatto.
  • Re: Applicazione Access non chiude file Excel aperto per importazione di alcuni dati

    epiworld ha scritto:


    Riguardo all'earlybinding e latebinding mescolati, ammetto la mia ignoranzia in merito ai due metodi, ma ho letto in questo link
    https://support.microsoft.com/it-it/help/245115/using-early-binding-and-late-binding-in-automation
    e salvo essere smentito e non averci capito nulla, non credo di averli mescolati.
    Però se mi smentisci e mi mostri dove sbaglio, ti ringrazio anticipatamente.
    Infatti devo smentirti.
    Nell'articolo è chiaramente indicato che nel LateBinding la variabile oggetto va dichiara As Object.

    ti riporto la parte di codice dell'articolo, a scanso di equivoci:
    ' No reference to a type library is needed to use late binding.
    ' As long as the object supports IDispatch, the method can 
    ' be dynamically located and invoked at run-time.
    
    ' Declare the object as a late-bound object
      Dim oExcel As Object
    
      Set oExcel = CreateObject("Excel.Application")
    
    ' The Visible property is called via IDispatch
      oExcel.Visible = True
    
    Quindi le osservazioni fatte sono corrette.


    Per quanto riguarda la tua domanda sulla costante acSpreadsheetTypeExcel12, questa è semplicemente una costante, né più né meno.
    Ovvero dovrai essere tu a stabilire la versione (e quindi quale costante usare) in base alla versione di Excel in uso sul pc, per questo ti basta interrogare:
    Dim sVersion As String
    sVersion = objXL.Version
    
    A quel punto sarai tu a scegliere il formato del file.

    P.S. Tieni sempre presente che quando si usa il LateBinding le costanti intrinseche, come acSpreadsheetTypeExcel12, non hanno alcun valore e per cui non funzionano come te lo aspetti, per cui è indispensabile che tu le dichiari espressamente nel tuo codice:

    AcSpreadSheetType Enumeration (Access)
    https://msdn.microsoft.com/en-us/vba/access-vba/articles/acspreadsheettype-enumeration-access

  • Re: Applicazione Access non chiude file Excel aperto per importazione di alcuni dati

    epiworld ha scritto:


    ...
    
    DoCmd.TransferSpreadsheet acLink, acSpreadsheetTypeExcel12, strFileName, strPath, False, strSheetName & "!"
    
    dove con acSpreadsheetTypeExcel12 si specifica la versione excel 2010 e successive, come se la caverebbe se trovassi qualcuno con la versione 2003?
    Io finora ho sempre utilizzato versioni identiche alla versione Access.
    Quella riga non ha niente a che vedere con Excel, perché è codice puro di Access. Quindi qui si esula dal discorso latebinding.
    E' evidente che il codice che si scrive deve essere "leggibile" da tutte le versioni in cui si pensa possa essere usato, con particolare riguardo alla retrocompatibilità.
    La costante acSpreadsheetTypeExcel12 è entrata a far parte del modello ad oggetti di Access dalla versione 2010 (presumo, non so se anche dalla 2007). Di certo non sarebbe capita se l'applicativo - db girasse su A2003.
    Vedi le due "versioni" presenti sul sito Microsoft


    In questa situazione torna utile la compilazione condizionale di cui hai letto nelle pagine già citate, che permette di strutturare il codice in modo da eseguire una riga o un'altra in base alla versione di Access.
    Edit: nel frattempo aveva già detto la sua Gibra. Leggi il suo intervento, il mio lo lascio solo perché ormai avevo già fatto tutto.
  • Re: Applicazione Access non chiude file Excel aperto per importazione di alcuni dati

    gibra ha scritto:



    Infatti devo smentirti.
    Nell'articolo è chiaramente indicato che nel LateBinding la variabile oggetto va dichiara As Object.
    Premesso che non sapevo nulla di Earlybinding e Latebinding, quindi ho imparato qualcosa, grazie a prescindere, la questione smentita si riferiva al mio codice e alla confusione fra i due metodi.
    Dove avrei mischiato i due metodi?
  • Re: Applicazione Access non chiude file Excel aperto per importazione di alcuni dati

    epiworld ha scritto:


    gibra ha scritto:



    Infatti devo smentirti.
    Nell'articolo è chiaramente indicato che nel LateBinding la variabile oggetto va dichiara As Object.
    Premesso che non sapevo nulla di Earlybinding e Latebinding, quindi ho imparato qualcosa, grazie a prescindere, la questione smentita si riferiva al mio codice e alla confusione fra i due metodi.
    Dove avrei mischiato i due metodi?
    Li hai mischiati, ma non è un errore funziona ugualmente quanto di pulizia, in quanto hai dichiarato le Variabili in modo ESPLICITO(EarlyBinding) poi hai usato il CREATEOBJECT per istanziare l'oggetto... e se usi i riferimenti alle LIBRERIE(EarlyBinding) non serve... cosa diversa invece se devi recuperare un'istanza già essitente... allora il GETOBJECT è l'ideale...
    L'esempio di Phil mi pare chiaro... tu cosa non comprendi nello specifico... perchè inizia a sembrare aria fritta.
  • Re: Applicazione Access non chiude file Excel aperto per importazione di alcuni dati

    Vabbè, aria fritta...
    Saluti e grazie.
  • Re: Applicazione Access non chiude file Excel aperto per importazione di alcuni dati

    epiworld ha scritto:


    gibra ha scritto:



    Infatti devo smentirti.
    Nell'articolo è chiaramente indicato che nel LateBinding la variabile oggetto va dichiara As Object.
    Premesso che non sapevo nulla di Earlybinding e Latebinding, quindi ho imparato qualcosa, grazie a prescindere, la questione smentita si riferiva al mio codice e alla confusione fra i due metodi.
    Dove avrei mischiato i due metodi?
    Se dopo tutte le indicazioni che ti sono state date, fai ancora questa domanda, la vedo dura...
Devi accedere o registrarti per scrivere nel forum
15 risposte