1013 PSG

Descargar como doc, pdf o txt
Descargar como doc, pdf o txt
Está en la página 1de 124

VISUAL C#.

NET 2005

TABLAS EN ACCESS

TEMA 1: MICROSOFT ACCESS TABLAS

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:

1.- Cargar Microsoft Access y sale la siguiente pantalla:

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.

5.- Aparece ahora la siguiente pantalla:

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

INTRODUCION BASES DE DATOS VISUAL C# 2005

TEMA 2: ADO NET ACTIVE DATA OBJECT

EL NUEVO MODELO DE DATOS DE MICROSOFT ES ADO NET, ESTE MODELO DESCANSA EN


UNA SERIE DE OBJETOS ESPECIALIZADOS QUE FACILITAN EL PROCESAMIENTO DE UNA
BASE DE DATOS.

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.

OBJETO CONNECTION:- OBJETO QUE SE UTILIZA PARA ESTABLECER UNA CONECCION O


ENLACE A LA BASE DE DATOS.

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

OLEDB.NET DATA PROVIDER.- QUE SE ESPECIALIZA EN COMUNICARSE Y PROCESAR


BASES DE DATOS QUE A LA FECHA DEL PRESENTE LIBRO UTILIZEN ALGUNOS DE LOS
SIGUIENTES DRIVERS, SQLOLEDB ( VERSIONES ANTERIORES DE SQL SERVER DE
MICROSOFT), MSDAORA (ORACLE), MICROSOFT.JET ( ACCESS Y ALGUNOS OTROS
DBMS DE MICROSOFT)

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.

Ejemplo del objeto CONNECTION

Static OleDbConnection coneccion;

coneccion = new OleDbConnection(“Provider=Microsoft.Jet.OLEDB.4.0;Data


Source=c:\\progfacil\\tusitio\\mibase.mdb”);

Es una sola string y los dos parametros mencionados van separados por el punto y coma.

ATENCION es DATA SOURCE= no usar DATASOURCE= estan adevertidos.

Ejemplos de los otros poveedores o fuentes mencionados:

//Provider=MSDAORA; Data Source=ORACLE8i7; User ID=OLEDB; Password=OLEDB

//Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\bin\LocalAccess40.mdb;

//Provider=SQLOLEDB;Data Source=MySQLServer;Integrated Security=SSPI;

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:

la instruccion sql y el objeto conneccion que ya se vio en el parrafo anterior. ejemplo

OleDbCommand orden;

orden= new OleDbCommand("select * from mitabla", coneccion);

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;

String q="select * from mitabla";

orden= new OleDbCommand(q, coneccion);

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;

String clave=7;string nombre="rana"; string peso=3.14;

string q="insert into mitabla(clave,nombre,peso) values(@CLAVE, @NOMBRE, @PESO)";

orden= new OleDbCommand(q, coneccion);

**orden.Parameters.Add(new OleDbParameter("@CLAVE", OleDbType.Integer));**

orden.Parameters["@CLAVE"].Value = clave;

orden.Parameters.Add(new OleDbParameter("@NOMBRE", OleDbType.VarWChar, 40));

orden.Parameters["@NOMBRE"].Value = nombre;

orden.Parameters.Add(new OleDbParameter("@PESO", OleDbType.Double));

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.

Los OLEDBTYPE mas comunes son:

BigInt A 64-bit signed integer (DBTYPE_I8). This maps to Int64.

Binary A stream of binary data (DBTYPE_BYTES). This maps to an Array of type Byte.

Boolean A Boolean value (DBTYPE_BOOL). This maps to Boolean.

BSTR A null-terminated character string of Unicode characters (DBTYPE_BSTR). This maps to String.

Char A character string (DBTYPE_STR). This maps to String.

Currency A currency value ranging from -263 (or -922,337,203,685,477.5808) to 2 63 -1 (or


+922,337,203,685,477.5807) with an accuracy to a ten-thousandth of a currency unit (DBTYPE_CY). This
maps to Decimal.

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.

Empty No value (DBTYPE_EMPTY). This maps to Empty.

Error A 32-bit error code (DBTYPE_ERROR). This maps to Exception.

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.

Integer A 32-bit signed integer (DBTYPE_I4). This maps to Int32.

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.

LongVarChar A long string value (OleDbParameter only). This maps to String.

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.

SmallInt A 16-bit signed integer (DBTYPE_I2). This maps to Int16.

TinyInt A 8-bit signed integer (DBTYPE_I1). This maps to SByte.

UnsignedBigInt A 64-bit unsigned integer (DBTYPE_UI8). This maps to UInt64.

UnsignedInt A 32-bit unsigned integer (DBTYPE_UI4). This maps to UInt32.

UnsignedSmallInt A 16-bit unsigned integer (DBTYPE_UI2). This maps to UInt16.

UnsignedTinyInt A 8-bit unsigned integer (DBTYPE_UI1). This maps to Byte.

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.

VarNumeric A variable-length numeric value (OleDbParameter only). This maps to Decimal.

VarWChar A variable-length, null-terminated stream of Unicode characters (OleDbParameter only). This


maps to String.

WChar A null-terminated stream of Unicode characters (DBTYPE_WSTR). This maps to String.

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;

String clave=7;string nombre="rana";string peso=3.14;

string q="insert into mitabla(clave,nombre,peso) values(@CLAVE, @NOMBRE, @PESO)";

orden= new OleDbCommand(q, coneccion);

orden.Parameters.Add(new OleDbParameter("@CLAVE", OleDbType.Integer));

orden.Parameters["@CLAVE"].Value = clave;

orden.Parameters.Add(new OleDbParameter("@NOMBRE", OleDbType.VarWChar, 40));

orden.Parameters["@NOMBRE"].Value = nombre;

orden.Parameters.Add(new OleDbParameter("@PESO", OleDbType.Double));

orden.Parameters["@PESO"].Value = edad;

**orden.Connection.Open();**

orden.ExecuteNonQuery();

orden.Connection.Close()

sencillo abrir la coneccion, mandar o ejecutar la instruccion y cerrar la coneccion.

OBJETOS DATAADAPTER Y DATASET:(dos por uno)

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.

Con los objetos CONNECTION, COMMAND y DATAADAPTER ya se pueden efectuar cualquiera de la


operaciones SQL descritas ( ya estudiaron su tutorial de SQL) el problema es que pasa con el usuario
cuando va a ver base de datos o mejor aun las tablas que estan en la base de datos en disco.

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

canal = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data


Source=c:\\progfacil\\tusitio\\mibase.mdb");

// cargando el adapter con la instruccion sql

orden =new OleDbDataAdapter("select * from mitabla", coneccion);

// cargando el dataset

TABLA= new 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:

1.- COMPONENTE TABLE DE HTML(USADO EN EL CURSO DE CSHARP-CGI DE


PROGRAMACIONFACIL.COM)
2.- COMPONENTE HTMLTABLE DE ASP

3.- NUEVO COMPONENTE DATAGRIDVIEW DE ASP NET QUE SE USA EN ESTA UNIDAD

UNIDAD 3: INTRODUCION BASES DE DATOS VISUAL C# 2005

TEMA 7: CONSULTA O DESPLIEGUE O SELECCION

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:

SELECT [listacampos, * o ALL] FROM TABLA;

Esta instruccion se enviara a la base de datos usando un objeto DATAADAPTER

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:

1.- Crear una coneccion o enlace a la base de datos.

2.- Abrir la coneccion a la base de datos.

3.- Crear ADAPTER y cargarlo con la instruccion sql.

4.- Crear el dataset y cargarlo a travez del adapter

5.- Cargar el DataGridView con el dataset y enlazarlo(binding)

6.- Procesar el DataGridView (editar un renglon, agregar un renglon, modificar un renglon, etc)

7.- Cerrar la coneccion

Codigo prog

private void button1_Click_1(object sender, EventArgs e)

// declarando objetos coneccion, adapter y dataset

OleDbConnection CANAL;
OleDbDataAdapter ORDEN;

DataSet TABLA;

// creando y enlazando coneccion a la base de datos

CANAL = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data


Source=c:\\datos\\mibase.mdb");

// recordar espacion en balanco en DATA SOURCE=

// creando y cargando el adapter con la instruccion sql

// recordar usar DataAdapter para select's

ORDEN = new OleDbDataAdapter("select * from mitabla", CANAL);

// creando y cargando el dataset

TABLA = new DataSet();

ORDEN.Fill(TABLA, "mitabla");

// cargando y enlazando el DataGridView

GRID1.DataSource = TABLA;

GRID1.DataMember = "mitabla";

Corrida

Cuando coloquen el DataGridView en FORM1 las propiedades a usar son:

Name = GRID1 ←- nombre del grid dentro del programa


ColumnsHeadersVisible = true ←- Para que se muestren las celdas de encabezdos

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.

BackGroundColor, BorderStyle, CellBorderStyle, DefaultCellsStyle los pueden cargar con valores


apropiados para darle buena presentacion a la tabla.

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

El encabezado de este programa debe quedar asi:

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)

7.- Se crea el adapter y se carga el constructor con la instruccion sql y la coneccion.

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

9.- Al final se carga el datagrid, se enlaza al dataset y se cierra la base de datos.

TAREAS PROGRAMACION VISUAL C# 2005

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.

UNIDAD 5: INTRODUCION BASES DE DATOS VISUAL C# 2005

TEMA 8: INSERCION O ADICION DE REGISTROS

Insertar o agregar registros o renglones nuevos a una tabla en disco, es un proceso sencillo que usa la
siguiente instruccion sql:

INSERT INTO TABLA(CAMPO1,CAMPO2..) VALUES(VALOR1,VALOR2..);

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

// CONTADOR ES UNA VARIABLE GLOBAL

int cont =0;

private void button1_Click_1(object sender, EventArgs e)

// creando y cargando coneccion y command


OleDbConnection CANAL;

OleDbCommand ORDEN;

// abriendo la coneccion o enlace

CANAL=new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=c:\\datos\\mibase.mdb");

// creando y cargando un objeto OLEDBCOMMAND

// instruccion sql insert into mitabla(listacampos) values(listadatos)

// @variable es una variable de tipo parametro

string q="insert into mitabla(nombre,edad) values(@NOMBRE, @EDAD)";

ORDEN= new OleDbCommand(q, CANAL);

ORDEN.Parameters.Add(new OleDbParameter("@NOMBRE", OleDbType.VarWChar, 20));

ORDEN.Parameters["@NOMBRE"].Value = NOMBRE.Text;

ORDEN.Parameters.Add(new OleDbParameter("@EDAD", OleDbType.Integer));

ORDEN.Parameters["@EDAD"].Value = EDAD.Text;

ORDEN.Connection.Open();

ORDEN.ExecuteNonQuery();

ORDEN.Connection.Close();

// limpiando TEXTBOXS para otra inserccion

NOMBRE.Text=" ";

EDAD.Text=" ";

// avisando inserccion

cont = cont+1;

label4.Text = "REGISTRO no: "+ cont.ToString()+" Insertado";

Corrida
Notas:

Se agregaron dos textboxs arriba para capturar los nuevos datos a insertar en la tabla.

RECORDAR QUE CAMPO CLAVE ES DE TIPO AUTONUMBER Y ACCESS SE ENCARGA DE


INCREMENTARLO POR SU CUENTA.

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

TAREAS PROGRAMACION VISUAL C# 2005:

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

TEMA 9 : BUSQUEDA SQL SELECT

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:

SELECT [ *, all, campos] FROM TABLA WHERE clave=claveabuscar;

Y recordar que select usa objeto dataadapter

RECORDAR TAMBIEN QUE AGREGANDO CLAUSULAS CONDICIONALES WHERE A


ALGUNAS DE LAS OPERACIONES BASICAS DE SQL (SELECT, DELETE, UPDATE)
PERMITE SELECCIONAR UN SUBCONJUNTO DE REGISTROS DE LA TABLA PARA SU
PROCESAMIENTO.

