Windows Phone y SQL CE

Una de las características atractivas de las aplicaciones para Windows Phone, es la posibilidad de incorporar almacenamiento local en SQL CE. Mucho se discute y es sabido que existen diversas técnicas, pero como siempre muchos de vosotros preguntáis por la “Chuleta” paso a paso o pequeño laboratorio guía para iniciarnos en su uso.

La idea principal es utilizar “SQL Metal” para construir nuestro “Data Context”, nuestra clase se acceso a datos se creara a partir de nuestra BD. En tono de humor será nuestro “Entity Framework” trabajando en invertido J

Aquí tenéis el laboratorio de introducción paso, paso… espero que os sea asequible i de utilidad.

Crear la Base de datos.
Desde el explorador de servidores de Visual Studio, agregaremos una conexión :

WinPhoSql1
Seleccionaremos SQL CE

WinPhoSql2

Pondremos nombre a nuestra base de datos

WinPhoSql3

Seleccionar “Crear”

WinPhoSql4
Crear La tabla:

WinPhoSql5WinPhoSql6

WinPhoSql7

WinPhoSql8

Con esto finalizaremos la creación de nuestra BD “WinPhoneData” y la tabla “LocalizationData”.

El siguiente paso consistirá en crearnos la clase con el contexto de datos para nuestra aplicación.

En primer lugar deberemos invocar el “CMD” o “Power Shell”, dependiendo de vuestros gustos. Los siguientes pasos serán muy sencillos, pues requerirán simplemente dos mandatos:

Es importante observar la Invocación a SQL Metal, pasándole las ubicaciones de la “sdf” anteriormente creada y el lenguaje destino para la generación de nuestra clase de acceso a datos.

1) Añadir a nuestro Path la referencia a “\Program Files\Microsoft SDKs\Windows\v7.0A\bin”

2) sqlmetal d:\WinPhoneData.sdf /language:vb /namespace:WinPhoneData /pluralize /code:d:WinPhoneData.vb

WinPhoSql9
Una vez ejecutados dichos comandos, tendremos nuestra “WinPhoneData.vb” lista para ser utilizada en nuestro Windows Phone Project.

Por lo tanto nuestros próximos pasos serán muy fáciles, Desde nuestra instancia de Visual Studio, crearemos un nuevo proyecto “Windows Phone”.

image

Evidentemente seleccionaremos el SO 7.1.

WinPhoSql10

Para que todo ruede a la perfección no deberemos olvidar las referencias a System.Data.Linq

WinPhoSql11
Desde las propiedades del proyecto, seleccionaremos la de añadir un elemento existente:

WinPhoSql12

Agregando la clase generada anteriormente.

WinPhoSql13

La clase generada por Sqlmetal, no es 100% compatible, pues implementa ‘IDBConnection’ deberemos editar “WinPhoneData.vb” y eliminar los sub’s “New’s” sobrecargados, para conexiones ‘Idb’. 

        Public Sub New(ByVal connection As System.Data.IDbConnection)
            MyBase.New(connection, mappingSource)
            OnCreated()
        End Sub
 
        Public Sub New(ByVal connection As System.Data.IDbConnection,
                       ByVal mappingSource As System.Data.Linq.Mapping.MappingSource)
            MyBase.New(connection, mappingSource)
            OnCreated()
        End Sub

Una vez completado este punto, podremos compilar la aplicación. Sin ningún tipo de problemas. Luego es tarea de cada cual adaptar los requerimientos navegando a través de sus propiedades y métodos… por ejemplo: 

