GrialFileStorage

De GrialWIKI

Introducción al Framework Grial

Índice


El GrialFileStorage permite relacionar archivos con cualquier registro de cualquier tabla troncal del sistema. Y posteriormente adjuntar, almacenar y recuperar estos archivos desde el servidor.

Contenido

Como Incorporar GrialFileStorage a un módulo

Paso 1) Incorpore el Control GrialFileStorage a su proyecto

Coloque el control en el formulario. El control es una grilla de adjuntos, con botones para agregar, dar de baja, descargar y consultar el histórico.

Dentro del control el usuario podrá ver los archivos que ha adjuntado, tendrá la posibildad de adjuntar nuevos o dar de baja adjuntos existentes.

También dispondrá en el mismo espacio de la posibilidad de ver un "histórico" que le permitirá acceder a los adjunto agregados y dados de baja anterioremente. (Auditoría)

El control también puede funcionar en modo "invisible" (Visible=False), pudiéndose adjuntarse y recuperarse archivos mediante código.

Paso 2) Incorporar en la preparación de la Transacción

En el momento de preparar la transacción llamar a GrialFileStorage.Init:

SocuUsua01_grq.Init "select * from soc_usua_01 where id_socusua01=" & IdSocUsua01
SocuUsua02_grq.Init "select * from soc_usua_02 where rela_socusua01=" & IdSocUsua01
GrialFileStorage.Init GrialCont, "RRHH\LEGAJOS\FOTOS", "SOC_USUA_01", IdSocUsua01

En la llamada a GrialFileStorage.Init se indica:

El GrialCont principal de la transacción, el código para almacenamiento en el server, la tabla TRONCAL y el ID del registro al cual se han de adjuntar los archivos.

Con esta información el GrialFileStorage prepara un query de consulta sobre la tabla SYS_FUNC_30, recuperando la información de referencia de los archivos adjuntos al troncal e ID indicado.

Código de almacenamiento: El string “"RRHH\LEGAJOS\FOTOS"” del ejemplo representa un código para el almacenamiento de los archivos. El código no es arbitrario, debe estar configurado en la tabla SYS_FUNC_28 (SYS_FUNC_28_TAB_PATHS_STORAGE), campo SYSFUNC28_RELPATH. El campo SYSFUNC28_RELPATH actúa como -código identificador- para referenciar el registro de la tabla SYS_FUNC_28 desde los módulos.

Paso 3) Incorporar en la carga de datos de la Transacción

Luego ha de incluirse el objeto GrialFileStorage en la carga de datos junto con los otros GrialQuerys o Controles Registrados de la transacción.

El GrialFileStorage funciona como una grilla sobre la tabla SYS_FUNC_30_DET_ADJUNTOS

GrialCont.LoadData SocUsua01_grq, SocUsua02_grq, GrialFileStorage

Permisos del usuario

La carga de datos trae la grilla de los adjuntos y la muestra si el control está visible. Luego de la carga es posible limitar las acciones que el usuario puede realizar con los adjuntos (Agregar y Eliminar, ver histórico), por ejemplo:

 With GrialFileStorage
      .AllowAddNew = Not ModoConsulta 'si puede agregar
      .AllowDelete = Not ModoConsulta 'si puede dar de baja
      .ViewLogButton_Hidden = True 'si se oculta el boton para acceder al histórico
 End With

Carga Opcional: GrialFileStorage.RefreshIfNotLoaded

Normalmente el GrialFileStorage se coloca en una Solapa/Tab aparte dentro del módulo.

En esos casos se recomienda realizar la carga únicamente cuando el usuario selecciona la ficha correspondiente, para hacer más eficiente el modulo.

En lugar de colocar el GrialFileStorage en el LoadData de la transacción, se puede colocar GrialFileStorage.RefreshIfNotLoaded en el Click del tab correspondiente.

Private Sub TabDatos_Click(PreviousTab As Integer)
On Error GoTo ErrH
 
