views:

134

answers:

2

I know there's a way to get a list of all tables in an Access database by using the quering the MsysObjects: "SELECT MSysObjects.Name FROM MsysObjects WHERE (Left$([Name],1)<>'~') AND (Left$([Name],4)<>'Msys') AND (MSysObjects.Type)=1 ORDER BY MSysObjects.Name"

Does anybody know a similar (or other) way to retrieve a list of all indexes in an MS-Access database?

+1  A: 

I don't think you can use a SELECT statement to list index names. You can examine TableDef objects to access the index names.

Public Sub ShowIndexNames()
    Dim tdf As TableDef
    Dim idx As Index
    Dim num_indexes As Long

On Error GoTo ErrorHandler

    For Each tdf In CurrentDb.TableDefs
        num_indexes = tdf.Indexes.Count
        If Left$(tdf.Name, 4) <> "MSys" Then
            If num_indexes > 0 Then
                For Each idx In tdf.Indexes
                    Debug.Print tdf.Name, idx.Name
                Next idx
            End If
         End If
    Next tdf

ExitHere:
    Exit Sub

ErrorHandler:
    Select Case Err.Number
    Case 3110
        'Could not read definitions; no read definitions '
        'permission for table or query '<Name>'. '
        Debug.Print "No read definitions permission for " _
            & tdf.Name
        num_indexes = 0
        Resume Next
    Case Else
        Debug.Print Err.Number & "-> " & Err.Description
        GoTo ExitHere
    End Select
End Sub

Edit: Revised the sub to ignore MSys* (Access system) tables.

HansUp
HansUp > Thanks
waanders
A: 

Great! That works fine for me. I can even see if a index is unique or primary. One point: I've to delete the MSys stuff, but this is no problem.

One question: why do I see more indexes than there really are? I already did a Compact Database

waanders
I revised the code to ignore MSys tables.When you create relationships which enforce referential integrity, Access creates additional indexes "behind the scenes".
HansUp
It's not clear if your questions about "more indexes than there really are" is related to the system tables or to your "real" tables. If it's the latter, it's because when you create a relationship, Access creates a hidden index. Also, if you've got it turned on, Access will create indexes for fields ending in "ID" and other tags that you can set in your Access options. Both of these things can lead to duplicate indexes that can take up a significant amount of disk space and also slow things down in terms of maintaining them, so you really want to eliminate as many of them as you can.
David-W-Fenton
waanders - I've noticed for years if not a decade that Access/Jet creates some iodexes that you can't see using the tabledefs collection.
Tony Toews
David, duplicate indexes don't take any more room in the MDB. Jet is smart enough to handle those properly. That said I can see that arbitrarily creating indexes on fields ending in ID, num, etc, can be quite useless.
Tony Toews
With "more indexes than there really are" I meant the indexes besides the ones of the system tables that I not defined myself. But now I understand Access creates these as hidden ones. I've made a copy of my database and removed all relations and than ran the code again, and yes, now I only see the ones I've made.Thanks you all for the advice.
waanders
@Tony Toews: the relationship indexes are duplicates that take up space. Back in 2000 or so I rebuilt a Jet 3.5 replica set that had duplicate indexes and removed the dupes and it reduced the size of the data file by about 20%.
David-W-Fenton
David, I tested this in Jet 4.0 a few years back and duplicate indexes did not take extra room.
Tony Toews