2008-09-23 10 views

Respuesta

49

Depende de quién va a desarrollar y mantener el código. Los macro escritores típicos de "Power User" que piratean pequeñas aplicaciones ad-hoc pueden confundirse al usar las clases. Pero para un desarrollo serio, las razones para usar clases son las mismas que en otros idiomas. Tiene las mismas restricciones que VB6, sin herencia, pero puede tener polimorfismo mediante el uso de interfaces.

Un buen uso de las clases es representar entidades y colecciones de entidades. Por ejemplo, a menudo veo código VBA que copia un rango de Excel en una matriz de dos dimensiones, a continuación, manipula la matriz bidimensional con un código como:

Total = 0 
For i = 0 To NumRows-1 
    Total = Total + (OrderArray(i,1) * OrderArray(i,3)) 
Next i 

Es más fácil de leer para copiar el rango en una colección de objetos con propiedades con el nombre apropiado, algo así como:

Total = 0 
For Each objOrder in colOrders 
    Total = Total + objOrder.Quantity * objOrder.Price 
Next i 

Otro ejemplo es el uso de clases para implementar el patrón de diseño RAII (google para ello). Por ejemplo, una cosa que debo hacer es desproteger una hoja de cálculo, hacer algunas manipulaciones y luego protegerla de nuevo. Utilizar una clase asegura que la hoja de trabajo siempre estará protegido de nuevo, incluso si se produce un error en el código:

--- WorksheetProtector class module --- 

Private m_objWorksheet As Worksheet 
Private m_sPassword As String 

Public Sub Unprotect(Worksheet As Worksheet, Password As String) 
    ' Nothing to do if we didn't define a password for the worksheet 
    If Len(Password) = 0 Then Exit Sub 

    ' If the worksheet is already unprotected, nothing to do 
    If Not Worksheet.ProtectContents Then Exit Sub 

    ' Unprotect the worksheet 
    Worksheet.Unprotect Password 

    ' Remember the worksheet and password so we can protect again 
    Set m_objWorksheet = Worksheet 
    m_sPassword = Password 
End Sub 

Public Sub Protect() 
    ' Protects the worksheet with the same password used to unprotect it 
    If m_objWorksheet Is Nothing Then Exit Sub 
    If Len(m_sPassword) = 0 Then Exit Sub 

    ' If the worksheet is already protected, nothing to do 
    If m_objWorksheet.ProtectContents Then Exit Sub 

    m_objWorksheet.Protect m_sPassword 
    Set m_objWorksheet = Nothing 
    m_sPassword = "" 
End Sub 

Private Sub Class_Terminate() 
    ' Reprotect the worksheet when this object goes out of scope 
    On Error Resume Next 
    Protect 
End Sub 

entonces usted puede utilizar esto para simplificar el código:

Public Sub DoSomething() 
    Dim objWorksheetProtector as WorksheetProtector 
    Set objWorksheetProtector = New WorksheetProtector 
    objWorksheetProtector.Unprotect myWorksheet, myPassword 

    ... manipulate myWorksheet - may raise an error 

End Sub 

cuando este Sub salidas, objWorksheetProtector queda fuera del alcance y la hoja de trabajo está protegida de nuevo.

+2

Este es un buen ejemplo de una razón para usar clases en VBA. No estoy seguro de que alguna vez lo haga, pero sin embargo es un buen ejemplo. – cori

+1

Realmente es bueno saberlo. –

+0

@Joe este es un buen ejemplo. Con frecuencia tengo que usar/escribir clases en VBA. Creo que si se siente cómodo con los conceptos de programación orientada a objetos de otros lenguajes de OOP y las limitaciones de VBA, puede simplemente articular sus clases en VBA. Al final, todos estos * elementos * que utilizamos en Excel son objetos/propiedades/métodos de una estructura de clase. Tiene más sentido, es fácil de administrar, de transferencia que muchas líneas que se repiten aquí y allá :) – bonCodigo

-1

No veo por qué los criterios para VBA serían diferentes a los de otro idioma, especialmente si se refiere a VB.NET.

+4

Tal vez estoy equivocado, pero no creo que sea un candidato si buscas Herencia . –