Select Case TabDatos.Tab
 
    Case TABSDATOS.TAB_ADJUNTOS
        GrialFileStorage.RefreshIfNotLoaded
 
End Select
 
Exit Sub
ErrH:
    MsgError GrialCont
End Sub

Nota: Si se utiliza la carga opcional, NO es necesario modificar otros aspectos de la integración del GrialFileStorage en el módulo. Si nunca se realiza la carga por que el usuario no seleccionó el tab, la propiedad GrialFileStorage.Loaded permanecerá en "False", y el método usado al aceptar: AppendToTransaction no agregará nada a la transacción.

Paso 3) Incorporar en BottomButton_Click BUTTON_ACEPT (grabación de la transacción)

En el momento de grabar la transacción llamar a: GrialFileStorage.AppendToTransaction, como un detalle de la cabecera a la cual los archivos se adjuntan:

 Txn.Add SF20Grq.Rst, “Name=SF20:ID_SYSFUNC20”
 Txn.Add SF21Grq.Rst, “ID_SYSFUNC21;RELA_SYSFUNC20”
 GrialFileStorage.AppendToTransaction Txn, "SF20"

Mediante esta llamada el GrialFileStorage incorpora a la transacción el registro de la SYS_FUNC_30 con los cambios que haya realizado el usuario. El parámetro “SF20” es el NOMBRE DEL HEADER o ITEM en la transacción que contiene el registro al cual se adjuntan los archivos (ID y Troncal especificados en el Init)

Internamente AppendToTransaction agrega a la Transacción la grabación de la tabla SYS_FUNC_30 que contiene los nombres los archivos adjuntos.

En el ejemplo dado, el GrialFileStorage agregará internamente:

   GrialFileStorage.AppendToTransaction Txn, "SF20" ...
   'Agrega internamente...
   '=> Txn.AddItem SYSFUNC30.Rst, “Header=SF20:ID_SYSFUNC30, RELA_TRONCAL”

En el momento de grabar la transacción se grabará la referencia al nombre del archivo adjuntado, (tabla SYS_FUNC_30) quedando relacionados los archivos subidos al servidor con el registro cabecera indicado.

Paso 4) Incorporar en BottomButton_Click BUTTON_CANCEL

Aunque adjunte archivos, el usuario siempre puede cancelar la transacción. Para para eliminar los archivos subidos durante la operación, se debe incorporar una llamada a GrialFileStorage.CancelUploaded en el BUTTON_CANCEL.

              Case BUTTON_CANCEL
                   ID_SocUsua01_Gcb.CancelModifications
                   GrialFileStorage1.CancelUploaded


Esta llamada eliminará los archivos subidos durante esta transacción, que ha sido cancelada.

Adjuntos Específicos, por código

Crear un adjunto con un código específico

Para adjuntar un archivo con un codigo específico (“FOTO” en el siguiente ejemplo) se debe usar la función GrialFileStorage.StartAttachByCode

Ejemplo:

 Private Sub AdjuntarFotoCmd_Click()
 On Error GoTo ErrH 
 'Inicio un adjunto, con codigo "FOTO"
 If GrialFileStorage.StartAttachByCode("FOTO", “Foto Principal”) then 
        Rem OK, EL USUARIO selecciono un archivo y los adjuntó con el código "FOTO"
 End If
 Exit sub
 ErrH:
   MsgError GrialCont
 End Sub

La función StartAttachByCode inicial el proceso de adjuntar un Nuevo archivo. Si ya se encuentra el código en la lista, al mismo momento de adjuntar el nuevo archivo, el archivo anterior pasa a tener Fecha de Baja y pasará al histórico de adjuntos para este registro.

El código siempre es único en la lista de adjuntos activos.

La función retorna FALSE si el usuario cancela el proceso.

Buscar un adjunto con un código específico

Para buscar un adjunto, se puede utilizar la función SelectAttachment que acepta dos tipos de parámetro: el ID_SYSFUNC30 buscado, o el código único del adjunto.

La función retorna "false" si no halló el registro.

 With GrialFileStorage
   If .SelectAttachment("DOCUMENTO") Then 'Existe