Partial Public Class MainPage
    Inherits PhoneApplicationPage
 
    ' Constructor
    Private Dbas As WinPhoneData.WinPhoneData
    Public Sub New()
        InitializeComponent()
        InitializeData()
    End Sub
 
    Sub InitializeData()
        Me.Dbas = New WinPhoneData.WinPhoneData("Data Source=isostore:\GeoLocData.sdf")
        If Not Dbas.DatabaseExists Then
            Dbas.CreateDatabase()
        End If
        ' Simular una nueva entrada a la tabla de localizacion
        Dim c1 = New WinPhoneData.LocalizationData With {.Date = DateTime.Now, .Latitude = 10, .Longitude = 15, .Speed = 11}
        Dim ls As New List(Of WinPhoneData.LocalizationDataFrom {c1}
        Dbas.LocalizationDatas.InsertAllOnSubmit(ls)
        Dbas.SubmitChanges()
    End Sub
 
End Class

Espero que pequeño paso a paso os ayude a completar vuestra primera aplicación para Windows Phone y almacén SQL Ce en local. Si la descripción anterior no es suficiente, no dudéis en solicitármelo y puedo adjuntaros el documento en cuestión a titulo de Guía Rápida.
Saludos,
PepLluis,

Auto Data Entry Form’s

Muchos de los lectores de este blog muestran interés por ejemplos entorno a Windows forms y SQL Express, no hay duda y soy consciente de que este articulo no forma parte de esos “avances que están por venir” ni representa a ninguna novedad tecnológica actual; obviamente lejos de herramientas tan actuales como LightSwitch, sin embargo me complace compartirlo con vosotros pues creo que puede ser un buen soporte para ayudar en la comprensión de ciertos usos y técnicas sobre todo para los que empiezan.

Como digo, este es uno de esos artículos intemporales en varios aspectos, pues describe metodologías “retro” utilizando los clásicos SQL y Forms… si embargo no quiero que perdáis de vista que los “usos” y “técnicas” utilizadas pueden traspasar esa barrera atemporal y utilizarse en cualquier escenario actual… incluso en las nuevas aplicaciones “Metro Style” J

Al diseñar algunos ejemplos, disfruto partiendo de una plantilla de “Consola”, pues debido a la naturaleza y el propósito del mismo, esta concesión me permite “Salirme fuera de pistas” de lo que sería una aplicación comercial, pero a su vez me permite disfrutar de la libertad de construir algo desde los cimientos.

Como su nombre indica el objetivo del siguiente laboratorio es interactuar con la conocida base de datos para pruebas “NorthWnd”, utilizaremos la estructura de cualquiera de sus tablas para “Autogenerar” nuestro form de entrada (con todos sus textboxes) que nos permita añadir un nuevo registro a la tabla a través de un “Enlazador”. A modo de flecos para darle un poco mas de interés, he creído divertido incluir una pequeña funcionalidad que nos permita recorrer la tabla buscando todos los registros según la coincidencia del país introducido el textbox de búsqueda (con LINQ), y un par de botones para recorrer el enlazador, avanzando o retrocediendo a partir de la posición actual en el datagridview.

No creo que sea necesario un detalle mas exhaustivo, prefiero pasar al código, aunque antes quedo a vuestra disposición para continuar y desarrollar esta conversación según consideréis de interés.
Que disfrutéis
J

PepLluis,

Imports System.Drawing
Imports System.Windows.Forms
 
Imports System.Data
Imports System.Data.SqlClient
 
'
'
' Establecer un punto de entrada. Esto es una aplicacion VB
'
Module MiAplicacion
    Sub Main()
        Dim Ventana As New frmDinamico
        Ventana.Show()
        Application.Run()
    End Sub
End Module
 
 
Public Class frmDinamico
    Inherits Form
    'Punto de Inicializacion de nuestra ventana
 
    'Definicion de Variables de contexto
    Private MiConexion As New SqlConnection(
     "Data Source=.\SQLEXPRESS;" +
     "AttachDbFilename=D:\Bd_App\NORTHWND.MDF;" +
     "Integrated Security=True;Connect Timeout=30;User Instance=True")
 
    ' Adaptador, Enlazador y juego de datos para la tabla clientes
    Private MiAdaptador As New SqlDataAdapter("Select * from Customers", MiConexion)
    Private MiEnlazador As New BindingSource
    Private MiDataSet As New DataSet
 
    ''' <summary>
    ''' Al lanzar la ejecucion de la app
    ''' </summary>
    ''' <remarks></remarks>
    Sub New()
        Try
            Inicializacion()
        Catch fallo As Exception
            Messagebox.Show(fallo.Message, "Error Grave... no puedo continuar")
            End
        End Try
    End Sub
 
    ''' <summary>
    ''' Inicializar/Construir los objetos de la aplicacions
    ''' </summary>
    ''' <remarks></remarks>
    Sub Inicializacion()
        Me.Text = "Auto Entry Data Form"
        ' Crear y Enlazar datos
        Dim MiCommandBuild As New SqlCommandBuilder(MiAdaptador)
        MiConexion.Open()
        MiAdaptador.Fill(MiDataSet)
        MiENlazador.DataSource = MiDataSet.Tables(0)
        Dim MiDataGridView As New DataGridView
        MiDataGridView.DataSource = MiENlazador
        MiDataGridView.Anchor = AnchorStyles.Left Or AnchorStyles.Right Or AnchorStyles.Top
        MiDataGridView.Dock = DockStyle.Top
        '
        ' Añadir los controles al Form
        Me.Controls.Add(MiDataGridView)
        Me.Controls.AddRange({
            New TextBox With {.Name = "Buscar", .Text = "", .Dock = DockStyle.Bottom},
            New Button With {.Name = "Añadir", .Text = .Name, .Dock = DockStyle.Bottom},
            New Button With {.Name = "Avanza", .Text = .Name, .Dock = DockStyle.Bottom},
            New Button With {.Name = "Retrocede", .Text = .Name, .Dock = DockStyle.Bottom}
            })
' Apuntar los handlers a sus funciones         AddHandler Me.Controls("Añadir").Click, AddressOf Nuevo         AddHandler Me.Controls("Avanza").Click, AddressOf Avanzar         AddHandler Me.Controls("Retrocede").Click, AddressOf Retroceder         AddHandler Me.Controls("Buscar").TextChanged, AddressOf Seleccionar         Me.Controls("Buscar").Focus()     End Sub     ''' <summary>     ''' Al final la ejecucion de la app     ''' </summary>     ''' <remarks></remarks>     Sub Fin() Handles Me.FormClosed         Application.ExitThread()         End     End Sub     ''' <summary>     ''' Query para seleccionar solo los registros coincidentes     ''' con la cadena de texto introducida en el TextBox 'Buscar'     ''' </summary>     ''' <remarks></remarks>     Sub Seleccionar()         MiENlazador.DataSource =                         (                          From S In MiDataSet.Tables(0)                           Where S.Item("Country").Contains(Me.Controls("Buscar").Text)                           Select Nombre = S.Item("CompanyName"),                                  Ciudad = S.Item("City")                         ).ToList     End Sub     ''' <summary>     ''' Enlazador : MoveNext     ''' </summary>     ''' <remarks></remarks>     Sub Avanzar()         MiEnlazador.MoveNext()     End Sub     ''' <summary>     ''' Enlazador : MovePrevious     ''' </summary>     ''' <remarks></remarks>     Sub Retroceder()         MiEnlazador.MovePrevious()     End Sub     ''' <summary>     ''' Crear un nuevo form conteniendo un TextBox y una etiqueta     ''' con su descripcion para cada columna de la tabla     ''' </summary>     ''' <remarks></remarks>     Sub Nuevo()         Dim AutoForm As New Form         AutoForm.Name = "Nuevo"         AutoForm.Text = "Data Entry Form"         Dim Pos_x As Integer = 5         Dim Pos_y As Integer = 10         Dim Etiqueta As Label         Dim Entrada As TextBox         For Each col As DataColumn In MiDataSet.Tables(0).Columns             Etiqueta = New Label             Etiqueta.Location = New Point(Pos_x, Pos_Y)             Etiqueta.Text = Col.ColumnName             Pos_X += Etiqueta.Width             Entrada = New TextBox             Entrada.tag = Etiqueta.Text             Entrada.Location = New Point(Pos_X, Pos_Y)             AutoForm.Controls.AddRange(New Control() {Etiqueta, Entrada})             Pos_x = 5             Pos_Y += Etiqueta.Height + 5         Next         AutoForm.height = Pos_y + 75         AutoForm.Show()     End Sub End Class

Actualizar dos tablas vinculadas en una vista Maestro-Detalle

Una de las consultas comúnmente solicitadas a través del Blog, tiene que ver con la actualización de datos de dos tablas relacionadas en una BD de SQL, o sea actualizar una vista maestro-detalle vinculadas a sendas tablas.

Aunque por obvio y sencillo, las explicaciones acostumbran a ser de lo más diversas y finalmente te das cuenta que la mayoría de ejemplos se inician con un “desparrame” de jergas incomprensivas para la mayoría. Me decido postearos el ejemplo más básico posible, para que a partir de este punto podáis hacerlo crecer a vuestra necesidad.

Espero que os sea útil y despeje vuestras jaquecas cuando se trata de lidiar con diversas tablas.
PepLluis,

 (Para ejecutar el ejemplo, iniciar Visual Studio y crear un nuevo proyecto ‘Winform’, añadir dos DataGridView y un Button, copiar / pegar codigo y por supuesto F5)

Imports System.Data.SqlClient

Public Class Form1

    Private Maestro As SqlDataAdapter
    Private Detalle As SqlDataAdapter
    Private ConjuntoDeDatos As DataSet

    Private Sub Form1_Load() Handles MyBase.Load

        Dim miConexion As New SqlConnection("Data Source=.\SQLExpress;Initial Catalog=MaestroDetalle;Integrated Security=True")

        Maestro = New SqlDataAdapter("Select * From Maestro", miConexion)
        Dim MaestroCmdBuilder As New SqlCommandBuilder(Maestro)

        Detalle = New SqlDataAdapter("Select * From Detalle", miConexion)
        Dim DetalleCmdBuilder As New SqlCommandBuilder(Detalle)

        ConjuntoDeDatos = New DataSet
        Maestro.Fill(ConjuntoDeDatos, "Maestro")
        Me.DataGridView1.DataSource = ConjuntoDeDatos
        Me.DataGridView1.DataMember = "Maestro"

        Detalle.Fill(ConjuntoDeDatos, "Detalle")
        Me.DataGridView2.DataSource = ConjuntoDeDatos

        ConjuntoDeDatos.Relations.Add("Fk", ConjuntoDeDatos.Tables("Maestro").Columns("IdMaestro"),
                                            ConjuntoDeDatos.Tables("Detalle").Columns("IdDetalle"))

        Me.DataGridView2.DataMember = "Maestro.Fk"
    End Sub

    Private Sub Actualizar() Handles Button1.Click
        If ConjuntoDeDatos.HasChanges Then
            Maestro.Update(ConjuntoDeDatos, "Maestro")
            Detalle.Update(ConjuntoDeDatos, "Detalle")
        End If
    End Sub
End Class

Totalizadores y Contadores en una tabla de mi BD

Algunos de vosotros estáis preguntando como es posible totalizar ciertos valores ya sea de estadística o control en una de las tablas de nuestra aplicación.

Aquí os propongo una de las formas de implementarlo :
(Aunque no olvideis que existen otras formas de realizarlo, eso si quizas no tan accesibles :-))

En el lado de SQL podéis ejecutar este ‘script’ para generar la tabla…

CREATE TABLE [dbo].[Contadores](

      [Peras] [int] NOT NULL DEFAULT ((0)),

      [Naranjas] [int] NOT NULL DEFAULT ((0)),

      [Manzanas] [int] NOT NULL DEFAULT ((0))

) ON [PRIMARY]

Ahora solo tendréis que realizar el correspondiente ‘Update’ desde vuestra aplicación incrementando la columna que deseáis contabilizar. Esta pregunta es frecuente cuando se realizan aplicaciones tipo albaranes/facturas u otro tipo, en la que se requiere seguir o registrar una numeración aunque en ese caso no debéis olvidar bloquear el registro y más a lo sumo en aplicaciones que varios usuarios estén utilizando esa numeración.

    Private cn As New SqlClient.SqlConnection( _

          “Data Source=MiSrv\SQLEXPRESS;” + _

          “Initial Catalog=MiBd;” + _

          “Integrated Security=True”)

    Private da As New SqlClient.SqlDataAdapter( _

          “Select * from Contadores”, cn)

 

    Private Sub Button1_Click() Handles Button1.Click

        ‘En este caso simulamos incrementar el contador de Manzanas

        da.UpdateCommand = New SqlClient.SqlCommand( _

          “Update Contadores SET Manzanas = Manzanas + 1”, cn)

        cn.Open()

        da.UpdateCommand.ExecuteNonQuery()

        cn.Close()

    End Sub

 

Espero que os sea útil,
Buen fin de semana.
Pep Lluis,

Como enlazar columnas de una tabla SQL a unos ‘TextBox’

‘ En respuesta a la pregunta de como añadir o modificar registros

‘ a una tabla de SQL con bindings sin DGV y al viejo estilo ADO.

‘ Utilizaremos solo las columnas de Nombre y Telefono de la tabla ‘Shippers’

‘ Despues de insertar un nuevo registro, deberemos utilizar el boton

‘ de actualizar para que dichos cambios sean actualizados a la BD.

‘ En caso de modificacion solo necesitaremos llamar a la ‘actualizacion’

 

Imports System.Data

Imports System.Data.SqlClient

 

Public Class Form1

   

    ‘Constructores para el acceso a la tabla ‘Shippers’ y su correspondiente BindingSource

    Private MiConexion As New SqlConnection( _

               “Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Temp\Northwind\NORTHWND.MDF” + _

               “;Integrated Security=True;Connect Timeout=30;User Instance=True”)

 

    Private MiDataSet As New DataSet()

    Private MiAdaptador As New SqlDataAdapter(“SELECT * FROM Shippers”, MiConexion)

    Private MiEnlazador As New BindingSource

 

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

       

        ‘ Panel conteniendo los textbox para la entrada/modificacion

        Dim Nombre As New TextBox

        Dim Telefono As New TextBox

 

        Dim marcoDatos = New FlowLayoutPanel

        marcoDatos.Dock = DockStyle.Top

        marcoDatos.Controls.AddRange(New Control() {Nombre, Telefono})

        Me.Controls.AddRange(New Control() {marcoDatos})

 

       

        ‘ Panel conteniendo los botones de control

        Dim Avanza As New Button

        Dim Retrocede As New Button

        Dim Insertar As New Button

        Dim Actualizar As New Button

        Dim Controles As New FlowLayoutPanel

        Controles.Dock = DockStyle.Bottom

        Retrocede.Text = “<- Re”

        Avanza.Text = “Av ->”

        Insertar.Text = “Insertar”

        Actualizar.Text = “Actualizar”

        Controles.Controls.AddRange(New Control() {Retrocede, Avanza, Insertar, Actualizar})

        Me.Controls.AddRange(New Control() {Controles})

       

        ‘ Asignar el evento a las funciones de cada boton de control

        AddHandler Retrocede.Click, AddressOf retroceder

        AddHandler Avanza.Click, AddressOf Avanzar

        AddHandler Insertar.Click, AddressOf Nuevo

        AddHandler Actualizar.Click, AddressOf Actualizacion

       

        ‘ Conexion, relleno y asignacion del enlace a datos

        MiConexion.Open()

        MiAdaptador.Fill(MiDataSet)

        MiEnlazador.DataSource = MiDataSet.Tables(0)

        Dim Micommandbuilder As New SqlCommandBuilder(Me.MiAdaptador)

       

        ‘ Enlace de los TextBox a sus omologos en la tabla

        Dim EnlaceNombre As New Binding(“Text”, MiEnlazador, “CompanyName”)

        Nombre.DataBindings.Add(EnlaceNombre)

        Dim EnlaceDireccion As New Binding(“Text”, MiEnlazador, “Phone”)

        Telefono.DataBindings.Add(EnlaceDireccion)

    End Sub

    ‘ Avanzar un registro dentro del ‘recordset’ 🙂

    Sub Avanzar()

        MiEnlazador.MoveNext()

    End Sub

    ‘ Retroceder un registro

    Sub retroceder()

        MiEnlazador.MovePrevious()

    End Sub

    ‘Crear un nuevo registro

    Sub Nuevo()

        MiEnlazador.AddNew()

    End Sub

    ‘ Actualizar el registro en curso o el recien creado

    Sub Actualizacion()

        MiEnlazador.EndEdit()

        MiAdaptador.Update(CType(Me.MiEnlazador.DataSource, DataTable))

    End Sub

End Class

Saludos,
Pep Lluis,

Enumerar las tablas de una BD (SQL)

Imports System.Data.SqlClient

Public Class Form1
    Private MiConexion As New SqlConnection( _
       “Data Source=.\SQLEXPRESS;AttachDbFilename=C:\MisBDs\NORTHWND.MDF” + _
       “;Integrated Security=True;Connect Timeout=30;User Instance=True”) 

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        MiConexion.Open()
        Dim MisTablas As DataTable = MiConexion.GetSchema( _
            “Tables”, New String() {Nothing, “dbo”, Nothing, “Base Table”})
        ComboBox1.DataSource = MisTablas
        ComboBox1.DisplayMember = “TABLE_NAME”
    End Sub
End Class

Para probar este ejemplo, solo tenéis que crear un nuevo proyecto “windows forms application” arrastrar y soltar un ‘combobox’ desde el ‘toolbox’ al ‘form1’, copiar y pegar el código adjunto y modificar la ruta de la ubicación de la BD SQL en el valor ‘attachdbfilename’ de la cadena de conexión.

Saludos,
Pep Lluis,

 

 

 

Actualizar una Tabla de una BD SQL utilizando un DataGridView

A menudo en los foros aparece la pregunta de cómo actualizar una BD utilizando un DataGridView. Aquí os dejo una forma de realizarlo. Espero que os sea útil.

Saludos,
Pep Lluis,


‘Definir enlace a datos y objetos del form

Private MiConexion As New SqlConnection( _

   “Datasource=.\SQLEXPRESS;AttachDbFilename=C:\Temp\NORTHWND.MDF” + _
   “;Integrated Security=True;Connect Timeout=30;User Instance=True”)
Private MiAdaptador As New SqlDataAdapter(“SELECT * FROM Shippers”, MiConexion)
Private MiDataSet As New DataSet()

Private MiEnlazador As New BindingSource

 

Private MidataGriView As New DataGridView

Private BotonGuardar As New Button

‘En tiempo de carga…
Private Sub Form1_Load(…..) Handles MyBase.Load
    MessageBox.Show(My.Computer.FileSystem.CurrentDirectory)

    ‘Poner titulo a la aplicacion

    Me.Text = “Mantenimiento de Shippers”

    ‘Añadir DataGriView

    MidataGriView.Dock = DockStyle.Top

    Me.Controls.Add(MidataGriView)

    BotonGuardar.Dock = DockStyle.Bottom

    ‘Añadir Boton de Guardar

    BotonGuardar.Text = “Guardar Cambios”

    Me.Controls.Add(BotonGuardar)

    AddHandler BotonGuardar.Click, AddressOf Guardar
    Dim commandbuilder As New SqlCommandBuilder(Me.MiAdaptador)

    MiConexion.Open()

    MiAdaptador.Fill(MiDataSet)

    MiEnlazador.DataSource = MiDataSet.Tables(0)

    MidataGriView.DataSource = MiEnlazador

End Sub

‘Actualizar la tabla enlazada con el DataGridView

Private Sub Guardar(…..)
    Me.MiAdaptador.Update(CType(Me.MiEnlazador.DataSource, DataTable))

End Sub

Dar Grant Access a un usuario de SQL 2005 Express

Algunas de las preguntas relacionadas con SQL Express y los errores generados al intentar abrir una conexión en una implementación diferente de la máquina de desarrollo, son debidas a que el usuario no dispone del suficiente ‘Grant Access’ J

Desde el símbolo de sistema (Ejecutando como Administrador) y entendiendo que no dispones del  ‘Management Studio’ :

Cmd Grant Access

Salud!

Cargar/Descargar Archivos Desde y Hacia una Columna ‘image’ SQL

 


Friend Class Ejemplo


    Private _ms As MemoryStream  ‘Carga/descarga de archivos SQL


    Private _Fs As FileStream    ’Manejo archivos en memoria


    Private _By() As Byte = Nothing  ‘Array de intercambio


 


   


    ‘Guardar el Documento


    Private Sub Doc_Almacenar(ByVal Origen As String, ByVal Nombre As String)


        Try


            ‘crear un nuevo fstrm con el archivo apuntado en la ruta


            ‘contenida en el origen


            _Fs = New FileStream(Origen, FileMode.Open, FileAccess.Read)


            ‘redimensionarlo y adaptarlo a su longitud


            ReDim _By(_Fs.Length)


            ‘convertir el fstrm en un array de bytes


            _Fs.Read(_By, 0, _Fs.Length)


            ‘Archivos es el tableadapter


            ‘almacenar array en una imagen binaria Sql


            Archivos.Insert(Nombre, _By)


            _Fs.Close()               ‘cerrar el fstrm


            _Fs.Dispose()             ‘Liberarlo


        Catch ex As Exception


            ‘En caso de excepcion…


            Me.lblExcepciones.Text = “DocAlmacenar: “ + ex.Message


        End Try


    End Sub


   


    ‘Cargar documento desde la col imagen de SQL


    Private Sub Doc_Recuperar(ByVal Nombre As String)


        Try


            ‘Recuperar imagen de SQL a un array intermedio


            If Nombre.Length > 0 Then


                ‘el table adapter devuelve una imagen


                ‘resultante de la consulta ‘Recuperar(Col Nombre)’


                Dim Buffer() As Byte = Archivos.Recuperar(Nombre).Rows(0).Item(“Imagen”)


                ‘Crear un nuevo archivo


                _Fs = New FileStream(“Documento.tmp”, FileMode.Create, FileAccess.Write)


                ‘escribirlo a partir del array intermedio


                _Fs.Write(Buffer, 0, Buffer.Length)


                _Fs.Close()       ‘Cerrar el fstrm


                _Fs.Dispose()     ‘Liberarlo


            End If


        Catch ex As Exception


            ‘En caso de excepcion, reportar


            Me.lblExcepciones.Text = “DocRecuperar: “ + ex.Message


            Try


                My.Computer.FileSystem.DeleteFile(“Documento.tmp”)


            Catch ex2 As Exception


                Me.lblExcepciones.Text = “Eliminar: “ + ex.Message


            End Try


        End Try


    End Sub


End Class