Come sapere se la tabella è usata in una query di Access?

Mi è capitato di lavorare su un database non documentato, contenente moltissimi oggetti: molte tabelle e molte query.

Dovendo apportare alcune modifiche alle tabelle, la domanda che mi è sorta subito è stata: come sapere se la tabella è usata in una query?

Così ho implementato una procedura che controlla se una tabella è utilizzata all’interno di una query. Il risultato della procedura è visualizzato nella finestra immediata. Naturalmente si potrebbe modificare la procedura e memorizzare i risultati in modo più efficiente all’interno di una tabella, ma questo lo lascio a voi :-)

Sub sAnalisiTabelleUtilizzateInQuery()

Dim tdf As TableDef ' riferimento a una tabella
Dim qdf As QueryDef ' riferimento a una query
Dim fld As Field ' riferimento a un campo
Dim db As Database ' riferimento al database corrente
Dim blnUtilizzata As Boolean ' Vero / Falso se la tabella è utilizzata in una query
Set db = CurrentDb
' per ogni tabella presente nella collezione delle tabelle
For Each tdf In db.TableDefs
 ' escludo le tabelle di sistema
  If Left(tdf.Name, 4) <> "MSys" Then
 ' resetto la variabile che mi dice se la tabella è utilizzata
   blnUtilizzata = False
 ' per ogni query presente nella collezione delle query
  For Each qdf In db.QueryDefs
 ' se la query non è un oggetto temporaneo il cui nome inizia con tilde
   If Left(qdf.Name, 1) <> "~" Then
 ' per ogni campo presente nella collezione dei campi della query
    For Each fld In qdf.Fields
     If fld.SourceTable = tdf.Name Then
      Debug.Print "Tabella: " & tdf.Name & " è utilizzata nella query: " & qdf.Name
      blnUtilizzata = True
 ' non controllo più i rimanenti campi, ormai so che la tabella è utilizzata
      Exit For
     End If
    Next ' prossimo campo
   End If
 ' se la tabella non risulta utilizzata, controllo che il nome della tabella non sia eventualmente presente come stringa all'interno della query
 ' potrebbe accadere se c'è un campo calcolato, per es. DLOOKUP("nomecampo","nometabella","filtro")
 ' in questo caso fld.SourceField restituirebbe una stringa vuota
   If blnUtilizzata = False And InStr(qdf.SQL, tdf.Name) > 0 Then
     Debug.Print "? Forse la tabella " & tdf.Name & " è utilizzata in un campo calcolato della query " &   qdf.Name
     blnUtilizzata = True
   End If
  Next  ' prossima query
  If blnUtilizzata = False Then
     Debug.Print "* Tabella " & tdf.Name & " non è utilizzata in alcuna query"
  End If
 End If  ' chiude la If sul test se nome tabella non è MSys
Next   ' prossima tabella 
End Sub

Il codice è commentato approfonditamente.

In sintesi: per ogni tabella presente nel database viene verificato se è presente all’interno di una query. In caso affermativo, viene riportato un messaggio nella finestra immediata, es:

Tabella: tbl_1 è utilizzata nella query: sel_A

Attenzione! La query potrebbe contenere una colonna calcolata con un’espressione tipo DLookUp o DCount ecc, che fa riferimento alla tabella. Il tal caso il test effettuato non sarebbe in grado di identificare o meno un riferimento alla tabella. Perciò ho aggiunto un ulteriore  test che controlla se il nome della tabella è presente nell’istruzione SQL. Tuttavia, è possibile ottenere dei falsi positivi, qualora il nome della tabella sia anche sottostringa di un campo. Esempio:

nome tabella Codice

nome campo: CodiceIdentificativo

In tal caso la procedura troverebbe la stringa Codice all’interno dell’istruzione SQL, anche se in realtà la query non utilizza la tabella.