Errore 3078 ripetuto nella stessa sub

di il
6 risposte

Errore 3078 ripetuto nella stessa sub

Buonasera,

sono a chiedere un aiuto in relazione a questo problema. Nella procedura che allego vado a leggere su un db esterno tutte le form presenti.  In alcune di queste ci sono degli errori di run-time, per la precisione 3078, ma solo il primo di questi mi  viene intercettato da Err_Handler, negli altri casi mi mostra la solita finestra di messaggio di Warning e non entra nel controllo degli errori.

Ringrazio in anticipo chi mi può dare una mano.

Sub testFormEsterno()
    On Error GoTo Err_Handler
    Dim obj As AccessObject
    Dim accapp As Access.Application
    Dim CP As CodeProject
    Set accapp = New Access.Application
    
    Dim frm As Access.Form
    Dim rs As Recordset
    Dim ctl As Control
    Dim fld As Field
    Dim prp As Property
    Dim Sql As Variant
    ''' Apro db esterno
    accapp.OpenCurrentDatabase ("C:\Archivio\Access\database1.accdb")
    Set CP = accapp.CurrentProject
    ''' Itero tutti i nome delle Form
    For Each obj In CP.AllForms
        Debug.Print obj.Name
        ''' Apro la Form su Db esterno
        accapp.DoCmd.OpenForm obj.Name, acDesign, WindowMode:=acHidden
        
        ''' Apro il set
        Set frm = accapp.Forms(obj.Name)
        Debug.Print frm.Properties(Sql)
        ''' Scarto le form senza sql
        If Len(frm.Properties(Sql)) = 0 Then GoTo controlli
        Set rs = DBEngine(0)(0).OpenRecordset(frm.Properties(Sql))
            ''' Leggo i nomi di campi e tabelle contenute in SQL
            For Each fld In rs.Fields
    '            Debug.Print obj.Name, frm.Name, fld.SourceTable, fld.Name, FieldTypeName(fld)
            Next
controlli:
            ''' leggo i controlli della form
            For Each ctl In frm
                If ctl.Properties("ControlType") >= 105 And ctl.Properties("ControlType") <= 122 Then
                    Debug.Print ctl.Name, ctl.Properties("ControlType"), ctl.Properties("Visible"), , ctl.Properties("Enabled"), ctl.Properties("Tag"), ctl.Properties("ControlSource")
                 
                End If
            Next ctl
            
        ''' Chiudo la form
fine:
        accapp.DoCmd.Close acForm, obj.Name, acSaveNo
        Set rs = Nothing
    Next obj
    
Exit_Handler:
    accapp.CloseCurrentDatabase
    Set frm = Nothing
    Set rs = Nothing
    Set CP = Nothing
    Exit Sub
  
Err_Handler:
        If Err.Number = 2467 Then
            Debug.Print "scrivi errore" & Err.Number & ": " & Left(Err.Description, InStr(1, Err.Description, ".") - 1)
            GoTo fine
 
        ElseIf Err.Number = 3078 Then
            Debug.Print "scrivi errore" & Err.Number & ": " & Left(Err.Description, InStr(1, Err.Description, ".") - 1)
            Err.Clear
            GoTo controlli
           
        Else
             Debug.Print "scrivi errore" & Err.Number & ": " & Left(Err.Description, InStr(1, Err.Description, ".") - 1)
            GoTo Exit_Handler
        End If
 
End Sub

