Download 1. Almacenamiento 1.1 Introducción. 1.2 DataTable.

Document related concepts
no text concepts found
Transcript
1. Almacenamiento
1.1 Introducción.
Los objetos de almacenamiento son los nombrados, pero podríamos hacer alguna matización.
El DataReader es simultáneamente las dos facetas del trabajo y si observamos el código, podemos
observar que no se utiliza en su llenado el DataAdapter, porque la gestión de los datos la realiza dicho objeto.
Por lo tanto podríamos ponerlo en los dos apartados, conexión y almacenamiento, pero nos ha parecido
mejor este.
El DataRow escapa a lo considerado como elemento de almacenar datos, pero su utilización facilita en
mucho el manejo de datos, trasiego dentro de la aplicación, por lo tanto nos ha parecido adecuado nombrarlo.
Todos los objetos pertenecen al System.Data, excepto el DataReader, que pertenece al
System.Data.OleDb, podría ese ser un motivo para no incluirlo aquí, pero a pesar de eso pensamos que está
mejor ubicado aquí.
Escenarios de utilización, podemos encontrar dos básicamente.
Trabajando en modo desconectado pero sin establecer un conjunto de datos propio en la aplicación,
prescindir del DataSet.
Trabajar en un modo desconectado, pero creando al inicio del programa correspondiente la estructura
necesaria para el buen funcionamiento del mismo, creando un DataSet, para posteriormente volcar los datos
en la base de datos.
1.2 DataTable.
El espacio de nombres es
System.Data.DataTable
Hemos de tener en cuenta, que la utilización de una tabla con o sin un dataset no cambia en exceso.
Pero sin embargo hay algunas cosas que no se permiten hacer.
Veamos los pasos de un DataTable, desde un ejemplo de una tabla provisional de apoyo en el programa
y en el ejemplo de una tabla de la base de datos.
1.2.1 Creación.
La configuración de la conexión no cambia, es la vista con anterioridad.
El proceso de carga que sigue parte de objetos definidos a nivel de formulario, o programa.
Dim
Dim
Dim
Dim
Comando As New System.Data.OleDb.OleDbCommand
Adaptador As OleDb.OleDbDataAdapter
Tabla As System.Data.DataTable
EnlaceTabla As New BindingSource
' Enlace
La clave principal de esta tabla se crea en este procedimiento
Private Sub CrearRestriccion(ByVal Tabla As System.Data.DataTable)
Dim ColPri(1) As DataColumn
Dim Restriccion As UniqueConstraint
' Unica
' Campos que componen la clave
ColPri(0) = Tabla.Columns("Tipo")
ColPri(1) = Tabla.Columns("Codigo")
' Se asignan a la restricción, y se índica que es clave principal.
Restriccion = New UniqueConstraint("Principal", ColPri, True)
' Se añade a la tabla.
Tabla.Constraints.Add(Restriccion)
End Sub
El ejemplo crea una tabla de datos provisional que se enlaza a un DataGridView, por eso la necesidad
de que disponga de un campo de clave principal y única.
Pasos seguidos
Crear la referencia a la tabla.
' Se deshace de los datos anteriores
Tabla = New DataTable
El siguiente paso es crear la SQL, que como se puede observar es una tabla compuesta por datos de
varios tablas, y que dado que el dato no existe quedará vacía, pero el datagrid cargará la cabecera.
CadenaSql = "Select Movimientos.TipTitulo as Tipo, " & _
"Movimientos.Titulo as Codigo, " & _
"Titulos.Titulo, " & _
"Titulos.PreVenta as Precio, " & _
"Movimientos.Cantidad " & _
"From Movimientos " & _
"Inner Join Titulos On " & _
"(Movimientos.TipTitulo = Titulos.TipPub) and " & _
"(Movimientos.Titulo = Titulos.Codigo) " & _
"Where Movimientos.Numero = '" & Campo01.Text & "';"
Generar el DataAdapter
' Crear un nuevo adaptador de datos
Adaptador = New OleDb.OleDbDataAdapter(CadenaSql, Conexion)
' Llenar la tabla con los datos y enlazarza con el 'bindingsource'
Adaptador.Fill(Tabla)
Crear la clave principal.
' Se define la restricción
CrearRestriccion(Tabla)
El siguiente paso es el enlace con el datagrid.
' Se enlaza el objeto
ObjDataGrid.DataSource = Tabla
Cualquiera de los dos sistemas es válido.
' Se enlaza el objeto
ObjDataGrid.DataSource = EnlaceTabla
EnlaceTabla.DataSource = Tabla
Las siguientes líneas se encargan de la configuración del DataGrid.
Este es el código del ejemplo completo.
Private Sub CargaDataGrid()
Dim CadenaSql As String
' Se deshace de los datos anteriores
Tabla = New DataTable
CadenaSql = "Select Movimientos.TipTitulo as Tipo, " & _
"Movimientos.Titulo as Codigo, " & _
"Titulos.Titulo, " & _
"Titulos.PreVenta as Precio, " & _
"Movimientos.Cantidad " & _
"From Movimientos " & _
"Inner Join Titulos On " & _
"(Movimientos.TipTitulo = Titulos.TipPub) and " & _
"(Movimientos.Titulo = Titulos.Codigo) " & _
"Where Movimientos.Numero = '" & Campo01.Text & "';"
Try
Conexión.Open
' Crear un nuevo adaptador de datos
Adaptador = New OleDb.OleDbDataAdapter(CadenaSql, Conexion)
' Llenar la tabla con los datos y enlazarza con el 'bindingsource'
Adaptador.Fill(Tabla)
' Se define la restricción
CrearRestriccion(Tabla)
' Se enlaza el objeto
ObjDataGrid.DataSource = Tabla
‘ Configurar el DataGrid
ConfigDataGrid(Me, ObjDataGrid, False)
ObjDataGrid.Columns(0).Width = CInt(ObjDataGrid.Width * 0.08)
ObjDataGrid.Columns(1).Width = CInt(ObjDataGrid.Width * 0.1)
ObjDataGrid.Columns(2).Width = CInt(ObjDataGrid.Width * 0.5)
ObjDataGrid.Columns(3).Width = CInt(ObjDataGrid.Width * 0.1)
ObjDataGrid.Columns(3).DefaultCellStyle.Alignment = _
DataGridViewContentAlignment.MiddleRight
ObjDataGrid.Columns(4).Width = CInt(ObjDataGrid.Width * 0.12)
ObjDataGrid.Columns(4).DefaultCellStyle.Alignment = _
DataGridViewContentAlignment.MiddleRight
Catch ex As OleDb.OleDbException
MsgBox(ex.Message, MsgBoxStyle.Information)
End Try
Conexión.Close
End Sub
1.2.2 Actualización.
El proceso de la actualización pasa por la localización primero del registro que nos interesa.
Para ello utilizamos el método Find y le proporcionamos un valor acorde con el campo de clave definido
en la tabla.
También se puede realizar la actualización a partir del objeto que se ha enlazado a la tabla, desde un
DataGridView, sería lo más sencillo, como se ha visto antes.
El método del DataGrid solo requiere que el objeto se haya enlazado en el momento de la carga de la
tabla, como vemos en el ejemplo, o mediante el BindingSource.
' Se enlaza el objeto
ObjDataGrid.DataSource = Tabla
Y después solo se trata de dejar que se pueda editar en el DataGrid,
Para ello hay que actuar sobre estas propiedades convenientemente.
ObjDataGrid.AllowUserToAddRows = True
ObjDataGrid.AllowUserToDeleteRows = True
ObjDataGrid.AllowUserToOrderColumns = True
ObjDataGrid.EditMode = DataGridViewEditMode.EditOnEnter
ObjDataGrid.ReadOnly = False
El sistema de la búsqueda en la tabla es el que sigue.
1.2.3 Borrado.
Se trata de generar un objeto registro que exista y después utilizar el método remove del objeto
dataTable.
Dim Clave(1) As Object
Clave(0) = “01”
Clave(1) = “0002”
Dim Registro As System.Data.DataRow = _
ObjDataSet.Tables("Clientes").Rows.Find(Clave)
Tabla.Rows.Remove(Registro)
Este es otro ejemplo tomado de la documentación de Microsoft, que tiene la ventaja de utilizar más
recursos y comprobar que existe.
Dim Registros As DataRowCollection = Tabla.Rows
' Control de la existencia del dato
If Registros.Contains(“0001”) Then
Dim RegistroExistente As DataRow = Registros.Find(“0001”)
Registros.Remove (RegistroExistente)
End If
Otra posibilidad es la de hacerlo desde el objeto de visualización enlazado, en cuyo caso sería
ObjDataGrid.Rows.Remove(ObjDataGrid.CurrentRow)
Que traducido significa que borramos la fila actual del DataGrid, que como está enlazado a la tabla, se
efectúa en la tabla también.
1.2.4 Adición.
tabla.
Para añadir un registro creamos un objeto DataRow, al que asignaremos los datos del registro de la
Posteriormente el objeto DataRow se añade a la tabla.
Primer paso, crear el objeto, usamos el método NewRow, el cual nos devuelve un registro vacío con la
estructura de la tabla.
Dim Registro As DataRow = Tabla.NewRow
El siguiente paso es asignar los datos al registro que hemos creado.
Registro.Item("Tipo") = Titulo.Codigo.ToString
Registro.Item("Codigo") = Titulo.Codig2.ToString
La asignación podría hacerse por el índice del campo, es mejor utilizar el nombre del campo en la tabla,
es más seguro, pues no depende del cambio de orden en la Select.
Después de haber asignado los datos, añadir el registro a la tabla.
Tabla.Rows.Add(Registro)
La captura de errores, permitirá el control de duplicados, ya que antes hemos definido la clave principal.
El código completo es el que sigue.
Private Sub AnyadirTitulos(ByRef Tabla as System.Data.DataTable)
Dim Registro As DataRow = Tabla.NewRow
Dim Titulo As ItemLista = CType(Lista04.SelectedItem, ItemLista)
Dim RegTit As System.Data.DataRow
Registro.Item("Tipo") = Titulo.Codigo.ToString
Registro.Item("Codigo") = Titulo.Codig2.ToString
Registro.Item("Titulo") = Titulo.ToString
Registro.Item("Cantidad") = "0"
Registro.Item("Precio") = Titulo.Codig3
Try
Tabla.Rows.Add(Registro)
Catch ex As ConstraintException
MsgBox("Título existente", MsgBoxStyle.Critical, NomProgram)
End Try
End Sub
La otra posibilidad que se puede presentar es la de añadir datos a una tabla de la base de datos con una
instrucción SQL
Los pasos a seguir son generar la instrucción SQL a utilizar, del tipo Insert Into, asignar dicha instrucción
SQL a un objeto OleDbCommand.
En este objeto después utilizaremos el método ExecuteNonQuery, para enviar el registro a la base de
datos.
Crear la instrucción SQL
CadenaSQL = "INSERT INTO
Movimientos ( Fecha, Tipo, Codigo, " & _
"TipTitulo, Titulo, TipMov, Cantidad, " & _
"FacAbo, Numero ) " & _
"Values ('" & Fech & "', " & _
"'" & TiCl & "', " & _
"'" & CoCl & "', " & _
"'" & TipT & "', " & _
"'" & Titu & "', " & _
"'" & TiMv & "', " & _
"'" & Cant & "', " & _
"'0', " & _
"'" & Nume & "') "
Generar los parámetros del objeto OleDbCommand, que es el que realizará la tarea.
' código SQL a utilizar
Comando.CommandText = CadenaSQL
' Tipo de comando a ejecutar
Comando.CommandType = CommandType.Text
' Conexión a utilizar, configurada previamente.
Comando.Connection = Conexion
La ejecución se basa en la captura de cuantos registros se ven afectados por la ejecución del método,
comprobando en este caso que es cero o distinto de cero según interese.
Cuantos = Comando.ExecuteNonQuery
Fallo = Cuantos = 0
En este caso se asigna el valor a la variable Booleana Fallo que tomará cierto o true según proceda.
El ejemplo completo es el que sigue.
Private Sub GrabarMovim( _
ByVal Conexion As System.Data.OleDb.OleDbConnection, _
ByRef Comando As System.Data.OleDb.OleDbCommand, _
ByVal Fech As String, _
ByVal TiCl As String, _
ByVal CoCl As String, _
ByVal TipT As String, _
ByVal Titu As String, _
ByVal Cant As String, _
ByVal Nume As String, _
ByRef Fallo As Boolean)
Dim Cuantos As Integer
Dim TiMv As String = "3" ' entradas de almacen por devolución de cliente
Dim CadenaSQL As String
CadenaSQL = "INSERT INTO
Movimientos ( Fecha, Tipo, Codigo, " & _
"TipTitulo, Titulo, TipMov, Cantidad, " & _
"FacAbo, Numero ) " & _
"Values ('" & Fech & "', " & _
"'" & TiCl & "', " & _
"'" & CoCl & "', " & _
"'" & TipT & "', " & _
"'" & Titu & "', " & _
"'" & TiMv & "', " & _
"'" & Cant & "', " & _
"'0', " & _
"'" & Nume & "') "
' código SQL a utilizar
Comando.CommandText = CadenaSQL
' Tipo de comando a ejecutar
Comando.CommandType = CommandType.Text
' Conexión a utilizar, configurada previamente.
Comando.Connection = Conexion
Try
Cuantos = Comando.ExecuteNonQuery
Fallo = Cuantos = 0
Catch ex As OleDb.OleDbException
Fallo = True
MsgBox(ex.Message, MsgBoxStyle.Information)
End Try
End Sub
1.2.5 Relaciones y Claves.
Fuera de un DataSet no es posible crear relaciones.
La clave principal si es posible crearla.
Es similar al ejemplo de un DataSet.
1.2.5.1 Cargándola desde la tabla de la base de datos.
En el caso de cargarla desde el diseño de la base de datos, solo hay que utilizar el método FillSchema
Adaptador.Fill(Tabla)
Adaptador.FillSchema(Tabla, SchemaType.Source)
Es así de sencillo, con éste paso la tabla queda cargada con su clave principal.
1.2.5.2 Generándola en el programa.
La otra posibilidad es generarla en el programa, sobre todo es útil cuando se trabaja con una tabla
temporal.
Private Sub CrearRestriccion(ByVal Tabla As System.Data.DataTable)
Dim ColPri(1) As DataColumn
Dim Restriccion As UniqueConstraint
' Unica
' Campos que componen la clave
ColPri(0) = Tabla.Columns("Tipo")
ColPri(1) = Tabla.Columns("Codigo")
' Se asignan a la restricción, y se índica que es clave principal.
Restriccion = New UniqueConstraint("Principal", ColPri, True)
' Se añade a la tabla.
Tabla.Constraints.Add(Restriccion)
End Sub
Todo lo referente al objeto DataTable podemos encontrarlo en el siguiente Link.
http://msdn2.microsoft.com/es-es/library/system.data.datatable(VS.80).aspx
1.3 DataSet.
El espacio de nombres es
System.Data.DataSet
Este objeto permite crear un subconjunto de los datos de una base de datos, para su uso local.
Esto implica que al principio del programa se ha de crear un procedimiento que permita cargar los datos
desde la base de datos para su utilización en el mismo.
Posteriormente desde las tablas de este DataSet, se pueden llenar con datos los objetos del programa,
sin necesidad ya de acceder a la base de datos, ni de abrir una conexión con la misma.
Podemos añadir o borrar datos de dichas tablas y realizar la posterior actualización en la misma.
Veamos estos pasos.
1.3.1 Creación del DataSet.
La configuración de la conexión no cambia, es la vista con anterioridad.
El proceso de carga que sigue parte de objetos definidos a nivel de formulario, o programa.
En este primer ejemplo se carga una sola tabla, y el esquema de clave se genera en el mismo
procedimiento.
Los objetos a utilizar son
Dim ObjDataSet As System.Data.DataSet
Dim Comando As New System.Data.OleDb.OleDbCommand
Dim ComanAct As New System.Data.OleDb.OleDbCommandBuilder
Dim
Dim
Dim
Dim
Adaptador
AdapTitul
AdapAlbCa
AdapAlbDe
As
As
As
As
New
New
New
New
OleDb.OleDbDataAdapter
OleDb.OleDbDataAdapter
OleDb.OleDbDataAdapter
OleDb.OleDbDataAdapter
Dim Tabla As System.Data.DataTable
El procedimiento es el que sigue.
Private Sub CrearDataSet()
ObjDataSet = New System.Data.DataSet
Dim CadenaSQL As String
Dim ClavePri(1) As DataColumn
CadenaSQL = "Select * " & _
"From Titulos " & _
"Order by Titulos.TipPub, Titulos.Codigo "
Try
' Abrir la base de datos.
Conexion.Open()
Comando = New System.Data.OleDb.OleDbCommand
AdapTitul = New System.Data.OleDb.OleDbDataAdapter
Tabla = New Data.DataTable
' Tipo de comando a ejecutar
Comando.CommandType = CommandType.Text
' Genera el código SQL para la actualización
ComanAct = New OleDb.OleDbCommandBuilder(AdapTitul)
' Contenido del comando
Comando.CommandText = CadenaSQL
' Conexión a utilizar, configurada previamente.
Comando.Connection = Conexion
' Asignación del comando al objeto adapter.
AdapTitul.SelectCommand = Comando
' LLenar el adaptador
Try
' Solo si procede.
' ObjDataSet.Tables("Titulos").Rows.Clear() ' limpia la tabla
Catch ex As NullReferenceException
Finally
AdapTitul.Fill(Tabla)
End Try
' Establece la clave primaria.
ClavePri(0) = Tabla.Columns.Item("TipPub")
ClavePri(1) = Tabla.Columns.Item("Codigo")
Tabla.PrimaryKey() = ClavePri
Tabla.TableName = "Titulos"
ObjDataSet.Tables.Add(Tabla)
Catch Ex As Exception
MsgBox(Ex.Message, MsgBoxStyle.Information, _
"Crear tabla títulos en dataset ")
End Try
End Sub
Este paso se repetiría para cada una de las tablas que tengamos en la base de datos, y que deseemos
incluir en el DataSet.
En el ejemplo que sigue se hace la carga de dos tablas, utilizando dos sistemas distintos para la creación
de la clave principal.
El cambio es concretamente el que figura a continuación, después figura en el ejemplo completo.
' Captura de la clave de la tabla desde la tabla de la base de datos.
AdapAlbCa.FillSchema(Tabla, SchemaType.Source)
' Llenado de la tabla desde la base de datos
AdapAlbCa.Fill(Tabla)
Como podemos observar es solo el uso del método FillSchema del objeto DataAdapter, con los
parámetros que se especifican.
El código que sigue podría estar en el mismo procedimiento a continuación del anterior.
Private Sub CrearDataSet()
ObjDataSet = New System.Data.DataSet
Dim CadenaSQL As String
Dim ClavePri(1) As DataColumn
CadenaSQL = "Select * From AlbDetalle Order by NumAlb, Linea"
Try
Comando = New System.Data.OleDb.OleDbCommand
AdapAlbDe = New System.Data.OleDb.OleDbDataAdapter
Tabla = New Data.DataTable
' Tipo de comnndo a ejecutar
Comando.CommandType = CommandType.Text
' Genera el código SQL para la actualización
ComanAct = New OleDb.OleDbCommandBuilder(AdapAlbDe)
' Contenido del comando
Comando.CommandText = CadenaSQL
' Conexión a utilizar, configurada previamente.
Comando.Connection = Conexion
' Asignación del comando al objeto adapter.
AdapAlbDe.SelectCommand = Comando
' LLenar el adaptador
Try
' ObjDataSet.Tables("AlbDetalle").Rows.Clear() ' limpia la tabla
Catch ex As NullReferenceException
Finally
AdapAlbDe.Fill(Tabla)
End Try
ReDim ClavePri(1) 'As DataColumn
' Establece la clave primaria.
ClavePri(0) = Tabla.Columns.Item("NumAlb")
ClavePri(1) = Tabla.Columns.Item("Linea")
Tabla.PrimaryKey() = ClavePri
Tabla.TableName = "AlbDetalle"
ObjDataSet.Tables.Add(Tabla)
Catch Ex As Exception
MsgBox(Ex.Message, MsgBoxStyle.Information, _
"Crear tabla Albarán Detalle Dataset ")
End Try
CadenaSQL = "Select * From AlbCab Order by NumAlb"
Try
Comando = New System.Data.OleDb.OleDbCommand
AdapAlbCa = New System.Data.OleDb.OleDbDataAdapter
Tabla = New Data.DataTable
' Tipo de comnndo a ejecutar
Comando.CommandType = CommandType.Text
' Genera el código SQL para la actualización
ComanAct = New OleDb.OleDbCommandBuilder(AdapAlbCa)
' Contenido del comando
Comando.CommandText = CadenaSQL
' Conexión a utilizar, configurada previamente.
Comando.Connection = Conexion
' Asignación del comando al objeto adapter.
AdapAlbCa.SelectCommand = Comando
' LLenar el adaptador
Try
'ObjDataSet.Tables("AlbCab").Rows.Clear() ' limpia la tabla
Catch ex As NullReferenceException
Finally
' Cambio en la forma de crear la clave principal
' Captura de la clave de la tabla desde la tabla de la base de datos.
AdapAlbCa.FillSchema(Tabla, SchemaType.Source)
' Llenado de la tabla desde la base de datos
AdapAlbCa.Fill(Tabla)
End Try
ReDim ClavePri(0)
' Establece la clave primaria, este es el cambio
ClavePri(0) = Tabla.Columns.Item("NumAlb")
Tabla.PrimaryKey() = ClavePri
Tabla.TableName = "AlbCab"
ObjDataSet.Tables.Add(Tabla)
Catch Ex As Exception
MsgBox(Ex.Message, MsgBoxStyle.Information, _
"Crear tabla Albarán Cabecera Dataset ")
End Try
Conexion.Close()
End Sub
1.3.2 Añadido de datos a la tabla del DataSet.
El ejemplo que sigue añade un registro nuevo a la tabla de un DataSet.
Se reciben los datos que se van a insertar y se asignan a un objeto DataRow, que posteriormente se
añade a la tabla.
Veamos en detalle.
Primero definir el objeto DataRow.
Dim Registro As DataRow = ObjDataSet.Tables("AlbCab").NewRow
En el paso anterior se carga también la estructura del registro, por lo que ahora solo queda
Registro.Item("NumAlb") = NumAlb
Registro.Item("Fecha") = Fecha
Registro.Item("TipCli") = TipoCli
Una vez asignados los datos, solo queda añadir el registro a la tabla del DataSet.
ObjDataSet.Tables("AlbCab").Rows.Add(Registro)
El código completo es el que sigue.
Private Sub GrabarCabAlbaran(ByVal
ByVal
ByVal
ByVal
ByVal
NumAlb As String, _
FecAlb As String, _
TipoCli As String, _
CodCli As String, _
Pedido As String)
Dim Registro As DataRow = ObjDataSet.Tables("AlbCab").NewRow
Dim Fecha As String = FecAlb
Fecha
=
Strings.Right(Fecha,
4)
Strings.Left(Fecha, 2)
Try
Registro.Item("NumAlb") = NumAlb
Registro.Item("Fecha") = Fecha
Registro.Item("TipCli") = TipoCli
Registro.Item("CodCli") = CodCli
Registro.Item("NumPed") = Pedido
Registro.Item("Impres") = 1
Registro.Item("Factu") = 0
&
Strings.Mid(Fecha,
ObjDataSet.Tables("AlbCab").Rows.Add(Registro)
Catch ex As ConstraintException
MsgBox("Albaran
existente
en
cabecera
",
NomProgram)
End Try
End Sub
4,
2)
&
MsgBoxStyle.Critical,
Finalizado este paso, al acabar la ejecución del programa se actualizará la base de datos.
1.3.3 Búsqueda y actualización de datos en la tabla del DataSet.
En el ejemplo que sigue se reciben los datos que se van a usar en un registro de una tabla, por lo que
fila es del tipo DataRow.
Veamos los pasos.
Generamos el objeto que nos va a servir como clave principal para la búsqueda.
Dim Clave(1) As Object
El siguiente paso es asignar los valores a éste array, los datos se obtienen del objeto Fila recibido.
Clave(0) = CType(Fila.Item("Tipo"), Object)
Clave(1) = CType(Fila.Item("Codigo"), Object)
El siguiente paso es generar un objeto registro, para usarlo en la actualización y cargarlo con datos en la
búsqueda, no se usa NewRow, porque buscamos un registro que sabemos que existe, y usamos el método
Find.
Dim Registro As System.Data.DataRow = _
ObjDataSet.Tables("Titulos").Rows.Find(Clave)
A pesar de todo se comprueba que existe
If Not (Registro Is Nothing) Then
Y si procede se guarda la dirección del registro en la tabla,
Cual = ObjDataSet.Tables("Titulos").Rows.IndexOf(Registro)
para a continuación realizar el proceso de actualización
SalAcu = CLng(Registro.Item("SalAcu").ToString)
SalAcu = SalAcu + CLng(Fila.Item("Cantidad").ToString)
y grabar los datos en la posición conocida.
ObjDataSet.Tables("Titulos").Rows(Cual).Item("Salacu") = SalAcu
El código completo a continuación.
Private Sub ActualizarStock(ByVal Fila As DataRow)
Dim Clave(1) As Object
Dim SalAcu As Long
Dim Cual As Integer
Clave(0) = CType(Fila.Item("Tipo"), Object)
Clave(1) = CType(Fila.Item("Codigo"), Object)
Dim Registro As System.Data.DataRow = _
ObjDataSet.Tables("Titulos").Rows.Find(Clave)
Try
If Not (Registro Is Nothing) Then
Cual = ObjDataSet.Tables("Titulos").Rows.IndexOf(Registro)
SalAcu = CLng(Registro.Item("SalAcu").ToString)
SalAcu = SalAcu + CLng(Fila.Item("Cantidad").ToString)
ObjDataSet.Tables("Titulos").Rows(Cual).Item("Salacu") = SalAcu
End If
Catch ex As OleDb.OleDbException
MsgBox(ex.Message, MsgBoxStyle.Information, _
"Error en actualización stocks")
End Try
End Sub
No hay que utilizar
ObjDataSet.Tables("Titulos").Rows(Cual).SetModified()
porque ya se queda como fila modificada, al haberla actualizado.
Tampoco hay que utilizar
ObjDataSet.Tables("Titulos").AcceptChanges()
porque en ese caso desactivaríamos al registro como modificado y entonces al realizar el proceso de
actualización en la base de datos, no se produciría la actualización en la base de datos de origen.
1.3.4 Actualización de la base de datos.
El ejemplo que sigue es un procedimiento completo de actualización de los datos que se han modificado
en el DataSet sobre la base de datos.
Veámoslo por bloques
El primer paso es generar un objeto DataSet que asuma los cambios que ha habido en el que se utiliza
en el programa
Dim ObjDataSetCamb As New DataSet
datos.
El siguiente paso es condicionar la actualización a que se haya producido algún cambio en la base de
If ObjDataSet.HasChanges Then
A continuación se pasa los cambios del DataSet del programa al nuevo DataSet, definiendo que tipos de
cambios deseamos que se procesen.
ObjDataSetCamb = ObjDataSet.GetChanges(DataRowState.Modified _
Or DataRowState.Added _
Or DataRowState.Deleted)
Realizado este paso, ahora ya es ir tabla a tabla y actualizar su contenido en la base de datos.
AdapTitul.Update(ObjDataSetCamb.Tables("Titulos").GetChanges)
ObjDataSet.Merge(ObjDataSet.Tables("Titulos"))
ObjDataSet.AcceptChanges()
Private Sub ActualizarBaseDatos()
Try
Dim ObjDataSetCamb As New DataSet
If ObjDataSet.HasChanges Then
Conexion.Open()
ObjDataSetCamb = ObjDataSet.GetChanges(DataRowState.Modified _
Or DataRowState.Added _
Or DataRowState.Deleted)
Try
AdapTitul.Update(ObjDataSetCamb.Tables("Titulos").GetChanges)
ObjDataSet.Merge(ObjDataSet.Tables("Titulos"))
ObjDataSet.AcceptChanges()
Catch ex As ArgumentNullException
End Try
Try
AdapMovim.Update(ObjDataSetCamb.Tables("Movimientos").GetChanges)
ObjDataSet.Merge(ObjDataSet.Tables("Movimientos"))
ObjDataSet.AcceptChanges()
Catch ex As ArgumentNullException
End Try
Try
AdapAlbCa.Update(ObjDataSetCamb.Tables("AlbCab").GetChanges)
ObjDataSet.Merge(ObjDataSet.Tables("AlbCab"))
ObjDataSet.AcceptChanges()
Catch ex As ArgumentNullException
End Try
Try
AdapAlbDe.Update(ObjDataSetCamb.Tables("AlbDetalle").GetChanges)
ObjDataSet.Merge(ObjDataSet.Tables("AlbDetalle"))
ObjDataSet.AcceptChanges()
Catch ex As ArgumentNullException
End Try
Try
AdapClien.Update(ObjDataSetCamb.Tables("Clientes").GetChanges)
ObjDataSet.Merge(ObjDataSet.Tables("Clientes"))
ObjDataSet.AcceptChanges()
Catch ex As ArgumentNullException
End Try
Conexion.Close()
CrearDataSet()
MsgBox("Base actualizada.", MsgBoxStyle.Information, _
"Actualizando dataset")
Else
MsgBox("No se han realizado cambios", _
MsgBoxStyle.Information, "Actualizando dataset")
End If
Catch ex As System.Data.OleDb.OleDbException
MsgBox(ex.Message, MsgBoxStyle.Information, "Actualizando dataset")
End Try
End Sub
1.3.5 Carga de objetos.
El siguiente paso una vez que se ha generado el DataSet, o se ha credo la estructura local de la base de
datos, es explotarla, empecemos obteniendo datos de la misma, usando un listbox para cargarlo.
Observemos que no se utiliza la conexión, pues no hace falta.
El ejemplo que sigue funciona correctamente, pero falta comparar su eficacia con respecto al otro
ejemplo que hay después.
El motivo de ponerlo es debido a como parece que funciona las relaciones entre las tablas, pues se basa
en realidad en listas de datos en memoria, a las que suponemos se acude para tomar los datos que cumplen la
condición y obtener los datos.
Por lo tanto podría ser que realizando un acceso con el método Find, y luego el código que aquí
exponemos, fuera igual de rápido, y al menos queda una forma más de usar los datos en el DataSet.
El sistema no es más que una búsqueda secuencial, que hay que optimizar.
Private Sub CargaListaTitulo(ByRef Lista As ListBox, _
ByVal Tipo As String)
Dim Comando As New System.Data.OleDb.OleDbCommand
Dim Objeto As ItemLista
Dim Fila As System.Data.DataRow
Dim X As Integer
Lista.Items.Clear()
' Vaciar la lista
X = 0
Try
' Recorrido de la tabla
While X < ObjDataSet.Tables("Titulos").Rows.Count
' Obtención de un registro
Fila = ObjDataSet.Tables("Titulos").Rows(X)
' Filtrado
Select Case Fila.Item("TipPub").ToString = Tipo
Case True
Objeto = New ItemLista(Trim(Fila.Item("Titulo").ToString), _
Fila.Item("TipPub").ToString,
Fila.Item("Codigo").ToString)
Lista.Items.Add(Objeto)
End Select
X = X + 1
End While
Catch ex As OleDb.OleDbException
MsgBox(ex.Message, MsgBoxStyle.Information, "Leer dataset títulos")
End Try
End Sub
Este otro está mas de acorde con la filosofía del lenguaje.
Se basa en el uso del objeto DataView, que obtiene relaciones de datos de una tabla pudiendo filtrarlos
por el contenido de un campo, y estableciendo cual deseamos usar para la clasificación.
' campo a usar en el filtro
ObjDataView.RowFilter = "TipPub = '" & Tipo & "'"
Además permite obtener los datos de una tabla seleccionando los que se han modificado, los que se han
eliminado, etc.
ObjDataView.RowStateFilter = DataViewRowState.CurrentRows
Después solo queda pasar los datos del DataView a la lista.
Private Sub CargaListaTitulosDataSet(ByRef Lista As ListBox, _
ByVal Tipo As String)
Dim X As Integer
Dim Objeto As ItemLista
Dim ObjDataView As DataView
' Crear el objeto
ObjDataView = New DataView(ObjDataSet.Tables("Titulos"))
' Definir parámetros
With ObjDataView
' Asignación de la tabla
.Table = ObjDataSet.Tables("Titulos")
.AllowDelete = False
.AllowEdit = False
.AllowNew = False
' campo a usar en el filtro
.RowFilter = "TipPub = '" & Tipo & "'"
.RowStateFilter = DataViewRowState.CurrentRows
' campo a usar para la ordenación
.Sort = "Titulo"
End With
Lista.Items.Clear()
' Asignación de los datos al listbox
For X = 0 To ObjDataView.Count - 1
Objeto = New
_
ItemLista(Trim(ObjDataView(X).Row.Item("Titulo").ToString), _
ObjDataView(X).Row.Item("TipPub").ToString, _
ObjDataView(X).Row.Item("Codigo").ToString, _
ObjDataView(X).Row.Item("PreVenta").ToString)
Lista.Items.Add(Objeto)
Next
End Sub
Todo lo referente a este objeto podemos encontrarlo en el siguiente Link.
http://msdn2.microsoft.com/es-es/library/system.data.dataset(VS.80).aspx
1.4 DataReader.
El espacio de nombres es
System.Data.OleDb.OleDbDataReader
El uso de este objeto es muy sencillo, quizás el único problema que se puede presentar, pero que si no
se hacen pruebas con grandes volúmenes de datos no se sabe, es el tiempo que pueda requerir para su uso
en la conexión que no sea un gran inconveniente.
El ejemplo que exponemos carga una lista de datos ElementoLista.
Los pasos seguidos son:
Definir el objeto
Dim Reader As System.Data.OleDb.OleDbDataReader
Generar la cadena SQL que se va a usar en la consulta.
CadenaSQL = "Select Codigo, Nombre From Autores Order By Nombre"
Abrir la conexión
' Abrir la base de datos.
Conexion.Open()
Definir el objeto OleDbCommand
' Contenido del comando
Comando.CommandText = CadenaSQL
' Tipo de comando a ejecutar
Comando.CommandType = CommandType.Text
' Conexión a utilizar, configurada previamente.
Comando.Connection = Conexion
Ejecutar el objeto OleDbCommand, el cual asigna el resultado al objeto Reader.
' Ejecución de SQL
Reader = Comando.ExecuteReader
Después solo queda el ejecutar el bucle mientras haya posibilidad de leer, antes Not EOF.
While Reader.Read
Objeto = New ElementoLista(Trim(Reader.Item("Nombre").ToString), _
Reader.Item("Codigo").ToString)
Lista.Items.Add(Objeto)
End While
Los datos quedan almacenados en la colección Item del DataReader.
El acceso es mejor hacerlo por nombre de campo, que por índice.
Public Sub CargaListaAutores( _
ByRef Lista As ListBox, _
ByVal Conexion As System.Data.OleDb.OleDbConnection)
Dim CadenaSQL As String
Dim Comando As New System.Data.OleDb.OleDbCommand
Dim Reader As System.Data.OleDb.OleDbDataReader
Dim Objeto As ElementoLista
Lista.Items.Clear()
CadenaSQL = "Select Codigo, Nombre " & _
"From Autores " & _
"Order By Nombre"
Try
' Abrir la base de datos.
Conexion.Open()
' Contenido del comando
Comando.CommandText = CadenaSQL
' Tipo de comando a ejecutar
Comando.CommandType = CommandType.Text
' Conexión a utilizar, configurada previamente.
Comando.Connection = Conexion
' Ejecución de SQL
Reader = Comando.ExecuteReader
Try
While Reader.Read
Objeto = New ElementoLista(Trim(Reader.Item("Nombre").ToString), _
Reader.Item("Codigo").ToString)
Lista.Items.Add(Objeto)
End While
Catch ex As OleDb.OleDbException
MsgBox(ex.Message, MsgBoxStyle.Information, "Leer reader")
End Try
Catch Ex As OleDb.OleDbException
MsgBox(Ex.Message, MsgBoxStyle.Information, "Crear reader")
End Try
Conexion.Close()
End Sub
El objeto Reader, tiene una peculiaridad de la que hay que acordarse, y es que
While Reader.Read
Es simultáneamente lectura y condición, antes teníamos el EOF.
El ejemplo ha sido en una carga para un listbox, pero se puede usar para un listado, para cualquier
proceso que no requiera actualizaciones, solo lectura, y que deseemos que sea rápido.
Todo lo referente a este objeto podemos encontrarlo en el siguiente Link.
http://msdn2.microsoft.com/es-es/library/system.data.oledb.oledbdatareader(VS.80).aspx
1.5 DataRow.
El espacio de nombres es
System.Data.DataRow
El objeto DataRow posee la estructura de un registro de la tabla.
Se puede generar
A partir de la estructura de una tabla que ya existe en el programa, bien en DataSet o DataTable.
Dim Registro As DataRow = ObjDataSet.Tables("Tablagrid").NewRow
Como registro cargado con datos a partir de la asignación de un registro existente en una tabla.
Dim Registro As System.Data.DataRow
Registro = ObjDataSet.Tables("Titulos").Rows.Find(Clave)
Los datos del objeto están accesibles en la colección Item.
El acceso es mejor hacerlo por nombre de campo, que por índice.
Registro.Item("Tipo") = Titulo.Codigo.ToString
Registro.Item(0) = Titulo.Codigo.ToString
Estas dos líneas son equivalentes, pues en la línea en la que se genera la tabla, el campo “Tipo” ocupa
el primer lugar, pero es más seguro por nombre, pues si por cualquier motivo se cambia el orden en la Select,
no pasaría nada.
Esta colección se puede recorrer con un índice si es necesario.
Una vez que hemos creado el objeto su utilización es como sigue.
Registro.Item("Tipo") = Titulo.Codigo.ToString
Registro.Item("Codigo") = Titulo.Codig2.ToString
Registro.Item("Titulo") = Titulo.ToString
Registro.Item("Cantidad") = "10"
Registro.Item("Precio") = Titulo.Codig3.ToString
Try
ObjDataSet.Tables("tablaGrid").Rows.Add(Registro)
Catch ex As ConstraintException
MsgBox("Título existente", MsgBoxStyle.Critical, NomProgram)
End Try
En éste ejemplo se asignan datos a los campos del registro, y éste después se asigna a la tabla,
controlando la posible duplicidad de los datos en la misma.
El paso contrario es
Dim Dato as String
Dato = Registro.Item("Tipo").ToString
Todo lo referente a este objeto podemos encontrarlo en el siguiente Link.
http://msdn2.microsoft.com/es-es/library/system.data.datarow(VS.80).aspx