Algoritmo / class LIFO (Stack) para Excel VBA

Estoy buscando implementar una class "Stack" en VBA para Excel. Quiero usar una estructura Last In First Out. ¿Alguien se encontró con este problema antes? ¿Conoces bibliotecas externas que manejan estructuras como Stack, Hastable, Vector … (aparte de la colección original de Excel, etc.)

Gracias

Aquí hay una class de stack muy simple.

Option Explicit Dim pStack As Collection Public Function Pop() As Variant With pStack If .Count > 0 Then Pop = .Item(.Count) .Remove .Count End If End With End Function Public Function Push(newItem As Variant) As Variant With pStack .Add newItem Push = .Item(.Count) End With End Function Public Sub init() Set pStack = New Collection End Sub 

Pruébalo

 Option Explicit Sub test() Dim cs As New cStack Dim i As Long Set cs = New cStack With cs .init For i = 1 To 10 Debug.Print CStr(.Push(i)) Next i For i = 1 To 10 Debug.Print CStr(.Pop) Next i End With End Sub 

Bruce

No conozco ninguna biblioteca externa de VBA para estas estructuras. Para mi stack de llamadas a procedimientos, utilizo una matriz global y un puntero de matriz con methods Push y Pop.

Bruce McKinney proporcionó el código para una Pila, Lista y Vector en este libro (era VB5 (!), Pero eso probablemente no importa mucho):

http://www.amazon.com/Hardcore-Visual-Basic-Bruce-McKinney/dp/1572314222

(Está agotado, pero las copys usadas son baratas).

El código fuente parece estar disponible aquí:

http://vb.mvps.org/hardweb/mckinney2a.htm#2

(Advertencia: nunca he usado ninguno de sus códigos, pero sé que es un experto en VB de mucho prestigio y hace mucho time, y su libro se incluyó en MSDN durante mucho time).

Estoy seguro de que también hay muchas implementaciones diferentes para estas cosas que flotan en Internet, pero no sé si alguna de ellas es ampliamente utilizada por nadie más que por sus autores.

Por supuesto, ninguna de estas cosas es tan difícil de escribir su propio código, dado que VBA admite matrices networkingimensionables (la mayor parte del path hacia un vector) y proporciona una class de Colección incorporada (la mayor parte del path hasta una list). La respuesta de Charles William para una stack es toda la información que necesitas. Simplemente proporcione su propio contenedor alnetworkingedor de una matriz o una colección, pero el código interno puede ser relativamente trivial.

Para una tabla hash, MS Scripting Runtime incluye una class de dictionary que básicamente es una. Ver:

Tabla hash / matriz asociativa en VBA

Puede usar la class Pila en System.Collections, ya que puede usar Queue y otros. Simplemente busque vb.net stack para documentation. No he probado todos los methods (por ejemplo, Getenumerator: no sé cómo usar un iterador, si es posible en VBA). El uso de una stack o una queue le brinda algunos beneficios agradables, normalmente no tan fáciles en VBA. Puedes usar

 anArray = myStack.ToArray 

INCLUSO si la stack está vacía (Devuelve una matriz de tamaño 0 a -1).

Al usar un object de collections personalizado, funciona muy rápido debido a su simplicidad y puede reescribirse fácilmente (por ejemplo, para manejar únicamente varibles fuertemente tipadas). Es posible que desee verificar la stack vacía. Si intenta utilizar Pop en una stack vacía, VBA no lo manejará correctamente, como todos los objects nulos. Me pareció más razonable de usar:

 If myStack.Count > 0 Then 

de la function que usa la stack, en lugar de cocerla en clsStack.Pop. Si lo preparas en la class, una llamada a Pop puede devolver un valor del tipo elegido; por supuesto, puedes utilizarlo para manejar valores vacíos, pero obtienes mucho más dolor de esa manera.

Un ejemplo de uso:

 Private Sub TestStack() Dim i as long Dim myStack as clsStack Set myStack = New clsStack For i = 1 to 2 myStack.Push i Next For i = 1 to 3 If myStack.Count > 0 Then Debug.Print myStack.Pop Else Debug.Print "Stack is empty" End If Next Set myStack = Nothing End Sub 

¡Usar una stack LIFO puede ser extremadamente útil!

Class clsStack

 Dim pStack as Object Private Sub Class_Initialize() set pStack = CreateObject("System.Collections.Stack") End Sub Public Function Push(Value as Variant) pStack.Push Value End Function Public Function Pop() As Variant Pop = pStack.Pop End Function Public Function Count() as long Count = pstack.Count End Function Public Function ToArray() As Variant() ToArray = pStack.ToArray() End Function Public Function GetHashCode() As Integer GetHashCode = pStack.GetHashCode End Function Public Function Clear() pStack.Clear End Function Private Sub Class_terminate() If (Not pStack Is Nothing) Then pStack.Clear End If Set pStack = Nothing End Sub