Se recuerda que deben buscar y estudiar un buen tutorial de sql.

Y no olvidar agregar el using system.data.oledb; arriba en form1.cs

Codigo

private void button1_Click(object sender, EventArgs e)

// Objetos OLEDB que se ocupan

OleDbConnection CANAL;

DataSet TABLA;

OleDbDataAdapter ORDEN;

CANAL = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data


Source=c:\\datos\\mibase.mdb");

string q = "select * from mitabla where clave = @CLABUS";

ORDEN = new OleDbDataAdapter(q, CANAL);

ORDEN.SelectCommand.Parameters.Add(new OleDbParameter("@CLAVE", OleDbType.Integer));

ORDEN.SelectCommand.Parameters["@CLAVE"].Value = CLAVE.Text;

// Creando el dataset y cargandolo

TABLA= new DataSet();

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

TAREAS PROGRAMACION VISUAL C# 2005

1.- hacer programas de busquedas para las bases hechas e ir construyendo el programa de menu completo
para una sola tabla

UNIDAD 5: INTRODUCION BASES DE DATOS VISUAL C# 2005

TEMA 10: FILTROS SQL SELECT

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)

// objetos OLEDB que se ocupan

OleDbConnection CANAL;

DataSet TABLA;

OleDbDataAdapter ORDEN;

CANAL = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data


Source=c:\\datos\\mibase.mdb");

string q = "select * from mitabla where edad >= @EDAD";

ORDEN = new OleDbDataAdapter(q, CANAL);

ORDEN.SelectCommand.Parameters.Add(new OleDbParameter("@EDAD", OleDbType.Integer));

ORDEN.SelectCommand.Parameters["@EDAD"].Value = EDAD.Text;

// Creando el dataset y cargandolo

TABLA = new DataSet();

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

TAREAS PROGRAMACION VISUAL C# 2005

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

UNIDAD 5: INTRODUCION BASES DE DATOS VISUAL C# 2005


TEMA 11: OPERACIONES CON CAMPOS SQL UPDATE

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.

El siguiente programa convierte la edad a meses de todos los renglones de la tabla.

Programa

private void button1_Click_1(object sender, EventArgs e)

// objetos OLEDB que se ocupan

OleDbConnection CANAL;

OleDbCommand ORDEN;

CANAL = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data


Source=c:\\datos\\mibase.mdb");

string q = " UPDATE mitabla SET edad = edad * 12 ";

ORDEN = new OleDbCommand(q, CANAL);

// Mandando la ORDEN

ORDEN.Connection.Open();

ORDEN.ExecuteNonQuery();

ORDEN.Connection.Close();

// Avisando

label1.Text = "EDADES AUMENTADAS";

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

Si quieren ver los cambios usar el programa de consulta SELECT * ya construido.

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.

2.- Seguir construyendo su menu con varias opciones de update.

UNIDAD 5: INTRODUCION BASES DE DATOS VISUAL C# 2005

TEMA 12: BAJA O ELIMINACION SQL DELETE

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:

La instruccion sql a usar es:

DELETE FROM TABLA WHERE CONDICION

Y DELETE USA OBJETO COMMAND

Programa

private void button1_Click(object sender, EventArgs e)

// Objetos OLEDB que se ocupan

OleDbConnection CANAL;

OleDbCommand ORDEN;

CANAL = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data


Source=c:\\datos\\mibase.mdb");
// Instruccion sql DELETE FROM TABLA WHERE CLAVE=DATO

string q = "delete from mitabla where clave=@CLAVE";

ORDEN = new OleDbCommand(q, CANAL);

ORDEN.Parameters.Add(new OleDbParameter("@CLAVE", OleDbType.Integer));

ORDEN.Parameters["@CLAVE"].Value = CLAVE.Text;

ORDEN.Connection.Open();

ORDEN.ExecuteNonQuery();

ORDEN.Connection.Close();

// Avisando

label2.Text = " REGISTRO ELIMINADO";

No hay notas nuevas.

Corrida

TAREAS PROGRAMACION VISUAL C# 2005:

1.- Construir este proceso para las tablas y bases de datos que tengan del programa de menu.

UNIDAD 5: INTRODUCION BASES DE DATOS VISUAL C# 2005

TEMA 13: EDICION DE REGISTROS SQL UPDATE


Editar registros significa cambiar el contenido de algunos de los campos o columnas por nueva informacion
o para corregir algun error de captura original o para agregar alguna columna que no existia por
modificacion de la tabla o la base de datos.

En general se tiene otro problema de sql UPDATE (usando command por supuesto) con una serie de
textboxs arriba para capturar los nuevos datos.

Y no se olviden del using oledb arriba en form1.cs

Programa

private void button1_Click_1(object sender, EventArgs e)

// Objetos OLEDB que se ocupan

OleDbConnection CANAL;

OleDbCommand ORDEN;

CANAL = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data


Source=c:\\datos\\mibase.mdb");

// Instruccion sql UPDATE

string q = "Update mitabla set nombre=@nombre, edad=@EDAD where clave=" + CLAVE.Text;

ORDEN = new OleDbCommand(q, CANAL);

ORDEN.Parameters.Add(new OleDbParameter("@NOMBRE", OleDbType.VarWChar, 20));

ORDEN.Parameters["@NOMBRE"].Value = NOMBRE.Text;

ORDEN.Parameters.Add(new OleDbParameter("@EDAD", OleDbType.Integer));

ORDEN.Parameters["@EDAD"].Value = EDAD.Text;

ORDEN.Connection.Open();

ORDEN.ExecuteNonQuery();

ORDEN.Connection.Close();

// Limpiando TEXTBOXS para otra edicion

NOMBRE.Text = " ";

EDAD.Text = " ";

// Avisando edicion

label4.Text = "REGISTRO EDITADO";

}
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

TAREAS PROGRAMACION VISUAL C# 2005

1.- Construir el modulo o procedimeinto de edicion al sistema de menu que estan construyendo

UNIDAD 5: INTRODUCION BASES DE DATOS VISUAL C# 2005

TEMA 14: GRAFICOS PICTUREBOX

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

private void button1_Click(object sender, EventArgs e)

// Objetos OLEDB que se ocupan

OleDbConnection CANAL;

DataSet TABLA;

OleDbDataAdapter ORDEN;

CANAL = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data


Source=c:\\datos\\mibase.mdb");

string q = "select * from mitabla where clave = @CLABUS";

ORDEN = new OleDbDataAdapter(q, CANAL);

ORDEN.SelectCommand.Parameters.Add(new OleDbParameter("@CLAVE", OleDbType.Integer));

ORDEN.SelectCommand.Parameters["@CLAVE"].Value = CLAVE.Text;

// Creando el dataset y cargandolo

TABLA = new DataSet();

ORDEN.Fill(TABLA, "mitabla");

// Cargando el datagridVIEW

GRID1.DataSource = TABLA;

GRID1.DataMember = "mitabla";

// Cargando la imagen

string temp = TABLA.Tables["mitabla"].Rows[0][3].ToString();

FOTO.Image = Image.FromFile("c:\\datos\\" + temp);

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.

PROYECTO PROGRAMACION VISUAL C# 2005 CONSTRUIR UN SISTEMA COMPLETO


INTEGRADO CON TODAS LAS OPERACIONES USANDO AL MENOS UNA TABLAS.

POR ULTIMO RECORDAR QUE EL COMPONENTE DATAGRIDVIEW ES UNO DE LOS


CONTROLES QUE MAS HA SIDO MODIFICADO Y ACTUALIZADO POR MICROSOFT, ENTRE
SUS PRINCIPALES CAMBIOS ES LA CANTIDAD INCREIBLE DE EVENTOS QUE PUEDE
DETECTAR Y DE HECHO MUCHOS DE LOS PROCESOS QUE SE ESTUDIARON EN ESTA
UNIDAD SE PODRIAN FACILITAR MUCHO SI SE USARAN LOS EVENTOS DE DATAVIEWGRID,
SIN EMBARGO POR RAZONES PEDAGOGICAS SE SELECCIONO EL MODELO SEGUIDO EN LA
UNIDAD, SIN EMBARGO EN LA PROXIMA ACTUALIZACION DE ESTE LIBRO SE ANALIZARAN
Y ESTUDIARAN TODOS ESTOS NUEVOS CONCEPTOS.

tan tan el curso se acabo y esten pendiente de los proximos de perl, visual basic 2005, javascript, php,
phyton, xml, et al

CREAR UN FORMULARIO DENTRO DE OTRO

private void Form1_Load(object sender, EventArgs e)

Form2 frm2 = new Form2(); //Creamos un nuebo form

frm2.MdiParent=this; //Hacemos que form1 sea padre de form2

frm2.Show(); //Mostramos form2 (aparecera dentro de form1)

}
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.

Los formatos (codificación) de los ficheros


Antes de empezar "de verdad" con la forma de leer y escribir en los ficheros mediante las clase de .NET,
debemos saber que en .NET se pueden leer y escribir los ficheros usando diferentes codificaciones.

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.

¿Qué problema hay con esto?


Ninguno, al menos si siempre lees y escribes usando las clases de .NET, pero si tu intención es poder leer un
fichero guardado, por ejemplo, con una aplicación de Visual Basic 6 (o el Notepad de Windows), o quieres que
lo que tu guardes se pueda abrir también con cualquier otra aplicación, deberás tener cuidado con la
codificación usada.
Al menos si el contenido de ese fichero tiene caracteres como la eñe, vocales acentuadas, signos de apertura
de admiración o interrogación, etc., ya que en esos casos, el formato usado por defecto por otras aplicaciones
para Windows no será el adecuado, y esos caracteres no se leerán correctamente.
Por tanto, si decides que lo que vas a guardar o leer debe ser "compatible", tendrás que usar la codificación
predeterminada de Windows (ANSI), esa codificación puedes indicarla mediante la clase Encoding (definida en
el espacio de nombres System.Text) y usando el valor Default, después verás ejemplos de cómo usar esos
valores a la hora de leer o de escribir en un fichero.

Leer y escribir ficheros de texto


Leer y escribir en ficheros de texto es lo más sencillo del mundo, (al menos cuando se sabe cómo hacerlo, je,
je), ya que lo podemos hacer usando un par de líneas de código.

Veamos un ejemplo de cómo guardar en un fichero el contenido de una cadena de texto:

Visual Basic:

Const fic As String = "E:\tmp\Prueba.txt"


Dim texto As String = "Érase una vez una vieja con un moño..."

Dim sw As New System.IO.StreamWriter(fic)


sw.WriteLine(texto)
sw.Close()

ESCRIBE DATOS EN UN ARCHIVO C#.NET:

const string fic = @"E:\tmp\Prueba.txt";


string texto = "Érase una vez una vieja con un moño...";
System.IO.StreamWriter sw = new System.IO.StreamWriter(fic);
sw.WriteLine(texto);
sw.Close();

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

Dim sr As New System.IO.StreamReader(fic)


texto = sr.ReadToEnd()
sr.Close()

Console.WriteLine(texto)

LEE DATOS DE UN ARCHIVO C#.NET:

const string fic = @"E:\tmp\Prueba.txt";


string texto;

System.IO.StreamReader sr = new System.IO.StreamReader(fic);


texto = sr.ReadToEnd();
sr.Close();

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.

Anexar contenido a un fichero existente


Antes de ver otras cosas, veamos cómo agregar contenido a un fichero, es decir, si ese fichero existe, lo que
haremos es añadir más contenido, de forma que después de escribir, lo que tendrá será lo que antes hubiere
más lo que ahora escribamos.

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.

Veamos el código para añadir texto a un fichero existente (o crearlo si no existe):

Visual Basic:

Const fic As String = "E:\tmp\Prueba.txt"


Dim texto As String = "Pablito tenía una moto con un pito."

