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