...

Ubicar y mostrar un adjunto especifico

Luego de cargar los datos, se puede buscar una adjunto mediante un código especifico, recuperarlo y mostrarlo

Caso 1 - Imágenes

 'Decargo y muestro la foto si esta adjunta
 if Not GrialFileStorage.DownloadImage("FOTO", ImageFoto) Then MsgBox "No se halló Foto"

La Función DownloadImage permite descargar un archivo y asignarlo a un objeto Image de Visual Basic. Si el código indicado no está entre los adjuntos, la función devuelve false.


Caso 2 - Descargar otros archivos automáticamente:

 With GrialFileStorage
   If .SelectAttachment("DOCUMENTO") Then 'Existe
       Dim TempFileName As String
       If .GetSelectedAttachmentFile(TempFileName) Then 'Descargo el archivo
           If MsgBox("Desea abrir " &  .SelectedAttachmentInfo(), VbOkCancel) = VbOk then 
               .StartDoc(TempFileName) 'Abro el archivo con el programa asociado 
           End If
       End If
    End If
 End With

El Método SelectAttachment busca un código específico dentro de los adjuntos presentes, el parámetro corresponde al valor del campo SYSFUNC30_COD [string(10)]

La función SelectedAttachmentInfo devuelve un string descriptivo con la descripción del adjunto, el nombre del archivo original y el tamaño del archivo en KB. Es útil para mostrar en un label la información del archivo adjunto.

La función GetSelectedAttachmentFile(TempFileName) recupera el archivo seleccionado del servidor y retorna True si se pudo descargar correctamente. También retorna en TempFileName el path completo local donde se grabó el archivo descargado. Si no puede recuperar el archivo la función retorna FALSE y asigna TempFileName = "".

La función StartDoc(TempFileName) abre el archivo indicado con el programa asociado según la extensión del archivo. Retorna true si pudo iniciar el proceso normalmente o false si se produjo algún error.

Eliminar un adjunto con un código específico

Por último, si se desea incluir un botón para remover un adjunto específico se debe utilizar el metodo DeleteAttachment(SF30_Code) , que busca y remueve el adjunto con el código indicado.

Nota: Si el código no existe, el método retorna silenciosamente, sin generar un error.

Ejemplo:

 Private Sub RemoverFotoCmd _Click()
 On Error goto ErrH
 GrialFileStorage.DeleteAttachment "FOTO" 
 img_foto.Picture = LoadPicture("")
 LbFileName = ””
 ...

Eventos

El control posee dos eventos a ser utilizados cuando se mantiene en pantalla una visualización de una imagen adjunta.

El evento GrialFileStorage_FileAttached se dispara cuando el usuario o por código se adjunta un nuevo archivo. Se pueden usar las funciones .SelectedAttachment_cod y .SelectedAttachment_Value("FieldName")) para obtener información del nuevo adjunto.

El evento GrialFileStorage_FileRemoved se dispara cuando el usuario o por código da de baja un adjunto. Se pueden usar las funciones .SelectedAttachment_cod y .SelectedAttachment_Value("FieldName")) para obtener información del adjunto que está siendo dado de baja.

En el siguiente ejemplo de código, se mantiene una imagen de pantalla ("FotoImage") mostrando el contenido del adjunto con codigo "FOTO". Al adjuntar se muestra, y al dar de baja se borra la imagen de pantalla.

Private Sub GrialFileStorage_FileAttached()
With GrialFileStorage
    If .SelectedAttachment_Cod = "FOTO" Then
        FotoImage = LoadPicture(.SelectedAttachment_Value("LOCAL_FILE"))
    End If
End With
End Sub
Private Sub GrialFileStorage_FileRemoved()
With GrialFileStorage
    If .SelectedAttachment_Cod = "FOTO" Then
        FotoImage.Picture = LoadPicture("") 'Limpio imagen
    End If
End With
End Sub

Otras Operaciones

Descargar un Archivo por ID_SYSFUNC30