Dim sw As New System.IO.StreamWriter(fic, True)


sw.WriteLine(texto)
sw.Close()

C#:

private static void agregarTexto() {


const string fic = @"E:\tmp\Prueba.txt";
string texto = "Pablito tenía una moto con un pito.";

System.IO.StreamWriter sw = new System.IO.StreamWriter(fic, true);


sw.WriteLine(texto);
sw.Close();
}

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.

Usar una codificación específica


Como te he comentado antes, si no indicamos lo contrario, los ficheros se leerán y se guardarán usando la
codificación UTF-8. Pero si queremos usar una distinta, debemos indicarlo de forma expresa.

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:

Const fic As String = "E:\tmp\Prueba2.txt"


Dim texto As String

Dim sr As New System.IO.StreamReader(fic, System.Text.Encoding.Default)


texto = sr.ReadToEnd()
sr.Close()

Console.WriteLine(texto)

C#:

const string fic = @"E:\tmp\Prueba2.txt";


string texto;

System.IO.StreamReader sr = new System.IO.StreamReader(fic, System.Text.Encoding.Default);


texto = sr.ReadToEnd();
sr.Close();

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:

Const fic As String = "E:\tmp\Prueba2.txt"


Dim texto As String = "Érase una vez una vieja con un moño..."

Dim sw As New System.IO.StreamWriter(fic, False, System.Text.Encoding.Default)


sw.WriteLine(texto)
sw.Close()

C#:

const string fic = @"E:\tmp\Prueba2.txt";


string texto = "Érase una vez una vieja con un moño...";

System.IO.StreamWriter sw = new System.IO.StreamWriter(fic, false, System.Text.Encoding.Default);


sw.WriteLine(texto);
sw.Close();

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.

Utilizar una codificación para leer y escribir ca compatibles con MS-DOS


Si quieres escribir o leer ficheros compatibles con MS-DOS (no pienses que el Guille es muy viejo, que lo es,
pero ese formato también puedes usarlo si abres una ventana de comandos de Windows), puedes usar el valor
437 de la página de código, ese valor lo puedes obtener mediante el método GetEncoding 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..."

Dim sw As New System.IO.StreamWriter(fic, False, System.Text.Encoding.GetEncoding(437))


sw.WriteLine(texto)
sw.Close()

End Sub

Private Sub leerTexto437()


Const fic As String = "E:\tmp\Prueba4.txt"
Dim texto As String

Dim sr As New System.IO.StreamReader(fic, System.Text.Encoding.GetEncoding(437), True)


texto = sr.ReadToEnd()
sr.Close()

Console.WriteLine(texto)

End Sub

C#:

private static void guardarTexto437()


{
const string fic = @"E:\tmp\Prueba4.txt";
string texto = "Érase una vez una vieja con un moño...";

System.IO.StreamWriter sw =
new System.IO.StreamWriter(fic, false, System.Text.Encoding.GetEncoding(437));
sw.WriteLine(texto);
sw.Close();
}

private static void leerTexto437()


{
const string fic = @"E:\tmp\Prueba4.txt";
string texto;

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.

Indicar una codificación si no existe un valor BOM


Para terminar, vamos a ver cómo podemos abrir un fichero para que intente detectar el valor BOM del fichero,
si es que hay alguno, y en caso de que no exista esa marca se use la codificación que indiquemos.

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:

Private Sub guardarTextoBOM()


Const fic As String = "E:\tmp\Prueba5.txt"
Dim texto As String = "Érase una vez una vieja con un moño..."

Dim sw As New System.IO.StreamWriter(fic, False, System.Text.Encoding.UTF8)


sw.WriteLine(texto)
sw.Close()

End Sub

Private Sub leerTextoBOM()


Const fic As String = "E:\tmp\Prueba5.txt"
Dim texto As String

Dim sr As New System.IO.StreamReader(fic, System.Text.Encoding.Default, True)


texto = sr.ReadToEnd()
sr.Close()

Console.WriteLine(texto)

End Sub

C#:

private static void guardarTextoBOM()


{
const string fic = @"E:\tmp\Prueba5.txt";
string texto = "Érase una vez una vieja con un moño...";

System.IO.StreamWriter sw =
new System.IO.StreamWriter(fic, false, System.Text.Encoding.UTF8);
sw.WriteLine(texto);
sw.Close();
}

private static void leerTextoBOM()


{
const string fic = @"E:\tmp\Prueba5.txt";
string texto;

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:

?rase una vez una vieja con un mo?o...

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

Espacios de nombres usados en el código de este artículo:


System.IO
System.Text

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

GetPreamble (valores BOM):


Ayuda de Visual Studio 2005
Ayuda de Visual Studio 2005 en línea
METODO PARA RECORRER UN DATAGRID

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(".",",");
}

METODO DE DATAGRIP HACIENDO DOBLE CLIPS PARA VALERES ENTEROS

string columna1 = string.Empty;


string columna2 = string.Empty;

DataGridViewRow fila = dataGridView1.CurrentRow; // obtengo la fila actualmente


seleccionada en el dataGridView

columna1 = Convert.ToString(fila.Cells[0].Value); //obtengo el valor de la primer


columna
columna2= Convert.ToString(fila.Cells[1].Value); //obtengo el

valor de la segunda columna


MessageBox.Show(columna1, columna2);

OTRO EJEMPLOS

 Holas

Espero que este ejemplo te pueda ayudar


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 partial class Form1 : Form

public Form1()

InitializeComponent();

private void dataGridView1_DoubleClick(object sender, EventArgs e)

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);

private void Form1_Load(object sender, EventArgs e)

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.dataGridView1.Rows[0].Cells[1].Value = "1eraFila 2daColumna";

this.dataGridView1.Rows[0].Cells[2].Value = "1eraFila 3raColumna";

this.dataGridView1.Rows[0].Cells[3].Value = "1eraFila 4taColumna";

this.dataGridView1.Rows[1].Cells[0].Value = "2daFila 1eraColumna";

this.dataGridView1.Rows[1].Cells[1].Value = "2daFila 2daColumna";

this.dataGridView1.Rows[1].Cells[2].Value = "2daFila 3eraColumna";

this.dataGridView1.Rows[1].Cells[3].Value = "2daFila 4taColumna";

private void dataGridView1_Click(object sender, EventArgs e)

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);

Inicie sesión para votar

Holas

Espero que este ejemplo te pueda ayudar

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 partial class Form1 : Form

public Form1()

InitializeComponent();

private void dataGridView1_DoubleClick(object sender, EventArgs e)

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);

private void Form1_Load(object sender, EventArgs e)

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.dataGridView1.Rows[0].Cells[1].Value = "1eraFila 2daColumna";

this.dataGridView1.Rows[0].Cells[2].Value = "1eraFila 3raColumna";

this.dataGridView1.Rows[0].Cells[3].Value = "1eraFila 4taColumna";

this.dataGridView1.Rows[1].Cells[0].Value = "2daFila 1eraColumna";

this.dataGridView1.Rows[1].Cells[1].Value = "2daFila 2daColumna";

this.dataGridView1.Rows[1].Cells[2].Value = "2daFila 3eraColumna";

this.dataGridView1.Rows[1].Cells[3].Value = "2daFila 4taColumna";

private void dataGridView1_Click(object sender, EventArgs e)

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 Marcado como respuestaJuan Carlos Ruiz [BogotaDotNet.org]MVP, Moderadorlunes,


07 de diciembre de 2009 15:38
o
o Responder
o Citar

 miércoles, 22 de agosto de 2007 12:49 Carlos Jose


0

Inicie sesión para votar

Hermano un Millon de Gracias, Me funciono A la perfeccion

o Responder
o Citar

 miércoles, 22 de agosto de 2007 13:16 Carlos Siches

Inicie sesión para votar

Holas

si la respuesta te resulta util marcala como pregunta contestada para hacer crecer el foro

gracias,

Saludos,

Carlos Siches
o Responder
o Citar

 lunes, 10 de noviembre de 2008 22:50 martin859

Inicie sesión para votar

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

 miércoles, 12 de noviembre de 2008 15:15 Carlos Jose

Inicie sesión para votar

Hola martin

la Forma que Yo Lo hago es la Siguiente


En el Evento

private void GridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)

textBox1.Text = Convert.ToString(Grid_Incidencias.CurrentRow.Cells[0].Value);

textBox2.Text = Convert.ToString(Grid_Incidencias.CurrentRow.Cells[1].Value);

NUMEROS ALEATORIOS

Random rndNumbers = new Random();


int rndNumber = rndNumbers.Next(9999);//cuatro sifras
retesar.Text = rndNumber.ToString("N0");

CALCULAR LONGITUD DE CADENA


int a = label6.Text.Length;//CALCULA LA LONGITUD DE CADENA