6 Risposte

  • Re: Errore 3078 ripetuto nella stessa sub

    Puoi spiegare cosa ti aspetti da questa e cosa contiene SQL Variant...?

    Dim Sql As Variant
    Debug.Print frm.Properties(Sql)
    ''' Scarto le form senza sql
    If Len(frm.Properties(Sql)) = 0 Then GoTo controlli
  • Re: Errore 3078 ripetuto nella stessa sub

    Questo controllo è stato messo per evitare di aprire il RecordSet nel caso la form non abbia come sorgente una tabella.

  • Re: Errore 3078 ripetuto nella stessa sub

    29/10/2025 - Scolaretto ha scritto:

    Questo controllo è stato messo per evitare di aprire il RecordSet nel caso la form non abbia come sorgente una tabella.

    Ho letto il commento nel codice... ma sei sicuro funzioni...? Sembra quasi fatto in modo maldestro con CHATGPT e copiato...!!!!! 
    Tu puoi spiegare come funziona secondo te quel codice, al di la del commento...?

    Provo a farlo io, dando per assunto tu non lo abbia affatto compreso e ti spiego perchè...

    Partiamo dal sapere che Properties è una Collection di Property, l'accesso agli ITEMS della collection si fa per INDICE numerico:

    Me.Properties(1)

    Oppure si fa, usando la KEY(String) che rappresenta il Nome della property...!

    Me.Properties("NomeProperty")

    Quando scrivi, quello che scrivo sotto, tu pensi di passare il Nome della property o una variabile....? No perchè usi peraltro una Parola RISERVATA [SQL] che non andrebbe usata come Variabile Variant... tipico errore delle A.I. gratis.

    Debug.Print frm.Properties(Sql)

    [sql] in questo caso è una Variabile NON VALORIZZATA in nessun posto, quindi vale NULL, ne consegue che quello che tu hai definito necessario a scartare le Form senza SQL in realtà non fa nulla perchè è sbagliato.

    Quì trovi un esempio di come funziona la Collection Properties, ed a SX trovi la lista delle Properties accessibili... e guarda caso NON è presente quello che vuoi fare

    https://learn.microsoft.com/en-us/office/vba/api/access.form.properties

    Per vedere se una Maschera ha o meno un'Origine dati, basta testare la Property "RecordSource"... ma si usa cosi:

    Dim sPrp	As String
    sPrp="RecordSource"
    Debug.Print Me.Properties(sPrp)

    Saluti....

  • Re: Errore 3078 ripetuto nella stessa sub

    Ti ringrazio Alex per la tua risposta , grazie alla quale sono andato a rivedere il tutto , Ed in effetti di errore ve ne erano molti. Non sono sicuramente bravo a sviluppare sw , sono ormai passati anni da quando utilizzavo Clipper, ma ho sempre cercato di capire le cose anche scopiazzando un pò. Qui sotto trovi l'elaborato corretto e ti posso garantire che non utilizzo "in modo maldestro con CHATGPT". Utilizzo VBA solo per passione, per cui posso sicuramente fare arrosti ma, non mi si può dire che faccio le cose senza cercare di capire, purtroppo non sempre mi riesce. Ovviamente ogni tua osservazione e bene accetta.

    Sub TestDatiMascheraDBesterno()
        On Error GoTo Err_Handler
        Dim obj As AccessObject
        Dim accapp As Access.Application
        Dim CP As CodeProject
        Set accapp = New Access.Application
        Dim frm As Access.Form
        Dim rs As Recordset
        Dim ctl As Control
        Dim fld As Field
       
        ''' Apro db esterno
        accapp.OpenCurrentDatabase ("C:\Archivio\Access\database1.accdb")
        Set CP = accapp.CurrentProject
        
        ''' Itero tutti i nome delle Form
        For Each obj In CP.AllForms
            Debug.Print obj.Name
            ''' Apro la Form su Db esterno
            accapp.DoCmd.OpenForm obj.Name, acDesign, , , , acHidden
            ''' Apro il set
            Set frm = accapp.Forms(obj.Name)
            Set rs = accapp.DBEngine(0)(0).OpenRecordset(frm.Properties("recordsource"))
            ''' Leggo i nomi di campi e tabelle contenute in SQL e gli riporto i tabella  db_form
            For Each fld In rs.Fields
                Debug.Print obj.Name, frm.Name, fld.SourceTable, fld.Name, FieldTypeName(fld)
            Next fld
            
            ''' Leggo i nomi dei controlli e le loro proprieta
            For Each ctl In frm
                If ctl.Properties("ControlType") >= 105 And ctl.Properties("ControlType") <= 122 Then
                        Debug.Print ctl.Name, ctl.Properties("ControlType"), IIf(ctl.Properties("Visible") = "vero", True, False), 	ctl.Properties("Enabled"), ctl.Properties("Tag"), ctl.Properties("ControlSource")
                End If
            Next ctl
            accapp.DoCmd.Close acForm, obj.Name, acSaveNo
           Set rs = Nothing
        Next obj
        
    Exit_Handler:
        accapp.CloseCurrentDatabase
        Set frm = Nothing
        Set rs = Nothing
        Set CP = Nothing
        Exit Sub
      
    Err_Handler:
           ' Debug.Print DBEngine.Errors.Count
            If Err.Number = 2455 Or Err.Number = 2467 Then
                Debug.Print "scrivi errore" & Err.Number & ": " & Left(Err.Description, InStr(1, Err.Description, ".") - 1)
                Err.Clear
                Resume Next
            ElseIf Err.Number = 3078 Then
                Debug.Print "scrivi errore" & Err.Number & ": " & Left(Err.Description, InStr(1, Err.Description, ".") - 1)
                Err.Clear
                Resume Next
            ElseIf Err.Number = 3061 Then
                Debug.Print "scrivi errore" & Err.Number & ": " & Left(Err.Description, InStr(1, Err.Description, ".") - 1)
                Err.Clear
                Resume Next
            ElseIf Err.Number = 91 Or Err.Number = 92 Then
                Debug.Print "scrivi errore" & Err.Number '& ": " & Left(Err.Description, InStr(1, Err.Description, ".") - 1)
                Err.Clear
                Resume Next
            Else
                Debug.Print " errore Non previsto " & Err.Number & " : " & Err.Description
                GoTo Exit_Handler
            End If
     
    End Sub
  • Re: Errore 3078 ripetuto nella stessa sub

    Non hai messo il codice che Bypassa le form senza Connessione dati, prima sebrava importante...?

    Segnalo anche questo:

    Set frm = accapp.Forms(obj.Name)
    .....
    Debug.Print obj.Name, frm.Name, fld.SourceTable, fld.Name, FieldTypeName(fld)

    Nel codice [obj.Name] e [frm.Name] ti aspetti possano essere differenti...?

    Per la parte delle proprietà io lo scriverei così:

    For Each ctl In frm
    	Select Case ctl.ControlType
            Case 105 To 122
                Debug.Print ctl.Name, ctl.ControlType, ctl.Visible, ctl.Enabled, ctl.Tag, ctl.ControlSource
                
        	Case Else        
        
        End Select
    Next ctl

    Quando avevo voglia di giocare con Access avevo fatto questo attrezzo, non è perfetto, sicuramente ha dei BUGS, ma dentro trovi parecchio codice interessante e riutilizzabile...

    https://1drv.ms/u/c/8285b3eb6cb0b6b7/ESMEixb8uqBMj_ZEN49tdsgBKCnmi-aqnm9diYRUo7qA1Q?e=s97Gp8

  • Re: Errore 3078 ripetuto nella stessa sub

    Saltare le form senza connessioni non mi interessa più, gestisco la cosa tramite gli errori,  ovviamente obj.Name e Frm.name sono sempre uguali.

    Grazie di nuovo per l'aiuto

Devi accedere o registrarti per scrivere nel forum
6 risposte