Runtime Access-Errore Output Report in PDF

di il
6 risposte

Runtime Access-Errore Output Report in PDF

Buongiorno.
Ho un applicativo Access creato con il 365. Funziona tutto correttamente in una postazione con Win10 64 bit con Access installato, dal 2016 al 365.
Su una macchina con Win 10 (64bit) ma con il solo runtime, va in errore all'atto di creazione del pdf dal report appositamente aperto (seppur in modalità nascosta).
Ho provato a passare dal runtime Access 2016 a quello 365 ma il problema persiste. Qualcuno conosce il problema?

DoCmd.OpenReport "NomeReport", acViewReport, , "DocID='" & MEMDocID & "'", acHidden
DoCmd.OutputTo acReport, "NomeReport", acFormatPDF, "PathInCuiCreareIlFile\NomeFile.pdf", False
DoCmd.Close acReport, "NomeReport", acSaveNo

6 Risposte

  • Re: Runtime Access-Errore Output Report in PDF

    Mokor ha scritto:


    Ho un applicativo Access creato con il 365. ... ma con il solo runtime, va in errore all'atto di creazione del pdf dal report appositamente aperto (seppur in modalità nascosta)... Qualcuno conosce il problema?
    Sarebbe utile conoscere l'errore che dà. Ok, il runtime permette di conoscere poco in merito però qualcosa dovrebbe dire e se non lo fa devi cambiare la modalità di gestione degli errori proprio per non trovarsi in casi come questi, a tirare un po' a caso. E' sempre bene sviluppare con la versione più "vecchia" tra quelle su cui poi si distribuirà il prodotto, perché la compatibilità "in su" è solitamente più facile rispetto a quella "in giù".

    Mokor ha scritto:


    DoCmd.OpenReport "NomeReport", acViewReport, , "DocID='" & MEMDocID & "'", acHidden
    ...
    In attesa di sapere qualcosa di più ti suggerirei di aprire il report in modalità acViewPreview e di verificare che il percorso esista e che il nome del file non contenga cioè caratteri vietati (c'è di mezzo per caso una data?) e che su quel percorso si abbia il diritto di scrittura a livello di sistema operativo (dominio, ecc).
  • Re: Runtime Access-Errore Output Report in PDF

    La procedura di chiamata del report è in modalità nascosta perché deve stamparlo direttamente senza visualizzarlo, davo per scontato che almeno il report fosse corretto, ma mettendolo in visualizzazione, come dici, ho scoperto che il runtime va in errore già alla sua apertura, cosa che non avviene con Access e infatti la compilazione non da alcune errore in nessun punto.

    Il report incorpora un codice che serve per prelevare i dati di testata da una tabella diversa mentre il corpo punta a una apposita fonte dati, in questo caso una query.
    Guardando il codice non trovo comunque un motivo per cui possa andare in errore, pensavo che in runtime la causa fossero i valori null e allora ho forzato i campi con un NZ ma il risultato non cambia. Forse troppi recordset per il runtime?

    MEMIDISsuer è una variabile pubblica che passa l'ID del cliente che nelle tabelle è in formato stringa tipo 0907012334, pertanto è giusto che sia messo fra apici

    Private Sub Report_Load()
    Dim SQL As String
    Dim DB1 As ADODB.Recordset
    Dim DB2 As ADODB.Recordset
    Dim DB3 As ADODB.Recordset
    Dim DB4 As ADODB.Recordset
    Dim DB5 As ADODB.Recordset

    'Sezione dati emittente
    SQL = "SELECT TBLPeople.Sgg1ID, TBLPeople.Sgg1Name, TBLPeople.Sgg1Surname, " & _
    "TBLPeople.Sgg1CF, TBLPeople.Sgg1PIVA, TBLPeople.Sgg1Tel, " & _
    "TBLPeopleAddress.Sgg4ResNzn, TBLPeopleAddress.Sgg4ResLcl, TBLPeopleAddress.Sgg4ResCAP, TBLPeopleAddress.Sgg4ResPrv, TBLPeopleAddress.Sgg4ResAddress, TBLPeopleAddress.Sgg4Sgg1ID " & _
    "FROM TBLPeople INNER JOIN TBLPeopleAddress ON TBLPeople.Sgg1ID = TBLPeopleAddress.Sgg4Sgg1ID " & _
    "WHERE TBLPeople.Sgg1ID = '" & MEMIdIssuer & "' ;"
    'Apro recordset
    Set DB1 = New ADODB.Recordset
    With DB1
    .ActiveConnection = CurrentProject.Connection
    .CursorLocation = adUseClient
    .CursorType = adOpenStatic
    .LockType = adLockReadOnly
    .Open SQL
    End With
    'Assegno dati
    TxtCustomer = Nz(DB1("Sgg1Name")) & " " & Nz(DB1("Sgg1Surname"))
    TxtCF = Nz(DB1("Sgg1CF"))
    TxtPIVA = Nz(DB1("Sgg1PIVA"))
    TxtTel1 = Nz(DB1("Sgg1Tel"))
    TxtAddress = Nz(DB1("Sgg4ResAddress")) & " " & Nz(DB1("Sgg4ResLcl")) & " " & Nz(DB1("Sgg4ResPrv")) & " " & Nz(DB1("Sgg4ResCAP"))
    'Chiudo recordset
    DB1.Close
    Set DB1 = Nothing

    '...ripeto esattamente la stessa cosa per per gli altri 4 recordset (dati documento, dati cliente, dati bancari, ecc.) usando per sicurezza i loro appositi ADODB.Recordset

    End Sub
  • Re: Runtime Access-Errore Output Report in PDF

    Mokor ha scritto:


    ... il runtime va in errore già alla sua apertura,
    e che errore dà? c'è una descrizione, un numero, un qualcosa di più specifico?

    Mokor ha scritto:


    ... i dati di testata da una tabella diversa mentre il corpo punta a una apposita fonte dati, in questo caso una query...
    Mah... forse su questo aspetto ci sarebbe da discutere, cioè su come hai strutturato il tutto.
    Se le tabelle sono costruite bene non dovrebbe esserci bisogno di aprire così tanti recordset alla ricerca di informazioni che dovrebbero essere comunque collegate, poi si vede come metterle insieme in fase di stampa.
    Perché usi ADO invece di DAO?
    La cosa più importante è però il tipo di errore, almeno quello!
    In generale, esplicità le proprietà, in particolare mi riferisco a .Value dei campi (del recordset) e dei controlli (del report)
    La concatenazione del contenuto dei campi per valorizzare i controlli del report è rivedibile però non credo sia lì il problema principale.
  • Re: Runtime Access-Errore Output Report in PDF

    So che si esce dalle logiche abituali ma il programma è predisposto per poter essere usato in condivisione da più utenti che però emettono i propri documenti con i propri dati condividendo solo alcune risorse come il magazzino se comune, chat interna, scadenzario, ecc.. Insomma coworking di figure professionali diverse. Le tabelle sono relazionate solo da codice per evitare problemi in caso di migrazione esterna di una o più tabelle.

    Qualunque fosse il difetto reale o simulato, il runtime restituiva sempre lo stesso messaggio generico: "Esecuzione dell’applicazione interrotta a causa di un errore di run-time. ?L’applicazione verrà terminata." capirete che in tal modo non è possibile soddisfare la giusta richiesta dell'avere più riferimenti.

    Pertanto ho la tabella dell'anagrafe che ha un indice alla tabella indirizzi in quanto si possono avere più indirizzi per lo stesso soggetto (abitazione estiva/invernale, abitazione lavoro, residenza, consegna, ecc.) in cui una viene flaggata come default per essere usata nelle titolarità sui documenti.

    Abbiamo poi una tabella per le testate dei documenti e quella per le righe. Quella del doc ha gli id per riconoscere banca abbinata al cli, condizioni, il tipo di documento fra quelli configurati in una apposita tabella (e diversamente gestite dal codice nei form). Quella delle righe ha l’ID della tabella degli articoli e altri dati. Non sto a spiegare alcune altre peculiarità, ma i dati nel report sono mantenuti modulari per essere combinati con varie opzioni che possono includere/escludere questa o quell’altro gruppo di dati (ho escluso il codice perché è un pò intricato e confonde il problema).

    Fatto stà che, in seguito al sospetto insediatomi dopo la tua osservazione "Perché usi ADO invece di DAO?" ho risolto sostituendo l’ADODB con il DAO (avevo proseguito come mi era stato lasciato visto che sembrava comunque funzionare ma solo su Access). ??Ora funziona, compresa la procedura di generazione PDF, pertanto sembrerebbe che la differenza del codice funzionante su Access nel runtime invece:?
    - evitare ADODB per creare recordset all'interno dei report
    - i dati da iniettare nei campi del report non possono essere null (con NZ() su ogni dato passato si evita ogni rischio)

    Private Sub Report_Load()
    Dim SQL As String
    Dim RS1 As DAO.Recordset
    Dim RS2 As DAO.Recordset
    Dim RS3 As DAO.Recordset
    Dim RS4 As DAO.Recordset

    'Sezione dati emittente
    SQL = "SELECT TBLPeople.Sgg1ID, TBLPeople.Sgg1Name, TBLPeople.Sgg1Surname, " & _
    "TBLPeople.Sgg1CF, TBLPeople.Sgg1PIVA, TBLPeople.Sgg1Tel, " & _
    "TBLPeopleAddress.Sgg4ResNzn, TBLPeopleAddress.Sgg4ResLcl, TBLPeopleAddress.Sgg4ResCAP, TBLPeopleAddress.Sgg4ResPrv, TBLPeopleAddress.Sgg4ResAddress, TBLPeopleAddress.Sgg4Sgg1ID " & _
    "FROM TBLPeople INNER JOIN TBLPeopleAddress ON TBLPeople.Sgg1ID = TBLPeopleAddress.Sgg4Sgg1ID " & _
    "WHERE TBLPeople.Sgg1ID = '" & MEMIdIssuer & "' " & _
    "ORDER BY TBLPeopleAddress.Sgg4Default ASC;"
    'Apro recordset
    Set RS1 = CurrentDb.OpenRecordset(SQL)
    'Assegno dati
    If RS1.RecordCount > 0 Then
    TxtCustomer = RS1("Sgg1Name") & " " & RS1("Sgg1Surname")
    TxtCF = Nz(RS1("Sgg1CF"))
    TxtPIVA = Nz(RS1("Sgg1PIVA"))
    TxtTel1 = Nz(RS1("Sgg1Tel"))
    TxtAddress = Nz(RS1("Sgg4ResAddress")) & " " & Nz(RS1("Sgg4ResLcl")) & " " & Nz(RS1("Sgg4ResPrv")) & " " & Nz(RS1("Sgg4ResCAP"))
    End If
    'Chiudo recordset
    RS1.Close
    Set RS1 = Nothing

    '...ripeto esattamente la stessa sequenza per per gli altri 4 recordset (dati documento, dati cliente, dati bancari, ecc.) usando per sicurezza i loro appositi DAO.Recordset

    End Sub
  • Re: Runtime Access-Errore Output Report in PDF

    Mokor ha scritto:


    ... il runtime restituiva sempre lo stesso messaggio generico: "Esecuzione dell’applicazione interrotta a causa di un errore di run-time. ?L’applicazione verrà terminata."
    Ora lo so, prima no. Ecco che torna in campo l'uso di un sistema di log degli errori "tosto".

    Mokor ha scritto:


    ... ho risolto sostituendo l’ADODB con il DAO ... ??Ora funziona, ...
    invece:?
    ...
    Quell' "invece" finale è una sorta di refuso? cioè, alla fine, funziona o no?
    TxtCustomer = Nz(DB1("Sgg1Name")) & " " & Nz(DB1("Sgg1Surname"))
    ...
    
    Tutti i Txt... che si vedono qui sono controlli o variabili? I controlli di tipo testbox gestiscono anche il Null, visto che la proprietà Value è di tipo Variant. Se invece sono variabili stringa il discorso cambia radicalmente.
    L'uso di Nz qui è superfluo perché in presenza di un carattere non Null (lo spazio, appunto) e l'uso per la concatenazione della [&] impedisce la "Null propagation". Anzi, potresti sfruttare la propagazione del Null per non doverti curare del fatto che alcuni campi siano Null e trovarti spazi all'interno del controllo o stringa che creano problemi.
    Parliamo ad esempio di
    TxtAddress = Nz(DB1("Sgg4ResAddress")) & " " & Nz(DB1("Sgg4ResLcl")) & " " & Nz(DB1("Sgg4ResPrv")) & " " & Nz(DB1("Sgg4ResCAP"))
    Cosa succede se Sogg4ResPrv è Null? Ti trovi ad avere questo
    ResAddress ResLcl  ResCAP
    Il doppio spazio tra ResLcl e ResCAP è quasi impercettibile, ma c'è.
    In generale è per dire che bisogna conoscere bene come concatenare per evitare l'uso superfluo di funzioni.
  • Re: Runtime Access-Errore Output Report in PDF

    Sono controlli non associati.

    In realtà ho stabilito la colpa ad entrambe le cause sospettate, ovvero ADODB e valori null. Prima ho applicato il NZ perché pensavo che per motivi misteriosi il runtime non li accettasse e ho appunto applicato il NZ a prescindere (anche a campi che per forza di cosa potrebbero averli perché il report può anche essere visualizzato vuoto per essere stampato come modulo), e poi ho sostituito l'ADODB.
    Avendo fatto solo quelle due cose, mantenendo le stringhe SQL esattamente come erano, ho stabilito che la soluzione fosse in quei due punti. Non avendo in runtime riferimenti precisi nella segnalazione degli errori devo per forza provare ogni volta trasferendo il file sulla macchina vergine e andando per esclusione.
    Comunque appena posso li rimuovo anche per completare il post con un riferimento più preciso alla soluzione.

    Trovo solo strano che non siano reperibili in rete riferimenti al fatto che nei codici integrati nei report destinati all'uso in runtime non debbano essere usati gli ADODB. Forse, anche se il problema è risolto, mi sfugge ancora qualcosa nell'averlo capito.
Devi accedere o registrarti per scrivere nel forum
6 risposte