Cómo: Convertir un valor int a cadena (Guía de programación de C#)

// CONVIERTE EL ENTERO EN STRING


label12.Text = a.ToString("N0");

Cómo: Convertir una cadena en un valor int (Guía de programación de


C#)
Actualización: noviembre 2007

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.

Tipo numérico Método

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:

Un procedimiento es un sub-programa o rutina al que se le asigna un cierto nombre y


que realiza unas determinadas operaciones. La ventaja que tiene utilizar
procedimientos es que su código se escribe una sola vez pero pueden ser ejecutados
desde tantos puntos del script como se desee.

Un procedimiento puede recibir una serie de parámetros que variarán su


funcionamiento. Los parámetros a recibir (de qué tipo es cada uno y para qué se
utiliza) se determinan al escribir el procedimiento.

Dentro del código que determina el funcionamiento de un procedimiento se pueden a


su vez ejecutar otros procedimientos, incluso sí mismo de forma recursiva.

Funciones:

Una función es un procedimiento que, adicionalmente, devuelve un valor como


resultado de su ejecución.

La ventaja de las funciones es que pueden utilizarse en asignaciones, expresiones


matemáticas, etc.

Sintaxis:

Declaración y programación (escritura) de un procedimiento:

public int Maximo (int x, int y)

int mayor;

if (x==y)

return -1;
else

if (x>y)

return x;

else

return y;

En la primera parte de la declaración

public int Maximo (int x, int 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.

Maximo, es el nombre de la función

(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.

Equivalencias entre Visual Basic


y C# (3)
Publicado el 06/Ago/2006
Actualizado el 06/Ago/2006

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.

Estas son las equivalencias publicadas en esta página:

1. Select Case / switch

2. Conversiones entre datos

3. Sobre los redondeos de Visual Basic

4. Parámetros opcionales (y sobrecargas)

5. Array de parámetros opcionales

6. Parámetros por valor y por referencia

1- Select Case / switch


Pues sí, esta se me pasó totalmente... por suerte hay gente que te recuerda las cosas, je, je.
En esta ocasión ha sido Eugenio Estrada, que aunque él ya lo ha publicado, pues... en fin...
creo que es conveniente que estén todas en un mismo sitio para que resulte más fácil.
En realidad esta "equivalencia" debería estar en la primera página de equivalencias, pero como
ha pasado ya mucho tiempo desde su publicación... pues... he preferido publicarla en una nueva, así
te pongo algunas cosillas más.
Para "justificar" el retraso de más de tres años, te pongo algunas cosillas más que debes tener en
cuenta sobre esta instrucción, que como podrás comprobar es mucho más potente en Visual Basic
que en C#, aunque debemos ser precavidos a la hora de usar esa funcionalidad extra, tal como te
comento más abajo.

Visual Basic C#

Select Case <condición> switch (<condición>)


Case <opción 1> {
'... case <opción 1>:
Case <opción 2> //...
'... break;
Case Else case <opción 2>:
'... //...
End Select break;
default:
//...
break;
}

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.

2- Conversiones entre datos


En Visual Basic para .NET podemos usar muchas formas de convertir datos de diferentes tipos,
de hecho existen instrucciones propias para convertir entre tipos de datos "elementales", por
ejemplo del tipo Double o String a Integer. Para convertir otros tipos de datos, existen
ciertas instrucciones que nos permiten hacer esas conversiones, aunque solo funcionará si la
conversión es posible, por ejemplo, si queremos convertir un tipo Cliente (definido por
nosotros) en uno de tipo Empleado, esto solo será posible si hay alguna relación directa (por
herencia o implementación de interfaces) entre esos dos tipos, o bien hemos definido alguna
sobrecarga que permita hacer esa conversión (esto solo es posible en Visual Basic 2005 o
superior).

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#

Convertir a tipo entero (Integer):

<resultado> = CInt(<expresión>) <resultado> = (int)<expresión>

<resultado> = CType(<expresión>, Integer)

Convertir a tipo Double:

<resultado> = CDbl(<expresión>) <resultado> = (double)<expresión>

<resultado> = CType(<expresión>, Double)

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).

En todas las conversiones, excepto con TryCast, si la conversión no se puede hacer, se


produce una excepción del tipo InvalidCastException, con TryCast, si no se puede hacer la
conversión "simplemente" se devuelve un valor nulo.
3- Sobre los redondeos de Visual Basic
Comprobando el código de números a letras que mi amigo Harvey Triana ha publicado en las
colaboraciones, y después de proponerle unos cambios al código de Visual Basic, (el de C# no
llegué a probarlo), me comentó que el código de C# funcionaba correctamente.
A pesar de las calores de este mes de Agosto, me entró curiosidad, y pude comprobar que el
comportamiento de las conversiones a entero de C# y Visual Basic eran diferentes, y por
tanto, no siempre producían el mismo valor, al menos usando las "instrucciones" equivalentes
que te he comentado antes, en el caso de C# con (int) y en el de Visual Basic con CType(...,
Integer).
Me puse a examinar un poco el código IL generado por las dos clases, y para mi extrañeza,
(aunque en el fondo sabía que lo hacía, ya que las funciones de conversión a enteros de Visual
Basic siempre redondean usando el llamado "redondeo bancario", tal como indica la
documentación de Visual Studio), comprobé que Visual Basic añade una llamada a
Math.Round que C# no utiliza; por tanto, si conviertes código de Visual Basic a C#, debes
tener ese redondeo en cuenta, ya que C# no redondea cuando se hace el "cast" o conversión
con (int), mientras que Visual Basic siempre lo hará, tanto con CType como con CInt.

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.

4- Parámetros opcionales (y sobrecargas)


En Visual Basic, se pueden definir parámetros opcionales, usando la instrucción Optional, en
C# no hay equivalencia para esa instrucción, por tanto no se pueden definir parámetros
opcionales, al menos de la misma forma que en Visual Basic.

La única forma de definir parámetros opcionales en C# es usando un "array de parámetros",


pero eso lo verás en la siguiente sección.

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:

Public Shared Sub PruebaOptional(ByVal uno As Integer, _


Optional ByVal dos As Integer = 0, _
Optional ByVal tres As Boolean = True)
'...
End Sub
Lo puedes convertir a este otro, en el que se usan sobrecargas para tener las tres posibilidades
que nos da el código anterior:

Public Shared Sub PruebaOptional(ByVal uno As Integer)


PruebaOptional(uno, 0, True)
End Sub

Public Shared Sub PruebaOptional(ByVal uno As Integer, _


ByVal dos As Integer)
PruebaOptional(uno, dos, True)
End Sub

Public Shared Sub PruebaOptional(ByVal uno As Integer, _


ByVal dos As Integer, _
ByVal tres As Boolean)
'...
End Sub

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á.

En C#, el código anterior de las sobrecargas, lo definiremos de esta forma:

public static void PruebaOptional(int uno) {


PruebaOptional(uno, 0, true);
}

public static void PruebaOptional(int uno, int dos) {


PruebaOptional(uno, dos, true);
}

public static void PruebaOptional(int uno, int dos, bool tres) {


//...
}
La ventaja de Optional o de las sobrecargas, es que podemos usar parámetros de distintos
tipos.

5- Array de parámetros opcionales


La alternativa de C# a los parámetros opcionales es usando un array de parámetros
opcionales, esto mismo también se puede hacer con Visual Basic.

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.

Public Shared Function PruebaArrayOpcional( ByVal ParamArray datos() As Integer)


As Long
Dim total As Long = 0
For Each i As Integer In datos
total += i
Next
Return total
End Function

public static long PruebaArrayOpcional(params int[] datos)


{
long total = 0;
foreach( int i in datos )
{
total += i;
}
return total;
}

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:

Public Shared Sub PruebaRef(ByRef uno As Integer, ByVal dos As Integer)


' Esta asignación afectará al parámetro
uno += dos
' Esta no afectará al valor usado como segundo argumento
dos = 999
End Sub
Public Shared Sub ProbandoRef()
Dim uno As Integer = 5
Dim dos As Integer = 2
Console.WriteLine("uno= {0}, dos = {1}", uno, dos)
PruebaRef(uno, dos)
Console.WriteLine("uno= {0}, dos = {1}", uno, dos)
End Sub

public static void PruebaRef(ref int uno, int dos)


{
// Esta asignación afectará al parámetro
uno += dos;
// Esta no afectará al valor usado como segundo argumento
dos = 999;
}

public static void ProbandoRef()


{
int uno = 5;
int dos = 2;
Console.WriteLine("uno= {0}, dos = {1}", uno, dos);
PruebaRef(ref uno, dos);
Console.WriteLine("uno= {0}, dos = {1}", uno, dos);
}

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

No sé en qué fila del datagrid quieres guardar la información de los textbox.


Suponiendo que sea en la primera, el código sería el siguiente para tres columnas
llamadas NOMBRE, APELLIDO y EDAD:

private void bAgregarVenta_Click(object sender, EventArgs e)


{
this.dataGridView1.Rows[0].Cells["NOMBRE"].Value = this.tbNombre.Text;
this.dataGridView1.Rows[0].Cells["APELLIDO"].Value = this.tbApellido.Text;
this.dataGridView1.Rows[0].Cells["EDAD"].Value = this.tbEdad.Text;
}

No sé cómo quieres guardar la información del datagrid en un *.txt es decir, si


quieres guardar el nombre de la columna con su valor, sólo los valores,... ¿Podrías
explicarlo?

Actualizar DataGridview con C#


Julio 9, 2009 — jav0223

Siguiendo con el post anterior ahora veremos como podemos actualizar un datagridview y que este siempre

actualizado con la informacion que vamos ingresando.

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

formulario a tu gusto tendra una forma parecida a la siguiente imagen.

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:

private BindingSource bindingsource1=new BindingSource();

Private SqlDataAdapter dataAdapter=new SqlDataAdapter();

La primer linea nos servira como enlace de los datos de la tabla con el datagridview

La segunda linea nos permitira poder unir nuestra consulta y la conexion.

Al final tendremos algo asi.


Posteriormente vamos a crear la funcion llamada actualizar como en la imagen que se presenta.

Vamos a explicar esta funcion.

actualizar(string consulta) esto permite que pasemos una cadena para que nos devuelva un resultado.

Aqui definimos la ruta de nuestra base de datos.

String datasource = @”Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\Arturo\Documents\Visual Studio

2008\Projects\ventas\ventas\dbempresa.mdf;Integrated Security=True;User Instance=True”;

Aqui ya enlazamos la consulta con la BD

dataAdapter = new SqlDataAdapter(consulta, datasource);


Generamos un comando para asociarlo con nuestro dataAdapter y poder tener actualizada la informacion de

nuestra BD

SqlCommandBuilder comando = new SqlCommandBuilder(dataAdapter);

Creamos una nueva tabla.

DataTable tabla = new DataTable();

Llenamos nuestro dataAdapter con los campos de nuestra tabla

dataAdapter.Fill(tabla);

Asignamos la fuente de datos de nuestro bindingsource

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.

En el evento Clic de nuestro boton btnActualizar ira la siguiente linea:

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 form2=new Form2;

form2.show();

BORRA UNA FILA DE UN dataGridView1


dataGridView1.Rows.RemoveAt(dataGridView1.CurrentRow.Index);

En el ejemplo siguiente, se muestra cómo llamar al método Delete como eliminado


la primera fila de la tabla Customers:
dataSet1.Tables["Customers"].Rows[0].Delete();

CUENTA LA CANTIDAD DE FILAS QUE HAY


for (i = 0; i < dataGridView1.Rows.Count; i++)
{
label15.Text = Convert.ToString(this.dataGridView1.Rows[i].Cells[2].Value);
if (label15.Text != "")
{
a++;
}

}
label10.Text = a.ToString("N0");

AGREGAR UNA NUEVA FILA A UNA TABLA

LA TABLA SE LLAMA Customers

private void button1_Click(object sender, EventArgs e)


{
DataRow newCustomersRow =aSet1.Tables["Customers"].NewRow();
newCustomersRow[0] = "NOMBRE";
newCustomersRow[1] = "APELLIDO";
dataSet1.Tables["Customers"].Rows.Add(newCustomersRow);
}

MOSTRAR FECHA Y HORA

tbFecha.Text = DateTime.Now.ToString("dd/MM/yyyy");
tbHora.Text = DateTime.Now.ToString("hh:mm:ss");
METODO PARA CERRAR UN FORM1 DEL FORM2

private void btn_entrar_Click(object sender, EventArgs e)


{
//Crea una instancia de la calse Form1
Form1 t2 = new Form1();
//Muestra el formulario en pantalla
t2.Show();
//Oculta el formulario de la presentación
Hide();
Form2 ventana2 = new Form2();
ventana2.Show();
t2.Close();
}

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).

Public Shared Function Image2Bytes(ByVal img As Image) As Byte()


Dim sTemp As String = Path.GetTempFileName()
Dim fs As New FileStream(sTemp, FileMode.OpenOrCreate, FileAccess.ReadWrite)
img.Save(fs, System.Drawing.Imaging.ImageFormat.Png)
fs.Position = 0
'
Dim imgLength As Integer = CInt(fs.Length)
Dim bytes(0 To imgLength - 1) As Byte
fs.Read(bytes, 0, imgLength)
fs.Close()
Return bytes
End Function

Public Shared Function Bytes2Image(ByVal bytes() As Byte) As Image


If bytes Is Nothing Then Return Nothing
'
Dim ms As New MemoryStream(bytes)
Dim bm As Bitmap = Nothing
Try
bm = New Bitmap(ms)
Catch ex As Exception
System.Diagnostics.Debug.WriteLine(ex.Message)
End Try
Return bm
End Function

public static byte[] Image2Bytes(Image img)


{
string sTemp = Path.GetTempFileName();
FileStream fs = new FileStream(sTemp, FileMode.OpenOrCreate, FileAccess.ReadWrite);
img.Save(fs, System.Drawing.Imaging.ImageFormat.Png);
fs.Position = 0;
//
int imgLength = Convert.ToInt32(fs.Length);
byte[] bytes = new byte[imgLength];
fs.Read(bytes, 0, imgLength);
fs.Close();
return bytes;
}

public static Image Bytes2Image(byte[] bytes)


{
if (bytes == null) return null;
//
MemoryStream ms = new MemoryStream(bytes);
Bitmap bm = null;
try
{
bm = new Bitmap(ms);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
return bm;
}

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.

Veamos ahora cómo usar estos métodos.

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:

If dr("Foto") IsNot DBNull.Value Then


Dim img As Image = TablaNavegar.Bytes2Image(CType(dr("Foto"), Byte()))
If img IsNot Nothing Then
Me.FotoPictureBox.Image = img
End If
End If
if( dr["Foto"] != DBNull.Value )
{
Image img = TablaNavegar.Bytes2Image((byte[])dr["Foto"]);
if( img != null )
{
this.FotoPictureBox.Image = img;
}
}

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.

Si quieres crear la base de datos, te comento que la estructura de la tabla es la siguiente:

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.

Figura 1. Estructura de la tabla de prueba

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

private void stock_TextChanged(object sender, EventArgs e)


{
int Result = 0;
if (!int.TryParse(stock.Text, out Result))
stock.Text = "";
}
CARGAR UNA FOTO EN UN DATAGRID
private void button5_Click(object sender, EventArgs e)
{
OpenFileDialog dialog = new OpenFileDialog();
// Se muestra al usuario esperando una acción
DialogResult result = dialog.ShowDialog();
// Si seleccionó un archivo (asumiendo que es una imagen lo que seleccionó)
// la mostramos en el PictureBox de la inferfaz
if (result == DialogResult.OK)
{
this.pictureBox1.Image = Image.FromFile(dialog.FileName);
}
}
CARGA UN FORM DENTRO DE OTRO

Form3 vet3 = new Form3();


vet3.MdiParent = this;
vet3.Show()

CREAR UNA CARPETA


DirectoryInfo DIR=new DirectoryInfo("C:/Archivos de programa/Bat");

if (!DIR.Exists)
{
DIR.Create();
}

ESTA INTRUCCION DEVUELVE UN VALOR CERO SI NO ENCONTRO


EL DATO EN EL DAGRID
this.label5.Text =
Convert.ToString(pELICULASTableAdapter.PELIFillBy(pELICULASDataSet.PELICULAS,peli.Text

TRABAJAR CON CADENAS

METODO PARA BUSCAR UN DATO EN UN DATAGRID


sOCIOSTableAdapter.DNIFillBy(sOCIOSDataSet1.SOCIOS, buscar.Text);
En el siguiente ejemplo de código se muestra el método Remove. En el penúltimo caso, se quita todo el texto a partir
del índice especificado y hasta el final de la cadena. En el último caso, se quitan tres caracteres a partir del índice
especificado.

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

*/

Cambiar mayúsculas y minúsculas

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";

System.Console.WriteLine(s6.ToUpper()); // outputs "BATTLE OF HASTINGS 1066"


System.Console.WriteLine(s6.ToLower()); // outputs "battle of hastings 1066"

ACTUALIZAR UN ARCHIVO EXCEL


private void button1_Click(object sender, EventArgs e)
{
int[] data = new int[] { 12, 123, 3, 7 };
string strConnnectionOle = @"Provider=Microsoft.Jet.OLEDB.4.0;" + @"Data
Source=C:\ejemplo-excel.xls;" +
@"Extended Properties=" + '"' + "Excel 8.0;HDR=NO" + '"';
OleDbConnection oleConn = new OleDbConnection(strConnnectionOle);
oleConn.Open();

OleDbCommand cmd = new OleDbCommand();


cmd.Connection = oleConn;

cmd.CommandText = "UPDATE [Hoja1$B2:B2] SET F1=" + data[0];


cmd.ExecuteNonQuery();

cmd.CommandText = "UPDATE [Hoja1$B3:B3] SET F1=" + data[1];


cmd.ExecuteNonQuery();

cmd.CommandText = "UPDATE [Hoja1$B4:B4] SET F1=" + data[2];


cmd.ExecuteNonQuery();

cmd.CommandText = "UPDATE [Hoja1$B5:B5] SET F1=" + data[3];


cmd.ExecuteNonQuery();

oleConn.Close();

Cadena de conexion de un excel

string strConnnectionOle = @"Provider=Microsoft.Jet.OLEDB.4.0;" +


@"Data Source=C:\libro1.xls;" +
@"Extended Properties=" + '"' + "Excel 8.0;HDR=YES" + '"';

CARGA UNA HOJA DE EXCEL EN UN DATAGRID

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;

OleDbCommand cmd = new OleDbCommand();


cmd.Connection = oleConn;
orden = new OleDbDataAdapter("select * from [Hoja1$]", oleConn);
tabla = new DataSet();
orden.Fill(tabla, "[Hoja1$]");
dataGridView1.DataSource = tabla;
dataGridView1.DataMember = "[Hoja1$]";
oleConn.Close();
}
AYUDA http://msdn.microsoft.com/es-es/library/ekw4dh3f(v=VS.71).

Importar hoja de cálculo Excel de datos en SQL


Server base de datos de tabla mediante
SqlBulkCopy
por David Hayden ( ASP.NET C # para desarrolladores de la Florida )

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:

/ Connection String to Excel Workbook


string excelConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=Book1.xls;Extended
Properties=""Excel 8.0;HDR=YES;""";

// Create Connection to Excel Workbook


using (OleDbConnection connection =
new OleDbConnection(excelConnectionString))
{
OleDbCommand command = new OleDbCommand
("Select ID,Data FROM [Data$]", connection);
connection.Open();

// Create DbDataReader to Data Worksheet


using (DbDataReader dr = command.ExecuteReader())
{
// SQL Server Connection String
string sqlConnectionString = "Data Source=.;
Initial Catalog=Test;Integrated Security=True";

// Bulk Copy to SQL Server


using (SqlBulkCopy bulkCopy =
new SqlBulkCopy(sqlConnectionString))
{
bulkCopy.DestinationTableName = "ExcelData";
bulkCopy.WriteToServer(dr);
}
}
}

Exportar un DataGridView a Excel en


C#
hola chavos yo tenia el mismo problema para guardar el contenido de un Datagrid a excel usando c#,
pero ya lo resolvi y les comparto el metodo para exporta, solo hay que cambiar el nombre del
DataGridView por el tuyo en donde dice "TuDataGrid"

para esto tiene que agregar la referencia "Microsoft Excel 12.0 Object Library"

que se encuentra en la pestaña de COM

public void exporta_a_excel()

Microsoft.Office.Interop.Excel.ApplicationClass excel = new ApplicationClass();

excel.Application.Workbooks.Add(true);

int ColumnIndex = 0;

foreach (DataGridViewColumn col in TuDataGrid.Columns )

ColumnIndex++;

excel.Cells[1, ColumnIndex] = col.Name;

int rowIndex = 0;
foreach (DataGridViewRow row in TuDataGrid.Rows )

rowIndex++;

ColumnIndex = 0;

foreach (DataGridViewColumn col in TuDataGrid.Columns)

ColumnIndex++;

excel.Cells[rowIndex + 1, ColumnIndex] = row.Cells[col.Name].Value ;

excel.Visible = true;

Worksheet worksheet = (Worksheet)excel.ActiveSheet;

worksheet.Activate();

Cómo utilizar ADO.NET para recuperar y modificar registros en un libro


de Excel con Visual Basic .NET

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

proveedor OLE DB de Jet cuando Excel es el origen de datos de destino.

Volver al principio

Cómo utilizar el proveedor OLE DB de Jet con libros de Microsoft Excel


El motor de base de datos Microsoft Jet tener acceso a datos en otros formatos de archivo base de datos, como libros de

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

una propiedad para indicar o no las tablas incluyen los encabezados.

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

MAXSCANROWS establecer en las propiedades extendidas de la cadena de conexión.

Convenciones de nomenclatura de tabla


Hay varias formas de puede hacer referencia a una tabla (o rango) en un libro de Excel:

 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.

Seleccionar * desde [Sheet1 $]

 Utilizar un rango con un nombre definido (por ejemplo, [MyNamedRange]):

Seleccionar * desde [MyNamedRange]

 Utilizar un rango con una dirección específica (por ejemplo, [Hoja1 $ A1: B10]):

Seleccionar * desde [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

Cómo usar Excel Workbooks como orígenes de datos de ADO.NET

Recuperar registros

Puede recuperar registros de una base de datos utilizando uno de estos dos enfoques de ADO.NET: con un conjunto de

datos o con un DataReader .

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

base de datos subyacente.

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 .

Agregar y actualizar registros


Con ADO.NET, puede insertar y actualizar registros en un libro en una de estas tres maneras:

 Ejecutar directamente un comando para insertar o actualizar los registros de uno a la vez. Para ello, puede crear

un objeto OLEDbCommand en la conexión y establezca su propiedad CommandText en un comando válido

para insertar registros

INSERT INTO [Sheet1$] (F1, F2) values ('111', 'ABC')

o un comando para actualizar registros

UPDATE [Sheet1$] SET F2 = 'XYZ' WHERE F1 = '111'

y, a continuación, llame al método ExecuteNonQuery .

 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

parametrizada del DataAdapter es InsertCommand

INSERT INTO [Sheet1$] (F1, F2) values (?, ?)

y UpdateCommand :

UPDATE [Sheet1$] SET F2 = ? WHERE F1 = ?

comandos parametrizados INSERT y UPDATE son necesarios porque OleDbDataAdapterno proporciona

información de clave o índice de libros de Excel; sin campos de clave o índice CommandBuilder no puede

generar automáticamente los comandos para.

 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 [Sheet1$] IN 'C:\Book1.xls' 'Excel 8.0;' SELECT * FROM MyTable"

INSERT INTO requiere que la tabla de destino (o la hoja de cálculo) ya existe; datos se anexan a la tabla de

destino.

También puede utilizar SELECTINTO para exportar la consulta de tabla a un libro:


SELECT * INTO [Excel 8.0;Database=C:\Book1.xls].[Sheet1] FROM [MyTable]

al utilizar SELECTINTO, si el libro o tabla de destino no existe, se creará para usted. Si la tabla ya existe antes

de la instrucción SELECTINTO comando es emitido, recibirá un error.

El Sample Code de la sección más adelante en este artículo muestra cada uno de estos métodos para agregar y

actualizar registros en un libro.

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:

Este ISAM no admite la eliminación de datos de una tabla vinculada.

Esta limitación es inherente en el tratamiento de los libros de Excel como bases de datos.

Crear libros y tablas

Para crear una tabla en un libro de Excel, ejecute CREATE TABLE comando:

CREATE TABLE Sheet1 (F1 char(255), F2 char(255))


al ejecutar este comando, se crea una nueva hoja de cálculo con el nombre de la tabla especificar en el comando. Si el

libro para la conexión no existe, también se crearán.

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

1. Inicie un nuevo proyecto de Aplicación para Windows de Visual Basic.NET.

se creará Form1 de forma predeterminada.

2. Agregar controles de RadioButton seis y un control Button a Form1 .

3. Seleccione todos los controles RadioButton y establezca la propiedad Size para 200,24 .

4. En el menú Ver , haga clic en código .

5. Agregue la línea siguiente al principio del módulo de código:

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.

11. Private m_sConn2 As String = "Provider=Microsoft.Jet.OLEDB.4.0;" & _

12. "Data Source=C:\ExcelData2.xls;" & _


13. "Extended Properties=""Excel 8.0;HDR=YES"""
14.

15. Private m_sNorthwind = _

16. "C:\Program Files\Microsoft Office\Office10\Samples\Northwind.mdb"


17.

18. Private m_sAction As String

19.

20. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)

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.

30. Private Sub RadioButtons_Click(ByVal sender As Object, ByVal e As System.EventArgs) _

31. Handles RadioButton1.Click, RadioButton2.Click, RadioButton3.Click, _


32. RadioButton4.Click, RadioButton5.Click, RadioButton6.Click
33. m_sAction = sender.Text'Store the text for the selected radio button
34. End Sub

35.

36. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)

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.

48. Catch ex As OleDbException


49. Dim er As OleDbError
50. For Each er In ex.Errors
51. MsgBox(er.Message)
52. Next
53. Catch ex2 As System.InvalidOperationException
54. MsgBox(ex2.Message)
55. End Try
56.

57.

58. End Sub

59.

60. Public Sub Create_Workbook()

61.

62. ' If the workbooks already exist, prompt to delete.


63. Dim answer As MsgBoxResult
64. If Dir("C:\ExcelData1.xls") <> "" Or Dir("C:\ExcelData2.xls") <> "" Then
65. answer = MsgBox("Delete existing workbooks (C:\ExcelData1.xls and " & _
66. "C:\ExcelData2.xls)?", MsgBoxStyle.YesNo)
67. If answer = MsgBoxResult.Yes Then
68. If Dir("C:\ExcelData1.xls") <> "" Then Kill("C:\ExcelData1.xls")
69. If Dir("C:\ExcelData2.xls") <> "" Then Kill("C:\ExcelData2.xls")
70. Else
71. Exit Sub
72. End If
73. End If
74.

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. '==========================================================================

79. Dim conn As New OleDbConnection()


80. conn.ConnectionString = m_sConn1
81. conn.Open()
82. Dim cmd1 As New OleDbCommand()
83. cmd1.Connection = conn
84. cmd1.CommandText = "CREATE TABLE EmployeeData (Id char(255), Name char(255),
BirthDate date)"
85. cmd1.ExecuteNonQuery()
86. cmd1.CommandText = "INSERT INTO EmployeeData (Id, Name, BirthDate) values ('AAA',
'Andrew', '12/4/1955')"
87. cmd1.ExecuteNonQuery()
88. conn.Close()
89.

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.

95. conn.ConnectionString = m_sConn2


96. conn.Open()
97. Dim cmd2 As New OleDbCommand()
98. cmd2.Connection = conn
99. cmd2.CommandText = "CREATE TABLE InventoryData (Product char(255), Qty float,
Price currency)"
100. cmd2.ExecuteNonQuery()
101. cmd2.CommandText = "INSERT INTO InventoryData (Product, Qty, Price) values
('Cola', 200, 1.35)"
102. cmd2.ExecuteNonQuery()
103. cmd2.CommandText = "INSERT INTO InventoryData (Product, Qty, Price) values
('Chips', 550, 0.89)"
104. cmd2.ExecuteNonQuery()
105. conn.Close()
106.

