2011-02-02 20 views
5

Estoy buscando implementar una clase "Apilada" en VBA para Excel. Quiero usar una estructura Last In First Out. ¿Alguien se encontró con este problema antes? ¿Sabe usted bibliotecas externas estructura de manejo tales como Pila, Hastable, vector ... (aparte de la colección original de Excel, etc ...)LIFO (Apilado) Algoritmo/Clase para Excel VBA

Gracias

Respuesta

7

Aquí está una clase de pila 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 

prueba que

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

+1

¡Bienvenido a stackoverflow! +1 para proporcionar algún código y mostrar lo simple que puede ser. Algunas advertencias: 1) El uso de '=' para devolver un valor en sus rutinas 'Push' y 'Pop' fallará cuando los objetos estén involucrados debido a la molesta sintaxis 'Set' de VBA. Consulte el final de esta respuesta: http://stackoverflow.com/questions/4716382/excel-select-case/4719706#4719706 2) Tenga en cuenta que la indexación en una Colección es O (n) por tiempo. Ver http://stackoverflow.com/questions/4827963/what-is-the-difference-between-the-time-complexity-of-these-two-ways-of-using-loo/4830157#4830157 – jtolle

1

No sé de ninguna biblioteca VBA externos para estas estructuras. Para mi pila de llamadas a procedimientos, utilizo una matriz global y un puntero de matriz con métodos Push y Pop.

1

Bruce McKinney proporciona código para una pila, List y vectorial en este libro (que era VB5(), pero que probablemente no importa mucho!):

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

(Está fuera de El trabajo de impresión copias usadas son baratos)

El código fuente parece estar disponible aquí:.

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

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

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

Por supuesto, nada de esto es tan difícil de escribir su propio código, dado que VBA admite matrices redimensionables (la mayor parte del camino a un vector) y proporciona una clase de Colección incorporada (la mayor parte del una lista). La respuesta de Charles William para una pila es toda la información que necesitas. Simplemente proporcione su propio contenedor alrededor 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 clase de diccionario que básicamente es una. Ver:

Hash Table/Associative Array in VBA

+1

Debo señalar que el código de McKinney no es bastante "trivial". También proporciona clases de iterador para sus colecciones, etc. – jtolle

+0

muchas gracias, le daremos un vistazo – BlackLabrador

0

Puede utilizar la pila de clases en System.Collections, como se puede usar cola y otros. Simplemente busque vb.net stack para documentación. No he probado todos los métodos (por ejemplo, Getenumerator: no sé cómo usar un iterador, si es posible en VBA). El uso de una pila o una cola le brinda algunos beneficios agradables, normalmente no tan fáciles en VBA. Puede usar

anArray = myStack.ToArray 

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

Al usar un objeto de colecciones personalizado, funciona muy rápido debido a su simplicidad y se puede volver a escribir fácilmente (por ejemplo, para manejar solo varibles fuertemente tipadas). Es posible que desee verificar la pila vacía. Si intenta utilizar Pop en una pila vacía, VBA no lo manejará correctamente, como todos los objetos nulos.Me pareció más razonable utilizar:

If myStack.Count > 0 Then 

de la función utilizando la pila, en lugar de hornearlo en clsStack.Pop. Si lo preparas en la clase, una llamada a Pop puede devolver un valor del tipo elegido; por supuesto, puedes usarlo 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 

Usando una pila LIFO-puede ser extremadamente útil!

Clase 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