1013 PSG
1013 PSG
1013 PSG
NET 2005
TABLAS EN ACCESS
En este ejercicio construiremos una base de datos llamada mibase que solo contendra una tabla llamada
mitabla con tres campos que son clave, nombre y edad que se estaran usando a lo largo de esta unidad a
manera de ejemplo.
Se usa access97 en virtud de que es el mas sencillo de todas las versiones aunque pueden usar cualquier
version que tengan sin embargo solo se responde por access97.
PROCEDIMIENTO:
2.- Usar la opcion FILE–>NEW DATABASE y seleccionar de la pantalla que sale BLANK DATABASE.
3.- Inmediatamente ACCESS pregunta donde se almacenara y como se llamara la base de datos usando la
pantalla normal de grabacion de archivos:
4.- Ponerla en un lugar o folder adecuado y para este ejemplo llamarla mibase (como se ve en la pantalla de
arriba),luego usar el boton create.
6.- Esta ultima pantalla permite construir una o mas tablas que contendra la base de datos (mibase),
observar que tambien permite agregar mas elementos a una base de datos (querys, forms, reports, etc), pero
para este ejercicio solo se agrega una tabla a la base de datos, para crear mitabla solo usar boton new y
access ofrecera construirla de varias maneras distintas de preferencia seleccionar la manera DESIGN VIEW
que manda la siguiente pantalla:
7.- En FIELD NAME escribir el nombre del campo, en DATA TYPE solo hacer click y salen opciones de
los diversos tipos de datos que ofrece access, en DESCRIPTION se puede poner una descripcion de los
propositos del campo, para el ejemplo que se esta mostrando se usa number para la clave, texto con tamano
30 caracteres (seleccionar abajo) para nombre y number para edad.
NOTA, PARA ESTE CURSO CLAVE USAR AUTONUMBER PARA QUE SEA ACCESS QUIEN
VAYA GENERANADO AUTOMATICAMENTE LA CLAVE O ID DEL REGISTRO
8.- Observar que CLAVE tiene una pequena llave a un lado, esto significa que CLAVE es la llave primaria
de la tabla, para marcarla como llave primaria primero seleccionar todo el renglon haciendo un click en el
cuadrito gris que esta antes de la palabra clave y luego hacer un click derecho y del minimenu que sale usar
opcion primary key
9.- Ahora cerrar la tabla usando la [x] de arriba y access pregunta como se llamara la tabla, llamarla
mitabla.
10.- Ahora se regresa a la vista de diseno de access97 y ya estara registrada mitabla en mibase, como lo
muestra el sigiente grafico:
11.- Usar ahora el boton OPEN, para cargar unos cuantos datos o renglones de prueba como lo demuestra el
siguiente ejemplo:
12.- Cerrar microsoft access con la [x] de arriba con esto ya se tiene construida MIBASE.MDB que a su
vez contiene MITABLA que a su vez contiene unos cuantos renglones de datos.
13.- El ultimo paso es ponerla en el mismo folder donde esta tu programa para que ya este lista y preparada
para procesarla con visual c# 2005
fuente microsoft.net
Como ven esta bastante claro y no ocupa explicacion,
Empezando:
El problema es comunicar un programa o aplicacion con una base de datos y mas que comunicar se pretende
que el programa o aplicacion realize una serie de procesos u operaciones con la base de datos o mejor aun
con el conjunto de tablas que contiene una base de datos.
La primera nota a recordar es que una base de datos puede estar fisicamente en algun folder o directorio del
disco duro de dicha maquina servidora, por ejemplo, c:\progfacil\misitio\mibase.mbd, como se observa la
base que se construyo en MICROSOFT access (mibase.mbd) se almaceno en el disco c en el folder
progfacil y dentro del subfolder misitio.
Sin embargo tambien es necesario conocer que asi como existen servidores de paginas (web server),
servidores de correo (mail server), servidores de ftp (ftp server), etc, tambien existen servidores de bases de
datos (database server), los mas comunes son el sqlserver de microsoft, oracle, mysql, etc, estos servidores
tambien pueden crear, administrar y procesar una base de datos, por supuesto que el procedimiento que se
dio para crearla en access en el tema anterior no se puede usar para crear y cargar una base de datos en un
servidor de bases de datos.(esperar libros de bases de datos en programacionfacil en un proximo futuro).
El modo de comunicarse entre nuestro programa o aplicacion y la base de datos (ya sea fisica o un
dbserver), implica que ambos manejen un lenguaje de programacion comun, es decir no se puede mandar
una instruccion de visual c# 2005 o en basic o pascal a la base de datos y ademas esperar que esta ultima la
entienda ( para entender esto, una razon muy sencilla es que la base de datos tendria que conocer o
comprender todos los lenguajes de programacion), para resolver este problema de comunicacion es que se
usa un lenguaje comun de bases de datos que tanto los lenguajes de programacion existentes como las bases
de datos entienden, este lenguaje comun de bases de datos es el SQL (structured query languaje) o lenguaje
estructurado de consultas.
En otras palabras, ustedes mis estimados lectores tendran que aprender este nuevo lenguaje de
programacion SQL, la buena noticia es que es un lenguaje con muy pocas instrucciones y ademas
existen muy buenos tutoriales en internet incluyendo uno aqui en programacionfacil.com que hay que
buscar y estudiar.
PROPAGANDA, ya ven que en este curso estan aprendiendo el lenguaje de programacion VISUAL C#
2005 y ahora el lenguaje de programacion SQL, !wow! dos lenguajes por el precio de uno.
Bueno las principales instrucciones de SQL, que se usan en este curso son SELECT, INSERT, UPDATE y
DELETE.
La pregunta es ahora como mandamos las instrucciones sql a la base de datos, la respuesta son los
OBJETOS ADO NET que estamos analizando en orden y proposito de uso, los estaremos explicando.
Este objeto primero se tendra que crear en el programa y luego se tendra que cargar con dos parametros (ver
ejemplo mas abajo), el primer parametro es el provedor o la fuente que proporcionara los datos, los
provedores o fuentes de datos que existen son:
SQLSERVER NET DATA PROVIDER.- QUE SE ESPECIALIZA EN COMUNICARSE Y PROCESAR
BASES DE DATOS CONSTRUIDAS CON MICROSOF SQL SERVER V7.0
NOTA: Este es el que se usa en los ejemplos siguientes, observar que aunque visual C# 2005 trae por
default los controles SQL, en este capitulo se usaran los objetos OLEDB, lo malo es que se tendran que
crear, cargar y codificar a mano y no olvidar incluir en la parte de arriba del programa la instruccion using
System.Data.OleDb;
ODBC.NET .- BASES DE DATOS QUE USAN ODBC COMO MEDIO DE COMUNICACION CON
OTRAS BASES DE DATOS Y APLICACIONES COMO NOTA A CONSIDERAR ODBC.NET NO
ESTA INCLUIDA POR DEFAULT EN MICROSOFT.NET, SE TIENE QUE BAJAR DE
MICROSOFT.
El segundo parametro es la propia base de datos con la cual se comunicara el programa o aplicacion.
Es una sola string y los dos parametros mencionados van separados por el punto y coma.
OBJETO COMMAND.
Ya establecido el canal o enlace entre el programa y la base de datos via el objeto CONECCION, se debe
mandar la instruccion SQL a la propia base de datos, sin embargo en un programa de visual c# 2005 por
supuesto que no puede contener instrucciones de otros lenguajes de programacion como el de SQL, es por
esto que se deberan usar algunos de los otros objetos de ADO NET para que estos objetos transporten la
instruccion sql hacia la base de datos (y transporte de regreso al servidor los datos de alguna tabla)
uno de estos objetos es el objeto COMMAND.
En particular se usara COMMAND principalmente para que transporte las instrucciones SQL insert, update
y delete.
Este objeto puede contener directamente una instruccion SQL y enviarla al objeto coneccion ya descrito.
Este objeto command primero se tendra que crear y luego cargarle dos parametros que son:
OleDbCommand orden;
Si esta muy grande o muy compleja la instruccion sql, es mas conveniente crearla en una
variable string y poner la variable como parametro ejemplo:
OleDbCommand orden;
Sin embargo ciertas instrucciones de sql (ya estudiaron su tutorial del sql??) requieren que se manden los
datos a la base de datos, respetando el tipo de dato con los cuales los creo el software de bases de datos, por
ejemplo si edad en access97 se declaro como NUMBER, la instruccion sql que prentenda cargar dicho
campo, tiene la obligacion de mandarla con este tipo de dato asociado, instrucciones SQL usan ese campo
edad son INSERT o UPDATE ( ya estudiaron su tutorial de SQL??).
Para resolver este problema, usaremos en la string q, unas variables especiales llamadas VARIABLES
PARAMETROS que se simbolizan usando el simbolo @ antes de la variable y ademas al objeto
COMMAND le agregamos dos instrucciones extras que permiten agregar a la string q el dato y el tipo de
dato, ejemplo, se tienen seis renglones ya capturados en nuestra tabla y se quiere agregar un septimo renglon
con los siguientes datos, clave=7, nombre=“rana” peso=3.14 usaremos una instruccion SQL INSERT ej:
OleDbCommand orden;
orden.Parameters["@CLAVE"].Value = clave;
orden.Parameters["@NOMBRE"].Value = nombre;
orden.Parameters["@PESO"].Value = edad;
Observar que para cada variable parametro se tienen que cargar dos elementos el valor y el tipo de dato
correpondiente.
Aunque en valor se manda string's en oledbtype se hace un mapeo, relacion o conversion al tipo de dato que
se uso en access97, tener mucho cuidado que exista una relacion igual o cuando este pograma se ejecute el
compilador les va a mandar un error o excepcion de sql que les intenta decir que el tipo de dato que
mandaron a la base de datos, no es igual al que se uso para crearlo en la base de datos.
Binary A stream of binary data (DBTYPE_BYTES). This maps to an Array of type Byte.
BSTR A null-terminated character string of Unicode characters (DBTYPE_BSTR). This maps to String.
Date Date data, stored as a double (DBTYPE_DATE). The whole portion is the number of days since
December 30, 1899, while the fractional portion is a fraction of a day. This maps to DateTime.
DBDate Date data in the format yyyymmdd (DBTYPE_DBDATE). This maps to DateTime.
DBTime Time data in the format hhmmss (DBTYPE_DBTIME). This maps to TimeSpan.
DBTimeStamp Data and time data in the format yyyymmddhhmmss (DBTYPE_DBTIMESTAMP). This
maps to DateTime.
Decimal A fixed precision and scale numeric value between -1038 -1 and 10 38 -1 (DBTYPE_DECIMAL).
This maps to Decimal.
Double A floating point number within the range of -1.79E +308 through 1.79E +308 (DBTYPE_R8). This
maps to Double.
Filetime A 64-bit unsigned integer representing the number of 100-nanosecond intervals since January 1,
1601 (DBTYPE_FILETIME). This maps to DateTime.
Guid A globally unique identifier (or GUID) (DBTYPE_GUID). This maps to Guid.
IDispatch A pointer to an IDispatch interface (DBTYPE_IDISPATCH). This maps to Object. Note This data
type is not currently supported by ADO.NET. Usage may cause unpredictable results.
IUnknown A pointer to an IUnknown interface (DBTYPE_UNKNOWN). This maps to Object. Note This
data type is not currently supported by ADO.NET. Usage may cause unpredictable results.
LongVarBinary A long binary value (OleDbParameter only). This maps to an Array of type Byte.
LongVarWChar A long null-terminated Unicode string value (OleDbParameter only). This maps to String.
Numeric An exact numeric value with a fixed precision and scale (DBTYPE_NUMERIC). This maps to
Decimal. PropVariant An automation PROPVARIANT (DBTYPE_PROP_VARIANT). This maps to
Object.
Single A floating point number within the range of -3.40E +38 through 3.40E +38 (DBTYPE_R4). This
maps to Single.
VarBinary A variable-length stream of binary data (OleDbParameter only). This maps to an Array of type
Byte. VarChar A variable-length stream of non-Unicode characters (OleDbParameter only). This maps to
String.
Variant A special data type that can contain numeric, string, binary, or date data, as well as the special
values Empty and Null (DBTYPE_VARIANT). This type is assumed if no other is specified. This maps to
Object.
Fuente:microsoft net
Aun mas, con el ejemplo anterior el objeto COMMAND esta construido y preparado y cargado pero todavia
no se manda desde el programa a la base de datos, es decir le faltan activar las siguientes tres
propiedades, ejemplo;
OleDbCommand orden;
orden.Parameters["@CLAVE"].Value = clave;
orden.Parameters["@NOMBRE"].Value = nombre;
orden.Parameters["@PESO"].Value = edad;
**orden.Connection.Open();**
orden.ExecuteNonQuery();
orden.Connection.Close()
Son los otros dos objetos de ADONET que tambien permiten transportar una instruccion sql desde el
programa hasta la base de datos y transportar de regreso hacia el programa los datos contenidos en
alguna de las tablas.
En particular se usa DataAdapter para mandar la instruccion SQL select en nuestros programas.
DATASET:- Es una copia en memoria (d la maquina cliente) de la base de datos( y todas sus tablas) que se
encuentra en disco.
DATAADAPTER.- En principio es muy similar al objeto COMMAND es decir se usa para transportar
instrucciones SQL ( en especial la instruccion sql SELECT) a la base en disco, de hechos sus formatos e
instrucciones son muy similares a los vistos para el objeto COMMAND, su diferencia principal es que
dataadapter esta mas especializado(en select) y contiene una serie de metodos que facilitan la
interaccion entre el DATASET y la Base de Datos en disco
En particular muchos de los programas que se veran en temas posteriores solo usan los objetos
CONNECTION, DATAADAPTER y DATASET
Ejemplo:
// abriendo la coneccion
// cargando el dataset
orden.Fill(TABLA, "mitabla");
Como se observa en este ejemplo muy sencillo, el dataadapter (orden) esta funcionando de manera muy
similar al primer ejemplo que se vio del objeto COMMAND pero tengan la seguridad que tambien se
pueden usar variables parametros y agregarles los dos tipos de parametros a este objeto dataadpater.
Observar que su propiedad FILL carga el DATASET(TABLA) con una de las tablas en disco, recordar que
en la base de datos puede contener muchas tablas.
Ademas esa propiedad FILL es equivalente a las tres ultimas instrucciones del objeto COMMAND, es decir
open, executenonquery y close, mas facil verdad.
DATAREADER y DATASET:
Observar que tambien se usan en forma conjunta, primero es muy similar en uso y funcion que el objeto
DATAADAPATER y COMMAND, la diferencia entre datareader y dataadapter es el tipo de base de datos
con las cuales se pueden comunicar, dataadpater se especializan en bases de datos relacionales y datareader
se especializa en archivos, que no se estudian en este curso.
Tambien es importante mencionar que datareader es el objeto de ADO NET mas parecido al objeto
RESULTSET que uso mucho en el ADO anterior de microsoft.
EN general se han visto de manera sencilla los principales objetos ADO ASP( connection, command,
datareader, dataadapter, dataset), sin embargo la tabla o las tablas o la base de datos que se tiene en disco
o sirviendola algun servidor de bases de datos, se ha quedado en la memoria de la maquina del cliente,
ADO NET ha terminado su trabajo y su funcion.
Para mandar el dataset a el browser o a una ventana de windows se tendra que pasar a algun tipo de objeto
visible que soporte el browser o la ventana los objetos que se pueden usar para mandar el dataset a pantalla
son:
3.- NUEVO COMPONENTE DATAGRIDVIEW DE ASP NET QUE SE USA EN ESTA UNIDAD
Existen una serie de operaciones y procesos que son muy comunes contra una tabla en una base de datos en
disco la mas comun es desplegar todos los renglones de la tabla que estan almacenados en disco, a este
proceso le llamaremos SELECCION consulta o despliegue (muy original).
Como se indico anteriormente la comunicacion con la base de datos se tendran que dar usando el lenguaje
especializado de bases de datos llamado SQL (structured query language), la instruccion sql que se usa para
resolver este problema tiene el siguiente formato:
Tambien es importante recordar que de las cuatro operaciones basicas de SQL ( ya leyeron el
tutorial ??) SELECT, INSERT, UPDATE y DELETE sus formato INST SQL ??? FROM TABLA;
afectara a todos los renglones de la tabla.
El procedimiento que se intenta seguir cuando se construya un programa asp net que tenga que manipular
una tabla en disco debera seguir los siguientes pasos:
6.- Procesar el DataGridView (editar un renglon, agregar un renglon, modificar un renglon, etc)
Codigo prog
OleDbConnection CANAL;
OleDbDataAdapter ORDEN;
DataSet TABLA;
ORDEN.Fill(TABLA, "mitabla");
GRID1.DataSource = TABLA;
GRID1.DataMember = "mitabla";
Corrida
ReadOnly = True ←- Para evitar que el usuario entre a editar una celda
RowHeaderVisible = false ←- Para que no se muestre una columna de celdas con numero de renglon.
notas:
1.- Se sigue el procedimiento generico para procesar tablas usando ADO NET
2.- Observar y siempre incluir using System.Data.OleDb; en la parte de using arriba dentro del
Form1.CS
3.- Se usa un objeto button = select con este codigo cargado en su evento onclick.
4.- Recordar que DATAGRIDVIEW es un objeto por tanto hay que crearlo e inicializarlo al principio del
programa, tambien recordar que datagridview tiene muchas propiedades que le mejoran la interfase con que
se despliega y es en esta parte donde se cargan dichas propiedades.
5.- Se empieza creando los objetos ADO NET a ocupar y abriendo la coneccion a la base de datos si se les
hace muy grande la string del provedor, pueden cargarla primero en una variable string y carguen la string
en el constructor de la coneccion, pero esto es opcional.
5.1) Recordar que hay otros provedores de bases de datos para cuando se quieran accesar bases de datos
diferentes de access.
6.- Tomar nota como se hace una referencia a la base de datos, esto es en c:\\datos\\mibase.mdb ( ojo con las
diagonales)
8.- Luego se creo el dataset y se cargo con toda la base de datos en disco, entender esto bien, DataSet puede
quedar cargado con todas las tablas que tenga la base de datos por eso se usa un FILL para pasar al dataset
solo una de las tablas (mitabla), esto da origen a dos notas:
8.1.- Al programar mas adelante se ocupara explicitamente indicarle al compilador con cual tabla se va a
trabajar es por esta razon que se veran instrucciones tales como tabla.tables[“clientes”].etc.etc. Aqui se esta
diciendo al compilador que del dataset (TABLA) se va a realizar una proceso con la tabla de clientes.
8.2.- Para procesar dos o mas tablas, entonces se tendra que usar mucho el formato que se vio en la nota 8.1
1.- Construir y desplegar una primera base de datos que contenga la primera tabla que disenaron en el tema
de tablas.
2.- Construir una segunda base de datos que contenga cuando menos tres de las tablas ya disenadas y
desplegar cualquiera de ellas usando una ventana de menu y ventanas para cada tabla, en menu el usuario
selecciona cual quiere desplegar.
Insertar o agregar registros o renglones nuevos a una tabla en disco, es un proceso sencillo que usa la
siguiente instruccion sql:
Recordar que solo se esta usando lo minimo de cada instruccion sql, es conveniente estudiar un tutorial de
sql.
Tambien recordar que INSERT, UPDATE y DELETE van dentro de un objeto COMMAND.
Programa
OleDbCommand ORDEN;
CANAL=new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=c:\\datos\\mibase.mdb");
ORDEN.Parameters["@NOMBRE"].Value = NOMBRE.Text;
ORDEN.Parameters["@EDAD"].Value = EDAD.Text;
ORDEN.Connection.Open();
ORDEN.ExecuteNonQuery();
ORDEN.Connection.Close();
NOMBRE.Text=" ";
EDAD.Text=" ";
// avisando inserccion
cont = cont+1;
Corrida
Notas:
Se agregaron dos textboxs arriba para capturar los nuevos datos a insertar en la tabla.
En funcion INSERTAR(), se crea la string q con el formato apropiado sql( como se dijo al principio de este
tema), observar que existen dos variables que llevan un @ antes, estas variables se llaman VARIABLES
PARAMETROS y se cargan con el objeto command.parameters()
Otra vez, en este ejemplo para mandar la instruccion sql a la base de datos se crea y se usa un objeto
command (llamado orden) que lleva como datos la string q y la coneccion, pero se deben agregar dos
metodos command.parameters (orden.parameters()) por cada textbox que se vaya a enviar a la tabla
de la base de datos , en estos metodos se cargan las variables parametro primero con el valor de dato del
textbox y luego se transforman al tipo de dato apropiado usando los oledbtype(que hay que estudiar porque
se tienen que asociar directamente a los tipos de datos que se usaron en access)
Ya con el objeto COMMAND (orden) listo y cargado para comunicar la instruccion sql a la base de datos se
abre la coneccion a la base de datos se manda el executenonquery(no se quiere regresar nada en esta parte,
recordar la nota respectiva que se dio en un tema anterior) y se cierra la coneccion y ya se mando el nuevo
renglon a la base de datos en disco.
Para asegurarse que ya se efectuo la inserccion en la base de datos, se tendra que usar el programa de
consulta o despliegue (SELECT) de el tema anterior
1.- Construir muchos programas de inserccion en las tablas de las bases de datos que tengan construidas
2.- Ir Preparando un menu que contenga las opciones de consulta (select) e inserccion (INSERT) para una
tabla.
UNIDAD 5: INTRODUCION BASES DE DATOS VISUAL C# 2005
En este tema se analiza la busqueda de un registro o renglon determinado en este proceso el usuario del
programa quiere que se despliegue un y solo un registro de informacion proporcionando un dato de
busqueda generalmente la clave del registro.
La solucion es sencilla, solo usar otra vez la instruccion select, con el siguiente formato:
Codigo
OleDbConnection CANAL;
DataSet TABLA;
OleDbDataAdapter ORDEN;
ORDEN.SelectCommand.Parameters["@CLAVE"].Value = CLAVE.Text;
ORDEN.Fill(TABLA, "mitabla");
// Cargando el datagridview
GRID1.DataSource=TABLA;
GRID1.DataMember="mitabla";
nota: hay nada nuevo es una combinacion de los dos programas anteriores con las mismas notas, solo se usa
un textbox para pedir la clave, aunque se puede usar cualquier campo para buscar.
Corrida prog
1.- hacer programas de busquedas para las bases hechas e ir construyendo el programa de menu completo
para una sola tabla
Otro problema similar al anterior es el de filtros es decir en muchas ocasiones es necesario obtener
informacion acerca de un subconjunto de renglones de la tabla.
Por ejemplo todos los estudiantes que sean mayores de 17 anos, todos los clientes que sean de Tijuana, etc. a
esto le llamamos filtros o condiciones.
Tambien se resuelve de manera similar al anterior, es decir usando la instruccion select y objeto adapter etc,
from tabla, where CONDICION; y no olvidar poner el using oledb arriba en .cs
Codigo
private void button1_Click(object sender, EventArgs e)
OleDbConnection CANAL;
DataSet TABLA;
OleDbDataAdapter ORDEN;
ORDEN.SelectCommand.Parameters["@EDAD"].Value = EDAD.Text;
ORDEN.Fill(TABLA, "mitabla");
// Cargando el datagridview
GRID1.DataSource=TABLA;
GRID1.DataMember="mitabla";
Nota: Es el programa anterior pero con otra condicion WHERE pero seria prudente mejor usar dos
combobox uno para la variable otro para el operador relacional y un text para el dato y mandar estos tres
datos al programa (se ocupan varios command.parameters()) pero eso queda de tarea.
Corrida
1.- preparar programas de filtrado para sus bases de datos y su programa de menu (ACUERDENSE USAR
PROCEDIMIENTOS Y USAR LOS OBJETOS COMMAND, ADAPTER, CONECCION, DATASET
COMO GLOBALES O TAMBIEN PUEDEN CONSTRUIR EL PROGRAMA DE MENU Y EN LAS
OPCIONES DE MENU IR ACTIVANDO UNA VENTANA CORRESPONDIENTE), recordar que sus
filtros deben construirlas con 2 combos y un text, suerte
Este es tambien un caso comun con elementos de una tabla, sin embargo es tambien facil de resolver.
Solo recordar la instruccion UPDATE (usando objeto command), que se puede manejar con SET para
definir los campos o columnas a cambiar y la clausula WHERE que permite condicionar los renglones a
actualizar.
Programa
OleDbConnection CANAL;
OleDbCommand ORDEN;
// Mandando la ORDEN
ORDEN.Connection.Open();
ORDEN.ExecuteNonQuery();
ORDEN.Connection.Close();
// Avisando
Nota: mo olvidar el using oldedb arriba y seguir estudiando y practicando su tutorial de SQL.
Y recordar que si usan TEXTBOX para el SET o el WHERE, deberan usar las variables parametros
(@TEXTBOX) y sus dos correspondientes orden.parameters
Corrida
TAREAS PROGRAMACION VISUAL C# 2005
1.- construir una tabla en access97 que traiga matricula, nombre, calif1, calif2, calif3 y promedio, cargar en
access unos 5 renglones de alumnos, no cargar promedio, el promedio lo deberan calcular en un programa.
Eliminacion es otro proceso simple y comun con las bases de datos el modelo con ADO NET que estamos
usando hace este tipo de operaciones muy faciles:
Programa
OleDbConnection CANAL;
OleDbCommand ORDEN;
ORDEN.Parameters["@CLAVE"].Value = CLAVE.Text;
ORDEN.Connection.Open();
ORDEN.ExecuteNonQuery();
ORDEN.Connection.Close();
// Avisando
Corrida
1.- Construir este proceso para las tablas y bases de datos que tengan del programa de menu.
En general se tiene otro problema de sql UPDATE (usando command por supuesto) con una serie de
textboxs arriba para capturar los nuevos datos.
Programa
OleDbConnection CANAL;
OleDbCommand ORDEN;
ORDEN.Parameters["@NOMBRE"].Value = NOMBRE.Text;
ORDEN.Parameters["@EDAD"].Value = EDAD.Text;
ORDEN.Connection.Open();
ORDEN.ExecuteNonQuery();
ORDEN.Connection.Close();
// Avisando edicion
}
Pantalla
Realmente este programa debe combinarse con el de busqueda por ejemplo en un panel buscar y desplegar
el registro y en otro panel este programa que hace la edicion.
Tambien se puede poner un boton que active el programa con la ventana de busqueda para que el usuario
vea el registro original y en un panel poner este codigo de edicion.
En ambos casos queda de tarea pero recordar que el menu que ya deben estar construyendo ya puede activar
la ventana de busqueda.
Un registro editado o modificado, analizar con cuidado el codigo del programa, que esta documentado,
suerte
1.- Construir el modulo o procedimeinto de edicion al sistema de menu que estan construyendo
Campos de graficos o de imagenes, se han convertido en elementos importantes de cualquier base de datos.
Para manejar este elemento con ado asp net existen dos maneras:
1.- Agregar un campo BLOB a la tabla en Access y usar componentes asp net especializados en imagenes
tanto para subirlas como para desplegar la imagen.
Este metodo provoca que la base de datos crezca mucho recordar que una imagen aun de tipo jpg ocupa
mucho espacio.
2.- El segundo metodo es mas sencillo primero poner las imagenes ( de preferencia jpg) en tu folder donde
esta la base de datos, despues agregar un objeto PictureBox en el programa y ademas agregar un campo de
texto llamado foto a la tabla en access y grabar el mombre de la imagen en este campo, por ejemplo pato.jpg
Usar el programa de busqueda normal ya visto y agregarle en tiempo real la propiedad apropiada al
componente PictureBox, como lo muestra el programa ejemplo.
Programa
OleDbConnection CANAL;
DataSet TABLA;
OleDbDataAdapter ORDEN;
ORDEN.SelectCommand.Parameters["@CLAVE"].Value = CLAVE.Text;
ORDEN.Fill(TABLA, "mitabla");
// Cargando el datagridVIEW
GRID1.DataSource = TABLA;
GRID1.DataMember = "mitabla";
// Cargando la imagen
corrida:
Recordar que para que no salga el campo foto en el datagridVIEW el select de sql puede pedirse como select
campo1,campo2, campo.. from mi tabla etcetera.
tan tan el curso se acabo y esten pendiente de los proximos de perl, visual basic 2005, javascript, php,
phyton, xml, et al
}
Leer y escribir en ficheros de texto
Publicado el 09/Ene/2007
Actualizado el 09/Ene/2007
Autor: Guillermo 'guille' Som
En este artículo te explico cómo leer y guardar cosas en ficheros de texto usando funciones y clases del propio .NET
Framework. Y como de costumbre, con código tanto para Visual Basic como para C#.
Introducción:
Una de las operaciones más comunes o al menos que se hacen con bastante frecuencia en cualquier aplicación
es la de leer y escribir en ficheros, particularmente de texto, es decir, ficheros normales y corrientes, sin
contenidos especiales.
Nota:
De cómo leer y escribir en ficheros que no sean "texto plano" nos ocuparemos en otra ocasión.
En este artículo veremos cómo realizar esas operaciones usando exclusivamente funciones y clases del
propio .NET Framework. Aclaro esto, porque en Visual Basic se pueden usar tanto las clases del propio .NET
como las definidas en la librería/espacio de nombres Microsoft.VisualBasic.
No te voy a explicar qué es eso de la codificación, ya que en la ayuda lo puedes leer, lo que te voy a decir
es que en .NET, de forma predeterminada, el formato o codificación usado para leer o escribir en los ficheros
es UTF-8.
Visual Basic:
Como puedes comprobar, lo único que necesitamos es crear un objeto del tipo StreamWriter (definido en el
espacio de nombres System.IO), pasarle al constructor el nombre del fichero en el que queremos guardar y
usar el método WriteLine al que le indicamos como argumento la cadena que queremos guardar.
Ahora vamos a leer de un fichero y asignaremos el contenido del mismo a una variable.
El código para Visual Basic y C# sería el siguiente:
Visual Basic:
Const fic As String = "E:\tmp\Prueba.txt"
Dim texto As String
Console.WriteLine(texto)
Console.WriteLine(texto);
En este caso también es muy simple, ya que solo necesitamos usar un objeto del tipo StreamReader,
(también definido en el espacio de nombres System.IO) al que le indicamos de que fichero queremos leer y
por medio del método ReadToEnd leemos todo el contenido, el cual asignamos a la variable que usemos en la
asignación.
En estos dos ejemplos al no indicar lo contrario estamos usando la codificación predeterminada, es decir, UTF-
8, por tanto, si escribimos primero en ese fichero y después lo leemos, el texto se mostrará correctamente, a
pesar de que en el primer ejemplo hayamos usado vocales acentuadas y eñes.
Además de que al usar la clase StreamWriter de esa forma, si había un fichero con ese mismo nombre, se
eliminará y se quedará el que acabamos de escribir, es decir, se sustituye el contenido del fichero.
Para conseguir esto lo único que tenemos que hacer es indicar en el constructor de la clase StreamWriter un
segundo argumento con un valor verdadero.
De esa forma, si el fichero existe, se añadirá el texto al final de lo que ya tuviera. Si el fichero no existe,
simplemente se creará y se guardará el texto actual, pero no dará error de que no existe.
Visual Basic:
C#:
Como ves lo único que hay que hacer es indicar como segundo argumento del constructor de la clase
StreamWriter un valor verdadero, y de esa forma le indicamos que queremos agregar el texto al fichero.
Si en vez de usar un valor verdadero, indicas un valor falso (false) el comportamiento será como el del primer
ejemplo, es decir, se sobrescribirá el fichero eliminando lo que antes hubiera.
Por ejemplo, si queremos leer ficheros escritos por otros programas que usan la codificación estándar de
Windows, por ejemplo los ficheros creados con Visual Basic 6.0, debemos indicar que NO queremos usar el
formato predeterminado, esto lo haremos de la siguiente forma:
Visual Basic:
Console.WriteLine(texto)
C#:
Console.WriteLine(texto);
En este caso lo único que debemos hacer es indicar en el constructor de la clase StreamReader un segundo
argumento que es la codificación que queremos usar, en este caso System.Text.Encoding.Default.
Para escribir en esa codificación (o en cualquier otra) tendremos que indicar la codificación a usar en el tercer
argumento del constructor de la clase StreamWriter, ya que en el segundo debemos indicar si queremos
agregar el texto a lo que ya tuviera o bien crear el fichero usando solo el contenido que queremos guardar.
En caso de que queramos crear un fichero con el contenido que tenemos en una variable, usaremos el
siguiente código:
Visual Basic:
C#:
Por supuesto, si lo que queremos hacer es agregar el texto al fichero, en vez de usar false en el segundo
argumento, debemos usar true.
Y si en vez de usar el valor "Default" queremos usar otro tipo de codificación, lo indicaremos en el tercer
argumento, seleccionando uno de los valores de la clase Encoding.
Debo aclarar que si usamos el valor UTF8, se guardará (o leerá) usando la codificación UTF-8, pero a la hora
de guardarlo, se indicará al principio del fichero que la codificación usada es UTF-8, esto es algo que no se
guarda cuando no indicamos la codificación. Es decir, se guarda en formato UTF-8, pero no se almacena nada
que indique que ese es el formato del fichero.
Esto es lo que se conoce como BOM (Byte Order Marks), que no es otra cosa que una marca al principio del
fichero en la que se indica la codificación usada. Las tres codificaciones que almacenan valores BOM son: UTF-
8, Unicode Little-Endian y Unicode Big-Endian, estos dos últimos pueden ser UTF-16 o UTF-32 (este último solo
en .NET Framework 2.0 o superior). Si quieres saber más sobre esto del BOM, puedes ver en la ayuda de
Visual Studio 2005 el método GetPreamble de la clase Encoding.
El siguiente código servirá para leer y guardar usando esa página de código:
Visual Basic:
Private Sub guardarTexto437()
Const fic As String = "E:\tmp\Prueba4.txt"
Dim texto As String = "Érase una vez una vieja con un moño..."
End Sub
Console.WriteLine(texto)
End Sub
C#:
System.IO.StreamWriter sw =
new System.IO.StreamWriter(fic, false, System.Text.Encoding.GetEncoding(437));
sw.WriteLine(texto);
sw.Close();
}
System.IO.StreamReader sr =
new System.IO.StreamReader(fic, System.Text.Encoding.GetEncoding(437), true);
texto = sr.ReadToEnd();
sr.Close();
Console.WriteLine(texto);
}
Recuerda que esa página de código (437) será válida para los ficheros creados con utilidades que trabajen con
el "viejo" MS-DOS o bien los que crees directamente usando una ventana de comandos de Windows.
Pero no será muy común que la uses... aunque si te hace falta, ya sabes cómo usarla.
Esto solo se puede hacer a la hora de leer el contenido del fichero, y será útil para los casos en los que no
sepamos con certeza el formato que se ha usado para guardar el fichero, de forma que si se ha usado uno de
los formatos que almacenan los valores en el BOM, se use ese formato, y si el fichero no tiene esa marca se
use la que nosotros indiquemos.
Visual Basic:
End Sub
Console.WriteLine(texto)
End Sub
C#:
System.IO.StreamWriter sw =
new System.IO.StreamWriter(fic, false, System.Text.Encoding.UTF8);
sw.WriteLine(texto);
sw.Close();
}
System.IO.StreamReader sr =
new System.IO.StreamReader(fic, System.Text.Encoding.Default, true);
texto = sr.ReadToEnd();
sr.Close();
Console.WriteLine(texto);
}
Para indicar que se use una codificación en concreto cuando no existe la marca BOM, debemos usar un valor
verdadero después de indicar la codificación que queremos usar.
En este ejemplo, se usará la codificación Default si no tiene esa marca.
En el método guardarTextoBOM, se guarda usando la codificación UTF8, de esa forma puedes comprobar
que aunque en leerTextoBOM se haya indicado Default, los caracteres "raros" se leerán correctamente, lo
que demuestra que se está usando la codificación correcta.
Si modificas el código del método leerTextoBOM para que no se detecte la codificación usada, (quitando el
tercer argumento del constructor de StreamReader), el texto se mostrará también correctamente, algo que
no ocurrirá si en lugar de guardarlo como UTF-8 lo hubiésemos guardado como Default y lo leyéramos como
UTF8, en ese caso, el texto mostrado sería el siguiente, que es lo que a algunos les ocurre cuando leen
ficheros de Visual Basic 6.0 sin indicar el valor Encoding.Default:
Bueno, pues esto es todo por ahora, espero que ahora tenga más claro cómo leer y guardar ficheros de texto
usando las clases de .NET.
En otra ocasión te explicaré cómo leer ficheros "binarios" y cómo convertir ristras de bytes en texto y
viceversa, pero eso será otro día, que ya es noche ;-)))
Nos vemos.
Guillermo
Referencias:
Utilizar codificación Unicode:
Ayuda de Visual Studio 2005 (en ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.es/)
Ayuda de Visual Studio 2005 en línea
Int32 i;
String celda;
DataGridViewCell dgc;
//Recorremos el DataGridView con un bucle for
for (i = 0; i < dataGridView1.Rows.Count; i++)
{
dgc = dataGridView1.Rows[i].Cells[0];
celda = ((String)dgc.Value) + "\r\n";
textBox1.Text += celda.Replace(".",",");
}
OTRO EJEMPLOS
Holas
Carlos Siches
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
public Form1()
InitializeComponent();
this.textBox1.Text = Convert.ToString(this.dataGridView1.CurrentRow.Cells[0].Value);
this.textBox2.Text = Convert.ToString(this.dataGridView1.CurrentRow.Cells[1].Value);
this.textBox3.Text = Convert.ToString(this.dataGridView1.CurrentRow.Cells[2].Value);
this.textBox4.Text = Convert.ToString(this.dataGridView1.CurrentRow.Cells[3].Value);
this.dataGridView1.Columns.Add("Columna1", "Columna1");
this.dataGridView1.Columns.Add("Columna2", "Columna2");
this.dataGridView1.Columns.Add("Columna3", "Columna3");
this.dataGridView1.Columns.Add("Columna4", "Columna4");
this.dataGridView1.RowCount = 2;
this.textBox1.Text = Convert.ToString(this.dataGridView1.CurrentRow.Cells[0].Value);
this.textBox2.Text = Convert.ToString(this.dataGridView1.CurrentRow.Cells[1].Value);
this.textBox3.Text = Convert.ToString(this.dataGridView1.CurrentRow.Cells[2].Value);
this.textBox4.Text = Convert.ToString(this.dataGridView1.CurrentRow.Cells[3].Value);
Holas
saludos
Carlos Siches
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
public Form1()
InitializeComponent();
this.textBox1.Text = Convert.ToString(this.dataGridView1.CurrentRow.Cells[0].Value);
this.textBox2.Text = Convert.ToString(this.dataGridView1.CurrentRow.Cells[1].Value);
this.textBox3.Text = Convert.ToString(this.dataGridView1.CurrentRow.Cells[2].Value);
this.textBox4.Text = Convert.ToString(this.dataGridView1.CurrentRow.Cells[3].Value);
this.dataGridView1.Columns.Add("Columna1", "Columna1");
this.dataGridView1.Columns.Add("Columna2", "Columna2");
this.dataGridView1.Columns.Add("Columna3", "Columna3");
this.dataGridView1.Columns.Add("Columna4", "Columna4");
this.dataGridView1.RowCount = 2;
this.dataGridView1.Rows[0].Cells[0].Value = "1eraFila 1eraColumna";
this.textBox1.Text = Convert.ToString(this.dataGridView1.CurrentRow.Cells[0].Value);
this.textBox2.Text = Convert.ToString(this.dataGridView1.CurrentRow.Cells[1].Value);
this.textBox3.Text = Convert.ToString(this.dataGridView1.CurrentRow.Cells[2].Value);
this.textBox4.Text = Convert.ToString(this.dataGridView1.CurrentRow.Cells[3].Value);
o Responder
o Citar
Holas
si la respuesta te resulta util marcala como pregunta contestada para hacer crecer el foro
gracias,
Saludos,
Carlos Siches
o Responder
o Citar
Hola !... como se haria para pasar datos de un datagridview a un texbox con solo seleccionarlo
en visual basic 2005 o 2003 ??? saludos.
o Responder
o Citar
Hola martin
textBox1.Text = Convert.ToString(Grid_Incidencias.CurrentRow.Cells[0].Value);
textBox2.Text = Convert.ToString(Grid_Incidencias.CurrentRow.Cells[1].Value);
NUMEROS ALEATORIOS
En estos ejemplos se muestran distintas formas de convertir una cadena en un valor int. Este tipo de conversión puede resultar
útil, por ejemplo, al obtener la entrada numérica de un argumento de línea de comandos. Existen métodos similares para
convertir las cadenas en otros tipos numéricos, como float o long. En la siguiente tabla se muestran algunos de esos
métodos.
Decimal ToDecimal(String)
Float ToSingle(String)
Doublé ToDouble(String)
Short ToInt16(String)
Long ToInt64(String)
Ushort ToUInt16(String)
Uint ToUInt32(String)
Ulong ToUInt64(String)
Ejemplo
Este ejemplo llama al método ToInt32(String) para convertir la cadena "29" en int. Después, suma 1 al resultado e imprime la
salida.
C#
Copiar código
int numVal = Convert.ToInt32("29");
numVal++;
Console.WriteLine(numVal);
// Output: 30
Otra forma de convertir string en int es mediante los métodos Parse o TryParse de la estructura System..::.Int32. El método
ToUInt32 utiliza Parse internamente. Si el formato de la cadena no es válido, Parse produce una excepción, mientras que
TryParse no produce ninguna excepción, pero devuelve false. En los siguientes ejemplos se muestran llamadas correctas e
incorrectas a Parse y TryParse.
C#
Copiar código
int numVal = Int32.Parse("-105");
Console.WriteLine(numVal);
// Output: -105
C#
Copiar código
int j;
Int32.TryParse("-105", out j);
Console.WriteLine(j);
// Output: -105
C#
Copiar código
try
{
int m = Int32.Parse("abc");
}
catch (FormatException e)
{
Console.WriteLine(e.Message);
}
// Output: Input string was not in a correct format.
C#
Copiar código
string inputString = "abc";
int numValue;
bool parsed = Int32.TryParse(inputString, out numValue);
if (!parsed)
Console.WriteLine("Int32.TryParse could not parse '{0}' to an int.\n",
inputString);
// Output: Int32.TryParse could not parse 'abc' to an int.
Procedimientos y Funciones
Procedimientos:
Funciones:
Sintaxis:
int mayor;
if (x==y)
return -1;
else
if (x>y)
return x;
else
return y;
public, es el nivel de acceso, indica que puede ser accedida desde cualquier scrip,
dentro o fuera del archivo donde se declaró.
int, es el valor que retornará la función, en este caso como es un numero el que
tiene que retornar, pero no siempre es así, algunas veces, hay funciones que piden
de argumento un string y retornan un bool u otro tipo de datos.
(int x, int y) son los argumentos de la función, los valores que necesita para operar,
en este caso son dos, siempre se separan con una coma y se debe de definir el
nombre y el tipo de datos.
Y dentro de esta función utiliza los argumentos que pide y realiza la comparación, lo
de adentro es un simple if...
Ojo, que existen tres lineas donde aparece return, pero solo uno se va a poder
ejecutar dentro del codigo ya que solo un caso se efectúa, si existieran dos return
que se ejecuten en el codigo daria un error, asi como en el caso de tener un solo
return y que este nunca se ejecutara.
Esta es la tercera página con equivalencias de las instrucciones entre los dos lenguajes más usados de .NET
Framework: Visual Basic para .NET y C#. En las páginas anteriores (primera y segunda) puedes encontrar más
equivalencias y algunas consideraciones que debes tener en cuenta a la hora de convertir código de Visual Basic a
C# o viceversa.
Visual Basic C#
En C# los valores de las opciones case deben ser valores constantes, no se permiten expresiones
ni variables, además de que solo se puede indicar un valor en cada "case", aunque se pueden
indicar varios case para contemplar más de un valor para ejecutar el código de un mismo bloque.
En Visual Basic se permiten expresiones y para ello existen instrucciones que podemos indicar en
cada bloque Case.
La condición, tanto en VB como en C#, puede ser una expresión.
Select Case <expresión con valor entero> switch (<expresión con valor entero>)
Case 1 {
'... case 1:
Case 2, 3, 4 //...
'... break;
Case Else case 2:
'... case 3:
End Select case 4:
//...
' También de esta forma break;
Select Case <expresión con valor entero> default:
Case 1 //...
'... break;
Case 2 To 4 }
'...
Case Else
'...
End Select
Además en Visual Basic se pueden usar varios valores en cada Case, separándolos con comas, y
esos valores pueden ser expresiones de cualquier tipo, además de poder usarse variables, etc., es
decir, cualquier cosa que produzca un valor del tipo esperado.
En Visual Basic, para indicar valores que requieran los operadores de comparación debemos usar
Is, por ejemplo, para indicar que el valor sea mayor que 7, lo haremos con: Case Is > 7.
Y si queremos que esté dentro de un rango de valores, podemos usar To, en el ejemplo anterior
hemos usado 2 To 4 para indicar los valores entre 2 y 4, pero también podemos combinar varias
expresiones, por ejemplo:
Case 2 To 4, 9 To 12, Is > 99, Is < 299
En este caso se tendrían en cuenta todos los valores posibles indicados en esas expresiones.
Como puedes comprobar, no podremos usar los operadores And, Or, etc., en su caso podemos
usar varios Is.
ATENCIÓN:
Si usas Is < 299 debes tener en cuenta que esa condición se evalúa de forma
independiente de las demás, por tanto el caso anterior, (si solo quieres valores hasta
299), lo puedes escribir solo con la última condición:
Case Is < 299
Ya que si no cumple ninguna de las anteriores, se evaluará esa, por tanto, si, por
ejemplo, el valor de la condición indicada en Select Case fuese 8, también se evaluaría,
ya que es menor de 299.
Pero el "problema" va a más y en el ejemplo Case 2 To 4, 9 To 12, Is > 99, Is < 299,
en realidad "capturará" cualquier valor, ya que si se cumple el Is > 99 también se
capturarán valores mayores de 298.
Por tanto, aunque en un Case puedas poner varias expresiones, debes ser consciente de
que es lo que "realmente" estás haciendo... y no "pensar" que es lo que
"supuestamente" estás haciendo.
Por último decir que como en Visual Basic los dos puntos se utilizan como separador de
instrucciones en una misma línea, podemos usar los dos puntos para separar instrucciones Case,
estén o no en la misma línea.
Case 2:
Case 3:
Case 2 : Case 3
Otra cosa a tener en cuenta (además de la advertencia anterior), es que cada sentencia Case
solo se evaluará después de las que haya antes.
Pero no nos complicaremos mucho, y solo veremos cómo convertir datos de diferentes tipos, y
compararemos cómo sería el equivalente en C#. Ya que en C# no existen instrucciones propias
para hacer las conversiones, por el contrario, todas las conversiones siempre se hacen de la
misma forma.
Todo esto suponiendo que no estamos usando los métodos de la clase Convert, ya que en ese
caso, las conversiones se hacen de la misma forma en ambos lenguajes.
Como ya he comentado, en Visual Basic usaremos instrucciones, cómo usar esas instrucciones, (y
que parámetros permiten), tendrás que buscarlo en la ayuda de Visual Studio, ya que aquí solo te
mostraré "la idea" de cómo usarlas.
Visual Basic C#
Aquí te muestro solo dos casos, pero para el resto sería lo mismo, las otras instrucciones de
conversión son:
CBool, CByte, CChar, CDate, CDec, CLng, CObj, CSByte, CShort, CSng, CStr, CUInt,
CULng, CUShort.
Algunas de estas, como CSByte y las tres últimas, solo están disponibles en Visual Basic 2005,
ya que sirven para convertir a tipos que se definen por primera vez en esa versión de Visual
Basic.
En todos los casos siempre puedes usar CType(<expresión>, <tipo>) para realizar la misma
conversión.
Y como has visto en el código de C#, en ese lenguaje siempre se usa de la misma forma:
(<tipo>)<expresión>, es decir, encerrando entre paréntesis el tipo y anteponiéndolo a la
expresión a convertir.
En Visual Basic, además de CType, también podemos usar, (al menos para convertir
expresiones a tipos por referencia), las instrucciones DirectCast y TryCast. Si sabemos que
estamos trabajando con tipos por referencia estas últimas son preferibles a CType, ya que
tienen mejor rendimiento.
DirectCast en realidad sirva para convertir cualquier tipo de datos, pero siempre que haya
alguna relación de herencia o de implementación de interfaces.
TryCast, (que está disponible en Visual Basic 2005 y posterior), se usa solo con tipos por
referencia, y se usa normalmente comprobando si el valor que devuelve no es nulo (Nothing).
Para que no haya comportamientos diferentes entre los dos lenguajes a la hora de hacer
conversiones, (ni redondeos "no deseados o controlados"), puedes usar las funciones de
conversión de la clase Convert, en el caso de convertir a un Integer (int en C#), tendrás que
usar Convert.ToInt32.
Con las conversiones de la clase Convert siempre se usa el redondeo bancario, se use desde
el lenguaje que se use.
Si te interesa que tu código de Visual Basic pueda convertirse fácilmente a C#, deberías evitar
el uso de parámetros opcionales con Optional. La solución es crear sobrecargas de los
métodos que reciban esos parámetros opcionales, que a la larga es casi lo mismo y así no
habrá conflictos entre los dos lenguajes.
Por ejemplo, si tienes este código de Visual Basic que usa Optional:
Como ves, cuando definimos un parámetro con Optional, ese parámetro debe tener un valor
predeterminado, que será el que se use cuando no se indique, y eso es lo que podemos hacer
al definir las sobrecargas: llamamos al método que recibe todos los parámetros, pero usando
los que debería tener si no se indican esos parámetros.
Si usamos parámetros opcionales, estos deben aparecer después de los que no son opcionales.
Lo que NO debes hacer es mezclar parámetros opcionales con sobrecargas, ya que en algunos
casos el propio compilador te indicará que algo anda mal en ese código porque hay conflictos,
ya que un parámetro Optional es opcional, pero también puede que se indique al llamar al
método, por tanto, en algunos casos no será opcional, sino que se usará.
Para definir un método que reciba un array de parámetros opcionales, en Visual Basic
usaremos la instrucción ParamArray, mientras que en C# usaremos params, en ambos
casos, después de esa instrucción hay que indicar un array del tipo de datos que queramos
usar internamente en el método.
En el siguiente código, los parámetros son de tipo entero y se devuelve la suma de todos ellos
como un valor de tipo Long.
En Visual Basic, podemos usar la instrucción ParamArray junto con Optional, es decir,
podemos declarar parámetros Optional y parámetros con ParamArray, pero este último debe
aparecer después de todos los Optional que tengamos.
Tanto en Visual Basic como en C#, el array de parámetros opcionales debe estar después de
los parámetros que no son opcionales.
6- Parámetros por valor y por referencia
Y ya que estamos con el tema de los parámetros, veamos cómo definir los parámetros por
valor y por referencia. Además de cómo usarlos.
Tanto en Visual Basic para .NET como en C#, de forma predeterminada, los parámetros son
por valor, es decir, se pasa como argumento una copia del valor del parámetro. En Visual
Basic, se puede usar la instrucción ByVal para indicar que el parámetro es por valor, de
hecho, el propio IDE de Visual Basic siempre añade esa instrucción si no indicamos nada.
Cuando nos interese que podamos modificar el valor de un parámetro, por ejemplo para
asignarle un nuevo valor, podemos usar los parámetros por referencia. En Visual Basic se
indican con la instrucción ByRef, y en C#, se pueden indicar de dos formas, usando ref o bien
usando out. La diferencia entre ref y out es que los argumentos pasados a parámetros ref
deben estar previamente iniciados, es decir, deben tener algún valor; mientras que los
parámetros out no es necesario que lo estén, y esa inicialización o asignación, hay que hacerla
en el propio método.
Nota:
No debemos confundir los parámetros por referencia con los tipos por
referencia, ya que un parámetro por referencia puede ser de un tipo por valor,
como Integer o Double.
De hecho, cuando usamos tipos por referencia, no es necesario usar la
instrucción ByRef para poder modificar el contenido de ese parámetro, ya que al
ser un tipo por referencia, lo que se pasa es precisamente una referencia a la
dirección de memoria en la que está dicho objeto, por tanto siempre tendremos
acceso al contenido.
Debido a la forma que Visual Basic trata las declaraciones de las variables, en teoría no se
podrían usar parámetros de tipo out, por tanto el equivalente más directo en C# es ref. Pero
ambos parámetros se pueden "simular" en Visual Basic por medio de ByRef.
A la hora de usar los métodos con parámetros por referencia, la diferencia entre los dos
lenguajes, es que en C# siempre tenemos que usar la instrucción out o ref que corresponda
con la definición del parámetro, mientras que en Visual Basic no se debe usar la instrucción
ByRef para usar un método que espere valores por referencia.
Veamos un método que recibe parámetros por valor y por referencia y cómo lo definiríamos en
los dos lenguajes:
Como ves, en Visual Basic no hace falta indicar si el argumento se pasa a un parámetro por
referencia o no, sin embargo en C# es obligatorio indicar si ese parámetro es ref, usando esa
misma instrucción, si no lo hacemos, el compilador nos avisará que debemos hacerlo.
RE: DataGrid C#
Hola
Siguiendo con el post anterior ahora veremos como podemos actualizar un datagridview y que este siempre
Para empezar agregaremos un nuevo item este sera un Windows Form como se muestra en la imagen.
Ahora agregaremos los siguiente:
un DataGridview y un boton el cual llevara como nombre btnActualizar, una vez que termines el diseño de tu
Aqui viene el codigo lo primero sera importar el namespace al principio del codigo que seria:
using.System.Data.SqlClient
Una vez que hemos importado el namespace declararemos dos variables privadas dentro de la clase form las
cuales seran:
La primer linea nos servira como enlace de los datos de la tabla con el datagridview
actualizar(string consulta) esto permite que pasemos una cadena para que nos devuelva un resultado.
nuestra BD
dataAdapter.Fill(tabla);
bindingsource1.DataSource = tabla;
Ahora vamos a asignarle a nuestro DataGridviewsu fuente de datos y llamar a la funcion actualizar con nuestro
parametro tal como se muestra en la imagen esto lo debemos realizar en el form load.
actualizar(dataAdapter.SelectCommand.CommandText);
su funcion es crear una consulta de seleccion es decir pasa el mismo parametro que pusimos en el Form Load
Con esto terminamos, solo resta abrir el form2 desde el form1 con ello agregaremos un nuevo boton en el form1
y pondremos:
form2.show();
}
label10.Text = a.ToString("N0");
tbFecha.Text = DateTime.Now.ToString("dd/MM/yyyy");
tbHora.Text = DateTime.Now.ToString("hh:mm:ss");
METODO PARA CERRAR UN FORM1 DEL FORM2
http://rapidshare.com/files/137821834/es_expression_studio_2_x86_dvd_x14-84217.part1.rar
http://rapidshare.com/files/137855981/es_expression_studio_2_x86_dvd_x14-84217.part2.rar
http://rapidshare.com/files/138256779/es_expression_studio_2_x86_dvd_x14-84217.part3.rar
http://rapidshare.com/files/138282864/es_expression_studio_2_x86_dvd_x14-84217.part4.rar
http://rapidshare.com/files/138266904/es_expression_studio_2_x86_dvd_x14-84217.part5.rar
http://rapidshare.com/files/138274252/es_expression_studio_2_x86_dvd_x14-84217.part6.rar
http://rapidshare.com/files/138275615/es_expression_studio_2_x86_dvd_x14-84217.part7.rar
Usar imágenes de una base de
SQL Server 2005
Introducción:
En este artículo te voy a explicar (de la forma más sencilla posible) cómo trabajar con imágenes para
guardarlas en una base de datos de SQL Server 2005.
Por supuesto también te explicaré cómo recuperar una imagen de la base de datos y mostrarla en un
control de tipoPictureBox.
Para este ejemplo, voy a usar una clase muy simple en la que tengo definido dos métodos
compartidos (o estáticos), uno de ellos te permitirá convertir una imagen en un array de
tipo Byte (¡espera! ¡no te desesperes! ahora te explico porqué convertir una imagen a un array de
bytes), y la otra para lo contrario, es decir, convertir un array de bytes en un objeto de tipo Image.
Lo de trabajar con un array de bytes es porque en realidad un campo de tipo image de SQL Server es
un array de bytes. Sabiendo esto, puedes adivinar que el primer método servirá para poder guardar
una imagen en el campo de la tabla y el segundo para leer el contenido de ese campo y poder usarlo
como una imagen normal.
Aquí tienes el código de esos dos métodos, tanto para Visual Basic como para C#. Estos dos métodos
están definidos en una clase llamada TablaNavegar y como ves son estáticos (compartidos), por
tanto para usarlos no es necesario crear una instancia de esa clase, sino que se usarán indicando el
nombre de la clase seguida del método a usar (en un momento te explico cómo usarlos).
El método Image2Bytes recibe como parámetro un objeto de tipo Image, crea un fichero temporal
y lo guarda como PNG, lee el contenido de ese fichero y lo asigna a un array de tipo Byte, para
finalmente devolver dicho array.
Por otro lado, el método Byte2Image recibe un array de bytes como parámetro, lo asigna a un
objeto del tipoMemoryStream y ese "stream" lo utiliza para crear un objeto del tipo Bitmap,
finalmente devuelve ese objeto que en el fondo es un objeto de tipo Image.
Como puedes comprobar la parte más simple es la de convertir el array de bytes en una imagen,
operación que puedes realizar en una sola pasada, al menos si no haces ningún tipo de comprobación
de error.
El primer caso, será para asignar a un campo de tipo image de una tabla de SQL Server el contenido
de un controlPictureBox. En el siguiente código, se supone que la variable dr es del tipo DataRow y
que el campo de la tabla en la que vamos a guardar la imagen se llama Foto, de igual forma el
control que tiene la imagen se llama FotoPictureBox.
dr("Foto") = TablaNavegar.Image2Bytes(Me.FotoPictureBox.Image)
dr["Foto"] = TablaNavegar.Image2Bytes(this.FotoPictureBox.Image);
Para asignar la imagen que está guardada en la base de datos al control FotoPictureBox lo haremos
de esta forma:
Por supuesto, esto también lo puedes hacer de una pasada, al menos si no quieres comprobar si el
objeto leído de la base de datos no es un valor nulo ni el resultado devuelto por la función tampoco lo
es.
Y esto es todo.
En el ZIP con el código tienes un proyecto de prueba tanto para Visual Basic como para C# (para
usar con la versión 2005 de Visual Studio o con las versiones Express) en el que se usa la
clase TablaNavegar y en el que se accede a una base de datos de SQL Server que está en la
instancia de SQLEXPRESS. Esa base de datos se llama conImagenes y la tabla se llama conFotos.
Campo Tipo
ID int
Nombre nvarchar(255)
Foto image
El campo ID es un campo de identidad (auto incremental), mejor será que te lo muestre. En la figura
1 puedes ver la estructura de la tabla.
En el ZIP incluyo una copia de seguridad de la base de datos de prueba, para restaurar esa base de
datos puedes leer lo que hace un rato publiqué, tal como está el código la instancia de SQL Server
debe ser SQLEXPRESS, pero si la restauras en la instancia predeterminada de SQL Server tendrás que
cambiar la cadena de conexión usada para acceder a la base de datos.
Sólo decirte que esa base de datos la tengo en el directorio: C:\Archivos de programa\Microsoft
SQL Server\MSSQL.1\MSSQL\Data, por tanto si te da error al restaurarla, tendrás que cambiar la
ubicación, pero eso ya te lo explico en el artículo del link anterior.
VALIDAR UN TEXBOOK
if (!DIR.Exists)
{
DIR.Create();
}
VB
C#
// This example demonstrates the String.Remove() method.
using System;
class Sample
{
public static void Main()
{
string s = "abc---def";
//
Console.WriteLine("Index: 012345678");
Console.WriteLine("1) {0}", s);
Console.WriteLine("2) {0}", s.Remove(3));
Console.WriteLine("3) {0}", s.Remove(3, 3));
}
}
/*
This example produces the following results:
Index: 012345678
1) abc---def
2) abc
3) abcdef
*/
Para cambiar las letras en una cadena a mayúsculas o minúsculas, se utiliza ToUpper() o ToLower(), de la siguiente
forma:
VB
C#
C++
F#
JScript
Copiar
string s6 = "Battle of Hastings, 1066";
oleConn.Close();
using System.Data.OleDb;
private void button1_Click(object sender, EventArgs e)
{
string strConnnectionOle = @"Provider=Microsoft.Jet.OLEDB.4.0;" +
@"Data Source=C:\libro1.xls;" +
@"Extended Properties=" + '"' + "Excel 8.0;HDR=YES" + '"';
OleDbConnection oleConn = new OleDbConnection(strConnnectionOle);
oleConn.Open();
OleDbDataAdapter orden;
DataSet tabla;
Por otra pregunta que he recibido, la última cosa que quería comentar sobre el tema de Excel es que
puede utilizar SqlBulkCopy para la transferencia de datos de Excel de hoja de cálculo a altas
velocidades a un SQL Server base de datos de la tabla. Hablé de SqlBulkCopy en un anterior ADO.NET
Tutorial:
SqlBulkCopy - Copiar la tabla de datos entre servidores SQL a altas velocidades - ADO.NET 2.0
Nuevas Características
Usted puede ver mis otros mensajes en Excel para obtener más información sobre el uso de ADO.NET
para leer y escribir en un libro de Excel y hojas de cálculo:
La lectura de información de esquema de hoja de cálculo Excel y la columna con ADO.NET 2.0 y
GetSchema
Leer y escribir hojas de cálculo Excel / Hojas de ADO.NET mediante C # DbProviderFactory
Uso de SqlBulkCopy para importar hoja de cálculo Excel de datos en SQL Server
Vamos a tomar un libro de Excel con una hoja de cálculo, llamada de datos, que contiene 1.000
registros de datos sin sentido dividida en dos columnas, de identificación y de datos.
Quiero copiar estos datos en una tabla de base de datos SQL Server, llamado Exceldata, con el
mismo esquema.
Sólo un poco de las transferencias de codificar los datos de la hoja de cálculo Excel en el cuadro de
base de datos de SQL Server:
para esto tiene que agregar la referencia "Microsoft Excel 12.0 Object Library"
excel.Application.Workbooks.Add(true);
int ColumnIndex = 0;
ColumnIndex++;
int rowIndex = 0;
foreach (DataGridViewRow row in TuDataGrid.Rows )
rowIndex++;
ColumnIndex = 0;
ColumnIndex++;
excel.Visible = true;
worksheet.Activate();
En este artículo se describe cómo puede utilizar ADO.NET para recuperar datos de un libro de Microsoft Excel, modificar
datos en un libro existente o agregar datos a un nuevo libro. Para tener acceso a libros de Excel con ADO.NET, puede
utilizar el proveedor OLE DB de Jet; este artículo proporciona la información que necesita por lo que puede utilizar el
Volver al principio
Excel a través de los controladores instalables de método de acceso secuencial indizado (ISAM). Para abrir formatos
externos admitidos por el proveedor OLE DB de Microsoft Jet 4.0, especificar el tipo de base de datos en las propiedades
extendidas para la conexión. El proveedor OLE DB de Jet admite los siguientes tipos de base de datos para libros de
Microsoft Excel:
Excel 3.0
Excel 4.0
Excel 5.0
Excel 8.0
Nota : utilizar el tipo de base de datos de origen de Excel 5.0 para libros de Microsoft Excel 5.0 y 7.0 (95) y utilizar el
tipo de base de datos de origen de Excel 8.0 para Microsoft Excel 8.0 (97), 9.0 (2000) y 10.0 (2002) libros. Los ejemplos
en este artículo utilizan los libros de Excel en el formato de Excel 2000 y Excel 2002.
Cadena de conexión
Para obtener acceso a un libro de Excel mediante el proveedor OLE DB de Jet, usar una cadena de conexión que tiene la
siguiente sintaxis:
Provider = Microsoft. Jet. OleDb. 4. 0; Data Source=C:\Book1.xls;Extended propiedades = "Excel 8.0; HDR = YES;"
En la cadena de conexión, especifique el nombre completo de ruta de acceso y para el libro en el parámetro Data
Source . El parámetro Propiedades extendidas puede contener dos propiedades: una propiedad para el ISAM de versión y
Con los libros de Excel, la primera fila de un rango es la fila de encabezado (o nombres de campo) de forma
predeterminada. Si el primer rango no contiene encabezados, puede especificar HDR = NO en las propiedades
extendidas de la cadena de conexión. Si especifica HDR = NO en la cadena de conexión, el proveedor OLE DB de Jet
automáticamente los nombres de los campos para usted (F1 representa el primer campo, F2 representa el segundo
campo etc.).
Tipos de datos
A diferencia de una base de datos tradicional, no hay ninguna forma directa de especificar los tipos de datos para las
columnas en tablas. En su lugar, el proveedor OLE DB examina ocho filas en una columna para estimar los datos de tipo
del campo. Puede cambiar el número de filas para explorar especificando un valor entre uno (1) y dieciséis (16) para el
Utilice el nombre hoja seguido por un signo de dólar (por ejemplo, [Hoja1 $] o [mi hoja de cálculo $]). Una tabla
de libro que se hace referencia de esta manera incluye el rango completo utilizado de la hoja de cálculo.
Utilizar un rango con una dirección específica (por ejemplo, [Hoja1 $ A1: B10]):
Nota : el signo de dólar sigue al nombre de hoja de cálculo es una indicación de que existe la tabla. Si está creando una
nueva tabla, como se describe en el Create New Workbooks and Tablessección de este artículo, no utilice el signo de
dólar.
Volver al principio
Recuperar registros
Puede recuperar registros de una base de datos utilizando uno de estos dos enfoques de ADO.NET: con un conjunto de
Un conjunto de datos es una caché de registros recuperados de un origen de datos. Los datos en el conjunto de
datos normalmente están una versión muy reducida de lo que está en la base de datos. Sin embargo, puede trabajar
con él de la misma forma que trabaja con los datos reales y permanece desconectado de la base de datos real. Además
de recuperación de datos, también puede utilizar un conjunto de datos para realizar operaciones de actualización en la
Como alternativa, puede utilizar un DataReader para recuperar una secuencia de sólo avance de sólo lectura de datos
de una base de datos. Cuando utiliza el programa de DataReader , el aumento del rendimiento y es la sobrecarga del
sistema disminuye porque nunca en memoria sólo una fila a la vez. Si tiene una gran cantidad de datos que se van a
recuperar y no desea realizar cambios en la base de datos subyacente, un DataReader es una opción mejor que
un conjunto de datos .
Ejecutar directamente un comando para insertar o actualizar los registros de uno a la vez. Para ello, puede crear
Realizar cambios en un DataSet que se han rellenado con una tabla o consulta desde un libro de Excel y que se
a continuación, llame al método Update del DataAdapter para resolver los cambios de DataSet volver al libro.
Sin embargo, utilizar el método Updatepara comandos de resolución de cambio se debe establecer
y UpdateCommand :
información de clave o índice de libros de Excel; sin campos de clave o índice CommandBuilder no puede
Exportar datos de datos de otro origen en un libro de Excel siempre que otro origen de datos puede utilizarse
con el proveedor OLE DB de Jet. Datos de orígenes que puede utilizar con el proveedor Jet OLE DB de esta
manera incluyen archivos de texto, bases de datos de Microsoft Access y, por supuesto, otros libros de Excel.
Con un solo comando INSERT INTO, puede exportar datos desde otra tabla o consulta en el libro:
INSERT INTO requiere que la tabla de destino (o la hoja de cálculo) ya existe; datos se anexan a la tabla de
destino.
al utilizar SELECTINTO, si el libro o tabla de destino no existe, se creará para usted. Si la tabla ya existe antes
El Sample Code de la sección más adelante en este artículo muestra cada uno de estos métodos para agregar y
Eliminar registros
Aunque el proveedor Jet OLE DB permite insertar y actualizar registros en un libro de Excel, no permite las operaciones
DELETE. Si intenta realizar una operación DELETE en uno o más registros, recibirá el siguiente mensaje de error:
Esta limitación es inherente en el tratamiento de los libros de Excel como bases de datos.
Para crear una tabla en un libro de Excel, ejecute CREATE TABLE comando:
La sección Sample Code muestra cómo puede utilizar el comando CREATE TABLE para crear un nuevo libro y la tabla.
Volver al principio
Paso a paso
Código de ejemplo
3. Seleccione todos los controles RadioButton y establezca la propiedad Size para 200,24 .
Imports System.Data.OleDb
6. Inserte el código siguiente en la clase Form :
7. Private m_sConn1 As String = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
8. "Data Source=C:\ExcelData1.xls;" & _
9. "Extended Properties=""Excel 8.0;HDR=YES"""
10.
19.
Handles MyBase.Load
21. RadioButton1.Text = "Create_Workbook"
22. RadioButton2.Text = "Retrieve_Records"
23. RadioButton3.Text = "Add_Records"
24. RadioButton4.Text = "Update_Records"
25. RadioButton5.Text = "Update_Individual_Cells"
26. RadioButton6.Text = "Use_External_Source"
27. Button1.Text = "Go!"
28. End Sub
29.
35.
Handles Button1.Click
37. Try
38. ' Call the associated routine to add/update/modify the workbook.
39. Select Case m_sAction
40. Case "Create_Workbook" : Create_Workbook()
41. Case "Retrieve_Records" : Retrieve_Records()
42. Case "Add_Records" : Add_Records()
43. Case "Update_Records" : Update_Records()
44. Case "Update_Individual_Cells" : Update_Individual_Cells()
45. Case "Use_External_Source" : Use_External_Source()
46. End Select
47.
57.
59.
61.
75. '==========================================================================
76. ' Create a workbook with a table named EmployeeData. The table has 3
77. ' fields: ID (char 255), Name (char 255) and Birthdate (date).
78. '==========================================================================
90. '==========================================================================
91. ' Create a workbook with a table named InventoryData. The table has 3
92. ' fields: Product (char 255), Qty (float) and Price (currency).
93. '==========================================================================
94.
107. ' NOTE: You can ALTER and DROP tables in a similar fashion.
108.
113. '==========================================================
114. 'Use a DataReader to read data from the EmployeeData table.
115. '==========================================================
116.
131. '========================================================
132. 'Use a DataSet to read data from the InventoryData table.
133. '========================================================
134. Dim conn2 As New OleDbConnection(m_sConn2)
135. Dim da As New OleDbDataAdapter("Select * From [InventoryData$]", conn2)
136. Dim ds As DataSet = New DataSet()
137. da.Fill(ds)
138. Debug.WriteLine(vbCrLf & "InventoryData:" & vbCrLf & "==============")
139. Dim dr As DataRow
140. For Each dr In ds.Tables(0).Rows'Show results in output window
141. Debug.WriteLine(System.String.Format("{0,-15}{1, -6}{2}", _
142. dr("Product"), dr("Qty"), dr("Price")))
143. Next
144. conn2.Close()
145.
150. '==========================================================================
151. ' Run an INSERT INTO command to add new records to the workbook.
152. '==========================================================================
153. Dim conn1 As New System.Data.OleDb.OleDbConnection(m_sConn1)
154. conn1.Open()
155. Dim cmd As New System.Data.OleDb.OleDbCommand()
156. cmd.Connection = conn1
157. cmd.CommandText = "INSERT INTO [EmployeeData$] (ID, Name, BirthDate) values
('CCC', 'Charlie', '10/14/48')"
158. cmd.ExecuteNonQuery()
159. cmd.CommandText = "INSERT INTO [EmployeeData$] (ID, Name, BirthDate) values
('DDD', 'Deloris', '7/19/98')"
160. cmd.ExecuteNonQuery()
161. conn1.Close()
162.
163. '====================================================================
164. 'Use the InsertCommand object to add new records to the InventoryData
165. 'table.
166. '====================================================================
167. Dim conn2 As New OleDbConnection(m_sConn2)
168. Dim da As New OleDbDataAdapter("Select * From [InventoryData$]", conn2)
169. Dim ds As DataSet = New DataSet()
170. da.Fill(ds, "MyExcelTable")
171.
172. ' Generate the InsertCommand and add the parameters for the command.
173. da.InsertCommand = New OleDbCommand( _
174. "INSERT INTO [InventoryData$] (Product, Qty, Price) VALUES (?, ?, ?)", conn2)
175. da.InsertCommand.Parameters.Add("@Product", OleDbType.VarChar, 255, "Product")
176. da.InsertCommand.Parameters.Add("@Qty", OleDbType.Double).SourceColumn = "Qty"
177. da.InsertCommand.Parameters.Add("@Price", OleDbType.Currency).SourceColumn =
"Price"
178.
186. ' Apply the dataset changes to the actual data source (the workbook).
187. da.Update(ds, "MyExcelTable")
188. conn2.Close()
189.
194. '==========================================================================
195. ' Run an UPDATE command to change a record in the EmployeeData
196. ' table.
197. '==========================================================================
198. Dim conn1 As New System.Data.OleDb.OleDbConnection(m_sConn1)
199. conn1.Open()
200. Dim cmd As New System.Data.OleDb.OleDbCommand()
201. cmd.Connection = conn1
202. cmd.CommandText = "UPDATE [EmployeeData$] " & _
203. "SET NAME = 'Aaron', BirthDate = '5/4/1975' WHERE ID = 'AAA'"
204. cmd.ExecuteNonQuery()
205. conn1.Close()
206.
207. '====================================================================
208. ' Use the UpdateCommand object to modify records in the InventoryData
209. ' table.
210. '====================================================================
211. Dim conn2 As New OleDbConnection(m_sConn2)
212. Dim da As New OleDbDataAdapter("Select * From [InventoryData$]", conn2)
213. Dim ds As DataSet = New DataSet()
214. da.Fill(ds, "MyInventoryTable")
215.
216. ' Generate the UpdateCommand and add the parameters for the command.
217. da.UpdateCommand = New OleDbCommand( _
218. "UPDATE [InventoryData$] SET Qty = ?, Price=? WHERE Product = ?", conn2)
219. da.UpdateCommand.Parameters.Add("@Qty", OleDbType.Numeric).SourceColumn = "Qty"
220. da.UpdateCommand.Parameters.Add("@Price", OleDbType.Currency).SourceColumn =
"Price"
221. da.UpdateCommand.Parameters.Add("@Product", OleDbType.VarChar, 255, "Product")
222.
229. ' Apply the dataset changes to the actual data source (the workbook).
230. da.Update(ds, "MyInventoryTable")
231. conn2.Close()
232.
237. '==========================================================================
238. ' Update individual cells on the EmployeeData worksheet;
239. ' specifically, cells F3, G3, and I4 are modified.
240. '==========================================================================
241.
242. ' NOTE: The connection string indicates that the table does *NOT*
243. ' have a header row.
244. Dim conn As New System.Data.OleDb.OleDbConnection(m_sConn1.Replace("HDR=YES",
"HDR=NO"))
245. conn.Open()
246. Dim cmd As New System.Data.OleDb.OleDbCommand()
247. cmd.Connection = conn
248. cmd.CommandText = "UPDATE [EmployeeData$F3:G3] SET F1 = 'Cell F3', F2 = 'Cell
G3'"
249. cmd.ExecuteNonQuery()
250. cmd.CommandText = "UPDATE [EmployeeData$I4:I4] SET F1 = 'Cell I4'"
251. cmd.ExecuteNonQuery()
252. conn.Close()
253.
265. '=======================================================================
266. ' Run an INSERT..INTO command on the Northwind database to append
267. ' the records from a table/query to an existing table in the Excel
268. ' workbook.
269. '=======================================================================
270. cmd.CommandText = "INSERT INTO [EmployeeData$] IN 'C:\ExcelData1.xls' 'Excel
8.0;'" & _
271. "SELECT EmployeeID AS ID, FirstName AS Name, BirthDate FROM Employees"
272. cmd.ExecuteNonQuery()
273.
274. '==========================================================================
275. ' Run a SELECT..INTO command on the Northwind database to insert
276. ' all the records from a table/query into a new sheet in the Excel
277. ' workbook.
278. '==========================================================================
279. cmd.CommandText = "SELECT * INTO [Excel 8.0;Database=C:\ExcelData2.xls].
[ProductSales]" & _
280. "FROM [Product Sales for 1997]"
281. cmd.ExecuteNonQuery()
282.
283. conn.Close()
284.
End Sub
285. Modificar la ruta de acceso a la base de datos de Access de ejemplo, Neptuno, del miembro
Pruébelo
1. En el menú Ver , elija Otras ventanas y, a continuación, haga clic en resultados para mostrar la
ventana resultados .
CREATE TABLE para crear dos nuevos libros: C:\ExcelData1.xls y C:\ExcelData2.xls. ExcelData1.xls contiene una
hoja (tabla) denominado EmployeeData y ExcelData2.xls contiene una hoja (tabla) denominada InventoryData.
Nota : en cada paso restante en esta prueba, abra los libros en Excel para examinar los resultados. O bien,
haga clic en Retrieve_Records para ver el contenido de las tablas en la salida ventana de Visual Studio.NET.
5. EmployeeData:
6. =============
7. AAA Andrew 12/4/1955
8.
9. InventoryData:
10. ==============
13. EmployeeData:
14. =============
19. InventoryData:
20. ==============
libro:
25. EmployeeData:
26. =============
31. InventoryData:
32. ==============
específicas de la hoja de cálculo EmployeeData ExcelData1.xls; específicamente, se actualizan las celdas F3, G3
y I4.
37. Haga clic en Use_External_Source y haga clic en Ir . Cuando se utiliza una instrucción INSERTINTO comando,
la rutina Use_External_Source anexa los registros de la tabla Northwind 'Empleados' en la hoja de cálculo
EmployeeData ExcelData1.xls. YUse_External_Source utiliza una instrucción SELECTINTO comando para crear
una nueva tabla (o la hoja) en ExcelData2.xls que contiene todos los registros de la tabla Northwind 'Productos'.
Nota : si hace clic en Use_External_Source más de una vez, la lista de empleados se anexará varias veces
Volver al principio
Formato de celda
Si utiliza ADO.NET para agregar o actualizar registros en un libro existente, puede aplicar formato al libro que se utilizará
con los registros nuevos o actualizados de la celda. Cuando se actualiza un registro existente (o fila) en un libro, el
formato de celda se mantiene. Y cuando se inserta un nuevo registro (o fila) en un libro, el nuevo registro hereda el
El siguiente procedimiento muestra cómo puede utilizar el formato en un libro con el código de ejemplo:
9. Abra C:\ExcelData1.xls en Excel y observe que las dos nuevas filas han heredado el formato de la primera fila.
Volver al principio
Limitaciones
Los siguientes son algunas limitaciones del proveedor Jet OLE DB con respecto a orígenes de datos de Excel:
El proveedor OLE DB de Jet es incapaz de proporcionar información de clave o índice para las tablas de un libro
de Excel. Por este motivo, no puede utilizar CommandBuilder para generar automáticamente las actualizaciones
Volver al principio
To always use IMEX=1 is a safer way to retrieve data for mixed data columns. Consider the scenario that one Excel file might work fine
cause that file's data causes the driver to guess one data type while another file, containing other data, causes the driver to guess
another data type. This can cause your app to crash.
Xlsb files
This one is for connecting to Excel 2007 files with the Xlsb file extension. That is the Office Open XML format saved in a binary format. I
e the structure is similar but it's not saved in a text readable format as the Xlsx files and can improve performance if the file contains a
lot of data.
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\myFolder\myBinaryExcel2007file.xlsb;Extended
Properties="Excel 12.0;HDR=YES";
You can also use this connection string to connect to older 97-2003 Excel workbooks.
"HDR=Yes;" indicates that the first row contains columnnames, not data. "HDR=No;" indicates the opposite.
Xlsm files
This one is for connecting to Excel 2007 files with the Xlsm file extension. That is the Office Open XML format with macros enabled.
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\myFolder\myExcel2007file.xlsm;Extended
Properties="Excel 12.0 Macro;HDR=YES";
Important note!
The quota " in the string needs to be escaped using your language specific escape syntax.
c#, c++ \"
VB6, VBScript ""
xml (web.config etc) "
or maybe use a single quota '.
"HDR=Yes;" indicates that the first row contains columnnames, not data. "HDR=No;" indicates the opposite.
http://www.megaupload.com/?d=1UPQ2DXO
Las empresas de hoy se enfrentan a varios desafíos de información inéditos: la proliferación de sistemas y datos en
el seno de sus empresas; la necesidad de proporcionar a sus empleados, clientes y partners acceso coherente a
dichos datos; el deseo de ofrecer información plena de sentido a quienes trabajan con ésta para que
puedan tomar decisiones fundamentadas y el imperativo de controlar los costes sin sacrificar por ello la disponibilidad
de las aplicaciones, la seguridad o la fiabilidad.
SQL Server 2005 ha sido diseñado para ayudar a las empresas a enfrentarse a estos retos. SQL Server 2005 es la
solución de gestión de la información de Microsoft que procura mayor escalabilidad, disponibilidad y seguridad a la
información empresarial y las aplicaciones de análisis al tiempo que simplifica su creación, implantación y gestión.
1era parte
http://www.megaupload.com/?d=S20UNCF9
2da parte
http://www.megaupload.com/?d=F1YM3OL7
Introducción
Este artículo en realidad consta de varias partes, aunque todas esas partes formarán un todo, y ese
todo es un ejemplo muy básico (o elemental) de cómo acceder a una base de datos de tipo SQL
Server usando ADO.NET y Visual Basic, (cualquier versión, ya sea la 1.x o la 2.0), permitiendo
navegar entre los registros, añadir nuevos datos, modificar o borrar los existentes.
También veremos cómo saber las instancias de SQL Server que hay instaladas en el equipo, las cuales
se mostrarán en un combo; al seleccionar la instancia, veremos cómo mostrar las bases de datos que
tiene esa instancia, (excepto las del sistema o propias de SQL), las cuales estarán en otro combo.
Si la tabla de prueba no existe en la base de datos seleccionada, tendremos la posibilidad de crearla.
Espero que te sea de utilidad y que esté más claro y menos "liante" que el otro ejemplo que ya tenía
publicado.
Nota:
A lo largo de este artículo, te muestro el código de Visual C#, pulsa este link si quieres ver el
artículo con el código de ejemplo para Visual Basic.
Al final tienes el link al zip con el código de ejemplo para Visual C#, el cual es válido tanto para las
versiones 2003 y 2005.
Nos vemos
Guillermo
P.S.
Pulsa aquí para ver un ejemplo parecido para una base de datos de tipo Access con OleDb.
Como vemos, este formulario utiliza los campos que tiene la tabla que vamos a usar, por tanto, si vas
a usar otra tabla diferente a la usada en el ejemplo, tendrás que crear tu propio diseño del formulario.
En el código he intentado separar el código que depende de los campos, de forma que te resulte fácil
de modificar.
Empezando por arriba, tenemos un ComboBox (cboInstancias) en el que mostraremos las instancias
de SQL Server que hay instaladas en el equipo. Pulsa aquí si quieres saber cómo averiguar las
instancias de SQL Server que hay en el equipo usando código de Visual C#.
A la derecha, tenemos otro ComboBox (cboBases) en el que mostraremos las bases de datos que
tiene la instancia de SQL Server que hayamos seleccionado del primer combo. Pulsa aquí para saber
cómo averiguar las bases de datos que contiene una instancia de SQL Server usando código de Visual
C#.
El botón que está en la parte derecha, (btnConectar), (en la misma fila que los dos combos) nos
servirá para conectarnos a la base de datos y a la instancia seleccionadas usando autenticación de
Windows.
En ese botón se crea la conexión a la base de datos y se asigna el DataAdapter que usaremos para
conectar directamente con la base de datos. Por tanto será en el código de ese botón donde tendrás
que escribir todo lo necesario para realizar la conexión, cargar los datos en la tabla (DataTable) y
empezar a mostrar los datos.
Al pulsar en el botón de conectar, el código comprueba si la tabla de pruebas existe, de no ser así,
nos preguntará si la queremos crear.
En el GroupBox tenemos los controles para mostrar los datos, navegar entre las filas, actualizar, crear
y eliminar registros.
Los botones de navegación (o movimiento) nos servirán para ir a los distintos registros: Primero,
anterior, siguiente y último.
El botón de Actualizar lo usaremos para actualizar los datos del registro actual.
El botón Nuevo lo usaremos para añadir un nuevo registro. Cuando pulsamos en ese botón, se
usarán los datos que actualmente tengamos en las cajas de textos, salvo el ID, ya que en la tabla de
ejemplo es autonumérico, y por tanto se crea solo.
El botón de Eliminar lo usaremos para eliminar el registro que esté actualmente activo. Cuando se
elimina el registro, los datos permanecen en los controles, por si queremos volver a crearlo,
(pulsando en el botón Nuevo), aunque el ID usado será diferente al mostrado, ya que al crear un
nuevo registro (o fila) el valor del campo ID se genera automáticamente.
Nota IMPORTANTE:
Las tres operaciones indicadas se hacen directamente en la base de datos, es decir, no
trabajamos en modo desconectado, sino que cualquier cambio se reflejará inmediatamente en
la base de datos.
En este evento utilizamos una función llamada instanciasInstaladas, esa es la que nos indica las
instancias de SQL Server que tenemos instaladas en nuestro equipo y si quieres ver el código puedes
hacerlo desde este link.
En este mismo evento y en el correspondiente al cambio de selección del combo de las instancias,
también usamos una función (basesDeDatos), que recibe como parámetro el nombre de la instancia
seleccionada, para saber las bases de datos que tiene la instancia de SQL Server que hemos
seleccionado, el código de esa función lo puedes ver siguiendo este link.
Como te he comentado antes, cuando seleccionamos una de las instancias del combo con los
servidores (o instancias) de SQL Server, asignamos en el combo de las bases de datos, las que esa
instancia contiene.
El código del evento SelectedIndexChanged es el siguiente, en el que comprobamos si hay alguna
base de datos (la función que comprueba las bases que hay en la instancia indicada,
devuelve Nothing si solo están las bases del propio SQL Server), las agregamos al combo y
seleccionamos el primer elemento.
En el siguiente código comprobamos también si la tabla que usaremos existe en la base de datos
seleccionada, para ello usaremos la función existeTabla a la que le pasaremos el objeto conexión
que hemos creado y el nombre de la tabla que queremos comprobar si existe o no, que en nuestro
ejemplo se llama Prueba.
Nota:
En realidad el objeto SqlConnection no hace falta para rellenar los datos por medio
del DataAdapter, pero si lo necesitamos para comprobar si la tabla existe.
Una vez que tenemos la conexión creada y que sabemos que la tabla existe, crearemos los objetos
que nos permitirán acceder a la base de datos (mediante un objeto del tipo SqlDataAdapter), y
llenaremos el objeto DataTable con los datos que hayamos indicado en la cadena de selección.
Crearemos los comandos que necesitaremos para actualizar los datos en la base de datos
(UPDATE, INSERT y DELETE). Esos comandos los creamos con un objeto del
tipo SqlCommandBuilder que aunque no es la forma más efectiva, al menos es la más fácil de usar,
y como de lo que en este artículo se trata es que sea fácil, pues eso... Los comandos los asignaremos
a los objetos correspondientes del adaptador, esto en realidad no es necesario, pero algunas veces
me ha dado error al no hacerlo, así que... ¡mejor estar seguros de que se asignan!.
Debido a que la tabla de ejemplo utiliza un campo autoincremental, tendremos que asignar a la
propiedad MissingSchemaAction el valor AddWithKey, de esta forma, al añadir nuevos registros
se incrementará el valor del ID.
En la tabla de ejemplo, estamos usando un campo que contiene caracteres que pueden ser
conflictivos, en este caso es simplemente un guión, pero podría ser una vocal acentuada, una eñe o
contener espacios, en este caso lo que hacemos es indicar en el objeto del
tipo CommandBuilder que utilice prefijo y sufijo para "envolver" automáticamente esos campos
conflictivos, esa indicación la hacemos mediante las propiedades QuotePrefix y QuoteSufix.
Por último creamos el nuevo objeto del tipo DataTable, que será el que usemos con el
método Fill del adaptador, al usar ese método, será cuando se conecte con la base de datos y asigne
a la tabla los datos indicados en la cadena de selección (SELECT).
En este ejemplo, le indico que traiga todos los datos, pero también podría haber seleccionado con una
cláusula WHERE otros diferentes.
Finalmente habilitamos nuevamente los controles que están en el GroupBox para que podamos
navegar, añadir, eliminar, actualizar y escribir en las cajas de texto, y mostraremos el primer registro,
para ello llamamos al código del evento del botón para mostrar el primer registro.
Si no hay datos, (es decir, si la tabla no contiene alguna fila), deshabilitamos el botón de actualizar y
el de eliminar, para permitir solo añadir nuevos datos.
// La cadena de selección
string sSel = "SELECT * FROM Prueba ORDER BY ID";
//
// Comprobar si hay algún error
try{
// Crear un nuevo objeto del tipo DataAdapter
da = new SqlDataAdapter(sSel, sCnn);
// Crear los comandos de insertar, actualizar y eliminar
SqlCommandBuilder cb = new SqlCommandBuilder(da);
// Como hay campos con caracteres especiales,
// al usarlos incluirlos entre corchetes.
cb.QuotePrefix = "[";
cb.QuoteSuffix = "]";
// Asignar los comandos al DataAdapter
// (se supone que lo hace automáticamente, pero...)
da.UpdateCommand = cb.GetUpdateCommand();
da.InsertCommand = cb.GetInsertCommand();
da.DeleteCommand = cb.GetDeleteCommand();
//
// Esta base de datos usa el ID con valores automáticos
da.MissingSchemaAction = MissingSchemaAction.AddWithKey;
//
dt = new DataTable();
// Llenar la tabla con los datos indicados
da.Fill(dt);
//
// Habilitar los controles
foreach(Control c in this.GroupBox1.Controls){
c.Enabled = true;
}
this.GroupBox1.Enabled = true;
this.GroupBox1.Text = "Conexión realizada";
}
catch(Exception ex){
MessageBox.Show("ERROR: " + ex.Message, "Comprobar tabla");
return false;
}
}
cmd.ExecuteNonQuery();
creada = true;
}
catch(Exception ex){
MessageBox.Show("Error al crear la tabla:\n" + ex.Message);
}
finally{
if( cnn != null ){
if( cnn.State == ConnectionState.Open ){
cnn.Close();
}
}
}
return creada;
}
Al usar ese método, nos aseguramos que la nueva fila creada tiene todos los datos sobre la estructura
de la tabla (o de la selección que hemos hecho), de forma que podamos asignar los campos, etc.
Una vez que la fila tiene asignados los valores de los campos, la añadimos a las fila de la tabla. Esto
es necesario, ya que el métodoNewRow solo crea una fila, pero no la "relaciona" (o añade) a la tabla
actual.
Una vez actualizados los datos en la base de datos, le indicamos a la tabla que acepte los cambios
que hayamos hecho, de forma que quede sincronizada nuevamente.
Esto es necesario, ya que si no lo hacemos, la tabla mantendrá los cambios que hayamos hecho y si
nuevamente "sincronizamos" esos datos con la base real, se podrían producir errores.
Es importante que sepamos que cuando llamamos al método Update del adaptador, se
realizan todas las actualizaciones, es decir, no solo añadir nuevos datos, como "se supone"
que es lo que hace este método, sino que si hubiésemos eliminado filas, o modificado algunas,
esas modificaciones también se reflejarían en la base de datos.
Debido a cómo funcionan los campos autincrementales, para asegurarnos de que en realidad el valor
de ese ID se actualiza correctamente, si es el primer registro que añadimos (o vale cero, como es la
comprobación que hacemos aquí), deberíamos volver a leer los datos reales de la base de datos (que
será después de haber añadido el primer registro) con idea de que ese ID tenga el valor correcto.
Esto no es necesario en los siguientes datos que vayamos añadiendo, ya que en otros casos el valor
del ID se asignará correctamente.
Como ves, también controlamos los errores que se puedan producir... ¡nunca está de más!
Si la caja de textos para la fecha no tiene nada, usamos un valor "nulo" para asignar a ese campo.
De todas formas, deberíamos usar un try/catch para comprobar que la fecha asignada es válida.
private void asignarDatos(DataRow dr) {
// Usar los datos que hay en los textbox
dr["Nombre"] = txtNombre.Text;
dr["e-mail"] = txtEmail.Text;
if( txtFechaAlta.Text == "" ){
dr["FechaAlta"] = DBNull.Value;
}
else{
dr["FechaAlta"] = txtFechaAlta.Text;
}
dr["Comentario"] = txtComentario.Text;
}
Si es así, asignamos a una variable del tipo DataRow la fila en cuestión y posteriormente llamamos
al método asignarDatos que vimos antes, que como sabes es el que se encarga de asignar las cajas
de texto a los campos correspondientes.
Una vez que la fila tiene los nuevos datos, volvemos a llamar al método Update del adaptador, como
comenté antes, esta llamada al método Update solo es necesario si queremos asignar directamente
los datos en la base, es decir, hacer que los cambios se hagan en ese preciso momento.
También encerramos esa actualización dentro de un Try/Catch para detectar los errores que se
puedan producir.
DataRow dr = dt.Rows[fila];
// Asignar los datos de los textbox a la fila
asignarDatos(dr);
try{
da.Update(dt);
dt.AcceptChanges();
}catch(DBConcurrencyException ex){
MessageBox.Show("Error de concurrencia:\n" + ex.Message);
}catch(Exception ex){
MessageBox.Show(ex.Message);
}
}
Cuando eliminamos un registro, en nuestro programa se dejan los datos, de forma que si nos
arrepentimos, podamos volver a crearlos, no recuperarlos, sino crear un registro nuevo, con su nuevo
ID, etc.
try{
// Eliminar la fila de la tabla
dt.Rows[fila].Delete();
// Actualizar físicamente la base de datos
da.Update(dt);
// Aceptar los cambios en la copia local
dt.AcceptChanges();
}catch(DBConcurrencyException ex){
MessageBox.Show("Error de concurrencia:\n" + ex.Message);
}catch(Exception ex){
MessageBox.Show(ex.Message);
}
Nota:
Si lo que realmente te interesa es que los datos NO se eliminen directamente en la base de
datos, (ni se actualicen ni creen nuevos), hasta que tu quieras, la llamada al
método Update del adaptador y la llamada al métodoAcceptChanges de la tabla no deberías
llamarla en estos tres métodos que acabamos de ver, sino que puedes hacerlo, por ejemplo,
cuando el usuario "realmente" quiera que todos esos cambios se hagan físicamente en la base
de datos.
Pero eso es, como siempre, a tu criterio.
En estos cuatro métodos usaremos un método extra que será el que se encargue de comprobar si
todo está correcto (o casi) y de mostrar los datos adecuados en cada caja de texto. Al igual que antes
con el método asignarDatos, lo he puesto por separado, entre otras cosas para facilitar la
modificación del código para otras tablas.
También para que no haya que estar repitiendo en el resto de los métodos las comprobaciones de que
el valor de fila indicado está dentro del rango válido. Ese rango debe estar entre cero para el primer
registro y uno menos del número total de filas para el último, por tanto, si el valor del número de la
fila indicado no es correcto, no hacemos nada, simplemente salimos del método.
En caso de que sigamos, quiere decir que es un valor de fila correcto, por tanto leemos esa fila
(asignándola a una variable de tipo DataRow) y asignamos los valores a las cajas de texto, en este
caso si que usamos el valor del campo ID con idea de que veamos ese valor.
Por último habilitamos el botón de actualizar y eliminar, ya que se supone que hay datos.
Nota:
Como veremos en el código, en realidad no hace falta pasarle ningún parámetro al
método mostrarDatos, ya que al tener la variable fila disponible en todo el formulario,
podríamos usar esa variable en lugar del parámetro, pero... lo dejo así por si se te ocurre
hacer cambios y no usar esa variable, que hay gente que no le gusta usar variables "globales"
al formulario o clase...
Para ir al primero, simplemente asignamos cero a la variable de la fila actual y llamamos al método de
mostrar los datos.
Para ir al último, averiguamos cual es la última fila, que como vemos es el valor devuelto por la
propiedad Count de la colección de filas (Rows), menos uno, ya que como sabemos todos los arrays y
colecciones de .NET siempre empiezan con el índice cero.
Para ir al anterior simplemente le restamos uno al valor de la fila actual, pero debemos hacer una
comprobación de que no sea menor de cero, ya que es posible que estemos en el primer registro y
pulsemos en el botón de ir al anterior. En caso de que estemos en el primero, seguiremos en ese
mismo registro.
Por último, para ir al siguiente, hacemos lo mismo que antes, pero en lugar de restar uno, lo que
hacemos es añadir uno al valor de la fila actual, y en el caso de que sea mayor que la última fila, pues
nos quedamos en esa última fila.
Introducción
Este artículo en realidad consta de varias partes, aunque todas esas partes formarán un todo, y ese
todo es un ejemplo muy básico (o elemental) de cómo acceder a una base de datos de tipo SQL
Server usando ADO.NET y Visual Basic, (cualquier versión, ya sea la 1.x o la 2.0), permitiendo
navegar entre los registros, añadir nuevos datos, modificar o borrar los existentes.
También veremos cómo saber las instancias de SQL Server que hay instaladas en el equipo, las cuales
se mostrarán en un combo; al seleccionar la instancia, veremos cómo mostrar las bases de datos que
tiene esa instancia, (excepto las del sistema o propias de SQL), las cuales estarán en otro combo.
Si la tabla de prueba no existe en la base de datos seleccionada, tendremos la posibilidad de crearla.
Espero que te sea de utilidad y que esté más claro y menos "liante" que el otro ejemplo que ya tenía
publicado.
Nota:
A lo largo de este artículo, te muestro el código de Visual C#, pulsa este link si quieres ver el
artículo con el código de ejemplo para Visual Basic.
Al final tienes el link al zip con el código de ejemplo para Visual C#, el cual es válido tanto para las
versiones 2003 y 2005.
Nos vemos
Guillermo
P.S.
Pulsa aquí para ver un ejemplo parecido para una base de datos de tipo Access con OleDb.
Como vemos, este formulario utiliza los campos que tiene la tabla que vamos a usar, por tanto, si vas
a usar otra tabla diferente a la usada en el ejemplo, tendrás que crear tu propio diseño del formulario.
En el código he intentado separar el código que depende de los campos, de forma que te resulte fácil
de modificar.
Empezando por arriba, tenemos un ComboBox (cboInstancias) en el que mostraremos las instancias
de SQL Server que hay instaladas en el equipo. Pulsa aquí si quieres saber cómo averiguar las
instancias de SQL Server que hay en el equipo usando código de Visual C#.
A la derecha, tenemos otro ComboBox (cboBases) en el que mostraremos las bases de datos que
tiene la instancia de SQL Server que hayamos seleccionado del primer combo. Pulsa aquí para saber
cómo averiguar las bases de datos que contiene una instancia de SQL Server usando código de Visual
C#.
El botón que está en la parte derecha, (btnConectar), (en la misma fila que los dos combos) nos
servirá para conectarnos a la base de datos y a la instancia seleccionadas usando autenticación de
Windows.
En ese botón se crea la conexión a la base de datos y se asigna el DataAdapter que usaremos para
conectar directamente con la base de datos. Por tanto será en el código de ese botón donde tendrás
que escribir todo lo necesario para realizar la conexión, cargar los datos en la tabla (DataTable) y
empezar a mostrar los datos.
Al pulsar en el botón de conectar, el código comprueba si la tabla de pruebas existe, de no ser así,
nos preguntará si la queremos crear.
En el GroupBox tenemos los controles para mostrar los datos, navegar entre las filas, actualizar, crear
y eliminar registros.
Los botones de navegación (o movimiento) nos servirán para ir a los distintos registros: Primero,
anterior, siguiente y último.
El botón de Actualizar lo usaremos para actualizar los datos del registro actual.
El botón Nuevo lo usaremos para añadir un nuevo registro. Cuando pulsamos en ese botón, se
usarán los datos que actualmente tengamos en las cajas de textos, salvo el ID, ya que en la tabla de
ejemplo es autonumérico, y por tanto se crea solo.
El botón de Eliminar lo usaremos para eliminar el registro que esté actualmente activo. Cuando se
elimina el registro, los datos permanecen en los controles, por si queremos volver a crearlo,
(pulsando en el botón Nuevo), aunque el ID usado será diferente al mostrado, ya que al crear un
nuevo registro (o fila) el valor del campo ID se genera automáticamente.
Nota IMPORTANTE:
Las tres operaciones indicadas se hacen directamente en la base de datos, es decir, no
trabajamos en modo desconectado, sino que cualquier cambio se reflejará inmediatamente en
la base de datos.
En este evento utilizamos una función llamada instanciasInstaladas, esa es la que nos indica las
instancias de SQL Server que tenemos instaladas en nuestro equipo y si quieres ver el código puedes
hacerlo desde este link.
En este mismo evento y en el correspondiente al cambio de selección del combo de las instancias,
también usamos una función (basesDeDatos), que recibe como parámetro el nombre de la instancia
seleccionada, para saber las bases de datos que tiene la instancia de SQL Server que hemos
seleccionado, el código de esa función lo puedes ver siguiendo este link.
Como te he comentado antes, cuando seleccionamos una de las instancias del combo con los
servidores (o instancias) de SQL Server, asignamos en el combo de las bases de datos, las que esa
instancia contiene.
El código del evento SelectedIndexChanged es el siguiente, en el que comprobamos si hay alguna
base de datos (la función que comprueba las bases que hay en la instancia indicada,
devuelve Nothing si solo están las bases del propio SQL Server), las agregamos al combo y
seleccionamos el primer elemento.
En el siguiente código comprobamos también si la tabla que usaremos existe en la base de datos
seleccionada, para ello usaremos la función existeTabla a la que le pasaremos el objeto conexión
que hemos creado y el nombre de la tabla que queremos comprobar si existe o no, que en nuestro
ejemplo se llama Prueba.
Nota:
En realidad el objeto SqlConnection no hace falta para rellenar los datos por medio
del DataAdapter, pero si lo necesitamos para comprobar si la tabla existe.
Una vez que tenemos la conexión creada y que sabemos que la tabla existe, crearemos los objetos
que nos permitirán acceder a la base de datos (mediante un objeto del tipo SqlDataAdapter), y
llenaremos el objeto DataTable con los datos que hayamos indicado en la cadena de selección.
Crearemos los comandos que necesitaremos para actualizar los datos en la base de datos
(UPDATE, INSERT y DELETE). Esos comandos los creamos con un objeto del
tipo SqlCommandBuilder que aunque no es la forma más efectiva, al menos es la más fácil de usar,
y como de lo que en este artículo se trata es que sea fácil, pues eso... Los comandos los asignaremos
a los objetos correspondientes del adaptador, esto en realidad no es necesario, pero algunas veces
me ha dado error al no hacerlo, así que... ¡mejor estar seguros de que se asignan!.
Debido a que la tabla de ejemplo utiliza un campo autoincremental, tendremos que asignar a la
propiedad MissingSchemaAction el valor AddWithKey, de esta forma, al añadir nuevos registros
se incrementará el valor del ID.
En la tabla de ejemplo, estamos usando un campo que contiene caracteres que pueden ser
conflictivos, en este caso es simplemente un guión, pero podría ser una vocal acentuada, una eñe o
contener espacios, en este caso lo que hacemos es indicar en el objeto del
tipo CommandBuilder que utilice prefijo y sufijo para "envolver" automáticamente esos campos
conflictivos, esa indicación la hacemos mediante las propiedades QuotePrefix y QuoteSufix.
Por último creamos el nuevo objeto del tipo DataTable, que será el que usemos con el
método Fill del adaptador, al usar ese método, será cuando se conecte con la base de datos y asigne
a la tabla los datos indicados en la cadena de selección (SELECT).
En este ejemplo, le indico que traiga todos los datos, pero también podría haber seleccionado con una
cláusula WHERE otros diferentes.
Finalmente habilitamos nuevamente los controles que están en el GroupBox para que podamos
navegar, añadir, eliminar, actualizar y escribir en las cajas de texto, y mostraremos el primer registro,
para ello llamamos al código del evento del botón para mostrar el primer registro.
Si no hay datos, (es decir, si la tabla no contiene alguna fila), deshabilitamos el botón de actualizar y
el de eliminar, para permitir solo añadir nuevos datos.
private void btnConectar_Click(object sender, EventArgs e) {
// Conectar y mostrar los datos
//
// La cadena de conexión
string sCnn = "Server=" + cboInstancias.Text +
"; " + "database=" + cboBases.Text +
"; integrated security=yes";
// La cadena de selección
string sSel = "SELECT * FROM Prueba ORDER BY ID";
//
// Comprobar si hay algún error
try{
// Crear un nuevo objeto del tipo DataAdapter
da = new SqlDataAdapter(sSel, sCnn);
// Crear los comandos de insertar, actualizar y eliminar
SqlCommandBuilder cb = new SqlCommandBuilder(da);
// Como hay campos con caracteres especiales,
// al usarlos incluirlos entre corchetes.
cb.QuotePrefix = "[";
cb.QuoteSuffix = "]";
// Asignar los comandos al DataAdapter
// (se supone que lo hace automáticamente, pero...)
da.UpdateCommand = cb.GetUpdateCommand();
da.InsertCommand = cb.GetInsertCommand();
da.DeleteCommand = cb.GetDeleteCommand();
//
// Esta base de datos usa el ID con valores automáticos
da.MissingSchemaAction = MissingSchemaAction.AddWithKey;
//
dt = new DataTable();
// Llenar la tabla con los datos indicados
da.Fill(dt);
//
// Habilitar los controles
foreach(Control c in this.GroupBox1.Controls){
c.Enabled = true;
}
this.GroupBox1.Enabled = true;
this.GroupBox1.Text = "Conexión realizada";
}
catch(Exception ex){
MessageBox.Show("ERROR: " + ex.Message, "Comprobar tabla");
return false;
}
}
cmd.ExecuteNonQuery();
creada = true;
}
catch(Exception ex){
MessageBox.Show("Error al crear la tabla:\n" + ex.Message);
}
finally{
if( cnn != null ){
if( cnn.State == ConnectionState.Open ){
cnn.Close();
}
}
}
return creada;
}
Al usar ese método, nos aseguramos que la nueva fila creada tiene todos los datos sobre la estructura
de la tabla (o de la selección que hemos hecho), de forma que podamos asignar los campos, etc.
Una vez actualizados los datos en la base de datos, le indicamos a la tabla que acepte los cambios
que hayamos hecho, de forma que quede sincronizada nuevamente.
Esto es necesario, ya que si no lo hacemos, la tabla mantendrá los cambios que hayamos hecho y si
nuevamente "sincronizamos" esos datos con la base real, se podrían producir errores.
Es importante que sepamos que cuando llamamos al método Update del adaptador, se
realizan todas las actualizaciones, es decir, no solo añadir nuevos datos, como "se supone"
que es lo que hace este método, sino que si hubiésemos eliminado filas, o modificado algunas,
esas modificaciones también se reflejarían en la base de datos.
Debido a cómo funcionan los campos autincrementales, para asegurarnos de que en realidad el valor
de ese ID se actualiza correctamente, si es el primer registro que añadimos (o vale cero, como es la
comprobación que hacemos aquí), deberíamos volver a leer los datos reales de la base de datos (que
será después de haber añadido el primer registro) con idea de que ese ID tenga el valor correcto.
Esto no es necesario en los siguientes datos que vayamos añadiendo, ya que en otros casos el valor
del ID se asignará correctamente.
Como ves, también controlamos los errores que se puedan producir... ¡nunca está de más!
Si la caja de textos para la fecha no tiene nada, usamos un valor "nulo" para asignar a ese campo.
De todas formas, deberíamos usar un try/catch para comprobar que la fecha asignada es válida.
Si es así, asignamos a una variable del tipo DataRow la fila en cuestión y posteriormente llamamos
al método asignarDatos que vimos antes, que como sabes es el que se encarga de asignar las cajas
de texto a los campos correspondientes.
Una vez que la fila tiene los nuevos datos, volvemos a llamar al método Update del adaptador, como
comenté antes, esta llamada al método Update solo es necesario si queremos asignar directamente
los datos en la base, es decir, hacer que los cambios se hagan en ese preciso momento.
También encerramos esa actualización dentro de un Try/Catch para detectar los errores que se
puedan producir.
private void btnActualizar_Click(object sender, EventArgs e) {
// Actualizar los datos en la fila actual
if( fila < 0 || fila > dt.Rows.Count - 1 ) return;
DataRow dr = dt.Rows[fila];
// Asignar los datos de los textbox a la fila
asignarDatos(dr);
try{
da.Update(dt);
dt.AcceptChanges();
}catch(DBConcurrencyException ex){
MessageBox.Show("Error de concurrencia:\n" + ex.Message);
}catch(Exception ex){
MessageBox.Show(ex.Message);
}
}
Cuando eliminamos un registro, en nuestro programa se dejan los datos, de forma que si nos
arrepentimos, podamos volver a crearlos, no recuperarlos, sino crear un registro nuevo, con su nuevo
ID, etc.
try{
// Eliminar la fila de la tabla
dt.Rows[fila].Delete();
// Actualizar físicamente la base de datos
da.Update(dt);
// Aceptar los cambios en la copia local
dt.AcceptChanges();
}catch(DBConcurrencyException ex){
MessageBox.Show("Error de concurrencia:\n" + ex.Message);
}catch(Exception ex){
MessageBox.Show(ex.Message);
}
Nota:
Si lo que realmente te interesa es que los datos NO se eliminen directamente en la base de
datos, (ni se actualicen ni creen nuevos), hasta que tu quieras, la llamada al
método Update del adaptador y la llamada al métodoAcceptChanges de la tabla no deberías
llamarla en estos tres métodos que acabamos de ver, sino que puedes hacerlo, por ejemplo,
cuando el usuario "realmente" quiera que todos esos cambios se hagan físicamente en la base
de datos.
Pero eso es, como siempre, a tu criterio.
En estos cuatro métodos usaremos un método extra que será el que se encargue de comprobar si
todo está correcto (o casi) y de mostrar los datos adecuados en cada caja de texto. Al igual que antes
con el método asignarDatos, lo he puesto por separado, entre otras cosas para facilitar la
modificación del código para otras tablas.
También para que no haya que estar repitiendo en el resto de los métodos las comprobaciones de que
el valor de fila indicado está dentro del rango válido. Ese rango debe estar entre cero para el primer
registro y uno menos del número total de filas para el último, por tanto, si el valor del número de la
fila indicado no es correcto, no hacemos nada, simplemente salimos del método.
En caso de que sigamos, quiere decir que es un valor de fila correcto, por tanto leemos esa fila
(asignándola a una variable de tipo DataRow) y asignamos los valores a las cajas de texto, en este
caso si que usamos el valor del campo ID con idea de que veamos ese valor.
Por último habilitamos el botón de actualizar y eliminar, ya que se supone que hay datos.
Los cuatro métodos para movernos son los siguientes, veamos que es lo que hacemos en cada uno de
ellos, aunque creo que viendo el código queda clara la intención.
Nota:
Como veremos en el código, en realidad no hace falta pasarle ningún parámetro al
método mostrarDatos, ya que al tener la variable fila disponible en todo el formulario,
podríamos usar esa variable en lugar del parámetro, pero... lo dejo así por si se te ocurre
hacer cambios y no usar esa variable, que hay gente que no le gusta usar variables "globales"
al formulario o clase...
Para ir al primero, simplemente asignamos cero a la variable de la fila actual y llamamos al método de
mostrar los datos.
Para ir al último, averiguamos cual es la última fila, que como vemos es el valor devuelto por la
propiedad Count de la colección de filas (Rows), menos uno, ya que como sabemos todos los arrays y
colecciones de .NET siempre empiezan con el índice cero.
Para ir al anterior simplemente le restamos uno al valor de la fila actual, pero debemos hacer una
comprobación de que no sea menor de cero, ya que es posible que estemos en el primer registro y
pulsemos en el botón de ir al anterior. En caso de que estemos en el primero, seguiremos en ese
mismo registro.
Por último, para ir al siguiente, hacemos lo mismo que antes, pero en lugar de restar uno, lo que
hacemos es añadir uno al valor de la fila actual, y en el caso de que sea mayor que la última fila, pues
nos quedamos en esa última fila.