107. ' NOTE: You can ALTER and DROP tables in a similar fashion.
108.

109. End Sub


110.

111. Public Sub Retrieve_Records()


112.

113. '==========================================================
114. 'Use a DataReader to read data from the EmployeeData table.
115. '==========================================================
116.

117. Dim conn1 As New System.Data.OleDb.OleDbConnection(m_sConn1)


118. conn1.Open()
119. Dim cmd1 As New System.Data.OleDb.OleDbCommand("Select * From [EmployeeData$]",
conn1)
120. Dim rdr As OleDbDataReader = cmd1.ExecuteReader
121.

122. Debug.WriteLine(vbCrLf & "EmployeeData:" & vbCrLf & "=============")


123. Do While rdr.Read()
124. Debug.WriteLine(System.String.Format("{0,-10}{1, -15}{2}", _
125. rdr.GetString(0), rdr.GetString(1), _
126. rdr.GetDateTime(2).ToString("d")))
127. Loop
128. rdr.Close()
129. conn1.Close()
130.

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.

146. End Sub


147.

148. Public Sub Add_Records()


149.

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.

179. ' Add two new records to the dataset.


180. Dim dr As DataRow
181. dr = ds.Tables(0).NewRow
182. dr("Product") = "Bread" : dr("Qty") = 390 : dr("Price") = 1.89 :
ds.Tables(0).Rows.Add(dr)
183. dr = ds.Tables(0).NewRow
184. dr("Product") = "Milk" : dr("Qty") = 99 : dr("Price") = 2.59 :
ds.Tables(0).Rows.Add(dr)
185.