5

No diría que hay un criterio específico, pero nunca he encontrado un lugar útil para usar Classes en el código VBA. En mi opinión, está tan vinculado a los modelos existentes alrededor de las aplicaciones de Office que agregar abstracción adicional fuera de ese modelo de objetos solo confunde las cosas.

Eso no quiere decir que no pudo encontrar un lugar útil para una clase en VBA, o hacer cosas perfectamente útiles con una clase, solo que nunca los he encontrado útiles en ese entorno.

+0

-1: No estoy de acuerdo, ya que el modelo de Office se basa en clases, es bastante consistente usar clases en tu código. – Joe

+0

Debidamente observado, aunque * he * notado específicamente que en particular nunca los encuentro tan útiles; no es que * no * puedan ser útiles. – cori

+0

Pongo funciones comunes dentro de clases suplementarias, a menudo la clase tiene una función principal única para realizar, y puede factorizar los procesos secundarios, haciendo que todo sea más fácil de mantener. Las clases son siempre más útiles si el mantenimiento va a ser una preocupación futura, si por supuesto no te importan las personas que te siguen ... por supuesto crea funciones complicadas y repetidas, código de espagueti ... un poco como la mayoría otras cosas en MS;) – DaveM

3

También puede reutilizar el código VBA sin utilizar clases reales. Por ejemplo, si tiene una llamada, VBACode. Se puede acceder a cualquier función o sub en cualquier módulo con la siguiente sintaxis:

VBCode.mysub(param1, param2) 

Si crea una referencia a una plantilla/doc (como lo haría un DLL), puede hacer referencia código de otros proyectos en el mismo camino.

8

creo que el criterio es el mismo que otros idiomas

Si necesita unir varias piezas de datos y algunos métodos y también se ocupan específicamente lo que sucede cuando se crea el objeto/terminado, las clases son ideales

decir si tiene unos procedimientos que se activan cuando se abre un formulario y uno de ellos está tomando mucho tiempo, es posible que decida que desea vez cada etapa ......

se puede crear un cronómetro clase con métodos para las funciones obvias para iniciar y detener, puede agregar una función para recuperar el tiempo hasta ahora e informarlo en un archivo de texto, usando un argumento que representa el nombre del proceso que se está programando. Podría escribir lógica para registrar solo las actuaciones más lentas para la investigación.

A continuación, podría agregar un objeto de barra de progreso con los métodos para abrir y cerrarla, y para visualizar los nombres de la acción actual, junto con los tiempos en ms y tiempo probable permanecer sobre la base de los informes anteriores almacenados etc

Otro ejemplo podría ser si no le gusta la basura del grupo de usuarios de Access, puede crear su propia clase de usuario con métodos para entrar y salir y funciones para control de grupo de usuarios/auditoría/registro de ciertas acciones/errores de seguimiento, etc.

Por supuesto podrías hacer esto usando un conjunto de métodos no relacionados y muchos pases variables, pero tener todo encapsulado en una clase me parece mejor.

Llegará tarde o temprano a los límites de VBA, pero es un lenguaje bastante poderoso y si su empresa lo ata, de hecho puede obtener algunas soluciones buenas y complejas.

2

El desarrollo de software, incluso con Microsoft Access, mediante programación orientada a objetos es generalmente una buena práctica. Permitirá escalabilidad en el futuro al permitir que los objetos se acoplen libremente, junto con una serie de ventajas.Esto básicamente significa que los objetos en su sistema serán menos dependientes entre sí, por lo que la refacturación se vuelve mucho más fácil. Puede lograr esto es Acceso utilizando módulos de clase. El inconveniente es que no puede realizar herencia de clase o polimorfismo en VBA. Al final, no hay una regla rígida sobre el uso de clases, solo mejores prácticas. Pero tenga en cuenta que a medida que su aplicación crece, es más fácil mantener el uso de clases.

2

Para la recursión de datos (por ejemplo, el manejo de la BOM), una clase personalizada es críticamente útil y creo que a veces es indispensable. Puede hacer una función recursiva sin un módulo de clase, pero muchos problemas de datos no se pueden abordar de manera efectiva.

