Serie ficheros virtuales 



VBA. Ficheros virtuales



VBA Ficheros virtuales. Lógicos


1 Introducción
2 Funcionamiento del libro de muestra


3 El código del libro de muestra
 3.1 Generación inicial de la base de datos virtual
 3.2 La grabación de ítems
 
3.3 La rutina de volcado desde el fichero virtual a la hoja en curso
 3.4 La supresión de ítems

4 El CRTLF
                                                                                                    _______


1 Introducción

En la interfaz W además de poder usar nombres en los ficheros, se introducen las vistas lógicas de los datos. Con los lógicos el sistema alcanza una potencia extraordinaria al poder manipular los datos de los ficheros desde cualquiera de sus perspectivas.

El ejemplo más sencillo de uso se plantea con los listines de teléfonos, donde interesa presentarlos por nombre o por número. Aunque es un tema simple que puede resolverse de diversas formas en hojas de cálculo, aquí vamos a resolverlo utilizando un fichero virtual ordenado por nombre, junto con su lógico ordenado por número.

Para darle versatilidad, el nombre del fichero coincidirá con el nombre de la hoja, permitiendo así llevar una multiagenda telefónica sencilla como se muestra en las imágenes





                                                                                                    _______

2 Funcionamiento del libro de muestra

El funcionamiento de cada hoja del libro es muy sencillo:

 - Se teclea un nombre en A2, se pulsa intro, se autositua en B2, se introduce el número, se pulsa intro y la línea se inserta en su lugar.

 - En una versión más elaborada, se añade un campo de observaciones en C, con lo que el esquema quedaría como:


    Se teclea un nombre en A2, se pulsa intro, se autositua en B2, se introduce el número, se pulsa intro, se autositua en C2, se introducen observaciones o un punto "." se pulsa intro y la línea se inserta en su lugar.

 - Con el botón de reordenar las posiciones se intercambian, presentándose entonces los datos ordenados por número y cambiando el funcionamiento a nº+intro, nombre+intro, etc.


 - También se incluye un botón de borrado total (con preaviso) y la facilidad de poder borrar entradas.


Las tareas de mantenimiento de la lista de agendas nos la proporciona el propio excell porque al generar una nueva hoja por copia de una preexistente se copia también el breve código específico de cada hoja.


( Tan simple como



       [Private Sub Worksheet_Activate() Cabecera End Sub] 

     +
    
       [Private Sub Worksheet_Change(ByVal Target As Range)  Cambios  End Sub] 
                                                                                                                

                                                                                                                       ).


Aunque el programa es sencillo, las cuestiones de detalle se llevan unas cuantas sentencias. El fuente completo se encuentra en libro Agen en donde se pueden consultar las rutinas Cabecera y Cambios junto con el resto del código, del que aquí se van a poner de relieve las sentencias principales.

 

Empezamos por las sentencias dedicadas a la generación inicial de los ficheros

                                                                                                    _______

3 El código del libro de muestra


3.1 Generación inicial de la base de datos virtual


' Generación inicial de ficheros

Sub GenFicherosVirtuales()

Dim lResul As Long  ' Control invocaciones W
Dim sHoja As String ' Nombre de la hoja actual


' Toma el nombre de la hoja

With ActiveSheet
    sHoja = .Name
End With


' Crea los ficheros virtuales de soporte si procede

lResul = W_NID(sHoja)
If lResul = 0 Then
                                                 
                                                  '      30/10    | 30       10
    lResul = W_NEW(sHoja, 30, 40)                 ' Base: Nombre  | Nombre + Nº
    lResul = W_CRTLF(sHoja & "01", sHoja, 31, 10) ' Lf01: Nº      | Nombre + Nº


    ' Restaura ficheros desde el contenido actual de la hoja

    RSTF

End If


End Sub

                                                                                                    _______

3.2 La grabación de ítems


El siguiente grupo de sentencias relevantes es el dedicado a la grabación de ítems



' Rutina control de introducción de nueva línea de datos


Sub NuevaLinea()

Dim sHoja As String       ' Nombre de la hoja en curso
Dim sClavW As String * 30 ' Paso auxiliar de claves
Dim sDatoW As String * 40 ' Paso auxiliar de datos
Dim lResul As Long        ' Control de resultados intermedios

On Error Resume Next ' Elude errores


' Toma el nombre de la hoja

With ActiveSheet
    sHoja = .Name
End With


' Pasa clave

If Left(Range("A1"), 6) = "Nombre" Then
    sClavW = NAME30(Range("A2"))
Else
    sClavW = NAME30(Range("B2"))
End If


' Pasa datos

If Left(Range("A1"), 6) = "Nombre" Then
    sDatoW = sClavW & long2string(Range("B2"))
Else
    sDatoW = sClavW & long2string(Range("A2"))
End If


' Graba ítem

lResul = W_WRITE(sHoja, sClavW, sDatoW) ' Aquí graba en el físico y en el lógico relacionado


' Limpia origen

Range("A2:B2").Select
Selection.ClearContents


' Salva a la hoja el contenido del fichero

SAVF

   
' Reselecciona A2

Range("A2").Select


End Sub

                                                                                                    _______


3.3 La rutina de volcado desde el fichero virtual a la hoja en curso

Dentro de la lista de rutinas asociadas a la hoja de presentación, a continuación hay que destacar la lectura de datos desde el fichero. De hecho se ha tomado la rutina SAVF genérica del módulo W y se la ha reescrito de forma específica para incluir básicamente una condición de lectura condicional bien desde el físico, bien desde el lógico que se vuelcan a la misma hoja. Aunque también se podría haber utilizado el SAVF de W con cierto código de ayuda adicional, en este caso he optado por una solución particular más directa.

' Rutina auxiliar de volcado desde el fichero virtual a la hoja en curso