186. ' Apply the dataset changes to the actual data source (the workbook).
187. da.Update(ds, "MyExcelTable")
188. conn2.Close()
189.

190. End Sub


191.

192. Public Sub Update_Records()


193.

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.

223. ' Update the first two records.


224. ds.Tables(0).Rows(0)("Qty") = 1000
225. ds.Tables(0).Rows(0)("Price") = 10.1
226. ds.Tables(0).Rows(1)("Qty") = 2000
227. ds.Tables(0).Rows(1)("Price") = 20.2
228.

229. ' Apply the dataset changes to the actual data source (the workbook).
230. da.Update(ds, "MyInventoryTable")
231. conn2.Close()
232.

233. End Sub


234.

235. Public Sub Update_Individual_Cells()


236.

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.

254. End Sub


255.

256. Public Sub Use_External_Source()


257.

258. ' Open a connection to the sample Northwind Access database.


259. Dim conn As New System.Data.OleDb.OleDbConnection( _
260. "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & m_sNorthwind & ";")
261. conn.Open()
262. Dim cmd As New System.Data.OleDb.OleDbCommand()
263. cmd.Connection = conn
264.

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

m_sNorthwind en el código, si es necesario.

Pruébelo
1. En el menú Ver , elija Otras ventanas y, a continuación, haga clic en resultados para mostrar la

ventana resultados .

2. Presione F5 para generar y ejecutar el programa.

3. Haga clic en Create_Workbook y haga clic en Ir . El procedimiento Create_Workbookejecuta comandos de

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.

Las tablas se rellenan con los registros.

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.

4. Haga clic en Retrieve_Records y haga clic en Ir . El procedimiento Retrieve_Recordsextrae los registros de

las tablas y mostrarlos en la ventana resultados , similar a ésta:

5. EmployeeData:
6. =============
7. AAA Andrew 12/4/1955
8.

9. InventoryData:
10. ==============

11. Cola 200 1.35


Chips 550 0.89
12. Haga clic en Add_Records y haga clic en Ir . La rutina Add_Records agrega dos registros a cada tabla:

13. EmployeeData:

14. =============

15. AAA Andrew 12/4/1955


16. CCC Charlie 10/14/1948
17. DDD Deloris 7/19/1998
18.

19. InventoryData:

20. ==============

21. Cola 200 1.35


22. Chips 550 0.89
23. Bread 390 1.89
Milk 99 2.59
24. Haga clic en Update_Records y haga clic en Ir . La rutina Update_Records actualiza dos registros en cada

libro:

25. EmployeeData:

26. =============

27. AAA Aaron 5/4/1975


28. CCC Charlie 10/14/1948
29. DDD Deloris 7/19/1998
30.

31. InventoryData:

32. ==============

33. Cola 1000 10.1


34. Chips 2000 20.2
35. Bread 390 1.89
Milk 99 2.59
36. Haga clic en Update_Individual_Cells y haga clic en Ir . La rutinaUpdate_Individual_Cells modifica celdas

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

porque la clave principal no se reconoce o forzada.

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

formato de la fila por encima de él.

El siguiente procedimiento muestra cómo puede utilizar el formato en un libro con el código de ejemplo:

1. Presione F5 para generar y ejecutar el ejemplo.

2. En Form1, haga clic en Create_Workbook y haga clic Buscar .

3. Inicie Microsoft Excel y abra C:\ExcelData1.xls.

4. Aplicar un estilo de negrita a la celda A2.

5. Aplicar una cursiva, el estilo a la celda B2 de subrayado y centrar.

6. Aplicar un formato de fecha larga a la celda C2.

7. Guarde y cierre C:\ExcelData1.xls.

8. En Form1, haga clic en Add_Records y haga clic Buscar .

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:

 No puede insertar las fórmulas en celdas mediante ADO.NET.

 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

e inserciones de registros en un libro de Excel.

Volver al principio

Connection strings for Excel 2007


Providers for Excel 2007
» ACE OLEDB 12.0
» .NET Framework Data Provider for OLE DB (OleDbConnection)
» .NET xlReader for Microsoft Excel (ExcelConnection)
Community Forums
Find solutions and post questions regarding connection string related issues.
Forum for Excel 2007 >>

ACE OLEDB 12.0


Type: OLE DB Provider
Usage: Provider=Microsoft.ACE.OLEDB.12.0
Manufacturer: Microsoft
More info about this provider »
Customize string example values »
Xlsx files
This one is for connecting to Excel 2007 files with the Xlsx file extension. That is the Office Open XML format with macros disabled.
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\myFolder\myExcel2007file.xlsx;Extended
Properties="Excel 12.0 Xml;HDR=YES";
"HDR=Yes;" indicates that the first row contains columnnames, not data. "HDR=No;" indicates the opposite.

Treating data as text


Use this one when you want to treat all data in the file as text, overriding Excels column type "General" to guess what type of data is in
the column.
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\myFolder\myExcel2007file.xlsx;Extended
Properties="Excel 12.0 Xml;HDR=YES;IMEX=1";
If you want to read the column headers into the result set (using HDR=NO even though there is a header) and the column data is
numeric, use IMEX=1 to avoid crash.

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) &quot;
or maybe use a single quota '.

"HDR=Yes;" indicates that the first row contains columnnames, not data. "HDR=No;" indicates the opposite.

.NET Framework Data Provider for OLE DB


Type: .NET Framework Wrapper Class Library
Usage: System.Data.OleDb.OleDbConnection
Manufacturer: Microsoft
More info about this wrapper class library »
Customize string example values »
Bridging to ACE OLEDB 12.0
This is just one connection string sample for the wrapping OleDbConnection class that calls the underlying OLEDB provider. See
respective OLE DB provider for more connection strings to use with this class.
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\myFolder\myExcel2007file.xlsx;Extended
Properties="Excel 12.0 Xml;HDR=YES";

.NET xlReader for Microsoft Excel


Type: .NET Framework Class Library
Usage: VM.xPort.ExcelClient.ExcelConnection
Manufacturer: xPortTools
More info about this class library »
Customize string example values »
Excel file with header row
Data Source =c:\myExcelFile.xlsx;HDR=yes;Format=xlsx;

Excel file without header row


Data Source =c:\myExcelFile.xlsx;HDR=no;Format=xlsx;

CONEXIÓN C# - SQL SERVER 2005

http://www.megaupload.com/?d=1UPQ2DXO

Sql server 2005

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

pd: porsiacaso no es sqlexpress

Acceso a una base de datos de


SQL Server con ADO.NET y
Visual C#
Publicado el 05/Feb/2006
Actualizado el 05/Feb/2006
Autor: Guillermo 'guille' Som

Código de ejemplo válido para cualquier versión de Visual C#

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.

Además de lo dicho, en este ejemplo también verás cómo hacer lo siguiente:


-Deshabilitar los controles que estén incluidos en un GroupBox.
-Conectar a la base de datos de SQL Server usando la autenticación integrada de Windows.
-Obtener todos los datos indicados en una orden SELECT y guardarlos en un DataTable.
-Moverse por los registros de la tabla usando los típicos comandos: Primero, Anterior, Siguiente y
Último.
-Añadir nuevos registros (o filas) a la tabla.
-Eliminar una fila de la tabla.
-Actualizar los datos de la fila actual.

Y como valor añadido, la utilidad de ejemplo también tiene código para:


-Saber las instancias de SQL Server.
-Saber las bases de datos de una instancia de SQL Server.
-Saber si una tabla en concreto existe en una base de datos de SQL.
-Crear una tabla (la usada en esta aplicación de ejemplo).

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.

Estructura de la tabla de ejemplo


Para que este código funcione, debes tener una base de datos en la que se incluya una tabla
llamada Prueba.
Pulsa aquí si quieres saber cómo crear una base de datos de SQL Server usando código de Visual C#.

La estructura de esa tabla (Prueba) es la que se muestra en la siguiente tabla.


Si no la tienes creada en la base de datos que elijas, el programa te preguntará si la quieres crear, así que no
te preocupes de que no la tengas creada.

Nombre campo Tipo Comentario


ID int Clave principal auto-numérica (identidad)
Nombre nvarchar 50 caracteres
e-mail nvarchar 128 caracteres
FechaAlta datetime -
Comentario nvarchar 2048 caracteres

El formulario para acceder a la base de datos


La aplicación de ejemplo tiene un formulario con el siguiente aspecto:
El formulario de la aplicación de ejemplo

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.

El resto de controles simplemente los usamos para mostrar los datos.

