1

I am using some code that I found at AllenBrowne.com, which works fine, but I have a question about what it's doing.

The code is designed to return information about any index found on a specific column of a table in MS Access. Index types are identified with a constant, and there are four possible index types (including None):

Private Const intcIndexNone As Integer = 0
Private Const intcIndexGeneral As Integer = 1
Private Const intcIndexUnique As Integer = 3
Private Const intcIndexPrimary As Integer = 7

The relevant piece of code is as follows:

Private Function IndexOnField(tdf As DAO.TableDef, fld As DAO.Field) As Integer

    'Purpose:   Indicate if there is a single-field index on this field in this table.
    'Return:    The constant indicating the strongest type.
    
    
    
    Dim ind As DAO.Index
    Dim intReturn As Integer
    
    intReturn = intcIndexNone
    
    For Each ind In tdf.Indexes
        If ind.Fields.Count = 1 Then
            If ind.Fields(0).Name = fld.Name Then
                If ind.Primary Then
                    intReturn = (intReturn Or intcIndexPrimary)
                ElseIf ind.Unique Then
                    intReturn = (intReturn Or intcIndexUnique)
                Else
                    intReturn = (intReturn Or intcIndexGeneral)
                End If
            End If
        End If
    Next
    
    'Clean up
    Set ind = Nothing
    IndexOnField = intReturn

End Function

To be truthful, I didn't really understand the concept of a bitwise OR operator, so I've spent the last couple of hours researching that, so now I think I do. And along the way, I noticed that the four possible index values equate to a clear binary pattern:

None:    0
General: 1
Unique: 11
Primay: 111

All of which is good. But I don't understand the use in the function of the OR operator, in the lines:

 If ind.Primary Then
     intReturn = (intReturn Or intcIndexPrimary)
 ElseIf ind.Unique Then
     intReturn = (intReturn Or intcIndexUnique)
 Else
     intReturn = (intReturn Or intcIndexGeneral)
 End If

Given that the structure of this code means that only one path can ever be returned, why not just return the actual required constant, without the use of OR? I know that Allen Browne's code is always well crafted, so he won't, I assume, have done this without good reason, but I can't see what it is.

Can someone help, so that I can better understand - and write better code myself in future?

Thanks

2 Answers 2

2

As basodre pointed to about the bitwise is correct, but not the 2, 4, 8 basis.

When dealing with an index, ALL of the possibilities are possible, hence the 1, 3, 7 (right-most 3 bits).

0000 = No index
0001 = regular index
0011 = unique index
0111 = PRIMARY index

So, the IF block is testing with the HIGHEST QUALIFIER of the type of index.

Any index can be regular, no problem.

some indexes can be unique, and they could be on some sort of concatenated fields to want as unique that have NOTHING to do with the primary key of the table

Last IS the primary key of the table - which is ALSO UNIQUE.

So, if the index you are testing against IS the primary, it would also show as true if you asked if it was an index or even if it was a unique index.

So, what it is doing is starting the

 intReturn = intcIndexNone

which in essence sets the return value to a default of 0. Then it cycles through all indexes in the table that have the given field as part of an index. A table could have 20 indexes on it and 5 of them have an index using the field in question. That one field could be used as any possible part of a regular, unique or primary key index.
So the loop is starting with NONE (0). Then going through each time the field is found as associated with an index. Then whatever type of index that current index is, ORs the result.

So lets say that the index components as it goes through show a given field as Unique first, then regular, then Primary just for grins to see the result of the OR each cycle.

def intReturn     0000
   OR Unique      0011
                  ====
                  0011  NEW value moving forward


    intReturn     0011
   OR Regular     0001
                  ====
                  0011  Since unique was higher classification, no change


    intReturn     0011
   OR Primary     0111
                  ====
                  0111 Just upgraded to the highest classification index

So now, its returning the OR'd result of whatever the previous value was. In this case, the highest index association is "Primary" index

Does that clarify it for you?

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks so much for that - both the information and the very clear explanation. I think what I'd missed was the concept that it was looping through fields - and might encounter them more than once as part of multiple indexes. Thanks again - superb.
@AndrewRichards, glad it helped. I prefer to clarify WHY things work, not just the here's the answer. Hopefully next time you see something similar you would be like "0hhh.. now I get it". Give a fish, Teach to fish, right?
0

The bitwise OR is useful in cases where combinations of values can exist, and you'd want to return an additive value. In this specific code block, the code is looping through each of the indices, and setting the flag based on the specific index. If there are two indexes, and one of them is general and the other is primary, you can encode this information in resultant bit pattern.

I'm confused by the choice of bitmaps, though. By choosing values with all of the bits set to true, you'd lose information about individual items (maybe that's a design element).

Generally, bitmaps might look something like:

Option A = 2 --> 0010
Option B = 4 --> 0100
Option C = 8 --> 1000

If you want both Option A and Option B to be true, the BIT OR would return 6, which is 0110. Now, if you need to test if option A is true, you use the BIT AND operation. If you test (6 BIT AND 2) it will return a value greater than 0. However, if you test (8 BIT AND 6), which is the value for option c, it will return a 0.

Hopefully that adds some clarity. I don't have much information about how Access specifically works with indexes, so I'm just speaking to the general case.


EDIT: So I re-read the function definition, and it seems like the choice of integers is intentional. The function intentionally returns the strongest type of index. So, if there is a primary index, it will only show a primary. Considering this, I'm not sure that the bitwise or is the most self-descriptive option here. Maybe there is another consideration at play.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.