Sub SAVF()

 Dim Rango As String       ' Selección de rango para limpiar
 Dim sHoja As String       ' Nombre de la hoja en curso
 Dim sClavW As String * 30 ' Aux.paso de claves
 Dim sDatoW As String * 40 ' Aux.paso de datos
 Dim Er As Integer         ' Control de errores intermedios
 Dim l As Long             ' Contador de for
 Dim lResul As Long        ' Control de resultados intermedios
 Dim lNIDw As Long         ' Identificador de fichero
 Dim lNCPY As Long         ' Contador de registros copiados
 

 On Error GoTo EtError

 
 ' Inhibe actualización de pantalla

 Application.ScreenUpdating = False



 ' Toma el nombre de la hoja

 With ActiveSheet
     sHoja = .Name
 End With


 ' Recupera estadísticos del fichero virtual
 
 Er = W_INF(sHoja, lDimC, lDimD, lNITEM, lBAJAS, lNIDD)

 lNCPY = lNITEM - lBAJAS ' NºItems a copiar


 ' Limpia hoja destino
 
 Rango = "A3:"
 
 Range("F3").Select
 Selection.End(xlDown).Select
 
 Rango = Rango & ActiveCell.Address
 Range(Rango).ClearContents
 


 ' Bucle de proceso
 
 If lNCPY > 0 Then
 
  For l = 1 To lNCPY
 

   ' Lee

   If Left(Range("A1"), 6) = "Nombre" Then
       Er = W_READ(sHoja, l, sDatoW, sClavW)
   Else
       Er = W_READ(sHoja & "01", l, sDatoW, sClavW)
   End If
   If Er > 0 Then Exit For
  


   ' Vuelca clave y datos
 
   If Left(Range("A1"), 6) = "Nombre" Then
       Range("A" & (l + 2)) = sClavW
       Range("B" & (l + 2)) = Mid(sDatoW, 31, 10)
    Else
       Range("A" & (l + 2)) = sClavW
       Range("B" & (l + 2)) = Left(sDatoW, 30)
    End If
 
  Next l


 End If
 
 
 ' Restaura visualización
 
 Range("A2").Select
 
 Application.ScreenUpdating = True


EtError:

End Sub


                                                                                                    _______

3.4 La supresión de ítems

Y como parte final a destacar dentro de esta relación de rutinas, está la de supresión de datos (Del conjunto de la base de datos, esto es, de la vista principal y de su lógico)

' Suprime línea marcada como x + intro

Sub SuprimeLinea()

Dim Fila
Dim sHoja As String  ' Nombre de la hoja en curso
Dim sClavW As String ' Paso auxiliar de claves
Dim lResul As Long   ' Control de resultados intermedios

On Error Resume Next ' Elude errores

 
 ' Inhibe actualización de pantalla

 Application.ScreenUpdating = False


' Toma el nombre de la hoja

With ActiveSheet
    sHoja = .Name
End With


' Recupera fila activa

Fila = ActiveCell.Row
Fila = Fila - 1 ' x + intro desplaza la línea


' Limpia la marca consumida

Range("D" & Fila).Select
Selection.ClearContents


' Elimina ítem de la fila activa

If Left(Range("A1"), 6) = "Nombre" Then
    sClavW = NAME30(Range("A" & Fila))
Else
    sClavW = long2string(Range("A" & Fila))
End If
 
 
If Left(Range("A1"), 6) = "Nombre" Then
    lResul = W_DELETE(sHoja, sClavW)             ' Al emitir la supresión, tanto en la vista principal como en la lógica,
Else                                             
    lResul = W_DELETE(sHoja & "01", sClavW)      ' se eliminan los registros de ambas vistas
End If



 ' Vuelca fichero a pantalla s/formato
 
 SAVF
 
 
 ' Restaura actualización de pantalla

 Application.ScreenUpdating = True


End Sub


                                                                                                    _______

4 El CRTLF


En cuanto al código maestro, se sustenta en ficheros internos de relaciones entre nombres de físicos y lógicos, directas e inversas, así como de las posiciones relativas de claves.


Así, al ejecutar W_CRTLF se establecen los ficheros de relaciones internas de soporte como sigue


 ' Asigna nid's para enlace entre físicos y lógicos
 

                         '           K      D
  lNIDpf = M_NEW(66, 33) ' Fichero PF-LF  LF
  lNIDlf = M_NEW(33, 43) ' Fichero LF     PF-KPOS
 

  . . .
 

 
 ' Obtiene estadísticos del PF base
 
 Er = M_INF(lNIDwf, lDimC, lDimD, lNITEM, lBAJAS, lNIDD)



 ' Genera el nid del LF a crear
 
 lNIDwl = W_NEW(sLF, lKLEN, lDimD)
 


 ' Construye la via de acceso asociada
 
 For l = 1 To lNITEM
 
 
   ' Lee origen
  
   Er = M_READ(lNIDwf, l, sDato)
   If Er > 0 Then Exit For
  
  
   ' Graba destino
  
   sClave = Mid(sDato, lKPOS, lKLEN)
   lResul = M_WRITE(lNIDwl, sClave, sDato)

 Next l
 
 
 
 ' Graba enlaces entre ficheros fisicos-lógicos


 ' Graba enlace físico-lógico
 
 sDato = sPF & sLF
 lResul = M_WRITE(lNIDpf, sDato, sLF)


 ' Graba enlace lógico-físico
  
 sKPOS = Long2String(lKPOS)
 sDato = sPFb & sKPOS
 lResul = M_WRITE(lNIDlf, sLF, sDato)


  . . .

Junto con un mecanismo de replicación de las operaciones de escritura a toda la base de datos relacionada, para conseguir aplicar las sentencias núcleo del bucle anterior.


                                                                                                   _______