Las variables comunes para todo el código


A lo largo de la aplicación usaremos algunas variables comunes, en realidad son tres:
dt del tipo DataTable, será la tabla a la que asignaremos los datos de la tabla de la base de datos
da del tipo SqlDataAdapter, será el adaptador que nos permitirá acceder a la base de datos, para leer
los datos y actualizarlos.
fila del tipo int, será el índice de la fila actual, con idea de saber cual será la siguiente, la anterior o la
fila que queremos actualizar.

// Las variables que usaremos en este ejemplo


private DataTable dt;
private SqlDataAdapter da;
private int fila;

Form_Load: Deshabilitar los controles y asignar el path de la base


de datos
Al empezar la aplicación, en el evento Form_Load, deshabilitaremos los controles que están en el
GroupBox, además, averiguaremos las instancias de SQL Server que hay actualmente en el equipo y
las asignaremos en el combo correspondiente, también añadiremos al otro combo las bases de datos
que contenga la instancia predeterminada de SQL Server, y si hay alguna base de datos (que no sea
del sistema), seleccionaremos la primera (índice cero).

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.

private void Form1_Load(object sender, EventArgs e) {


this.Text="Ejemplo acceso SQL Server C#";

// Limpiar los controles del GroupBox y


// deshabilitarlos hasta que se conecte a la base de datos
foreach(Control c in this.GroupBox1.Controls){
// Limpiar los textbox
if( c is TextBox ){
c.Text = "";
}
// Deshabilitarlos
c.Enabled = false;
}
this.GroupBox1.Enabled = false;
this.GroupBox1.Text = "Debes conectar antes de usar los datos";
//
// Las instancias de SQL Server que hay instaladas
string[] instancias;
instancias = instanciasInstaladas();
foreach(string s in instancias){
if( s == "MSSQLSERVER" ){
cboInstancias.Items.Add("(local)");
}else{
cboInstancias.Items.Add(@"(local)\" + s);
}
}
cboInstancias.Text = "(local)";

// Los nombres de las bases de datos


string[] bases = basesDeDatos("(local)");
if( bases != null ){
this.cboBases.Items.AddRange(bases);
}
if( this.cboBases.Items.Count > 0 ){
this.cboBases.SelectedIndex = 0;
}
}
Al seleccionar una instancia, asignar las bases de datos que contiene

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.

private void cboInstancias_SelectedIndexChanged(object sender, EventArgs e) {


string[] bases = basesDeDatos(cboInstancias.Text);
cboBases.Items.Clear();
if( bases != null ){
this.cboBases.Items.AddRange(bases);
}
if( cboBases.Items.Count > 0 ){
cboBases.SelectedIndex = 0;
}
}

Conectar a la base de datos


Para conectar con la base de datos y obtener los datos, necesitamos una cadena de conexión al
servidor de SQL Server que indique que base de datos vamos a usar. Los datos los obtendremos
mediante una cadena de selección (SELECT).

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.

Otra cosa importante que debemos tener en cuenta con el código de


selección (SELECT) es que si en lugar de indicar un asterisco para que se utilicen todos los
campos ( SELECT * ), indicamos solo los campos que nos interesan, en las actualizaciones y
lecturas de datos solo podremos incluir los campos indicados.
Por ejemplo, si hacemos: SELECT ID, Nombre FROM Prueba, tan solo tendremos acceso a
esos dos campos, y cualquier intento de acceder a otros campos (aunque sean válidos y
existan en la tabla) dará error.

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";

SqlConnection cnn = new SqlConnection(sCnn);


if( existeTabla(cnn, "Prueba") == false ){
if( MessageBox.Show("NO existe la tabla Prueba, que es la usada para este ejemplo.\n"
+
"¿Quieres crearla?", "No existe la tabla", MessageBoxButtons.YesNo) ==
DialogResult.Yes )
{
if( crearTablaPrueba() == false ){
return;
}
}
else{
return;
}
}

// 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";

// Y mostrar el primer registro


if( dt.Rows.Count > 0 ){
btnFirst_Click(null, null);
}
else{
fila = -1;
btnActualizar.Enabled = false;
}
}
catch(Exception ex){
MessageBox.Show("ERROR al conectar o recuperar los datos:\n" +
ex.Message, "Conectar con la base",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

La función para saber si existe la tabla indicada

private bool existeTabla(SqlConnection cnn, string nombreTabla) {


// Devuelve true si la tabla indicada está en la base usada con la conexión
DataTable dt = new DataTable();
bool existe = false;
//
try{
SqlDataAdapter da = new SqlDataAdapter(
"SELECT * FROM INFORMATION_SCHEMA.TABLES " +
"WHERE TABLE_TYPE = 'BASE TABLE' " +
"ORDER BY TABLE_TYPE", cnn);
//
da.Fill(dt);
if( nombreTabla == null)
nombreTabla = "Prueba";
foreach(DataRow dr in dt.Rows){
if( dr["TABLE_NAME"].ToString() == nombreTabla ){
return true;
}
}
//
return existe;

}
catch(Exception ex){
MessageBox.Show("ERROR: " + ex.Message, "Comprobar tabla");
return false;
}
}

El método para crear la tabla de ejemplo (Prueba)

private bool crearTablaPrueba() {


// Crear la tabla de prueba en la base e instancias seleccionadas
// Devuelve true si todo fue bien
bool creada = false;
string sCnn = "Server=" + cboInstancias.Text + "; database=" + cboBases.Text + ";
integrated security=yes";
string sCmd = "CREATE TABLE [dbo].[Prueba]( " +
"[ID] [int] IDENTITY(1,1) NOT NULL, " + "[Nombre] [nvarchar](50) COLLATE
Modern_Spanish_CI_AS NULL," +
"[e-mail] [nvarchar](128) COLLATE Modern_Spanish_CI_AS NULL," +
"[FechaAlta] [datetime] NULL," + "[Comentario] [nvarchar](2048) COLLATE
Modern_Spanish_CI_AS NULL," +
"CONSTRAINT [PK_Prueba] PRIMARY KEY CLUSTERED (" +
"[ID] ASC)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY])" +
" ON [PRIMARY]";
SqlConnection cnn = null;
try{
cnn = new SqlConnection(sCnn);
cnn.Open();
SqlCommand cmd = new SqlCommand(sCmd, cnn);

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;
}

Añadir nuevos registros


Para añadir nuevos registros, lo primero que tenemos que hacer es crear una nueva fila.
Para ello utilizamos el método NewRow del objeto DataTable.

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.

La asignación de los campos la hacemos mediante el método asignarDatos, aunque podríamos


haberlo hecho directamente.
El hacerlo mediante ese método es para que nos resulte más cómo adaptar este ejemplo a otra tabla
diferente a la que yo propongo, ya que en ese método haríamos todas las asignaciones que debamos
hacer, salvo la del campo ID ya que al ser autonumérico no podemos asignarle un valor, porque ese
valor lo asignará automáticamente ADO.NET.

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.

Finalmente actualizamos los datos mediante el método Update del adaptador.


En realidad no hace falta hacer esa actualización en este preciso momento, pero si no lo hacemos,
debemos añadir otro botón para que los datos se asignen a la base de datos, ya que al añadir un
nuevo valor a la tabla, lo haremos en la "copia" que tenemos localmente en memoria, y no
directamente en la base de datos, como ocurría, por ejemplo, con VB6 y los Recordsets.

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!

private void btnNuevo_Click(object sender, EventArgs e) {


// Crear un nuevo registro
DataRow dr = dt.NewRow();
// Asignar los datos de los textbox a la fila
asignarDatos(dr);

// Añadir la nueva fila a la tabla


dt.Rows.Add(dr);
// Guardar físicamente los datos en la base
try{
da.Update(dt);
dt.AcceptChanges();
// Si es el primer registro de la base,
// volver a leer los datos para actualizar los IDs
if( Convert.ToInt32("0" + dr["ID"].ToString()) == 0 ){
dt = new DataTable();
da.Fill(dt);
}
// Posicionarlo en la última fila
btnLast_Click(null, null);
}catch(DBConcurrencyException ex){
MessageBox.Show("Error de concurrencia:\n" + ex.Message);
}catch(Exception ex){
MessageBox.Show(ex.Message);
}
}

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;
}

Actualizar los registros modificados


La actualización de los datos, es decir, cuando modificamos un registro (o fila) y queremos que esos
datos se guarden, es muy simple. En el código del método de actualizar, primero comprobamos que el
valor de la variable fila sea válido, es decir, esté dentro del rango de filas que tiene el DataTable.

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);
}
}

Eliminar el registro actual


Una vez que tenemos un registro mostrado, podemos pulsar en el botón Eliminar, para hacerlo,
usamos el método Delete de la fila indicada y a continuación le indicamos al adaptador que actualice
los datos físicamente en la base y a la tabla le tenemos que indicar que acepte los cambios, con idea
de que esa fila que hemos eliminado, la elimine también de la memoria.

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.