Ejemplo:

 With GrialFileStorage
    .SelectAttachment_IDSF30(IDSysFunc30)
    Dim TempFileName as String 
    If .GetSelectedAttachmentFile(TempFileName) Then 
          .StartDoc TempFileName
    End If
 End With

Cache de Descargas

Cada vez que se descarga un archivo, el control guarda el nombre del archivo temporal descargado en un campo del recordset llamado “LOCAL_FILE”. Mientras el campo .SelectedAttachment_value(“LOCAL_FILE”) tenga valor, la función GetSelectedAttachmentFile asignará ese archivo sin ir a buscarlo nuevamente al servidor. El campo “LOCAL_FILE” se limpia con cada carga del control GrialFileStorage (GrialCont.LoadData GrialFileStorage)

Descargar Todos los Archivos

Para descargar todos los archivos adjuntos, se puede llamar a la function GetAllFiles que devuelve el número de archivos descargados correctamente. Ejemplo:

' Descargo todos los archivos adjuntos
Dim CantFiles as Long
CantFiles = GrialFileStorage.GetAllFiles()

Agregar un 'link' a un archivo ya cargado

Es posible agregar un 'link' a un archivo ya cargado en otro GrialFilStorage.

Por ejemplo, si se está creando un registro de reporte de error, usando como en base un correo del sistema con archivos adjuntos; es posible tomar los archivos adjuntos al correo, y asociarlos al reporte de error (mediante un link) sin necesidad de bajar y subir los archivos.

El 'link' funciona como un archivo adjunto normal. Luego de agregado el 'link', el mismo archivo almacenado en el servidor, queda relacionado a los dos registros del sistema involucrados.

     With GrialFileStorageCorreo
            If .Count > 0 Then 'Si hay adjuntos
                Dim SF30Grq As New GrialQuery
                Set SF30Grq.Rst = .SysFunc30_Full_Rst 'Lista completa de Adjuntos al correo
                SF30Grq.MovePreStart
                While SF30Grq.NextRecord
                    If NoDataIn(SF30Grq.Rst!SYSFUNC30_FBAJA) Then 'si no esta dado de baja
                        GrialFileStorageReporte.AddLink SF30Grq.Rst 'agrego al nuevo GrialFileStorage 
                                                                   '(debe estar correctamente inicializado y cargado)
                    End If
                Wend
            End If
        End With

Otras Propiedades

Filtros para seleccionar un tipo de archivo

Si se desea filtrar por tipo los archivos que el usuario ve al adjuntar, puede utilizar el método AddFileFilter. Este método adiciona filtros a la propiedad FileFilters (de tipo string).

Por Ejemplo:

 GrialFileStorage.AddFileFilter "Text Files","*.txt"  'Solo archivos txt

Para restaurar el valor default: All Files (*.*) puede poner FileFilters = “”

Property Loaded as Boolean

Retorna True si se han cargado los datos de los adjuntos.

Se pone en "True" luego de la llamada a GrialCont.LoadData GrialFileStorage o a GrialFileStorage.RefreshIfNotLoaded

Se pone en "False" durante la llamada a GrialFileStorage.Init

Propiedad Count

Retorna la cantidad de adjuntos activos

Propiedades para Modificar la visualización

Property Let AllowAddNew(aValue As Boolean)
Permite o no adjuntar nuevos archivos
Deshabilita el botón "Adjuntar"
Property Let AllowDelete(aValue As Boolean)
Permite o no dar de baja archivos adjuntos perviamente
Deshabilita el botón "Eliminar"
Property Let ViewLogButton_Hidden(Hidden As Boolean)
Permite o no visualizar el histórico
Oculta el botón "Ver Histórico"
Property Let ColCaptions_Hidden(Hidden As Boolean)
Oculta las cabeceras de columnas en la grilla
Property Let UserName_Hidden(Hidden As Boolean)
Oculta la columna que informa el usuario que adjuntó cada archivo
Property Let AttachDate_Hidden(Hidden As Boolean)
Oculta la columna que informa la fecha en que se adjuntó cada archivo

