Access Cookbook - Ken Getz [142]
Public Sub acbInitStack( )
' Resets the stack top to 0.
mintStackTop = 0
End Sub
You can add an item to the stack at any time by calling acbPushStack. Pass to this subroutine the item you want pushed. To push the item, the code places the item in the array at the location stored in mintStackTop and then increments the value of mintStackTop. Its code is:
Public Sub acbPushStack(strToPush As String)
' Push a string onto the call stack.
' If the stack is full, display an error.
' Otherwise, add the new item to the call stack.
' Handle the error case first.
If mintStackTop > acbcMaxStack Then
MsgBox acbcMsgStackOverflow
Else
' Store away the string.
mastrStack(mintStackTop) = strToPush
' Set mintStackTop to point to the NEXT
' item to be filled.
mintStackTop = mintStackTop + 1
End If
End Sub
The only problem that might occur is that the stack might be full. The constant acbcMaxStack is originally set to 20, which should be enough levels. (Remember that mintStackTop goes up one only when a procedure calls another procedure. If you have 20 levels of procedure calling, you might consider rethinking your application, instead of worrying about procedure stacks!) If the stack is full, acbPushStack will pop up an alert and will not add the item to the stack.
When leaving a procedure, you'll want to remove an item from the stack. To do so, call the acbPopStack procedure:
Public Sub acbPopStack( )
' Pop a string from the call stack.
' If the stack is empty, display an error.
' Otherwise, set the current item to be the
' next one to be filled in. If you're logging,
' send the information out to the log file.
' Handle the error case first.
If mintStackTop = 0 Then
MsgBox acbcMsgStackUnderflow
Else
' Because you're removing an item, not adding one,
' set the stack top back to the previous row. Next time
' you add an item, it'll go right here.
mintStackTop = mintStackTop - 1
End If
End Sub
Just as in acbPushStack, this code first checks to make sure that the stack integrity hasn't been violated; you can't remove an item from the stack if there's nothing to remove! If you try, acbPopStack will pop up an alert and exit. If the stack is intact, the procedure will decrement the value of mintStackTop. Decrementing that value sets up the next call to acbPushStack so that it will place the new value where the old one used to be.
To retrieve the value at the top of the stack without pushing or popping anything, call the acbCurrentProc function:
Public Function acbCurrentProc( ) As String
' Since mintStackTop always points to the next item to
' be filled in, retrieve the item from mintStackTop - 1.
If mintStackTop > 0 Then
acbCurrentProc = mastrStack(mintStackTop - 1)
Else
acbCurrentProc = ""
End If
End Function
This function retrieves the value most recently placed on the stack (at the location one less than mintStackTop, because mintStackTop always points to the next location to be filled). You can't look at mastrStack yourself, because it's local to basStack—and that's the way it ought to be. Since the details of how the stack works are kept private, you can replace basStack, using a different architecture for the stack data structure, and the rest of your code won't have to change at all.
To retrieve more information about what's in the stack, you can call acbGetStackItems, to find out how many items there are in the stack, and acbGetStack, which retrieves a specific item from the stack. For example, write code like this to dump out the entire stack (see subroutine D, which does just this, in the basTestStack module):
Debug.Print "Stack items currently:"
For intI = 0 To acbGetStackItems( ) - 1
Debug.Print , acbGetStack(intI)
Next intI
The acbGetStackItems function is simple: it returns the value of mintStackTop, because