private void btnEliminar_Click(object sender, EventArgs e) {


// Eliminar la fila actual
if( fila < 0 || fila > dt.Rows.Count - 1 ) return;

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.

Moverse entre registros, con comandos para ir al primero, al


último, al anterior y al siguiente
Para movernos entre los registros usaremos cuatro métodos, uno para ir al principio, otro para ir al
final, otro para ir al registro anterior y otro para el siguiente.

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.

private void mostrarDatos(int f) {


int uf = dt.Rows.Count - 1;
if( f < 0 || uf < 0 ) return;
//
DataRow dr = dt.Rows[f];
txtID.Text = dr["ID"].ToString();
txtNombre.Text = dr["Nombre"].ToString();
txtEmail.Text = dr["e-mail"].ToString();
txtFechaAlta.Text = dr["FechaAlta"].ToString();
txtComentario.Text = dr["Comentario"].ToString();
//
btnActualizar.Enabled = true;
btnEliminar.Enabled = true;
}
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.

private void btnFirst_Click(object sender, EventArgs e) {


// Posicionarse en la primera fila
fila = 0;
// Mostrar los datos de la fila indicada
mostrarDatos(fila);
}

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.

private void btnLast_Click(object sender, EventArgs e) {


// Posicionarse en la última fila
fila = dt.Rows.Count - 1;
// Mostrar los datos de la fila indicada
mostrarDatos(fila);
}

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.

private void btnPrev_Click(object sender, EventArgs e) {


// Posicionarse en la fila anterior
fila = fila - 1;
if( fila < 0 ) fila = 0;
// Mostrar los datos de la fila indicada
mostrarDatos(fila);
}

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.

private void btnNext_Click(object sender, EventArgs e) {


// Posicionarse en la fila siguiente
int uf = dt.Rows.Count - 1;
fila = fila + 1;
if( fila > uf ) fila = uf;
// Mostrar los datos de la fila indicada
mostrarDatos(fila);
}

Acceso a una base de datos de


SQL Server con ADO.NET y
Visual C#
Publicado el 05/Feb/2006
Actualizado el 05/Feb/2006
Autor: Guillermo 'guille' Som

Código de ejemplo válido para cualquier versión de Visual C#

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.

Además de lo dicho, en este ejemplo también verás cómo hacer lo siguiente:


-Deshabilitar los controles que estén incluidos en un GroupBox.
-Conectar a la base de datos de SQL Server usando la autenticación integrada de Windows.
-Obtener todos los datos indicados en una orden SELECT y guardarlos en un DataTable.
-Moverse por los registros de la tabla usando los típicos comandos: Primero, Anterior, Siguiente y
Último.
-Añadir nuevos registros (o filas) a la tabla.
-Eliminar una fila de la tabla.
-Actualizar los datos de la fila actual.

Y como valor añadido, la utilidad de ejemplo también tiene código para:


-Saber las instancias de SQL Server.
-Saber las bases de datos de una instancia de SQL Server.
-Saber si una tabla en concreto existe en una base de datos de SQL.
-Crear una tabla (la usada en esta aplicación de ejemplo).

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.

Estructura de la tabla de ejemplo


Para que este código funcione, debes tener una base de datos en la que se incluya una tabla
llamada Prueba.
Pulsa aquí si quieres saber cómo crear una base de datos de SQL Server usando código de Visual C#.

La estructura de esa tabla (Prueba) es la que se muestra en la siguiente tabla.


Si no la tienes creada en la base de datos que elijas, el programa te preguntará si la quieres crear, así que no
te preocupes de que no la tengas creada.

Nombre campo Tipo Comentario


ID int Clave principal auto-numérica (identidad)
Nombre nvarchar 50 caracteres
e-mail nvarchar 128 caracteres
FechaAlta datetime -
Comentario nvarchar 2048 caracteres

El formulario para acceder a la base de datos


La aplicación de ejemplo tiene un formulario con el siguiente aspecto:

El formulario de la aplicación de ejemplo

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.

El resto de controles simplemente los usamos para mostrar los datos.

Las variables comunes para todo el código


A lo largo de la aplicación usaremos algunas variables comunes, en realidad son tres:
dt del tipo DataTable, será la tabla a la que asignaremos los datos de la tabla de la base de datos
da del tipo SqlDataAdapter, será el adaptador que nos permitirá acceder a la base de datos, para leer
los datos y actualizarlos.
fila del tipo int, será el índice de la fila actual, con idea de saber cual será la siguiente, la anterior o la
fila que queremos actualizar.

// Las variables que usaremos en este ejemplo


private DataTable dt;
private SqlDataAdapter da;
private int fila;
Form_Load: Deshabilitar los controles y asignar el path de la base
de datos
Al empezar la aplicación, en el evento Form_Load, deshabilitaremos los controles que están en el
GroupBox, además, averiguaremos las instancias de SQL Server que hay actualmente en el equipo y
las asignaremos en el combo correspondiente, también añadiremos al otro combo las bases de datos
que contenga la instancia predeterminada de SQL Server, y si hay alguna base de datos (que no sea
del sistema), seleccionaremos la primera (índice cero).

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.

private void Form1_Load(object sender, EventArgs e) {


this.Text="Ejemplo acceso SQL Server C#";

// Limpiar los controles del GroupBox y


// deshabilitarlos hasta que se conecte a la base de datos
foreach(Control c in this.GroupBox1.Controls){
// Limpiar los textbox
if( c is TextBox ){
c.Text = "";
}
// Deshabilitarlos
c.Enabled = false;
}
this.GroupBox1.Enabled = false;
this.GroupBox1.Text = "Debes conectar antes de usar los datos";
//
// Las instancias de SQL Server que hay instaladas
string[] instancias;
instancias = instanciasInstaladas();
foreach(string s in instancias){
if( s == "MSSQLSERVER" ){
cboInstancias.Items.Add("(local)");
}else{
cboInstancias.Items.Add(@"(local)\" + s);
}
}
cboInstancias.Text = "(local)";
// Los nombres de las bases de datos
string[] bases = basesDeDatos("(local)");
if( bases != null ){
this.cboBases.Items.AddRange(bases);
}
if( this.cboBases.Items.Count > 0 ){
this.cboBases.SelectedIndex = 0;
}
}

Al seleccionar una instancia, asignar las bases de datos que contiene

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.

private void cboInstancias_SelectedIndexChanged(object sender, EventArgs e) {


string[] bases = basesDeDatos(cboInstancias.Text);
cboBases.Items.Clear();
if( bases != null ){
this.cboBases.Items.AddRange(bases);
}
if( cboBases.Items.Count > 0 ){
cboBases.SelectedIndex = 0;
}
}

Conectar a la base de datos


Para conectar con la base de datos y obtener los datos, necesitamos una cadena de conexión al
servidor de SQL Server que indique que base de datos vamos a usar. Los datos los obtendremos
mediante una cadena de selección (SELECT).

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.

Otra cosa importante que debemos tener en cuenta con el código de


selección (SELECT) es que si en lugar de indicar un asterisco para que se utilicen todos los
campos ( SELECT * ), indicamos solo los campos que nos interesan, en las actualizaciones y
lecturas de datos solo podremos incluir los campos indicados.
Por ejemplo, si hacemos: SELECT ID, Nombre FROM Prueba, tan solo tendremos acceso a
esos dos campos, y cualquier intento de acceder a otros campos (aunque sean válidos y
existan en la tabla) dará error.

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";

SqlConnection cnn = new SqlConnection(sCnn);


if( existeTabla(cnn, "Prueba") == false ){
if( MessageBox.Show("NO existe la tabla Prueba, que es la usada para este ejemplo.\n"
+
"¿Quieres crearla?", "No existe la tabla", MessageBoxButtons.YesNo) ==
DialogResult.Yes )
{
if( crearTablaPrueba() == false ){
return;
}
}
else{
return;
}
}

// 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";

// Y mostrar el primer registro


if( dt.Rows.Count > 0 ){
btnFirst_Click(null, null);
}
else{
fila = -1;
btnActualizar.Enabled = false;
}
}
catch(Exception ex){
MessageBox.Show("ERROR al conectar o recuperar los datos:\n" +
ex.Message, "Conectar con la base",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

La función para saber si existe la tabla indicada

private bool existeTabla(SqlConnection cnn, string nombreTabla) {


// Devuelve true si la tabla indicada está en la base usada con la conexión
DataTable dt = new DataTable();
bool existe = false;
//
try{
SqlDataAdapter da = new SqlDataAdapter(
"SELECT * FROM INFORMATION_SCHEMA.TABLES " +
"WHERE TABLE_TYPE = 'BASE TABLE' " +
"ORDER BY TABLE_TYPE", cnn);
//
da.Fill(dt);
if( nombreTabla == null)
nombreTabla = "Prueba";
foreach(DataRow dr in dt.Rows){
if( dr["TABLE_NAME"].ToString() == nombreTabla ){
return true;
}
}
//
return existe;

}
catch(Exception ex){
MessageBox.Show("ERROR: " + ex.Message, "Comprobar tabla");
return false;
}
}

El método para crear la tabla de ejemplo (Prueba)

private bool crearTablaPrueba() {


// Crear la tabla de prueba en la base e instancias seleccionadas
// Devuelve true si todo fue bien
bool creada = false;
string sCnn = "Server=" + cboInstancias.Text + "; database=" + cboBases.Text + ";
integrated security=yes";
string sCmd = "CREATE TABLE [dbo].[Prueba]( " +
"[ID] [int] IDENTITY(1,1) NOT NULL, " + "[Nombre] [nvarchar](50) COLLATE
Modern_Spanish_CI_AS NULL," +
"[e-mail] [nvarchar](128) COLLATE Modern_Spanish_CI_AS NULL," +
"[FechaAlta] [datetime] NULL," + "[Comentario] [nvarchar](2048) COLLATE
Modern_Spanish_CI_AS NULL," +
"CONSTRAINT [PK_Prueba] PRIMARY KEY CLUSTERED (" +
"[ID] ASC)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY])" +
" ON [PRIMARY]";
SqlConnection cnn = null;
try{
cnn = new SqlConnection(sCnn);
cnn.Open();
SqlCommand cmd = new SqlCommand(sCmd, cnn);

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;
}

Añadir nuevos registros


Para añadir nuevos registros, lo primero que tenemos que hacer es crear una nueva fila.
Para ello utilizamos el método NewRow del objeto DataTable.

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.

La asignación de los campos la hacemos mediante el método asignarDatos, aunque podríamos


haberlo hecho directamente.
El hacerlo mediante ese método es para que nos resulte más cómo adaptar este ejemplo a otra tabla
diferente a la que yo propongo, ya que en ese método haríamos todas las asignaciones que debamos
hacer, salvo la del campo ID ya que al ser autonumérico no podemos asignarle un valor, porque ese
valor lo asignará automáticamente ADO.NET.
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.

Finalmente actualizamos los datos mediante el método Update del adaptador.


En realidad no hace falta hacer esa actualización en este preciso momento, pero si no lo hacemos,
debemos añadir otro botón para que los datos se asignen a la base de datos, ya que al añadir un
nuevo valor a la tabla, lo haremos en la "copia" que tenemos localmente en memoria, y no
directamente en la base de datos, como ocurría, por ejemplo, con VB6 y los Recordsets.

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!

private void btnNuevo_Click(object sender, EventArgs e) {


// Crear un nuevo registro
DataRow dr = dt.NewRow();
// Asignar los datos de los textbox a la fila
asignarDatos(dr);

// Añadir la nueva fila a la tabla


dt.Rows.Add(dr);
// Guardar físicamente los datos en la base
try{
da.Update(dt);
dt.AcceptChanges();
// Si es el primer registro de la base,
// volver a leer los datos para actualizar los IDs
if( Convert.ToInt32("0" + dr["ID"].ToString()) == 0 ){
dt = new DataTable();
da.Fill(dt);
}
// Posicionarlo en la última fila
btnLast_Click(null, null);
}catch(DBConcurrencyException ex){
MessageBox.Show("Error de concurrencia:\n" + ex.Message);
}catch(Exception ex){
MessageBox.Show(ex.Message);
}
}

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;
}

Actualizar los registros modificados


La actualización de los datos, es decir, cuando modificamos un registro (o fila) y queremos que esos
datos se guarden, es muy simple. En el código del método de actualizar, primero comprobamos que el
valor de la variable fila sea válido, es decir, esté dentro del rango de filas que tiene el DataTable.

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);
}
}

Eliminar el registro actual


Una vez que tenemos un registro mostrado, podemos pulsar en el botón Eliminar, para hacerlo,
usamos el método Delete de la fila indicada y a continuación le indicamos al adaptador que actualice
los datos físicamente en la base y a la tabla le tenemos que indicar que acepte los cambios, con idea
de que esa fila que hemos eliminado, la elimine también de la memoria.

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.

private void btnEliminar_Click(object sender, EventArgs e) {


// Eliminar la fila actual
if( fila < 0 || fila > dt.Rows.Count - 1 ) return;

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.

Moverse entre registros, con comandos para ir al primero, al


último, al anterior y al siguiente
Para movernos entre los registros usaremos cuatro métodos, uno para ir al principio, otro para ir al
final, otro para ir al registro anterior y otro para el siguiente.

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.

private void mostrarDatos(int f) {


int uf = dt.Rows.Count - 1;
if( f < 0 || uf < 0 ) return;
//
DataRow dr = dt.Rows[f];
txtID.Text = dr["ID"].ToString();
txtNombre.Text = dr["Nombre"].ToString();
txtEmail.Text = dr["e-mail"].ToString();
txtFechaAlta.Text = dr["FechaAlta"].ToString();
txtComentario.Text = dr["Comentario"].ToString();
//
btnActualizar.Enabled = true;
btnEliminar.Enabled = true;
}

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.

private void btnFirst_Click(object sender, EventArgs e) {


// Posicionarse en la primera fila
fila = 0;
// Mostrar los datos de la fila indicada
mostrarDatos(fila);
}

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.

private void btnLast_Click(object sender, EventArgs e) {


// Posicionarse en la última fila
fila = dt.Rows.Count - 1;
// Mostrar los datos de la fila indicada
mostrarDatos(fila);
}

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.

private void btnPrev_Click(object sender, EventArgs e) {


// Posicionarse en la fila anterior
fila = fila - 1;
if( fila < 0 ) fila = 0;
// Mostrar los datos de la fila indicada
mostrarDatos(fila);
}

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.

private void btnNext_Click(object sender, EventArgs e) {


// Posicionarse en la fila siguiente
int uf = dt.Rows.Count - 1;
fila = fila + 1;
if( fila > uf ) fila = uf;
// Mostrar los datos de la fila indicada
mostrarDatos(fila);
}

También podría gustarte