Funciones y Métodos de Utilidad

Public Function DownloadImage(SF30Cod As String, ImageControl As Object) As Boolean
Descarga y muestra una imagen si el código existe entre los adjuntos.
Public Function SelectAttachment(SF30Code As Variant) As Boolean

Selecciona el adjunto según el código indicado. Solo puede existir un adjunto activo para un código dado.

Public Function SelectAttachment_IDSF30(IDSF30 As Long) As Boolean

Selecciona un adjunto en base al ID_SYSFUNC30

Public Function SelectedAttachmentInfo() As String
Retorna un string descriptivo con la descripción del adjunto, el nombre del archivo original y el tamaño del archivo en KB
Property Get SelectedAttachment_Value(SF30_FieldName as string)
Retorna el valor de cualquiera de los campos del registro de la SYS_FUNC_30 actualmente seleccionado en la lista de adjuntos
Public Sub SetViewMode(Mode As Integer) '0=Normal 1=historico
Muestra registros Activos o Históricos
Public Property Get SysFunc30_scbx() As Object
Retorna el objeto interno de tipo GrialCombo(Display_mode_Grid) que se utiliza para mostrar los archivos.
Public Function SysFunc30_Full_Rst() As Recordset
Retorna el recordset interno con todos los registros de la SYS_FUNC_30 cargados. Nota: Se incluyen los históricos (con fecha de baja)
Public Property Get CurrentQuery() As String
Retorna el query de la SYS_FUNC_30 usado para cargar los registros, incluye los filtros por Troncal e ID.
Public Property Get Count() As Long
Retorna la cantidad de adjuntos activos
Public Function GetOpenFile(hwnd As Long, Optional TitleForDialog As String) As Boolean
Abre un cuadro de díalogo para que el usuario seleccione un archivo para abrir.
Retorna "false" si el usuario cancela la operación
El archivo elegido (full path) se almacena en la propiedad GrialFileStorage.SelectedFileName
Public Function GetSaveFile(hwnd As Long, InitialFileName as String, Optional TitleForDialog As String) As Boolean
Abre un cuadro de díalogo para que el usuario seleccione un lugar donde guardar un archivo.
Retorna "false" si el usuario cancela la operación
El archivo elegido (full path) se almacena en la propiedad GrialFileStorage.SelectedFileName
Public Function GetFileExtension(Path As String) As String
Retorna la extensión del archivo, por ejemplo "docx", "jpg", etc.
Public Function GetFileNameFromPath(Path As String) As String
Retorna el nombre del arcivo (sin el path).
Por ejemplo de "C:\Documentos\Datos.doc" retorna "Datos.doc"
Public Function MakePath(ByVal a As String, b As String) As String
Concatena un path con un nombre de archivo, agregando "\" si es necesario.
Retorna el path concatenado.
Public Sub CheckMakeDir(Path As String)
Crea el directorio en el disco si no existiera

Avanzado, Configuración en el Server WEB

El path de almacenamiento de archivos debe ser accesible desde el WEB server.

Se configura en la Registry, clave: SOFTWARE\Grial\DVMServer\Paths\FileStorageRoot (de tipo string)

El valor default para esta configuración es "C:\GrialFileStorage"

Cómo se conforma el path final para un archivo

Al "FileStorageRoot" configurado en el server, se le agrega la Instancia de base de datos y luego el path configurado en la tabla SYS_FUNC_28, que es el mismo que el desarrollador indica al momento de inicializar el componente GrialFileStorage.

Por ejemplo, considerando el default FileStorageRoot (C:\GrialFileStorage) y para un usuario conectado a "PROD", que accede al modulo de correo interno (SYSFUNC28_CODE="CORREO"), el path final es:

C:\GrialFileStorage\PROD\CORREO

ATENCION: Este comportamiento puede ser modificado mediante los mapeos de paths en la registry del servidor. Ver: SYS_FUNC_28



GrialPrint <<< >>> GrialTextStorage

Herramientas personales