Esta es la segunda parte de “Maximizando el reúso de código”. La parte uno se enfocó en asignar más de un manejador de eventos al mismo evento de un objeto o compartir el mismo manejador de eventos para diferentes objetos. Ahora hablaremos de cómo podemos escribir automatizaciones en tiempo de diseño para ayudarnos a ahorrar tiempo a la hora de programar.
Si le encanta escribir, deténgase no continúe leyendo esto.
Algunas veces recibimos una base de datos de otra persona y nos damos cuenta que necesitamos hacer mucho trabajo para optimizarla. Para comenzar, supongamos que queremos agregar KeyNavigator -mencionando en la parte uno -a 100 formularios continuos repartidos en la base de datos de Access. Recuerde que le mostramos como podíamos reducir los requerimientos de configuración en cada formulario con solo 4 líneas de código, pero 400 líneas de código siguen siendo mucho por escribir.
¿Para qué escribir cuando podemos hacer que VBA lo haga por nosotros?
Verifique antes de ejecutar el código que tenga la referencia de “Microsoft Visual Basic para Aplicaciones Extensible 5.3”. Solo la necesita mientras se ejecuta el código, puede removerla después.
Utilizando el objeto Module, podemos escribir un procedimiento desde cero en un módulo para optimizar el trabajo por nosotros. Es típico tener un módulo principal agregado a nuestro proyecto – quizás llamado “zzScrathPad” así que la lista lo organiza al final de manera ascendente. También preferimos hacer todos los procedimientos privados, porque la intensión no es usarlo en tiempo de ejecución. La única manera de ejecutarlo es desde el editor de VBA, el cual es el apropiado para nuestro propósito.
Como necesitamos agregar 4 líneas de código para todos los formularios continuos, necesitamos configurar un ciclo que los recorra todos. Para reducir los errores asociados con los múltiples formularios que están abierto (ej.. usted no puede abrir un formulario en modo diseño cuando ya está abierto como subformulario de otro formulario), cerraremos todo los objetos y trabajaremos solo con uno a la vez, además, es posible que no tengamos un módulo para cada formulario, tenemos que asegurarnos de hacer uno.
Private Sub StartAddKNInitCode()
Dim ao As Access.AccessObject
On Error GoTo ErrHandler
DoCmd.RunCommand acCmdCloseAll
If Forms.Count Then
MsgBox "Cannot process; there are still open forms. Please close them."
Exit Sub
End If
For Each ao In CurrentProject.AllForms
DoCmd.OpenForm ao.Name, acDesign, , , , acHidden
With Forms(ao.Name)
If .DefaultView = 1 Then 'It's a continuous form
If .HasModule = False Then
.HasModule = True 'Add a module
DoCmd.Save acForm, ao.Name
End If
AddKNInitCode .Module
End If
End With
DoCmd.Close acForm, ao.Name
Next
ExitProc:
On Error Resume Next
Exit Sub
ErrHandler:
Select Case Err.Number
Case Else
MsgBox "Error " & Err.Number & " (" & Err.Description & ")"
End Select
Resume ExitProc
Resume
End Sub
Ahora tenemos el formulario correcto y su módulo adquirido, existen otras cosas que tenemos que tomar en cuenta. ¿Qué pasa si un formulario ya tiene un manejador de eventos creado? No queremos código duplicado ni con errores porque no compilará. Así que necesitamos examinar el módulo para determinar si hay un manejador de eventos y editarlo o agregar uno nuevo de una manera apropiada.
Private Sub AddKNInitCode(FormModule As Access.Module)
Dim l As Long 'Line Pointer
Dim i As Long 'Iterator
Dim b As Long 'Start point
Dim c As Long 'End point
Dim s As String 'Current Line Text
Dim bolHasIt As Boolean
Const Evented As String = "[Event Procedure]"
Const VariableLine As String = "Private kn As KeyNavigator"
Const InitLines As String = "Set kn = New KeyNavigator" & vbNewLine & "kn.Init Me"
Const DestLine As String = "Set kn = Nothing"
On Error GoTo ErrHandler
bolHasIt = False
b = 1
c = FormModule.CountOfDeclarationLines
For i = b To c
s = FormModule.Lines(i, 1)
Select Case s
Case VariableLine
bolHasIt = True
Exit For
End Select
Next
If Not bolHasIt Then
FormModule.InsertLines c + 1, VariableLine
End If
bolHasIt = False
l = 0
On Error Resume Next
l = FormModule.ProcBodyLine("Form_Load", vbext_pk_Proc)
On Error GoTo ErrHandler
If l Then
s = FormModule.Lines(l, FormModule.ProcCountLines("Form_Load", vbext_pk_Proc))
If InStr(s, InitLines) = 0 Then
If InStr(s, "On Error GoTo") = 0 Then
FormModule.InsertLines l + 1, InitLines
Else
b = l
c = l + FormModule.ProcCountLines("Form_Load", vbext_pk_Proc)
For i = b To c
s = FormModule.Lines(i, 1)
If InStr(s, "On Error GoTo") Then
FormModule.InsertLines i + 1, InitLines
Exit For
End If
Next
End If
End If
Else
FormModule.Parent.OnOpen = Evented
FormModule.InsertText _
"Private Sub Form_Load()" & vbNewLine & _
InitLines & vbNewLine & _
"End Sub" & vbNewLine
End If
bolHasIt = False
l = 0
On Error Resume Next
l = FormModule.ProcBodyLine("Form_Close", vbext_pk_Proc)
On Error GoTo ErrHandler
If l Then
s = FormModule.Lines(l, FormModule.ProcCountLines("Form_Close", vbext_pk_Proc))
If InStr(s, DestLine) = 0 Then
If InStr(s, "On Error GoTo") = 0 Then
FormModule.InsertLines l + 1, DestLine
Else
b = l
c = FormModule.ProcCountLines("Form_Close", vbext_pk_Proc)
For i = b To c
s = FormModule.Lines(i, 1)
If InStr(s, "On Error GoTo") Then
FormModule.InsertLines i + 1, DestLine
bolHasIt = True
Exit For
End If
Next
If bolHasIt = False Then
FormModule.InsertLines l + 1, DestLine
End If
End If
End If
Else
FormModule.Parent.OnClose = Evented
FormModule.InsertText _
"Private Sub Form_Close()" & vbNewLine & _
DestLine & vbNewLine & _
"End Sub"
End If
DoCmd.Save acForm, FormModule.Parent.Name
ExitProc:
On Error Resume Next
Exit Sub
ErrHandler:
Select Case Err.Number
Case Else
MsgBox "Error " & Err.Number & " (" & Err.Description & ") on Line: " & Erl
End Select
Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
Resume
End Sub
Ahora tenemos 4 líneas agregadas automáticamente en todos nuestros formularios. Como el código también verifica si existen esas 4 líneas, lo podemos ejecutar una y otras vez si agregamos más formularios continuos y solo le agrega la 4 líneas de código si el formulario no las tiene. Esto es muy útil cuando usted posee 100 formularios en un archivo de Access que no existen en otro.
Obviamente, usted tendrá que adaptar el código a sus necesidades. Crear un conjunto de rutinas para actualizar una base de datos vieja y adaptarla con sus nuevas librerías y objetos ahora es bien sencillo. ¡Feliz automatización!


Deja tu comentario