(no sé por qué la gente no está vendiendo fuera de lista de materiales de la biblioteca-sets para VBA. Tal vez las herramientas XML han hecho una diferencia.)

casos de forma múltiple es la aplicación común de una clase (muchos los problemas de automatización son de otro modo irresolubles), supongo que la pregunta es sobre clases personalizadas.

+0

Mi pregunta es sobre clases personalizadas. –

2

Uso las clases cuando necesito hacer algo y una clase lo hará mejor :) Por ejemplo, si necesita responder a eventos (o interceptarlos), entonces necesita una clase. Algunas personas odian los UDT (tipos definidos por el usuario) pero me gustan, así que los uso si quiero un código de auto-documentación en inglés. Pharmacy.NCPDP es mucho más fácil de leer que strPhrmNum :) Pero un UDT es limitado, así que supongamos que quiero establecer Pharmacy.NCPDP y que todas las demás propiedades se completen. Y también quiero hacerlo para que no puedas alterar accidentalmente los datos. Entonces necesito una clase, porque no tiene propiedades de solo lectura en un UDT, etc.

Otra consideración es simplemente la facilidad de lectura. Si está haciendo estructuras de datos complejas, a menudo es beneficioso saber que solo necesita llamar a Company.Owner.Phone.AreaCode y luego intentar realizar un seguimiento de dónde está estructurado todo. Especialmente para las personas que tienen que mantener esa base de código 2 años después de su partida :)

Mis dos centavos es "Código con propósito". No uses una clase sin una razón.Pero si tiene una razón, hágalo :)

2

Uso las clases si deseo crear un paquete de código autoencapsulado que usaré en muchos proyectos de VBA que se encuentran para varios clientes.

5

Las clases son extremadamente útiles cuando se trata de las funciones API más complejas, y particularmente cuando requieren una estructura de datos.

Por ejemplo, las funciones GetOpenFileName() y GetSaveFileName() toman una estructura OPENFILENAME con muchos miembros. es posible que no necesite aprovechar todas ellas, pero están ahí y deben inicializarse.

Me gusta ajustar la estructura (UDT) y las declaraciones de función API en una clase CfileDialog. El evento Class_Initialize establece los valores predeterminados de los miembros de la estructura, de modo que cuando uso la clase, solo necesito establecer los miembros que deseo cambiar (a través de los procedimientos de Propiedad). Las constantes de bandera se implementan como Enum. Así, por ejemplo, elegir una hoja de cálculo para abrir, mi código podría tener este aspecto:

Dim strFileName As String 
Dim dlgXLS As New CFileDialog 

With dlgXLS 
    .Title = "Choose a Spreadsheet" 
    .Filter = "Excel (*.xls)|*.xls|All Files (*.*)|*.*" 
    .Flags = ofnFileMustExist OR ofnExplorer 

    If OpenFileDialog() Then 
    strFileName = .FileName 
    End If 
End With 
Set dlgXLS = Nothing 

La clase establece el directorio predeterminado en Mis documentos, aunque si quería que podría cambiar con la propiedad InitDir.

Este es solo un ejemplo de cómo una clase puede ser muy beneficiosa en una aplicación de VBA.

0

Puede definir una clase contenedora sql en el acceso que sea más conveniente que los conjuntos de registros y los querydefs. Por ejemplo, si desea actualizar una tabla basada en un criterio en otra tabla relacionada, no puede usar uniones. Podrías crear un vb recorset y querydef para hacer eso, sin embargo, me resulta más fácil con una clase. Además, su aplicación puede tener algún concepto que necesite más de 2 tablas, podría ser mejor utilizar clases para eso. P.ej. Su aplicación rastrea incidentes. El incidente tiene varios atributos que se mantendrán en varias tablas {usuarios y sus contactos o perfiles, descripción del incidente; seguimiento del estado; Listas de verificación para ayudar al oficial de soporte a responder el incidente; Responder ...}. Para realizar un seguimiento de todas las consultas y relaciones involucradas, oop puede ser útil. Es un alivio poder hacer Incident.Update (xxx) en lugar de toda la codificación ...

Cuestiones relacionadas