Post on 23-Oct-2015
1
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
LENGUAJE VISUAL BASIC NET
Indice:
1.- Elementos básicos de Visual Basic NET pagina 4
1.1.-Introduccion a Visual Basic NET
1.2.- Plataforma .NET
1.3.- Entorno de ejecución CLR
1.4.- El Lenguaje Intermedio y el CLS 1.5.- La biblioteca de clases de .NET
1.6.-Los espacios de nombres
1.7.- Acceso a datos con ADO.NET 1.8.- Aplicaciones Windows Forms
2.- Elementos del Lenguaje Visual Basic pagina 10
2.1.- Variables Visual Basic NET
2.2.- Constantes en Visual Basic NET
2.3.- Listas enumeradas
2.4.- Estructuras
2.5.- Ambito de variables
2.6.- Operadores aritméticos
2.7.- Jerarquía de las operaciones
2.8.- Orden de las operaciones
2.9.- Comentarios en Visual Basic NET
3.- Programas, formas y componentes de Visual Basic NET pagina 17
3.1.- Programa ejemplo de Visual Basic NET
3.2.- Otros componentes
3.3.- Dos o más forms en Visual Basic NET
4.- Estructuras, ciclos, decisiones en visual Basic NET pagina 27
4.1.-Instrucciones condicionales en Visual Basic
4.2.- Operadores relacionales en Visual Basic
4.3.- Instrucciones If… Then Else en Visual Basic
4.4.- Condiciones compuestas en Visual Basic
4.5.- Instrucciones de control
4.6.- Ciclos For… To Next
4.7.- Ciclo Do… Loop While
4.8.- Arreglos en Visual Basic
4.9.- Funciones del lenguaje integradas
4.10.- Procedimientos o sub rutinas en Visual Basic
2
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
5.- Programando con controles en Visual Basic pagina 67
5.1- El cuadro de herramienta
5.2.-Controles Window Basicos
5.3.- Control Label
5.4.- Control TextBox
5.5. –Control Button
5.6.- Foco de entrada
5.7.- Funciones para presentar mensajes
5.8.- Funcion InputBox()
5.9- Funcion MsgBox()
5.10.- Codificando con los eventos de controles
5.11.- Codificando otros eventos de control
5.12.- Orden de tabulación de los controles
5.13.- Control ListBox
5.14.- Control Combobox
5.15.- Control CheckBox
5.16.- Controles RadioButton y GroupBox
5.17.- Controles tipo menú
5.18.- Controles avanzados de Visual Basic
Control temporizadores (Timer)
Control ImageList
Control ToolBar
Control StatusBar
Control DateTimePiker
Control NumericUpDown
Control DomainUpDown
Control MonthCalender
Control LinkLabel
Control NotifyIcon
6.- Programacion Orientada a Objeto (POO) en Visual Basic pagina 119
6.1.- Que es una clase
6.2.- Crear la primea clase
6.3.- Propiedades de solo lectura y escritura
6.4.- Agregar métodos a una clase
6.5.- Agregar evento a una clase
6.6.- Crear una instancia de clase
6.7.- Como utilizar los constructores
6.8.- Como utilizar los destructores
6.9.- Como utilizar los miembros datos compartidos
6.10.- Como utilizar los métodos compartidos
3
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
6.11.- Polimorfismo en Visual Basic NET
6.12.- Probar controladores de eventos
6.13.- Herencia de clases en Visual Basic NET
7.- Impresión en Visual Basic pagina 172
7.1.- La solucion: Como imprimier en .NET
7.2.- Las clases para imprimir en .NET
Clase PrintDocument
Clase PrintSetting
Clase PrintDialog
Clase PrintPreviewDialog
Calse PrintPreviewControl
7.4.- Conclusion Imprimir en .NET es fácil
7.5.-Hacer Crystal Report con DataSet en Visual Basic.NET
8.- Acceso a Datos con ADO.NET en Visual Basic pagina 184
8.1.- Acercandonos a ADO.NET
8.2.- SystemData
8.3.- Los proveedores de acceso a datos
8.4.- El concepto DataBinding
8.5.- Otras consideraciones
8.6.- El paradigama de conexión
8.7.- Conociendo el objeto DataReader
8.8.- Un primer contacto con el objeto DataReader
8.9.- ¿Trabaja DatReader en un ambiente conectado realmente?
8.10.- Usando DataSource con DataReader
8.11.- Usando componentes de acceso a datos de .NET
8.12.- Esquema general de la estrucutra desconectada de acceso a datos
8.13.- Conociendo el objeto DataAdapter
8.14.- Insertando datos a través del Objeto DataAdapter
8.15.- Actualizando datos a través del objeto DataAdapter
8.16.- Eliminando datos a través del objeto DataAdapter
8.17.- ¿Qué son los datos Maestro Detalle?
8.18.- Configurando la fuente de datos
8.19.- Preparando el origen de datos
8.20.- Inscrustando los datos Maestro Detalle
8.21.- Manipulando los datos.
4
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
1.- ELEMENTOS BASICOS DE VISUAL BASIC NET
1.1.- Introduccion a Visual Basic NET
Información y Conocimiento son los dos elementos claves del nuevo milenio ninguna
sociedad podrá alcanzar ni puede ignorar este nuevo esquema ya las naciones no se
miden por su riqueza industrial, ni sus activos físicos, ni por su poder militar, sino por la
cantidad de información que produce y consume, así como por la recombinación de
información nueva en un conocimiento de grado superior.
Nuevos sistemas de información, tienden a ser cada vez de mayor alcance y
complejidad sobre todo cuando se toman en cuenta las nuevas necesidades de
información y conocimiento que demandan las nuevas organizaciones.
VISUAL BASIC NET es un lenguaje de programacion desarrollado por Microsoft muy apropiado para construir sistemas de informacion basados en red o mejor aun en internet.
1.2.- Plataforma .NET Es un amplio conjunto de bibliotecas o librerías de desarrollo que pueden ser utilizadas
por otras aplicaciones para acelerar enormemente el desarrollo y obtener de manera
automática características avanzadas de seguridad, rendimiento, etc... .NET permite
compilar, depurar,y ejecutar aplicaciones .NET.
Desde que apareció la primera versión de Microsoft.NET Framework 1.0 en Visual
Studio 2002, hasta la ultima versión del 2010 se vienen realizando mejoras continuas
que permiten realizar una mejor integración de todos los componentes en aplicaciones
mas robustas y completas del mercado para la tecnología de desarrollo de Microsoft.
Microsoft.Net Framework es una apliacion que se iintegra en el entorno de desarrollo
de forma fácil y transparente al programador, el cualse utiliza para ayudarnos a
desarrollar de forma rápida, correcta, segura y en el menor tiempo posible nuestras
aplicaciones.
1.3.- Entorno de ejecución CLR .NET ofrece un entorno de ejecución para sus aplicaciones conocido como Common Language Runtime o CLR. La CLR es la implementación de Microsoft de un estándar llamado Common Language Infrastructure o CLI. Éste fue creado y promovido por la propia Microsoft pero desde hace años es un estándar reconocido mundialmente por el ECMA. El CLR/CLI esencialmente define un entorno de ejecución virtual independiente en el
5
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
que trabajan las aplicaciones escritas con cualquier lenguaje .NET. Este entorno virtual se ocupa de multitud de cosas importantes para una aplicación: desde la gestión de la memoria y la vida de los objetos hasta la seguridad y la gestión de subprocesos. 1.4.- El Lenguaje Intermedio y el CLS Al contrario que otros entornos, la plataforma .NET no está atada a un
determinado lenguaje de programación ni favorece a uno determinado frente a
otros. En la actualidad existen implementaciones para varias decenas de
lenguajes que permiten escribir aplicaciones para la plataforma .NET. Los más
conocidos son Visual Basic .NET, C# o J#, pero existen implementaciones de todo
tipo, incluso de ¡COBOL!.
Lo mejor de todo es que cualquier componente creado con uno de estos lenguajes
puede ser utilizado de forma transparente desde cualquier otro lenguaje .NET.
Además, como ya se ha comentado, es posible ejecutar el código .NET en diferentes
plataformas y sistemas operativos
1.5.- La biblioteca de clases de .NET Todo lo que se ha estado comentando hasta ahora en el curso constituye la base de la plataforma .NET. Si bien es muy interesante y fundamental, por sí mismo no nos serviría de mucho para crear programas si debiésemos crear toda la funcionalidad desde cero. Obviamente esto no es así, y la plataforma .NET nos ofrece infinidad de funcionalidades
"de fábrica" que se utilizan como punto de partida para crear las aplicaciones. Existen
funcionalidades básicas (por ejemplo todo lo relacionado con la E/S de datos o la
seguridad) y funcionalidades avanzadas en las que se fundamentan categorías enteras
de aplicaciones (acceso a datos, creación de aplicaciones Web...).
Toda esta funcionalidad está implementada en forma de bibliotecas de funciones que físicamente se encuentran en diversas DLL (bibliotecas de enlazado dinámico).
A su conjunto se le denomina Base Classes Library (Biblioteca de clases base o BCL) y
forman parte integral de la plataforma .NET, es decir, no se trata de añadidos que se
deban obtener o adquirir aparte.
La siguiente figura ilustra a vista de pájaro la arquitectura conceptual de la plataforma
.NET. En ella se pueden observar los elementos que se han mencionado en apartados
anteriores (lenguajes, CLR, CLS...) y en qué lugar de se ubican las bibliotecas de clases
base:
6
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Todo lo que se encuentra en la BCL forma parte de la plataforma .NET. De hecho existe
tal cantidad de funcionalidad integrada dentro de estas bibliotecas (hay decenas de
miles de clases) que el mayor esfuerzo que todo programador que se inicia en .NET
debe hacer es el aprendizaje de las más importantes. De todos modos Visual Studio
ofrece mucha ayuda contextual (documentación, Intellisense...) y una vez que se
aprenden los rudimentos resulta fácil ir avanzando en el conocimiento de la BCL a
medida que lo vamos necesitando.
1.6.- Los espacios de nombres Dada la ingente cantidad de clases que existen debe existir algún modo de organizarlas
de un modo coherente. Además hay que tener en cuenta que podemos adquirir más
funcionalidades (que se traducen en clases) a otros fabricantes, por no mencionar que
crearemos continuamente nuevas clases propias. Para solucionar este problema
existen en todos los lenguajes .NET los espacios de nombres o namespaces. Un
espacio de nombres no es más que un identificador que permite organizar de modo
estanco las clases que estén contenidas en él así como otros espacios de nombres.
Así, por ejemplo, todo lo que tiene que ver con el manejo de estructuras de datos XML
en la plataforma .NET se encuentra bajo el espacio de nombres System.Xml. La
funcionalidad fundamental para crear aplicaciones Web está en el espacio de nombres
System.Web. Éste a su vez contiene otros espacios de nombres más
7
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
1.7.- Acceso a datos con ADO.NET El acceso a fuentes de datos es algo indispensable en cualquier lenguaje o lataforma de
desarrollo. La parte de la BCL que se especializa en el acceso a datos se denomina de
forma genérica como ADO.NET.
Si usted ha programado con Visual Basic 6.0 o con ASP, ha empleado en su código con
total seguridad la interfaz de acceso a datos conocida como ADO (ActiveX Data
Objects), puede que combinado con ODBC (Open Database Connectivity). Si además es
usted de los programadores con solera y lleva unos cuantos años en esto es probable
que haya usado RDO o incluso DAO, todos ellos métodos mucho más antiguos.
ADO.NET ofrece una funcionalidad completamente nueva, que tiene poco que ver con
lo existente hasta la fecha en el mercado. Sin embargo, con el ánimo de retirar barreras
a su aprendizaje, Microsoft denominó a su nuevo modelo de acceso a datos con un
nombre similar y algunas de sus clases recuerdan a objetos de propósito análogo en el
vetusto ADO.
ADO.NET es un modelo de acceso mucho más orientado al trabajo desconectado de las
fuentes de datos de lo que nunca fue ADO. Si bien este último ofrecía la posibilidad de
desconectar los Recordsets y ofrecía una forma de serialización de estos a través de las
diferentes capas de una aplicación, el mecanismo no es ni de lejos tan potente como el
que nos ofrece ADO.NET.
El objeto más importante a la hora de trabajar con el nuevo modelo de acceso a datos
es el DataSet. Sin exagerar demasiado podríamos calificarlo casi como un motor de
datos relacionales en memoria. Aunque hay quien lo asimila a los clásicos Recordsets su
funcionalidad va mucho más allá como se verá en el correspondiente módulo.
1.8.- Aplicaciones Windows Forms Las aplicaciones de escritorio son aquellas basadas en ventanas y controles comunes de
Windows que se ejecutan en local. Son el mismo tipo de aplicaciones que antes
construiríamos con Visual Basic 6 u otros entornos similares.
En la plataforma .NET el espacio de nombres que ofrece las clases necesarias para
construir aplicaciones de escritorio bajo Windows se denomina Windows Forms. Este
es también el nombre genérico que se le otorga ahora a este tipo de programas
basados en ventanas.
8
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Windows Forms está constituido por multitud de clases especializadas que ofrecen
funcionalidades para el trabajo con ventanas, botones, rejillas, campos de texto y todo
este tipo de controles habituales en las aplicaciones de escritorio. Visual Studio ofrece
todo lo necesario para crear visualmente este tipo de programas, de un modo similar
aunque más rico al que ofrecía el entorno de desarrollo integrado de Visual Basic.
Diseñador de interfaces de aplicaciones de escritorio con Windows Forms en Visual Studio
Este es el aspecto que presenta parte del código que genera la interfaz mostrada en
la anterior figura:
9
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
2.- Elementos del Lenguaje Visual Basic
2.1.- VARIABLES VISUAL BASIC NET
Identificadores son conjuntos de letras y/o numeros que se utilizan para simbolizar
todos los elementos que en un programa, son definibles por el usuario (programador o
ingeniero de software) del mismo, como son las variables donde se almacenan datos,
funciones (pequenos modulos con codigo), etiquetas, clases, objetos, etc.
En VISUAL BASIC NET un identificador es una palabra compuesta de letras y/o numeros de hasta 32 caracteres significativos, empezando siempre con una letra.
Una variable se define como un identificador que se utiliza para almacenar todos los datos generados durante la ejecucion de un programa.
Existen ciertas reglas en cuanto a variables:
Claras y con referencia directa al problema. No espacios en blanco, ni simbolos extranos en ellas. Se pueden usar abreviaturas, pero solo de caracter general. No deben ser palabras reservadas del lenguaje.
Ejemplos de buenas variables:
Nombre, Edad, SdoDiario, IngMensual, Perimetro, Calif1, etc.
2.1.1.- Declaracion y tipos de datos
En Visual Basic NET a toda variable que se use en un programa, se le debe asociar (generalmente al principio del programa) un tipo de dato especifico.
Un tipo de dato define todo el posible rango de valores que una variable puede tomar al momento de ejecucion del programa y a lo largo de toda la vida util del propio programa. Los tipos de datos más comunes en Visual Basic NET son:
Tipo Rango
BYTE 0-255
INTEGER(%) +-2,147,483,698
SINGLE(!) 3.4E+-38(7 DECIMALES)
DOUBLE(#) 1.8E+308(16 DECIMALES)
CURRENCY 15 DIG IZQ 4 DIG DEECHA
STRING($) 2 BILLONES CHARS
BOOLEAN TRUE, FALSE
DATE FECHA
10
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
VARIANT TODOS LOS TIPOS y mas usado en este curso
Recordar Tambien que en Visual Basic NET toda variable usada en un programa se debera declarar al principio del programa el formato de declaracion mas sencillo es:
DIM VARIABLE AS TIPO
Ejemplos
DIM ALFA AS INTEGER
DIM ALFA AS LONG, BETA AS LONG
DIM ALFA AS INTEGER, NOMBRE AS STRING
DIM CIUDAD AS STRING * 20, ALFA AS DOUBLE
Observar último caso de ciudad asi de esta manera se consigue una string de tamano definido.
En Visual Basic NET un problema comun a lo largo de este curso, es la necesidad de convertir variables numericas a strings y tambien el problema inverso es decir convertir strings a su representacion numerica.
Para este último problema por ejemplo se tiene:
DIM ALFA AS STRING
ALFA = “3.1416”
Como se observa del ejemplo anterior, se puede dar en algun momento la necesidad de convertir la string ALFA a su valor numerico, para resolver este problema se deberan usar las siguientes funciones de conversion numerica que proporciona Visual Basic NET.
En Visual Basic NET para el ejemplo anterior se tendria:
DIM ALFA AS STRING
DIM BETA AS SINGLE
ALFA = “3.1416”
BETA= CINT (ALFA)
Tambien podemos declarar variables utilizando unos símbolos o caracteres detrás de las variables que indiquen el tipo de variable utilizada, la tabla muestra estos símbolos:
Tipo de dato Simbolo Caracter
Short S
Integer % I
Long & L
Single ! F
Double # R
Nota: Estamos usando una función de
Visual Basic para tomar solo el valor
entero de ALFA
11
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Decimal D
UShort US
UInteger UI
Ulong UL
String $
Tipos de datos Objetos
Object es un tipo de datos de forma implicitay del cual heredan el resto de tipos de datos
2.2.- Constantes en Visual Basic NET
Formato:
Const variables As tipo = valor
Ejemplos
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Const PI as double = 3.1416
Dim valor As decimal
Valor = (2 * PI) ^2
MessageBox.show(Valor)
End sub
2.3.- Listas enumeradas
Son listas de variables o datos que hacen referencia a índices y estos empiezan desde
0 en adelante. El formato que se utiliza es el siguiente:
Private Enum <Nombre_Variable> As <Tipo_Dato>
<Variable> = Valor_asignado
…
End Enum
Observemos el siguiente ejemplo:
Private Enum valores As Integer
Valor1 = 3
Valor2 = 5
Valor3 = 7
End Enum
12
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim valor As valores
Valor = valores.valor2
MessageBox.show(Valor)
End sub
Nota: Si deseamos conocer el nombre de la variable seleccionada de la lista
enumerada, podemos utilizar:
Dim valor As valores
Valor = valores.valor2
MessageBox.show(Valor.ToString() & “: “ & Valor)
Se presentara: valor2: 5
2.4.- Estructuras en Visual Basic
Las estructuras están formadas por uno o mas miembros y cada miembro puede ser de
un tipo de datos determinado. El formato a utilizar es:
Structure <nombre>
Public <nombre> As <tipo>
End Structure
Ejemplo de uso de estructura:
Private Structure Alumno
Public nombre As String
Public Edad As Integer
Public Id As String
End Structure
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim MiAlumno As Alumno MiAlumno.nombre = “Carlos “
MiAlumno.edad = 23
Mialumno.Id = “2011-23056”
MessageBox.show(MiAlumno.nombre & “ tiene “ & MiAlumno.edad & “ años”)
End sub
13
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Se presentara en pantalla: Carlos tiene 23 años
Tambien podemos utilizar la palabra reservada With para realizar acciones que se repiten, evitando escribir una parte del código, analicemos el siguiente ejemplo:
Private Structure Alumno
Public nombre As String
Public Edad As Integer
Public Id As String
End Structure
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim MiAlumno As Alumno With MiAlumno
.nombre = “Carlos “
.edad = 23
.Id = “2011-23056”
MessageBox.show(MiAlumno.nombre & “ tiene “ & MiAlumno.edad & “ años”)
End sub
2.5.- Ambito de variables en Visual Basic
El lugar donde sea declarada una variable afectara el uso que el programa quiera hacer de esa variable. Las reglas basicas que determinan como una variable puede ser usada depende del lugar donde se puede declarar una variable. Veamos la siguiente tabla:
Declaración
Lugar de Declaración Alcance o Ámbito
Public Módulo o Clase Global, en todo el proyecto.
Protected Clase En la clase declarada o en una derivada.
Friend Clase En el Assemblie.
Private Módulo Solo en el módulo.
Dim Procedimiento Solo en el Procedimiento.
Static Procedimiento Solo en el Procedimiento.
14
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
En escencia una variable local solo es conocida por el codigo de esa funcion o procedimiento y es desconocida por otras funciones o procedimientos.
En la programacion formal no es acostumbrado usar muchas variables globales por varias razones, una de ellas es que variables globales estan vivas todo el tiempo de ejecucion del programa.
Si una variable global solo la ocupa unos cuantos procedimientos no tiene caso que este viva para todo el resto, otra razon es que es peligroso tener variables globales porque todo el conjunto de procedimiento y funciones que componen un programa tienen acceso o comparten su valor y se corre el riesgo de que inadvertidamente alguno de ellos modifique su valor.
Programa
' Creando y cargando una variable global Dim varglobaluno as integer = 50 ‘Fuera de todo procedimiento Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' creando, cargando y mandando una var local Dim varlocaldos = 20 Call PROC1(varlocaldos) End Sub Sub PROC1(ByVal varlocaltres As Single) 'aqui se puede usar varglobaluno por ser global 'y varlocaltres por ser local pero no se puede usar varlocaldos ' porque es local en otro procedimiento Label1.Text = varglobaluno + varlocaltres End Sub
Este es un
procedimiento en
Visual Basic NET
15
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
2.6.-- Operadores aritmeticos
En Visual Basic NET un operador es un simbolo especial que indica al compilador que debe efectuar una operacion matematica o logica.
Visual Basic reconoce los siguientes operadores aritmeticos:
OPERADOR OPERACIÓN
+ Suma
- Resta
* Multiplicacion
/ Division flotante
\ Division Entera
^ Potencia
MOD Modulo
El Operador (/) Division Flotante es el operador de division normal.
El Operador (\) tambien es division pero los datos:
a) Primero son redondeados al entero más cercano (byte, integer, long)
b) Al final visual basic trunca la parte residual.
El Operador (^), resuelve dos problemas:
a) Ejemplo 5 2 se resuelve enVisual Basic NET:
dim alfa as integer
alfa = 5 ^ 2
Desplegar alfa, sale 9 en pantalla
b) Ejemplo para Raices solo recordar la ley de exponentes que dice:
Para estos casos:
= 5^8/3
= 9^1/2
En Visual Basic el operador (MOD) devuelve el residuo entero de una division entre enteros, ejemplo:
Dim alfa As Single
alfa = 23 MOD 4
Visualizar alfa; El resultado en pantalla es 3
3
9
16
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Otro ejemplo;
alfa = 108 MOD 10;
Visualizar alfa; El resultado en pantalla es 8
Ejercicios de programacion
Resolver algebraicamente en papel las siguientes ecuaciones expresándolas en formato de Visual Basic NET
1.-
2.-
3.-
2.7.- Jerarquia de operaciones
En Visual Basic NET el problema de no tomar en cuenta la jerarquia de los operadores al plantear y resolver una operacion casi siempre conduce a resultados muchas veces equivocados como estos:
Ejemplos:
a) 2 + 3 * 4 = 20 (incorrecto)
2 + 3 * 4 = 14 (correcto)
b) si calif1 = 60 y calif2 = 80 ; Entonces si en programa se usa
promedio = calif1 + calif2/2 ; Da como resultado promedio = 100
En Visual Basic NET recordar siempre, que antes de plantear una formula en un programa se debera evaluar respecto al orden siguiente:
2.8.- Orden de operaciones:
1.- Parentesis
2.- Potencias y raices
8
Actividades de reforzamiento de lo aprendido
Ordenes de operacion
17
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
3.- Multiplicaciones y divisiones
4.- Sumas y restas
5.- Dos o más de la misma jerarquia u orden, entonces resolver de izquierda a derecha
Ejemplo:
area = ( base * altura ) / 2
Aqui los parentesis estan de mas porque por orden de operaciones, multiplicacion y division tienen la misma jerarquia y entonces se resuelven de izquierda a derecha en otras palabras en visual basic NET ni que falten parentesis ni que sobren parentesis
2.9.- Comentarios en Visual Basic NET
Para agregar comentarios a nuestro código de programa podemos hacerlo de variasm
maneras:
1.- Utilizando el carácter ‘
area = base * altura / 2 ‘ Encontramos el área del cuadrado
2.- Utilizando la palabra reservada REM, se utiliza al comienzo de una línea: Rem Encontramos el área del cuadrado area = base * altura / 2 3.- Cuando queremos utilizar pequeñas porciones de regiones de comentarios y código que se puede contraer y expandir, el formato a utilizar es: #Region “ < texto >” … Aquí se escribe lo que quermos poner como comentario en varia líneas … Se puede escribir líneas de codigo #End Region
Ejemplo:
#Region “ Problema 1”
‘El problema permite encontrar el Mayor de los números de una lista
‘Proporcionada por el usuario
Nota: Si se quiere alterar el orden normal de operaciones, entonces usar parentesis.
Nota: Tampoco es bueno usar parentesis cuando no es necesario en una
operacion, esto solo indica que no se evaluo bien la formula
18
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Dim IValor As Integer = 0
#En Region
19
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
3.- PROGRAMAS, FORMAS y COMPONENTES VISUAL BASIC NET
Recordar que programas visuales, se construyen usando los siguientes elementos:
1.- Un objeto ventana o form1
2.- Objetos que permitan capturar y desplegar datos, de momento se usaran los dos objetos de entrada / salida más comunes:
2.1 Objeto label Permite desplegar textos o mensajes estaticos
2.2 Objeto textbox Permite tanto capturar datos, asi como desplegar el resultado de operaciones (recordar que textbox's) solo capturan o despliegan un dato a la vez, recordar tambien que todos los datos que entren y salgan de un textbox o un label son de tipo string.
2.3.- Objetos InputBox() Para obtener datos directos y sencillos del usuario
2.4.- Objetos MessageBox() Para presentar informacion relevante al usuario
3.- Objeto Button Es el componente principal de la forma, contiene el código principal del programa y su activación por el usuario provoca que se realicen los principales procesos del problema planteado (aquí es donde se capturan datos, se realizan operaciones, etc.).
De este componente se maneja su propiedad Text para etiquetarlo con la palabra “OK” o “ACEPTAR” o “EXE” y su evento Click para activarlo, es en dicho evento donde se construirá muchas veces el código del programa.
RECORDAR que todos los componentes vistos incluyendo el propio form y ventana estos tienen muchas propiedades que se pueden asignar o modificar y tambien tienen muchos eventos a los cuales les podemos asociar o cargar el codigo del programa, todos estas propiedades y eventos las podemos accesar dentro de la ventana de propiedades.
No olvidar que las palabras reservadas del lenguaje NO se deben utilizar como variables, esto producirá un error en al aplicacion
Regresando a Form1, es sobre esta forma donde se construira el programa y esta forma se convierte en ventana al momento de ejecutarse el programa.
Nota importante: Recordar que aunque no es un componente necesario en los
programas ya que el código se puede asociar o pegar a cualquier evento de
cualquier forma o componente del programa, Microsoft ya acostumbro a todos
los usuarios al boton OK, de acuerdo, OK.
20
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Es decir sera la primera ventana que el usuario ve al momento de ejecutarse el programa, su nombre es Form1.
Propiedades: Son todas las caracteristicas particulares que diferencian un objeto de
otro objeto, las propiedades o caracteristicas mas comunes son forma, tamano, color, etc., para objetos en visual basic, estas propiedades se modifican o individualizan usando la PAGINA DE PROPIEDADES, que es la parte del programa que las contiene.
Recordar que se pueden modificar las propiedades dentro de un programa, usando instrucciones apropiadas, mismas que llevan el siguiente formato:
NomObjeto.Propiedad = nvovalor;
Ejemplo: Form2.BackColor = Yellow
Eventos: son todos aquellos sucesos de caracter externo que afectan o llaman la
atencion del objeto, para estos casos la forma o ventana u objeto:
1. Debe tener capacidad de detectar el evento 2. Aun más importante debe tener capacidad de reaccionar y emitir una
respuesta, mensaje o conducta apropiada al evento detectado.
Evento es por ejemplo que otro objeto llamado humano pulse el objeto tecla ESC, o haga click derecho con el objeto raton en alguna parte de la ventana, etc. es en estos casos, cuando la ventana u objeto detecte un evento de estos la propia forma u objeto debera responder de manera apropiada.
Es tambien la VENTANA DE PROPIEDADES, quien contiene todos los posibles eventos asociados a la forma.
Para los primeros programas en VISUAL BASIC solo se usaran propiedades sencillas como color, font, etc. de Form1 y los objetos ya mencionados (LABEL, TEXTBOX, BUTTON, INPUTBOX, MESSAGEBOX, LISTBOX, COMBOBOX) y no se usan de momento los eventos que puede detectar Form1.
Esta forma o ventana es un objeto de VISUAL BASIC NET y como todos
los objetos de Visual Basic y del universo, la forma o ventana tiene
asociados propiedades y eventos.
Nota: Esta respuesta no es automatica, sino son la serie de instrucciones del
lenguaje (o programa) que los ingenieros de software diseñan (o programan) en
otras palabras son los eventos quienes contendran los programas.
21
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
3.1.- Programa ejemplo Visual Basic NET
Resolvemos el problema de calcular el área de un triangulo con la formula área = base * altura /2
Para resolver este problema se ocuparan los siguientes objetos. (para realizar el disño)
1.- Una ventana de windows (form1) para contener a todo el resto de componentes.
2.- Tres label's o etiquetas para desplegar mensajes apropiados al problema.
3.- Tres componentes TEXTBOX dos para capturar datos (base y altura) y el tercero para desplegar el resultado (area).
4.- Un componente BUTTON para que active y contenga el codigo del problema y/o programa.
Procedimiento detallado
1.- Crear un folder o directorio en su disco duro C:\ llamado PROGRAM1
2.- Cargar VISUAL BASIC desde la barra de start de windows
3.- Usar la opción FILE –> NEW PROJECT –> WINDOWS APPLICATION
4.-Usar Ahora la opcion FILE –> SAVEALL De la pantalla de grabación que sale ponerle un nombre al proyecto (dejar el default ) y apuntarlo al directorio que se hizo de programas:
22
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
5.- Queda ahora la pantalla de trabajo o diseno o construccion del programa
Recordar que pueden agregar TOOLBOX, (VENTANA DE PROPIEDADES Y EXPLORADOR DE SOLUCIONES) usando la opción VIEW de la barra del menú.
6.- Observar que en grafica de arriba esta seleccionada la propia forma o ventana.
Dentro del programa se estarán cargando todos los objetos que usa el programa y por ejemplo Visual Basic NET a los dos textbox's que se estarán usando los nombra por DEFAULT como TextBox1 y TextBox2, con esas mayúsculas y minúsculas así que estará dificil estar recordando su nombre por defecto
Es conveniente estar usando la propiedad NAME de todos los objetos sobre
todo textbox y label que se coloquen en una forma o ventana.
23
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Es decir es mas fácil construir una formula que diga num1.Text = num2.Text + 5 a el original que seria TextBox1.Text = TextBox2.Text + 5 por esta razón es conveniente asignarle un nombre relevante a cada TextBox usando la propiedad NAME de la pagina de propiedades, en este curso se les asigna NAME a todos los textbox's y muchos de los otros componentes que se usan.
7.- Arrastrar y acomodar desde la CAJA DE HERRAMIENTAS a FORM1 3 (tres) compontes LABEL y cargarles su PROPIEDAD TEXT con las palabras BASE, ALTURA y AREA respectivamente para escribir esto solo hacerlo usando la cajita que esta a un lado de la propiedad dentro dela pagina de propiedades.
8.- Arrastrar y acomodar ahora tres componentes textBox de los cuales en su propiedad TEXT, limpiarla y dejarla en blanco y en su propiedad (NAME) cargarlos con las palabras BASE, ALTURA y AREA respectivamente.
9.- Arrastrar y acomodar ahora un componente o control BUTTON, poner su propiedad text=OK.
La pantalla diseñada es:
NOTA: si de alguna manera el editor los manda al código del programa,
observar que arriba de FORM1 hay tres pestañas:
FORM1.VB la que contiener el codigo del programa en los procedimientos y
eventos
FORM1 DESIGN que contiene el diseño
START PAGE contiene las caracteristicas de la pagina de inicio
De solo click en form1 design para regresar al ambiente visual.
10.-Colocaremos el siguiente codigo dentro del evento click de BUTTON
Private Sub Button1_Click(ByVal sender
As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
AREA.Text=(BASE.Text*ALTURA.Text / 2)
End Sub
24
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Para escribir este código solo haga CLIK dentro de BUTTON1 y VISUAL BASIC los mandara a la pantalla de código, donde ya estará cargado el evento button1_clik(){}.
Los dos parámetros que van dentro de button_click (OBJETO, variable e)–> son para indicarle al compilador que se estarán enviando OBJETOS entre la forma o ventana y el usuario del programa ( LOS TEXTBOXS son los objetos y primero se mandan vacios al usuario y luego el sistema los recoge con datos desde el usuario).
La VARIABLE “e” (environment) es donde el sistema o compilador los va almacenando temporalmente, si ya vieron algo de msdos y conocen el comando set ahí observaran los textbox's con sus datos.
Regresando al código:
a.- Son las propiedades TEXT de los TEXTBOX'S quienes contienen los datos tanto capturados como los de salida.
b.- Recordar además que cualquier propiedad TEXT de cualquier CONTROL o COMPONENTE solo maneja datos de tipo TEXTO o STRING y por tanto para poder realizar operaciones con los TEXTBOX.TEXT visual basic NET internamente los convierte a los tipos apropiados.
c.- [VARNUMERICA COMPONENTE EXPRESION] .ToString() –> se uso para convertir el valor numérico a tipo string Y PODERLO FORMATEAR para que salga el resultado con dos decimales ( este tema de formateo se ve en el tema siguiente), para poderlo almacenar en la propiedad TEXT del TEXTBOX.
11.- Ya cargada la forma con sus componente y el evento click con su código respectivo, grabar el programa con la opción FILE→SAVE o usar el icono de grabación (el disquito o disquitos que esta en la barra de iconos arriba) y luego ejecutar el
programa usando el icono de RUN que también se encuentra en la barra de herramientas arriba o DEBUG START o F5.
12.- El programa en ejecucion:
Atención solo se escribe el código en rojo, el evento button1.click(){} ya lo
escribe visual basic por default y respetar todas las mayusculas y minusculas
dentro del codigo.
25
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
3.2.- Otros componentes Visual Basic
En este tema analizamos algunas instrucciones de VISUAL BASIC que nos permitirán facilitar algunas tareas que están pendientes y también algunos controles y componentes que también nos darán buena ayuda.
Formateo de datos numericos
Como se observa en los aplicaciones ya construidas los formatos numéricos de salida dejan mucho que desear, para corregir esta situación, solo basta agregar una string de control dentro del paréntesis de ToString(“strcontrol”) que son una serie de caracteres especiales que proporciona la plataforma NET.
Ejemplo;
Double alfa = 3456.678 * 21.456 / 73.78902
Es claro que cuando esta variable alfa se mande a un textbox o un label el valor numérico desplegado contendrá un montón de valores decimales, para mandar solo la cantidad de decimales apropiados, solo usar la string de control con los caracteres apropiados ej;
Label1.Text = alfa.ToString(”#.##”)
Esta instrucción desplegara el resultado con solo dos decimales como resultado, si buscamos la documentación de Visual Basic, esta nos muestra todos los posibles caracteres que se pueden incluir en la string de control.
Nota: Si buscan muy bien dentro del folder project1 se encontraran con muchos archivos que creo VISUAL BASIC, dos de ellos son los interesantes:
FORM1.VB que contiene todo el código
fuente, es decir el programa original y
WINDOWSAPPLICATION1.EXE (dentro del
folder bin\debug) que es el archivo
ejecutable, basta darle un click desde el
explorer de windows y se ejecutara solo
sin necesidad de que este cargado el
compilador de visual basic.
26
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
User-Defined Numeric Formats (Format Function)
3.3.-Dos o más forms en Visual Basic NET
El siguiente problema común, con el manejo de programas en VISUAL BASIC, es el de poder crear, controlar y administrar mas de dos forms a la vez.
En este ejemplo o tema se crea un segundo form en diseño.
IMPORTANTE: TODOS LOS COMPONENTES LABEL'S TEXTBOX'S BUTTON'S, etc. que
se coloquen dentro de una forma o ventana deberan de asignarles su propiedad (NAME), es decir VISUAL BASIC por default si se pone un label en la primera ventana (Form1) le asigna el nombre de label1, si también se coloca otra label en la segunda ventana (Form2) también le asignara el nombre de label1 y cuando se este ejecutando el programa y se codifique una referencia a label1 visual basic tendrá problemas para conocer de cual label se está tratando.
Para resolver este problema la referencia deberá realizarse usando el formato
NOMBREFORMA.NOMBRECOMPONENTE.NOMBREPROPIEDAD
a) Crear un proyecto normal con su FORM1 normal.
b) Ahora se crea un segundo FORM2 o ventana, para lograr esto solo usar la opción PROJECT→ADD NEW→WINDOWSFORM y seleccionar windowsform y observar y tratar de usar algunos de los otros tipos de forma que ya trae incorporado visual basic .
Esta opción solo se muestra cuando ya se creó un proyecto, observar también que en el ADMINISTRADOR DE PROYECTOS aparece registradas los dos forms FORM1.vb y FORM2.vb.
También es recomendable usar la propiedad NAME para todos los componentes
que se usen dentro de una forma.
27
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
c) Solo hacer click en form2.vb en el administrador de proyectos (o usar la pestaña arriba en el compilador que ya debe mostrar las dos formas o ventanas) para tener en la pantalla de diseno la segunda ventana, cargarle con sus propios label's, textbox's y buttons, es decir contruirle su programa, recordar tambien asignarles sus propios NAME'S.
d) El codigo del BUTTON1 de la primera ventana Form1 es:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Form2.Show()
End Sub
Solo usar propiedad SHOW() con la ventana2 o FORM2
Recordar que si se quiere que FORM1 haga otro proceso u operación solo agregarle componentes y mas BUTTON's
El Código del botón OK de la segunda ventana Form2, es:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Me.Close()
End Sub
Estamos viendo ahora un nuevo operador de visual basic NET, el operador ME, este operador es una referencia o enlace directo al objeto activo, el evento button1_Clic() está contenido dentro de esta FORM2 por tanto el objeto activo es FORM2 Me.Close() sería equivalente a FORM2.CLOSE() pero visual basic prefiere trabajar mejor con referencias o enlaces a objetos, por eso es mejor usar THIS.
Corrida: form1
Recordar que les indique que windowsforms tiene muchos y valiosos controles o componentes en esta ventana se uso CALENDAR y se ve elegante
Nota:
Recordar que si se quiere que FORM2 haga otro
proceso u operación solo agregarle componentes
y mas BUTTON's
28
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Corrida form2:
Recordar otra vez que
windowsforms tiene muchos y
valiosos controles o
componentes en esta ventana se
uso WEBBROWSER y se ve
elegante
29
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
4.- Estructuras, ciclos, decisiones, en Visual Basic
4.1.-Instrucciones condicionales Visual Basic
Instrucciones de control de programa que permiten alterar la secuencia normal de ejecución de un programa. Estas instrucciones se dividen en tres grandes categorías:
1.- Instrucciones Condicionales que en VISUAL BASIC NET se implementan con las instrucciones if y select case.
Instrucciones de ciclos con
for do while loop do loop while Muchas de ellas con sus correspondientes componentes visuales, tanto en html
como en activex, htmlcontrols y webcontrols, pero para propósito del curso solo se usaran los Controls ASP NET
Una de las más poderosas caracteristicas de cualquier computador es la capacidad que tiene de tomar decisiones.
Es decir al comparar dos alternativas diferentes el computador puede tomar una decision basandose en la evaluacion que hace de alguna condicion. Ejemplo de instrucciones condicionales:
si sueldo > 3000 desplegar rico
si no desplegar pobre
Fin-si si sexo = 'm'
imprime mujer si no
imprime hombre Fin-si
De los ejemplos observar que los caminos a seguir por el computador dependeran de la evaluacion que el computador hace con la condicion. Todo lenguaje de programacion debe tener instrucciones que permitan formar condiciones e instrucciones que pueden evaluar esas condiciones.
Pero recordar que lenguajes modernos y orientados a clientes-servidores de igual forma tienen componentes que permiten del mismo modo al usuario tomar decisiones incluso directamente en pantalla, es decir tambien existen los objetos, controles o componentes de seleccion y decision en html, htmlcontontrols, activex, webcontrols.
30
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
El formato general de una instruccion condicional es:
Como se observa, son cuatro partes bien diferenciadas entre si;
La propia instruccion condicional en si La condicion El grupo cierto de instrucciones El grupo falso de instrucciones
Cuando el computador evalua una condicion el resultado de esa evaluacion solo es evaluado de dos maneras o la condicion es CIERTA o la condicion es FALSA.
Esto dependerá del valor que tenga asignado o que se haya capturado para la variable que está en la condició
Por ejemplo si se capturo 8000 en sueldo en el ejemplo a) entonces el computador indicaría que la condicion es CIERTA pero en otro caso si a la variable sueldo primero se le asigno un valor de 250 entonces el computador indicaría que la condicion es FALSA. Dependiendo del resultado de la evaluacion, el programa realiza las instrucciones contenidas en el grupo de cierto o falso respectivamente.
Empezaremos el análisis por la CONDICION presentada.
CONDICIONES SIMPLES VISUAL BASIC En general todas las condiciones se forman con tres elementos los cuales son:
Variables Operadores relacionales Constantes o variables
sexo = “m”
sueldo > 30000
Carrera = “informatica”
Una condicion simple en visual basic NET se define como el conjunto de variables y/o constantes unidas por los llamados operadores relacionales.
31
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
4.2- OPERADORES RELACIONALES EN VISUAL BASIC
Los operadores relacionales que reconoce Visual Basic NET se presentan en la siguiente tabla:
Operador Significado Descripcion
= Igual Es verdadero si las expresiones comparadas son iguales
< Menor que Es verdadero si la expresión de la izquierda es menor que la expresión de la derecha
> Mayor que Es verdadero si la expresión de la izquierda es mayor que la expresión de la derecha
<> Diferente que Es verdadero si la expresión de la izquierda es diferente de la expresión de la derecha
<= Menor o igual que Es verdadero si la expresión de la izquierda es menoro igual que la expresión de la derecha
>= Mayor o igual que Es verdadero si la expresión de la izquierda es mayor o igual que la expresión de la derecha
4.3.- INSTRUCCION IF… Then Else en VISUAL BASIC
Es la instrucción condicional más usada en los diversos lenguajes de programación, su formato completo y de trabajo en VISUAL BASIC es:
Si un if no ocupa un grupo falso de instrucciones entonces no usar la clausula else
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click If SUELDO.Text > 3000 Then
MessageBox.Show("RICO")
Else
MessageBox.Show("POBRE")
End If
End Sub Si lo corremos veremos algo asi:
If condicion Then
Instrucciones cuando la condicion sea cierta
Else
Instrucciones cuando la condicion sea falsa
End If
32
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
EJERCICIOS DE PROGRAMACION EN VISUAL BASIC NET
1.- Capturar un número cualesquiera e informar si es o no es mayor de 100
2.- Capturar un número entero cualesquiera e informar si es o no es multiplo de 4 (recordar el operador mod analizado en el tema de operadores aritmeticos).
3.- Capturar los cinco datos más importantes de un Empleado, incluyendo el sueldo diario y los dias trabajados desplegarle su cheque semanal solo si gano mas de $500.00 en la semana, en caso contrario desplegarle un bono de despensa semanal de $150.00, PUEDEN USAR PANELS PARA SEPARAR O MEJOR AUN OTRAS VENTANAS O FORMAS.
4.- Capturar los datos mas importantes de un estudiante incluyendo tres calificaciones construir una boleta de calificaciones en un PANEL O VENTANA de respuesta bien bonita si el estudiante es de la carrera de medicina, en caso contrario construir un PANEL O VENTANA mas bonita todavia que despliega un oficio citando a los padres del estudiante a una platica amistosa con los maestros de la escuela.
5.- Capturar los datos más importantes de un producto cualesquiera, incluyendo cantidad, precio, etc. desplegar una orden de compra, solo si el producto es de origen nacional, en caso contrario no hacer nada.
4.4.- CONDICIONES COMPUESTAS EN VISUAL BASIC
En muchas ocasiones es necesario presentar más de una condicion para su evaluacion al computador. Por ejemplo se necesita un programa que el computador muestre la boleta de un alumno si este estudia la carrera de medicina y su promedio de calificaciones es mayor de 70.
Actividades de reforzamiento de lo aprendido
Nota: Es muy importante realizar siempre un diseño visual de lo que queremos realizar
en el grograma y como esto se vera en la aplicación, Visual Basic NET facilita mucho esta
situacion
En Visual Basic NET es valido usar mas de
una instruccion dentro del grupo cierto o
falso del if.
33
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Una condicion compuesta se define como dos o más condiciones simples unidas por los llamados operadores lógicos.
Los operadores logicos que VISUAL BASIC NET reconoce son:
OPERADOR DESCRIPCION
AND Es verdadera si las dos expresiones comparadas son verdadera
OR Es verdadera si una de las dos expresiones es verdadera
NOT Invierte el valor de la expresión. Dos negaciones es una afirmación y negar una afirmación es el valor contrario de la afirmacion
Xor Es verdadera si una de las dos expresiones comparadas es verdadera
AndAlso Es verdadera si las dos expresiones comparadas son verdadera, con al particularidad de que evalua la segunda parte de la expresión si la primera la cumple
OrElse Es verdadera si una de las dos expresiones comparadas son verdadera, con al particularidad de que si cumple la primera expresión no continua la siguientedando como verdadera la comparación logica
La cantidad total de casos posibles cuando se unen dos o mas condiciones simples esta dada por la relacion 2n donde n es la cantidad de condiciones, la primera mitad de ellos empieza en cierto y la segunda mitad en falso. Ejemplo, si formamos una condicion compuesta con dos condiciones simples y el operador logico “y”, la cantidad total de casos posibles serian 22 = 4, y se puede construir la siguiente tabla de verdad.
Tabla de verdad con “AND”
PRIMERA CONDICION SIMPLE
SEGUNDA CONDICION SIMPLE
EVALUACION
C C C
C F F
F C F
F F F
La evaluacion final, se obtiene usando la regla anteriormente descrita para una condicion compuesta, que contiene el operador “AND”.
Esta tabla significa lo siguiente:
1.- Cualquiera que sean la cantidad de datos procesados, siempre caera en uno de estos cuatro casos generales. La tabla de verdad para una condicion compuesta con “OR” es la siguiente:
34
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
PRIMERA CONDICION SIMPLE
SEGUNDA CONDICION SIMPLE
EVALUACION
C C C
C F C
F C C
F F F
Otro ejemplo: Construir una tabla de verdad para una condicion compuesta de tres o mas condiciones simples es tambien tarea sencilla, solo recordar que;
1.- La cantidad posible de casos es 23 = 8 casos posibles, la mitad empiezan con Cierto y la otra mitad empiezan con Falso.
2.- Para evaluar esta condicion triple primero se evaluan las dos primeras incluyendo su operador bajo las reglas ya descritas y luego se evalua el resultado parcial contra la ultima condicion y ultimo operador para obtener la evaluacion final.
Ejemplo una condicion compuesta de tres condiciones simples, donde el primer operador logico es el “AND” y el segundo operador logico es el “OR”, daria la siguiente tabla de verdad.
PRIMERA CONDICION SIMPLE
SEGUNDA CONDICION SIMPLE
EVALUACION DE PRIMERA Y SEGUNDA CONDICION
TERCERA CONDICION SIMPLE
EVALUACION OR DE TERCERA Y CUARTA COL.
C C C C C
C C C F C
C F F C C
C F F F F
F C F C C
F C F F F
F F F C C
F F F F F
Programa ejemplo: Determinar de acuerdo a la edad si los datos del ususario son de un joven o de una persona “anciana”, (edad limite = 30)
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click If EDAD.Text < 30 And SEXO.Text = "H" Then Label3.Text = "Muchacho Joven" Else Label3.Text = "Anciano" End If End Sub
35
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Salida del programa
EJERCICIOS DE PROGRAMACION
1.- Construir un programa que capture un número cualesquiera e informe si es o no es mayor de 50 y múltiplo de tres. (Solo escribir el mensaje de respuesta de manera muy clara y esto resuelve el problema)
2.- Construir un programa que indique si un número es un par positivo.
3.- Capturar los datos de un producto incluyendo su cantidad en existencia, desplegar una orden de compra si la cantidad en existencia del producto es menor que el punto de reorden, o si el origen del producto es nacional.
4.- Construir un programa que capture los datos de un empleado, desplegar en un panel o ventana su cheque semanal si gana mas de $500.00 y si esta en el departamento de producción en caso contrario desplegarle en otro panel o ventana un bono de despensa del 25% de su sueldo semanal.
4.5.-Instrucciones de control en visual basic.
INSTRUCCION SELECT CASE VISUAL BASIC
También existen ocasiones o programas donde se exige evaluar muchas condiciones a la vez, en estos casos o se usa una condicion compuesta muy grande o se debe
Actividades de reforzamiento de lo aprendido
36
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
intentar convertir el problema a uno que se pueda resolver usando la instrucción SELECT CASE.
Select Case variableopcion
case const1
instruccion(es)
case const2
instruccion(es)
case const3
Instruccion(es)
…
case Else instruccion(es)
End Select Programa ejemplo : Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Select Case LETRA.TEXT Case "A" ANIMALITO.TEXT = "AGUILA" Case "B", "b" ANIMALITO.TEXT = "BESTIA" Case "C" Dim ALFA As Integer ALFA = 100 + 5 ' observar como se encadenan strings usando simbolo & ANIMALITO.TEXT = ALFA & " CABALLOS" Case Else ANIMALITO.TEXT = "NO HAY" End Select End Sub
Esta instrucción es una instrucción de
decisión múltiple donde el compilador
prueba o busca el valor contenido en
una variable ENTERA,
CHARACTER, STRING contra una
lista de constantes apropiadas, cuando
el computador encuentra el valor de
igualdad entre variable y constante
entonces ejecuta el grupo de
instrucciones asociados a dicha
constante, si no encuentra el valor de
igualdad entre variable y constante,
entonces ejecuta un grupo de
instrucciones asociados a un default,
aunque este ultimo es opcional. El
formato de esta instrucción es el
siguiente:
37
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
4.6.-Ciclo FOR TO NEXT
Instrucciones para ciclos resuelven el problema de repetir todo el programa o cierta parte del programa más de una vez. Este ciclo es uno de los más usados para repetir una secuencia de instrucciones sobre todo cuando se conoce la cantidad exacta de veces que se quiere que se ejecute una instruccion simple o compuesta. El formato es el siguiente:
FOR VARCICLO = VALINICIAL TO VALFINAL [STEP INCR O DECR] INSTRUCCION(ES) NEXT
Ejemplo:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim X As Integer LISTA.Items.Clear() For X = 1 To 10 LISTA.Items.Add(X & "= MAMA") Next X End Sub
.
Notas:
Se esta usando un objeto listbox con
NAME = LISTA para procesar el conjunto
de datos. O se usan muchos webcontrols
label o textbox para desplegar todo lo que
despliega el ciclo for o se esta usando
mejor un objeto listbox para procesar el
conjunto de datos. Se esta usando la
propiedad add de la coleccion items del
control listbox (lista). Observar que para
encadenar strings en visual basic se usa el
signo &
El metodo items.clear, es porque cuando
el usuario usa el click más de una vez, el
control listbox los va agregando de nuevo
abajo, por eso en cuanto se activa el
onclick lo primero que se realiza es limpiar
el listbox.
Observar el caso “b”, se pueden usar más
de dos constantes.
En el caso “C” recordar que cada CASE
puede llevar un conjunto de instrucciones
que se ejecutaran hasta que el compilador
encuentre el siguiente case.
Observar y recordar en caso “C” como se
unen dos o mas strings, usando el signo &.
38
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Casos Particulares del ciclo for:
1.- El ciclo comienza en uno y se incrementa de uno en uno, este es el caso más
general.
2.- Pero el valor inicial puede se diferente de uno, ejemplo;
FOR X=5 TO 28 Desplegar X
NEXT 3.- Incluso el valor inicial puede ser negativo, ejemplo; FOR X= -5 TO 18
Desplegar X NEXT 4.- Los incrementos tambien pueden ser diferentes al de uno en uno, ej.; FOR X=1 TO 50 STEP 4
Desplegar X NEXT 5.- Incluso pueden ser decrementos, solo que en este caso, recordar;
5.1.- el valor inicial de la variable debe ser mayor que el valor final y usar un step negativo.
FOR X=100 TO 20 STEP - 5 Desplegar X NEXT El uso, gestión y manipulación de matrices (Que estudiaremos adelante) utilizan el bucle : For … Each Instrucciones… Next Veamos este ejemplo: Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
El ciclo for es muy sencillo y no ocupa mucha explicacion, solo
empieza en UNO y se va incrementando de UNO en UNO
39
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Dim MiArreglo() As String = {“Uno”,”Dos”,”Tres”} Dim SCadena As String Dim Smensaje As String = “ ” For Each SCadena In MiArreglo Smensaje += SCadena & “ “
Next MessageBox.Show(Smensaje.trim) End Sub EJERCICIOS DE PROGRAMACION
1.- Construir un programa que despliegue los numeros del 20 al 30.
2.- Desplegar los enteros entre 50 y 30 acompañados de su potencia cuadrada y raiz cubica respectiva (revisar tema de operadores aritmeticos y buscar la libreria de funciones matematicas de Visual Basic).
3.- Desplegar los multiplos de 5, entre 10 y 50, acompañados de su factorial y logaritmo respectivo (La misma recomendacion del ejercio anterior).
4.- Desplegar la tabla de multiplicar que el usuario indique
5.- Evaluar la funcion y = 5x2 + 3x + 8 cuando x= -3…10 (rango de -3 hasta 10)
4.5.-Ciclo DO WHILE LOOP
En este ciclo el cuerpo de instrucciones se ejecuta mientras una condicion permanezca como verdadera en el momento en que la condicion se convierte en falsa el ciclo termina. Su formato general es :
DO WHILE CONDICION(ES)
INSTRUCCION(ES) CIERTAS
INSTRUCCION(ES) DE SALIDA DE CICLO
LOOP
Programa
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Actividades de reforzamiento de lo aprendido
40
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Dim X As Integer X = 1 LISTA.Items.Clear() Do While X <= 10 LISTA.Items.Add(X & "= GATO") X = X + 1 Loop End Sub
Corrida
A este ciclo tambien se le conoce tambien como ciclo de condicion de entrada o prueba por arriba porque este ciclo evalua primero la condicion y posteriormente ejecuta las instrucciones.
EJERCICIOS DE PROGRAMACION
1.- Desplegar enteros entre 50 y 80
2.- Desplegar multiplos de 4 entre 60 y 20 acompanados de su logaritmos de base 10 y base e respectivos (revisar tema operadores atitmeticos)
3.- Construir la tabla de dividir que el usuario indique
4.- Evaluar una función cualesquiera para el rango de valores de x de -3 a +5
Actividades de reforzamiento de lo aprendido
Nota:
While puede llevar dos condiciones; en este caso
inicializar 2 variables de condicion y cuidar que
existan 2 de rompimiento o terminacion de ciclo.
El grupo cierto de instrucciones puede ser una sola
instruccion o todo un grupo de instrucciones. La
condicion puede ser simple o compuesta.
41
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
4.7.-Ciclo DO LOOP WHILE
Su diferencia básica con el ciclo do while loop es que la prueba de condición es hecha al finalizar el ciclo, es decir las instrucciones se ejecutan cuando menos una vez porque primero ejecuta las instrucciones y al final evalúa la condición.
También se le conoce por esta razón como ciclo de condición de salida.
Su formato general es:
DO INSTRUCCION (ES) CIERTAS INSTRUCCION (ES) DE SALIDA DE CICLO LOOP WHILE CONDICION (ES) Programa
Private Sub EVENTO1(ByVal sender As Object, ByVal e As System.EventArgs)
Dim X As Integer
X = 1
LISTA.Items.Clear()
Do
LISTA.Items.Add(X & " perico")
X = X + 1
Loop While X <= 10
End Sub
Otra diferencia básica con el ciclo do while loop es que aunque la condición sea falsa desde un principio el cuerpo de instrucciones se ejecutara por lo menos una vez.
CONCLUSIONES CICLOS VISUAL BASIC
En Visual Basic NET dado un problema o programa cualesquiera que sea el tipo de ciclo
que se utilice, se resuelve con:
1. Si se conoce la cantidad exacta de veces que se quiere que se ejecute el ciclo o
si el programa de alguna manera puede calcularla usar for..net.
2. Si se desconoce la cantidad de veces a repetir el ciclo o se quiere mayor control
sobre la salida o terminacion del mismo entonces usar do while loop.
3. Si se quiere que al menos una vez se ejecute el ciclo entonces usar do loop
while.
42
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
4.7.-Arreglos en Visual Basic NET
Uno de los problemas más comunes en los diversos sistemas de información es el tratamiento o procesamiento de una gran volumen de datos o de información.
Las variables usadas hasta ahora reciben propiamente el nombre de variables escalares porque solo permiten almacenar o procesar un dato a la vez.
Por ejemplo si se quiere almacenar nombre y edad de 15 personas con el método tradicional se ocuparan 30 variables y solo es nombre y edad de 15 personas, agreguen más datos y más personas y ya es tiempo de empezar a analizar otro tipo de variables.
Es decir, en problemas que exigen manejar mucha información o datos a la vez, variables escalares no son suficientes ya que su principal problema es que solo permiten almacenar y procesar un dato a la vez.
Se ocupan entonces variables que sean capaces de almacenar y manipular conjuntos de datos a la vez.
Variables de tipo arreglo si permiten almacenar y procesar conjuntos de datos del mismo tipo a la vez.
Cada dato dentro del arreglo se le conoce como elemento del arreglo y se simboliza y procesa (captura, operación, visualizar) usando el nombre del arreglo respectivo y un subíndice indicando la posición relativa del elemento con respecto a los demás elementos del arreglo, solo recordar que en VISUAL BASIC NET la primera posición, elemento o renglón es el 0 (cero), ej.
NOMBRES
Juan –>nombres(0)
Pedro → nombres(1)
Rosa –> nombres(2)
Jose –> nombres(3)
Sin embargo sus problemas son similares a los de variables normales es decir hay que declararlos, capturarlos, hacer operaciones con ellos, desplegarlos, compararlos, etc.
En programacion tradicional siempre se manejan dos tipos de arreglos los arreglos tipo listas, vectores o unidimensionales y los arreglos tipo tablas, cuadros, concentrados, matrices o bidimensionales en ambos casos son variables que permiten almacenar un conjunto de datos del mismo tipo a la vez, su diferencia es en la cantidad de columnas que cada uno de estos tipos contiene, como en los siguientes ejemplos:
a) LISTAS
EDAD
Cada sub índice nos da la posición
de la variable en los arreglos y las
listas de dTOS
43
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
18
34
22
15 22 45
Como se observa la diferencia principal entre un arreglo tipo lista y un arreglo tipo tabla son las cantidades de columnas que contienen.
En algebra matricial, si son importantes los conceptos de vectores y matrices, pero las operaciones y metodos son precisamente los del algebra matricial.
ARREGLOS TIPO LISTA
Un arreglo tipo lista se define como una variable que permite almacenar un conjunto de datos del mismo tipo organizados en una sola columna y uno o mas renglones.
Tambien reciben el nombre de vectores en algebra o arreglos unidimensionales en programacion. Los procesos normales con una lista o con sus elementos incluyen declarar toda la lista, capturar sus elementos, desplegarlos, realizar operaciones con ellos, desplegarlos, etc.
Para declarar una lista se usa el siguiente formato;
SHARED DIM NOMLISTA(CANT ELEMENTOS -1) AS <TIPODATO>
Shared (compartido), se usa cuando la lista se tenga que compartir entre varias subutinas, observar que cada boton de comando en un programa empieza con sub-end sub, si un programa tiene varias subrutinas que compartan la misma lista, dicha lista debera ser SHARED.
La cantidad de elementos-1, significa que si se quiere una lista de 5 ciudades por ejemplo su declaracion sera shared dim ciudad(4) as string, la razon de esto es que visual basic empieza una lista por el elemento o renglon cero(0), por tanto cuando se pide crear una lista de 4 ciudades, visual basic net le agrega el renglon o elemento 0, que en total darian 5 ciudade.
Es tambien importante recordar que un arreglo en visual basic net es realmente un objeto derivado de la clase SYSTEM.ARRAY.
B) TABLAS
CIA ACME S.A.
INGRESOS MENSUALES DE VENTAS
(MILES DE $)
SUCURSAL ENERO FEBRERO MARZO ABRIL
SUCURSAL
A
10 20 30 40
SUCURSAL
B
60 70 80 90
SUCURSAL
D
100 110 90 120
44
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Recordar tambien que como objeto arreglo, tambien puede usar una serie de metodos pertenecientes a dicha clase system.array, los metodos principales de dicha clase y por tanto de los arreglos derivados de la misma puede estudiarlos en la ayuda del lenguaje.
En visual Basic recordar que la primera posicion o renglon en una lista es la posicion o renglon 0 (cero).
La captura del dato, puede venir de momento de un objeto textbox y/o se usan tantos de estos controles como elementos tenga el arreglo o mas facil aun se debera controlar la captura de elementos usando algun algoritmo sencillo de validacion como lo muestra el programa ejemplo.
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim MiArreglo(10) As Integer Dim I As Integer LISTA2.Items.Clear() ' CARGANDO EL ARREGLO LISTA ORIGINAL CON DATOS For I = 0 To 10 MiArreglo(I) = I * 2
Next ' DESPLEGANDO Dim SValores As String = “ “ For I = 0 To 10 SValores += MiArreglo(I) Next MessageBox.Show(SValores.trim) End Sub
Otro Ejemplo:
' DECLARANDO LISTA GLOBAL Y ESTA DECLARACION ESTAN FUERA DEL SUB Shared EDADARR(4) As Integer ' DECLARANDO RENG COMO GLOBAL Dim RENG As Integer Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 'En este modulo solo se trabaja con el arreglo en memoria
If RENG <= 5 Then EDADARR(RENG) = EDAD.Text RENG = RENG + 1 EDAD.Text = "" End If
0 2 4 6 8 10 12 14 16 18 20
PROCESO
x
45
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
If RENG >= 5 Then EDAD.Visible = False RENG = 0 End If End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click ' LIMPIANDO LISTAS LISTA1.Items.Clear() LISTA2.Items.Clear() ' CARGANDO LISTA ORIGINAL CON EDAD CAPTURADA For RENG = 0 To 4 LISTA1.Items.Add(EDADARR(RENG))
Next ' A MESES Y Y DESPLEGANDO For RENG = 0 To 4 EDADARR(RENG) = EDADARR(RENG) * 12 LISTA2.Items.Add(EDADARR(RENG)) Next End Sub
Corrida
Para el caso de operaciones y comparaciones con todos los elementos de la lista a la vez se debera usar un ciclo for con una variable entera llamada renglon, misma que tambien se usa como indice de la lista.
Recordar que todos los datos internos de la lista estaran almacenados en la memoria ram del computador, para despliegues se usa un componente visual que permite manipular un conjunto de datos a la vez, el ListBox con sus metodos apropiados pero
Observar que en el programa el arreglo edad y
la variable renglon se declararon de tipo
GLOBAL porque los dos metodos el de captura
y el de operacion-despliegue, las estan
compartiendo.
Ademas observar que se declararon antes
de los eventos “clickButton”, para
crearlos como objetos globales.
46
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
se tiene que usar un ciclo for para ir anadiendo o agregando elemento por elemento como se observa en el problema ejemplo que se ha venido desarrollando, en este caso se quiere desplegar las cinco edades convertidas a meses.
La ultima intruccion y muy importante es poner en cero las variables de control de ciclos o indice de arreglos, esto es porque el servidor mantiene el programa ejecutandose continuamente en memoria y si se vuelve a pedir la ejecucion del programa, en cuento se intente capturar un nuevo dato va a marcar el error arreglo fuera de limite o arrayofbound, estan avisados.
Para inicializar una lista con valores se debe usar el siguiente formato:
Shared Dim nomlista() As <tipodato> = {lista de valores separados por comas}
Ejemplo:
Shared Dim edad() as Integer = {15,16,17,18}
Shared Dim sueldo() as Double = {40.85, 65.30, 33.33}
Shared Dim ciudad() as String = {“Managua”, “Leon”, “Masaya”, “Granada”}
EJERCICIOS DE PROGRAMACION DE ARREGLOS TIPO LISTA
1.- Capturar y desplegar 5 precios de productos cualesquiera usando dos panel uno para capturar y uno para desplegar
2.- Capturar 4 sueldos en un panel desplegarlos aumentados en un 25% en otro panel
3.- Capturar los datos de 5 productos comprados en una tienda, incluyendo nombre, precio y cantidad en sus 3 listas respectivas, despues calcular una cuarta lista con el gasto total por cada producto desplegarlo todo en un segundo panel e incluir tambien el gran total
4.- Capturar en una lista solamente 6 numeros multiplos de 5, se debe de estar capture y capture numeros hasta que se completen los 6 multiplos de 5
Arreglos tipo tabla
Un arreglo tipo tabla se define como un conjunto de datos del mismo tipo organizados en dos o más columnas y uno o más renglones.
Para procesar (recordar solo operaciones y comparaciones) internamente todos los elementos de la tabla se ocupan dos ciclos for uno externo para controlar renglon y uno interno para controlar columna.
Los elementos de la tabla se deberan simbolizar con el nombre de la tabla y 2 subindices, el primer subindice referencia al renglon y el siguiente subindice referencia la columna los dos dentro del mismo corchete.
47
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
La declaracion de una tabla sera de acuerdo al siguiente formato:
SHARED DIM NOMTABLA(RENG-1,COL-1) AS <TIPODATO>
Ejemplo:
SHARED DIM SUELDO(3,4) AS DOUBLE
Recordar que va a generar una matriz que tendra cuatro renglones y cinco columnas empieza en sueldo(0,0)
Para capturar sus elementos, usaremos un textbox y un boton de captura, solo tener cuidado o mucho control sobre los indices rEN y col como lo muestra el ejemplo.
Para efectuar otros procesos tales como operaciones, despliegues con todos los elementos de la tabla se deberan usar 2 ciclos un for externo para controlar renglon y un for interno para controlar columna.
Programa
' DECLARANDO LISTA GLOBAL ' RECORDAR QUE SON 3 RENG Y 4 COLUMNAS Shared CALIFICACION(2, 3) As Integer ' DECLARANDO RENG Y COL COMO GLOBAL Dim R, C As Integer Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
' EN ESTE MODULO SOLO SE TRABAJA CON EL ARREGLO
' EN MEMORIA
CALIFICACION(R, C) = CALIF.Text
C = C + 1
CALIF.Text = ""
If C = 4 Then
R = R + 1
C = 0
End If
If R = 3 Then
CALIF.Visible = False
End If
End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button2.Click
48
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Dim TEMP As String
' PROCESANDO Y REGALANDO 50 PUNTOS A TODOS
For R = 0 To 2
For C = 0 To 3
CALIFICACION(R, C) = CALIFICACION(R, C) + 50
Next C
Next R
' desplegando
For R = 0 To 2
TEMP = CALIFICACION(R, 0) & " " & CALIFICACION(R, 1) & " " & CALIFICACION(R, 2) &
" " & CALIFICACION(R, 3)
LISTA1.Items.Add(TEMP)
' limpiando temporal antes de otro renglon
TEMP = " "
Next
End Sub
Notas: Observar el formato de declaracion y como se controlan los indices de captura r, c Para procesar los elementos se usan dos ciclos for y el formato tabla (reng,col).
En este problema se usa el objeto LISTBOX para presentar el resultado mas adelante se usara un objeto mas apropiado.
Diseño: Corrida:
Las matrices en Visual Basic tienen la capacidad de cambiar o modificar su tamaño, es decir su dimensión en memoria, utilizando las palabras reservadas:
ReDim ReDim Preserve Ejemplo:
49
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Dim MiArreglo() As String ‘ Declaro mi arreglo ReDim MiArreglo(2) ‘ Declaro nuevamente mi arreglo de dimension 3
MiArreglo(0) = “Uno” : MiArreglo(1) = “Dos” : MiArreglo(2) = “Tres”
ReDim Preserve MiArreglo(3) ‘Declaro nueva dimensión preservando los valores
MiArreglo(3) = “Cuatro”
MessageBox.Show(MiArreglo(0)) ‘Muestro el valor del primer dato
Nota : Podemos concatenar varias líneas de código separadas por :
Importante: Si deseamos conocer el tamaño o dimensión, podemos utilizar unmetodo de los arreglos :
MiArreglo.Length
Ejemplo, utilizando el anterior podemos escribir
MessageBox.Show(MiArreglo.Length)
Nos visualizaría 4, que es la dimensión del arreglo
Importante: Si deseamos eliminar los elementos de un arreglo de forma rápida utilizamos la palabra rservada Nothing, ejemplo:
MiArreglo = Nothing
If MiArreglo IsNothing then
MessageBox.Show(“ Nada”)
Else
MessageBox.Show(MiArreglo.Length) ‘presenta la dimension
Endif
Importante: Si deseamos copiar una matriz en otra podemos hacerlo de esta forma:
MiArreglo.CopyTo(OtroArreglo,0)
Ejemplo:
Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim MiArreglo() As String = {“Mercurio”,”Venus”,”Tierra”}
Dim OtroArreglo() As String
ReDim OtroArreglo(MiArreglo.Lenght – 1)
MiArreglo.CopyTo(OtroArreglo,0)
MessageBox.Show(OtroArreglo(0))
End Sub
50
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
TAREAS PROGRAMACION DE TABLAS
1.- Construir un cuadro que contenga los costos fijos de cuatro productos cualesquiera, que se producen en tres plantas diferentes de una empresa maquiladora (2 prog uno capturado y otro inicializado).
2.- Construir un cuadro que contenga los ingresos mensuales por ventas durante los tres primeros meses del ano de cuatro sucursales de una cadena de auto refacciones, agregar al final una lista que muestre los ingresos mensuales totales por meses y una segunda lista que muestre los ingresos mensuales totales por sucursal(2 progs uno capturado y otro inicializado).
3.-Construir un cuadro que contenga las comisiones ganadas por tres vendedores, de los 5 tipos de linea blanca de conocida muebleria, ademas listas de comisiones totales y promedios ganadas por los vendedores, asi como listas de comisiones totales y promedios por tipo de linea blanca
Analizar este codigo:
' PARA TOTALES Y PROMEDIOS POR RENGLON (FILAS) FOR R = 0 TO 3 FOR C = 0 TO 2 TOTRENG(R) = TOTRENG(R) + TABLA(R,C) NEXT C PROMRENG(R) = TOTRENG(R)/3 NEXT R 'PARA TOTALES Y PROMEDIOS POR COLUMNA FOR C = 0 TO 2 FOR R = 0 TO 3 TOTCOL(C)=TOTCOL(C) + TABLA(R,C) NEXT R PROMCOL(C) = TOTCOL(C) / 4 NEXT C
4.9--Funciones del lenguaje integradas
Cada lenguaje dispone de un grupo de funciones de apoyo, para ayudar al programador en su trabajo cotidiano. Las versiones anteriores de Visual Basic
Actividades de reforzamiento de lo a aprendido
51
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
contenían un gran número de funciones para realizar operaciones aritméticas, manipular cadenas, fechas, etc.
VB.NET también tiene funciones para las operaciones antes comentadas. No obstante, debido a la orientación a objetos sobre la que está construida la plataforma .NET, la gran potencia a la hora de resolver cualquier situación la encontraremos en el gran número de clases proporcionadas por el entorno para resolver las más variadas situaciones, lo que veremos en el tema dedicado a OOP.
En este apartado y organizadas por categorías, vemos una pequeña muestra
de las funciones disponibles en VB.NET. Consulte el lector la documentación
de la plataforma, para obtener información más detallada de todas las funciones
disponibles.
Funciones Numéricas
Int(Número), Fix(Número). Estas funciones devuelven la parte entera del
parámetro Número. La diferencia entre ambas reside en que cuando el parámetro
pasado es negativo, Int() devuelve el entero negativo menor o igual que Número,
mientras que Fix( ) devuelve el entero negativo mayor o igual que Número. Ver el
Código
Dim Resultado As Integer
Resultado = Int(66.87) ' 66
Resultado = Fix(66.87) ' 66
Resultado = Int(-66.87) ' -67
Resultado = Fix(-66.87) ' –66
Randomize([Número]). Inicializa el generador de números aleatorios, que utilizaremos posteriormente en la función Rnd( ). Opcionalmente recibe un número como parámetro que sirve al generador como valor inicial o semilla para la creación de estos números. Rnd([Número]). Devuelve un número aleatorio de tipo Single, que será menor
que 1, pero mayor o igual a cero.
Podemos, opcionalmente, variar el modo de generación del número pasando un
valor al parámetro de esta función. En función de si el parámetro es mayor, menor
de cero, o cero, el comportamiento de Rnd( ) a la hora de generar el número será
diferente. Ver el Código
Dim Contador As Integer
Dim Aleatorio As Single
Randomize()
For Contador = 1 To 5
Aleatorio = Rnd()
52
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
MsgBox("Número generado: es "&, Aleatorio)
Next
El anterior código produce una salida similar a la mostrada en la Figura
Generación de números aleatorios con Rnd( ).
Si necesitamos que el número aleatorio esté comprendido en un intervalo de números enteros, utilizaremos la fórmula del Código para generarlo.
Int((LímiteSuperior - LímiteInferior + 1) * Rnd() + LímiteInferior)
El ejemplo del Código crea números aleatorios comprendidos entre el intervalo de los números 7 y 12.
Dim Contador As Integer
Dim Aleatorio As Single
Randomize()
For Contador = 1 To 10
Aleatorio = Int((12 - 7 + 1) * Rnd() + 7)
MsgBox("Número generado: "& Aleatorio)
Next
Funciones Cadena de caracteres
Len(Cadena). Devuelve un número con la longitud de la cadena pasada como
parámetro. Ver el Código
Dim Longitud As Integer
Longitud = Len("comprobar cuantos caracteres hay")
MsgBox("La cadena tiene caracteres " & Longitud) ' 32
Space(Número). Devuelve una cadena de espacios en blanco, de una longitud igual al
número pasado como parámetro. Ver el Código.
Numero generado: 0,706402
Numero generado: 0,4058605
Numero generado: 0,337209
Numero generado: 0,8914912
Numero generado: 0,8711619
53
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Dim ConEspacios As String
ConEspacios = "Hola" & Space(7) & "a todos"
MsgBox("La cadena con espacios tiene el valor:" & ControlChars.CrLf & ConEspacios)
' Hola a todos
InStr([Comienzo, ]CadenaBuscar, CadenaBuscada [, TipoComparación]). Busca dentro de CadenaBuscar la cadena contenida en el parámetro CadenaBuscada. Opcionalmente podemos establecer en Comienzo, la posición en la que comienza la búsqueda y el tipo de comparación (texto, binaria) en el parámetro TipoComparación. Ver el Código
Dim CadBuscar As String Dim CadBuscada As String Dim PosComienzo As Integer CadBuscar = "El castillo del bosque" PosComienzo = InStr(CadBuscar, "tillo") MsgBox("La posición de comienzo de la cadena encontrada es: " & ,PosComienzo) ' 7
Left(Cadena, Longitud). Esta función extrae, comenzando por la parte izquierda de Cadena, una subcadena de Longitud de caracteres. Right(Cadena, Longitud). Esta función extrae, comenzando por la parte derecha
de Cadena, una subcadena de Longitud de caracteres.
El Código muestra ejemplos de Left( ) y Right( ).
Dim CadIzquierda As String Dim CadDerecha As String CadIzquierda = Left("Especial", 3) MsgBox("Resultado de la función Left(): "& CadIzquierda) ' Esp CadDerecha = Right("Especial", 3) MsgBox("Resultado de la función Right(): "& CadDerecha) ' ial
Mid(Cadena, Inicio [, Longitud]). Extrae de Cadena, comenzando en la posición Inicio,
una subcadena. Opcionalmente podemos utilizar el parámetro Longitud, para indicar el
largo de la subcadena. En caso de no utilizar este último parámetro, la subcadena se
obtendrá hasta el final. Ver Código
Dim MiCadena As String
Dim SubCadena As String
MiCadena = "El bosque encantado"
SubCadena = Mid(MiCadena, 6)
54
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
MsgBox("Subcadena hasta el final: "& SubCadena) ' sque encantado
SubCadena = Mid(MiCadena, 6, 3)
MsgBox("Subcadena de 3 caracteres: "& SubCadena) ' squ
Replace(Cadena,CadOrigen,CadNueva [,Inicio] [,Sustituciones] [,TipoComparación]).
Esta función toma la cadena situada en el primer parámetro y busca la cadena CadOrigen, sustituyendo las ocurrencias encontradas por la cadena CadNueva. Opcionalmente, el parámetro Inicio especifica la posición en la que comenzará la sustitución; el parámetro Sustituciones indica el número de sustituciones a realizar; y TipoComparación indica como se realizarán las comparaciones (texto, binaria). Veamos unos ejemplos en el Código
Dim MiCadena As String : Dim CadSustituida As String MiCadena = "Este coche es especial" CadSustituida = Replace(MiCadena, "es", "xx") ' resultado: Este coche xx xxpecial MsgBox("Resultado del reemplazo en la cadena: "& CadSustituida) ' en el anterior ejemplo los dos primeros caracteres no se sustituyen porque ' no se ha especificado el tipo de comparación, que a continuación sí indicaremos CadSustituida = Replace(MiCadena, "es", "xx", , , CompareMethod.Text) ' resultado: xxte coche xx xxpecial ' ahora sí se han sustituido todas las ocurrencias de "es" MsgBox("Resultado del reemplazo en la cadena: "& CadSustituida)
LTrim(Cadena), RTrim(Cadena), Trim(Cadena). Estas funciones eliminan de una cadena,
los espacios en blanco a la izquierda en el caso de LTrim( ); los espacios en blanco
a la derecha en el caso de RTrim(); o los espacios en blanco a ambos lados Trim( ). Ver el
Código
Dim CadEspacios As String : Dim CadResultante As String CadEspacios = " Barco " CadResultante = LTrim(CadEspacios) ' "Barco " CadResultante = RTrim(CadEspacios) ' " Barco" CadResultante = Trim(CadEspacios) ' "Barco"
UCase(Cadena), LCase(Cadena). Estas funciones, convierten la cadena pasada
como parámetro a mayúsculas y minúsculas respectivamente. Ver el Código .
Dim Cadena As String : Dim CadMay As String: Dim CadMin As String
Cadena = "Vamos a Convertir En Mayúsculas Y MinúscuLAS"
CadMay = UCase(Cadena)
CadMin = LCase(Cadena)
' "VAMOS A CONVERTIR EN MAYÚSCULAS Y MINÚSCULAS"
MsgBox("Conversión a mayúsculas: " & CadMay)
55
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
' "vamos a convertir en mayúsculas y minúsculas"
MsgBox("Conversión a minúsculas: " & CadMin)
Format(Expresión[,CadenaFormato][,PrimerDíaSemana[,PrimeraSemanaAño]). Formatea la expresión pasada en el primer parámetro, empleando de forma opcional una cadena para especificar el tipo de formateo a realizar. Si el valor a formatear es una fecha, podemos utilizar los dos últimos parámetros para especificar el primer día de la semana y la primera semana del año; estos dos últimos parámetros son enumeraciones, cuyos valores aparecen automáticamente al asignar su valor. Consulte el lector, la documentación de ayuda para más información.
Como cadena de formato, podemos utilizar los nombres predefinidos de formato, o una serie de caracteres especiales, tanto para formateo de números como de fechas. En lo que respecta a los nombres predefinidos, la Tabla 23 muestra algunos de los utilizados.
Nombre de formato Descripción
General Date Muestra una fecha con el formato largo del sistema.
Short Date Muestra una fecha empleando el formato corto del sistema.
Short Time Muestra un valor horario con el formato corto del sistema.
Standard Muestra un número utilizando los caracteres de separador de miles y decimales.
Currency Muestra un número con los caracteres correspondientes a la moneda establecida en la
configuración regional del sistema.
Percent Muestra un número multiplicado por 100 y con el carácter de tanto por ciento.
Nombres de formato para la función Format( ).
El Código fuente muestra algunos ejemplos de formateo con nombre
Dim MiFecha As Date Dim MiNumero As Double Dim ValorFormato As String MiFecha = #7/19/2002 6:25:00 PM# MiNumero = 1804 ValorFormato = Format(MiFecha, "Long Date")' "Viernes, 19 de julio de 2004”
56
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
ValorFormato = Format(MiFecha, "Short Date") ' "19/07/2002" ValorFormato = Format(MiFecha, "Short Time") ' "18:25" ValorFormato = Format(MiNumero, "Standard") ' "1.804,00" ValorFormato = Format(MiNumero, "Currency") ' "1.804 pta" ValorFormato = Format(MiNumero, "Percent") ' "180400,00%"
Para los caracteres especiales, la Tabla muestra un conjunto de los más habituales.
Carácter de
formato
Descripción
: Separador de hora.
/ Separador de fecha.
d Visualiza el número de día sin cero a la izquierda.
dd Visualiza el número de día con cero a la izquierda.
ddd Visualiza el nombre del día abreviado.
dddd Visualiza el nombre del día completo.
M Visualiza el número de mes sin cero a la izquierda.
MM Visualiza el número de mes con cero a la izquierda.
MMM Visualiza el nombre del mes abreviado.
MMMM Visualiza el nombre del mes completo.
yy Visualiza dos dígitos para el año.
yyyy Visualiza cuatro dígitos para el año.
H Visualiza la hora sin cero a la izquierda.
HH Visualiza la hora con cero a la izquierda.
m Visualiza los minutos cero a la izquierda.
mm Visualiza los minutos con cero a la izquierda.
s Visualiza los segundos cero a la izquierda.
ss Visualiza los segundos con cero a la izquierda.
0 En valores numéricos, muestra un dígito o cero.
# En valores numéricos, muestra un dígito o nada.
57
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
, Separador de millar.
. Separador decimal.
Caracteres de formato para la función Format( ).
El Código muestra algunos ejemplos de formato con caracteres especiales.
Dim MiFecha As Date Dim MiNumero As Double Dim ValorFormato As String MiFecha = #7/19/2002 6:25:00 PM# MiNumero = 16587.097 ValorFormato = Format(MiFecha, "dddd d/MMM/yyyy") ' "Viernes 19/jul/2002" ValorFormato = Format(MiFecha, "HH:mm") ' "18:25" ValorFormato = Format(MiNumero, "#,#.00") ' "16.587,10"
StrConv(Cadena, TipoConversión [,IDLocal]). Realiza una conversión de la cadena pasada como parámetro, utilizando algunos de los valores de la enumeración TipoConversión. Opcionalmente podemos pasar también un valor correspondiente al identificador local del sistema. Ver el Código fuente
Dim MiCadena As String Dim Conversion As String MiCadena = "el tren llegó puntual" ' convertir a mayúscula
Conversion = StrConv(MiCadena, VbStrConv.UpperCase) ' convertir a minúscula Conversion = StrConv(MiCadena, VbStrConv.LowerCase) ' convertir a mayúscula la primera letra de cada palabra Conversion = StrConv(MiCadena, VbStrConv.ProperCase)
Fecha y hora
Now( ). Devuelve un valor de tipo Date con la fecha y hora del sistema.
DateAdd(TipoIntervalo, ValorIntervalo, Fecha). Suma o resta a una fecha, un intervalo determinado por el parámetro TipoIntervalo. El intervalo a utilizar pueden ser días, semanas, meses, etc. Para determinar si se realiza una suma o resta, ValorIntervalo deberá ser positivo o negativo respectivamente.
DateDiff(TipoIntervalo, FechaPrimera, FechaSegunda). Calcula la diferencia existente entre dos fechas. En función de TipoIntervalo, la diferencia calculada serán días, horas, meses, años, etc.
DatePart(TipoIntervalo, Fecha). Extrae la parte de una fecha indicada en TipoIntervalo. Podemos obtener, el día, mes, año, día de la semana, etc.
El Código fuente muestra un conjunto de ejemplos que utilizan las funciones para
58
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
manipular fechas.
Dim MiFecha As Date Dim FechaPosterior As Date Dim DiasDiferencia As Long Dim ParteFecha As Integer MiFecha = Now() ' #1/19/2002 12:27:08 PM# FechaPosterior = DateAdd(DateInterval.Month, 2, MiFecha) ' #3/19/2002 12:27:08 PM# DiasDiferencia = DateDiff(DateInterval.Day, MiFecha, FechaPosterior) ' 59 ParteFecha = DatePart(DateInterval.Year, MiFecha) ' 2002
4.10.-PROCEDIMIENTOS O SUBRUTINAS EN VISUAL BASIC NET
Recordar que un objeto presenta tres aspectos, propiedades, metodos y eventos, en esta unidad se analizan algunos elementos que intervienen en la definicion de un metodo.
Estamos hablando de los llamados procedimientos y funciones, que quede claro que procedimientos y funciones son solo algunos aspectos (importantes) de la definicion de un metodo, pero que existen elementos tan o mas importantes que los analizados en esta unidad. Un procedimiento es un grupo de instrucciones, variables, constantes, etc, que estan disenados con un proposito particular y tiene su nombre propio.
Es decir un procedimiento es un modulo de un programa que realiza tareas especificas y que no puede regresar valores al programa principal u a otro procedimiento que lo este invocando. Despues de escribir un procedimiento se usara su propio nombre como una sola instruccion o llamada al procedimiento usando el formato:
CALL NOMPROC()
El formato para construir un procedimiento o subrutina en VISUAL BASIC NET es:
Sub NomProc() Instrucciones
End Sub Un programa puede tener tantos procedimientos o subrutinas como se deseen, para hacer una llamada o invocacion al procedimiento durante la ejecucion de un programa solo se debera escribir el nombre del procedimiento y los parentesis en blanco.
Programa
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
' llamando, invocando o activando procedimiento uno Call PROC1()
59
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
End Sub Sub PROC1() Label2.Text = EDAD.Text * 12 End Sub Corrida
Como se observa un procedimiento puede ser un programa completo.
EJERCICIOS DE PROGRAMACION DE FUNCIONES
Construir tres programas que contengan los procedimientos abajo del sub
buttonclick().
a) Convertir $800.00 Cordobas a dolares.
b) Calcular el Area de un triangulo
c) Deplegar una Boleta de calificaciones.
PARAMETROS EN VISUAL BASIC
Un parametro es una variable que puede pasar su valor a un procedimiento desde el
principal o desde otro procedimiento.
Existen ocasiones en que es necesario mandar al procedimiento ciertos valores para que los use en algun proceso.
Actividades de reforzamiento de lo
aprendido
60
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Estos valores que se pasan del cuerpo principal del programa o de un procedimiento a otros procedimientos se llaman parametros. Entonces la declaracion completa de un procedimiento es :
SUB NOMPROC(lista de parametros)
cuerpo de instrucciones
END SUB
Donde lista de parametros es una o mas variables separadas por comas como lo muestra el pograma ejemplo. Programa Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim nom As String nom = "pepe" 'Se puede mandar como parametro un dato, variable 'o expresion algebraica Call PROC1(3.75, nom, 4 + 8) End Sub Sub PROC1(ByVal deci As Single, ByVal nom As String, ByVal suma As Integer) ' pero siempre se recibe en una variable Label2.Text = EDAD.Text + deci + suma Label3.Text = nom End Sub
Observar que en el procedimiento los parametros crean dos variables de manera local, es decir variables que solo se pueden usar dentro del procedimiento estas variables son quienes reciben los datos o valores.
REGLAS PARA EL USO DE PARAMETROS:
1.- Cuando se usan variables como parametros la variable que se manda debe ser
declarada dentro del principal o del procedimiento de donde se esta enviando.
2.- La variable que se manda tiene un nombre, la que se recibe puede tener otro
nombre o el mismo nombre por claridad de programa, pero recordar que
internamente en la memoria del computador existiran dos variables diferentes.
3.- La cantidad de variables que se envian deben ser igual en cantidad, orden y tipo a
las variables que reciben.
4.- La variable que se recibe tiene un ambito local dentro del procedimiento, es decir
solo la puede usar ese procedimiento.
5.- Se puede mandar a un procedimiento un dato, una variable (como lo muestran los
ejemplos) o una expresion algebraica (no ecuacion o formula) pero siempre se deberan
recibir en una variable.
Corrida
61
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
EJERCICIOS DE PROGRAMACION DE FUNCIONES 1.- En una VENTANA recoger 3 calificaciones en el onclick, calcular promedio en procedimiento uno y desplegar nombre y promedio en un segundo procedimiento 2,- Construir una tabla de multiplicar que el usuario indique, captura y control de ciclo en button_click, calculo y despliegue en un procedimiento usar un solo listbox para la tabla resultado. 3.- Construir un procedimiento que reciba un numero entero y que mande llamar a un segundo procedimiento pasando el letrero “PAR O IMPAR” FUNCIONES EN VISUAL BASIC NET Una funcion es un modulo de un programa separado del cuerpo principal que realiza una tarea especifica y que puede regresar un valor a la parte principal del programa u otra funcion o procedimiento que la invoque. La forma general de una funcion es: Function NOMFUNCION(parametros) instrucciones NOMFUNCION = cargarlo porque es quien regresa el dato End Function La lista de parametros formales es una lista de variables separadas por comas (,) que almacenaran los valores que reciba la funcion estas variables actuan como locales dentro del cuerpo de la funcion. Aunque no se ocupen parametros los parentesis son requeridos. Dentro del cuerpo de la funcion deber haber una instruccion que cargue el NOMFUNCION para regresar el valor, de esta manera se regresan los datos.
Actividad de reforzamiento de lo
aprendido
62
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Sin embargo es de considerar que NOMFUNCION puede regresar un dato, una variable o una expresion algebraica (no ecuacion o formula) como lo muestran los siguientes ejemplos: a) NOMFUNCION = 3.1416 b) NOMFUNCION = area c) NOMFUNCION = x + 15 / 2 Recordar ademas: a) Una funcion no se llama usando CALL b) Cuando se llame a una funcion debera haber una variable que reciba el valor que regresara la funcion, es decir generalmente se llama una funcion mediante una sentencia de asignacion, por ejemplo resultado = funcion(5, 3.1416) Programa Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 'Creando variable que recibira el valor que regrese la funcion Dim alfa as integer 'llamando la funcion y mandandole datos o parámetros observar que se llama por 'igualdad alfa = FUNCION1(500) ' Aunque se puede llamarla directamente y cuantas veces sea necesario Label1.Text = FUNCION1(100) - alfa End Sub Function FUNCION1(ByVal varuno As Integer) ' cargando y regresando el nomfuncion FUNCION1 = 100 + varuno End Function Corrida
Nota: Es permitido cargar más de un
NOMFUNCION en el cuerpo de
instrucciones sobre todo en
condiciones, pero solo uno de ellos se
ejecutara
63
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Ejemplo;
if suma >= 10 then funcion50 = 300
else funcion50 = 20
end if
TIPOS USUALES DE FUNCIONES.
Las primeras son de tipo computacional que son diseñadas para realizar operaciones con los argumentos y regresa un valor basado en el resultado de esa operacion.
Las segundas funciones son aquellas que manipulan informacion y regresan un valor que indican la terminacion o la falla de esa manipulacion.
Las terceras son aquellas que no regresan ningun valor, es decir son estrictamenta procedurales. Esto quiere decir que en general toda operacion o calculo en un programa debera convertirse a una o muchas funciones y el resto deberan ser procedimientos.
ARREGLOS COMO PARAMETROS
Para pasar un arreglo completo como parametro a un procedimiento o a una funcion solo se manda el nombre del arreglo sin corchetes e indices, en el procedimiento o funcion que recibe solo se declara un arreglo del mismo tipo y se puede usar el mismo o diferente nombre del arreglo sin corchetes e indices.
Sin embargo es conveniente aclarar, que a diferencia de variables escalares normales visual basic no genera una nueva variable en memoria ni tampoco copia los datos al arreglo que recibe, en su lugar visual basic sigue usando los datos que estan en el arreglo original, es por esta razon que cambios que se le hagan a los datos del arreglo que recibe realmente se esta haciendo al arreglo original como lo muestra el siguiente ejemplo:
Programa
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' creando y cargando una lista local con 5 elementos Dim lista1() As Integer = {1, 2, 3, 4, 5} ' pasandola a un procedimiento observar que se pasa sin parentesis Call PROC1(lista1) ' desplegando lista original y observar el resultado Dim r As Integer For r = 0 To 4
64
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
LISTA.Items.Add(lista1(r)) Next r End Sub Sub PROC1(ByVal vector) ' recibiendola con otro nombre y ' sumando a vector + 100 Dim r As Integer For r = 0 To 4 vector(r) = vector(r) + 100 Next r End Sub
Corrida
EJERCICIOS DE PROGRAMACION DE FUNCIONES
1.- Capturar 3 calificaciones y nombre en un procedimiento, calcular promedio en una
funcion, desplegar en otro procedimiento, BUTTONCLICK SOLO ACTIVA EL PRIMER
PROCEDIMIENTO
2.- Crear una tabla de multiplicar, captura y control de ciclo en el principal
(BUTTONCLICK), operaciones en una funcion, despliegue en el principal.
3.- Inicializar 10 edades en el principal(buttonclick) mandar la lista a un procedimiento
que la convierte a meses, desplegar en principal.
Es de recordar que los cambios que le
hagan al arreglo dentro del procedimiento
se reflejaran en el arreglo original, es por
esto que si se quiere modificar un arreglo
en un procedimiento funcion no hay
necesidad de regresar ningun valor y por
tanto no se ocupan funciones.
Solo para los casos que se quiera regresar
algun dato especial del arreglo, por ejemplo
regresar el primer dato par, o la suma de
todos los elementos del arrreglo o el
promedio de todos sus elementos, etc etc
etc, solo en casos como estos se mandara
una arreglo a una funcion.
Actividades de reforzamiento de lo aprendido
65
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
4.- Capturar un arreglo de 7 ciudades en un primer procedimiento, sortear en un
segundo y desplegar en un tercero, la lista original y la lista ordenada.
Funciones de comprobación de tipos de datos
Si tenemos desactivada la comprobación de tipos con Option Strict, pero en
ciertas situaciones necesitamos comprobar si determinada variable o expresión
contienen un valor numérico, fecha, etc., el lenguaje nos proporciona para ello, algunas
funciones con las que podremos comprobar el tipo de dato, para evitar posibles
errores.
IsNumeric( ). Esta función devuelve un valor lógico indicando si la expresión que
pasamos como parámetro contiene un número o una cadena que pueda ser
convertida a número. Ver el Código
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim Valor As Object Dim Total As Integer Valor = Inputbox(“ Introduzca un valor”) If IsNumeric(Valor) Then Total = Valor + 100 MsgBox("Resultado: "& Total) Else MsgBox("El valor introducido no es numérico") End If End Sub
IsDate( ). Esta función devuelve un valor lógico indicando si la expresión que pasamos como parámetro contiene una fecha o una cadena que pueda ser convertida a fecha. Ver el Código
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim Valor As Object Dim UnaFecha As Date Valor = Inputbox(“ Introduzca un valor”) If IsDate(Valor) Then UnaFecha = Valor MsgBox("La fecha es: "& UnaFecha) Else MsgBox("El valor introducido no es una fecha") End If End Sub
IsArray( ). Esta función devuelve un valor lógico indicando si la expresión que
66
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
pasamos como parámetro contiene un array. Ver el Código .
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim Colores() As String = {"Verde", "Azul", "Rojo"} Verificar(Colores) Verificar("prueba") End Sub Public Sub Verificar(ByVal ValorPasado As Object) ' comprobar si el parámetro contiene un array If IsArray(ValorPasado) Then MsgBox("El parámetro pasado es un array") Else MsgBox("El parámetro pasado no es un array") End If End Sub
67
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
5.- Programando con controles en Visual Basic Los controles proporcionan al usuario el medio para comunicarse con nuestro
formulario, y en definitiva, con la aplicación. Por ello, en los siguientes
apartados, mostraremos los principales aspectos que debemos tener en cuenta a
la hora de su creación, manipulación y codificación.
También realizaremos una revisión de los principales controles, mostrando
algunas de sus características más destacadas.
5.1.-El Cuadro de herramientas
Una vez creado un proyecto, o después de añadir un nuevo formulario, para
utilizar controles en el mismo, tendremos que tomarlos de la ventana Cuadro de
herramientas disponible en el IDE de VS.NET, y añadirlos al formulario. Ver Figura
Insertar un control en el formulario
Para añadir un control en el formulario, proceso que también se conoce como
dibujar un control, debemos seleccionar primeramente el control a utilizar de la
lista que aparece en el cuadro de herramientas.
Una vez localizado el control, haremos doble clic sobre él, o pulsaremos [INTRO], lo
que añadirá una copia del mismo en el formulario, que después, mediante el ratón o
teclado, situaremos en la posición adecuada.
Otra técnica, esta más habitual, consiste en hacer clic sobre el control, situar el
cursor del ratón en la superficie del formulario y hacer clic en él, arrastrando hasta
dar la forma deseada; de esta manera, proporcionamos al control en un solo paso
la ubicación y tamaño iniciales.
Dibujemos, a modo de práctica, un control Button sobre el formulario, con un
aspecto similar al mostrado en la
68
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Un control, al igual que un formulario, dispone a su alrededor de un conjunto de guías de redimensión, de modo que si después de situarlo en el formulario, queremos modificar su tamaño, sólo tenemos que hacer clic sobre alguna de estas guías, y arrastrar modificando las dimensiones del control. Además de utilizando el ratón, podemos desplazar un control, manteniendo pulsada la tecla[CONTROL], y pulsando además, algunas de las teclas de dirección.
Ajuste de la cuadrícula de diseño del formulario La cuadrícula de diseño del formulario, consiste en el conjunto de líneas de puntos que surcan la superficie del formulario, y nos sirven como ayuda, a la hora de realizar un ajuste preciso de un control en una posición determinada. Si el lector ya ha realizado algunas prácticas situando controles en el formulario, se percatará de que cuando movemos un control con el ratón, dicho control se ajusta a la cuadrícula obligatoriamente, por lo que no podemos ubicarlo entre dos líneas de puntos de la cuadrícula. Para solventar este problema tenemos algunas soluciones que proponemos a continuación: La más simple y directa, consiste en acceder a la ventana de propiedades del formulario, y en la propiedad GridSize, cambiar los valores de espaciado de puntos que tiene la rejilla. Cuanto menor sea ese valor, más junta estará la trama de puntos de la rejilla, con lo que podremos ajustar de forma más exacta el control. Este ajuste es válido sólo para el formulario sobre el que lo aplicamos. Probemos por ejemplo, a introducir 5 en cada valor, como muestra la Figura
69
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Cambiando el tamaño de la cuadrícula de diseño del formulario.
El otro modo consiste en asignar en el formulario, a la propiedad SnapToGrid, el valor False; esto deshabilita el ajuste a la cuadrícula automático de los controles, con lo que perdemos en precisión de ajuste, pero ganamos en libertad de ubicación para el control. Si no queremos que la cuadrícula se visualice, asignaremos False a la propiedad DrawGrid del formulario.
Los anteriores ajustes los podemos realizar también de modo genérico para todos los formularios. Seleccionaremos para ello, la opción de menú del IDE Herramientas + Opciones, y en la ventana Opciones, haremos clic sobre el elemento Diseñador de Windows Forms. En el panel derecho de esta ventana, podremos configurar estas propiedades de modo general para todo el IDE. Ver Figura
Ajuste general de las propiedades para la cuadrícula de diseño de formularios.
Organización-formato múltiple de controles Cuando tenemos un grupo numeroso de controles en el formulario, que necesitamos mover de posición, o cambiar su tamaño, para redistribuir el espacio; podemos optar por cambiar uno a uno los controles, tarea pesada y nada aconsejable; o bien, podemos seleccionar todos los controles a modificar, y realizar esta tarea en un único paso, mediante las opciones del menú Formato del IDE. Supongamos que en el formulario tenemos dos controles Button y un ListBox distribuidos como muestra la Figura
70
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
En primer lugar, para seleccionarlos todos, debemos hacer clic sobre el formulario y arrastrar, de modo que el rectángulo de selección que aparece, abarque a los controles, que quedarán con sus correspondientes marcas de redimensión visibles, señal de que están seleccionados.
En este punto, podemos hacer clic en uno de los controles y desplazarlos todos conjuntamente por el formulario, o bien, hacer clic en una de las guías de redimensión y cambiar su tamaño, lo que afectará a todos los controles seleccionados. Si necesitamos de alguna acción especial, utilizaremos las opciones del menú Formato del IDE.
Por ejemplo, podemos ejecutar la opción Formato + Alinear + Lados izquierdos, de modo que todos los controles se alinearán por la izquierda, tomando como referencia el control que tiene las marcas de redimensión negras. Ver Figura
Después ejecutaremos la opción de menú Formato + Igualar tamaño + Ambos, que ajustará tanto el ancho como el alto de todos los controles seleccionados. Ver Figura
71
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Igualando tamaño de controles.
Para evitar que, una vez completado el diseño y ajuste de todos lo controles, accidentalmente podamos modificar alguno, seleccionaremos la opción de menú Formato + Bloquear controles, que bloqueará
los controles seleccionados, impidiendo que puedan ser movidos o modificado su tamaño. Para desbloquear los controles del formulario, debemos seleccionar al menos uno y volver a utilizar esta opción de menú, que desbloqueará todos los controles.
Una característica interesante del bloqueo de controles, consiste en que una vez que tengamos bloqueados los controles del formulario, si añadimos un nuevo control, este no estará inicialmente bloqueado, lo que facilita su diseño. Una vez que hayamos finalizado de diseñar el último control, lo seleccionaremos en el formulario y seleccionaremos la opción de bloqueo de controles, de modo que ya estarán bloqueados todos de nuevo.
El menú Formato de VS.NET consta de un numeroso conjunto de opciones. Acabamos de ver una muestra de sus posibilidades, por lo que recomendamos al lector, que realice pruebas con el resto de opciones, para ver todas las posibilidades en cuanto a la disposición de los controles dentro del formulario.
5-2-Controles Windows Basicos
Como habrá comprobado el lector, el número de controles del cuadro de
herramientas es muy numeroso, por lo que en los próximos apartados, vamos a
trabajar con los que se consideran controles básicos o estándar, dada su gran
frecuencia de uso. La Tabla relaciona este conjunto de controles básico, junto a una
breve descripción.
Control Descripción
Button Botón de pulsación
Label Etiqueta de literal
72
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
TextBox Cuadro de texto
ListBox Lista de valores
ComboBox
Lista de valores desplegable, y cuadro
de texto
CheckBox Casilla de verificación
RadioButton Botón autoexcluyente
GroupBox
Caja de agrupación de controles
Controles básicos de formularios Windows.
5.3.-Control Label
El control Label o Etiqueta, muestra un texto informativo al usuario. Podemos
utilizar este control como complemento a otro control, por ejemplo, situándolo
junto a un TextBox, de modo que indiquemos al usuario el tipo de dato que
esperamos que introduzca en la caja de texto.
Se trata de un control estático; esto quiere decir que el usuario no puede interaccionar con él, a diferencia, por ejemplo, de un control Button, sobre el que sí podemos actuar pulsándolo; o de un TextBox, en el que podemos escribir texto.
Una de sus propiedades es BorderStyle, que permite definir un borde o recuadro alrededor del control, o que dicho borde tenga un efecto 3D; por defecto se muestra sin borde. Veamos unos ejemplos en la Figura
Controles Label.
5.4.-Control TextBox
Un control TextBox muestra un recuadro en el que podemos introducir texto. Para
poder escribir texto en un control de este tipo, debemos darle primeramente el foco,
lo que detectaremos cuando el control muestre el cursor de escritura en su interior.
73
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Entre las propiedades disponibles por este control, destacaremos las siguientes.
Text. Cadena con el texto del control.
Multiline. Permite establecer si podemos escribir una o varias líneas. Por
defecto contiene False, por lo que sólo podemos escribir el texto en una línea.
WordWrap. En controles multilínea, cuando su valor es True, al llegar al
final del control cuando estamos escribiendo, realiza un desplazamiento
automático del cursor de escritura a la siguiente línea de texto.
Enabled. Contiene un valor lógico mediante el que indicamos si el control está o
no habilitado para poder escribir texto sobre él.
ReadOnly. Permite indicar si el contenido del control será de sólo lectura o bien, podremos editarlo.
CharacterCasing. Esta propiedad, permite que el control convierta
automáticamente el texto a mayúsculas o minúsculas según lo estamos escribiendo.
MaxLength. Valor numérico que establece el número máximo de caracteres
que podremos escribir en el control.
PasswordChar. Carácter de tipo máscara, que será visualizado por cada
carácter que escriba el usuario en el control. De esta forma, podemos dar a un
cuadro de texto el estilo de un campo de introducción de contraseña.
AutoSize. Cuando esta propiedad tenga el valor True, al modificar el tamaño
del tipo de letra del control, dicho control se redimensionará automáticamente,
ajustando su tamaño al del tipo de letra establecido.
La Figura muestra un formulario con varios controles TextBox, a los cuales se han aplicado diferentes efectos mediante sus propiedades.
Pruebas con controles TextBox.
Al comenzar a ejecutar el programa, observaremos que el foco de entrada no está situado en el primer TextBox del formulario. Para asignar por código el foco a un determinado control, disponemos del método Focus( ). En este caso, al pulsar el
74
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
botón Foco nombre, desviamos el foco al primer TextBox del formulario. Ver Código fuente
Private Sub btnFoco_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnFoco.Click
Me.txtNombre.Focus()
End Sub
Observe el lector, que en el botón Foco nombre, que acabamos de mencionar, la letra F se encuentra subrayada, actuando de acelerador o hotkey. De este modo, no es necesario pulsar con el ratón sobre ese botón para ejecutarlo, basta con pulsar la tecla [CONTROL] junto a la letra subrayada para conseguir el mismo efecto.
Para definir una tecla aceleradora en un control, debemos anteponer el carácter & a la letra que vamos a definir como acelerador, en este ejemplo se ha logrado con &Foco nombre.
Por otro lado, mediante el botón btnSoloLectura conseguimos activar/desactivar la propiedad ReadOnly del TextBox txtNombre, cambiando el estado de dicha propiedad en cada pulsación del botón. Ver Código fuente
Private Sub btnSoloLectura_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnSoloLectura.Click
If (Me.txtNombre.ReadOnly) Then
Me.txtNombre.ReadOnly = False
Else
Me.txtNombre.ReadOnly = True
End If
End Sub-
Sin embargo, hay otro modo mucho más eficiente de cambiar el estado de una
propiedad que contiene un tipo Boolean: utilizando el operador Not.
Con el botón btnActivar, cambiamos el valor de la propiedad Enabled del cuadro de
texto que contiene los apellidos. Para ello, aplicamos el operador Not a dicha
propiedad, y el resultado lo asignamos a esa misma propiedad. Ver Código fuente
Private Sub btnActivar_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnActivar.Click
' utilizando operador Not simplificamos
Me.txtApellidos.Enabled = Not (Me.txtApellidos.Enabled)
End Sub
Finalizando con este ejemplo, y aunque no tiene relación directa con el control
TextBox, el formulario se muestra con un tipo de borde especial que no permite su
redimensión. La propiedad del formulario con la que podemos establecer el tipo de
75
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
borde es FormBorderStyle, y en este caso, su valor es Fixed3D. Alterando los
valores de esta propiedad, conseguiremos distintos bordes y tipos de
redimensión para el formulario.
Selección de texto en un TextBox
La selección de texto en un control TextBox es un proceso que funciona de
modo transparente al programador, en el sentido en que este no necesita añadir
código adicional para las operaciones de selección, cortar, copiar, etc., al ser tareas
integradas en el sistema operativo. Sin embargo, podemos necesitar en un
determinado momento, tener información acerca de las operaciones de
selección que está realizando el usuario en nuestros controles de texto. Para ello,
el control TextBox dispone de las siguientes propiedades.
SelectionStart. Posición del texto del control, en la que comienza la selección que hemos realizado.
SelectionLength. Número de caracteres seleccionados en el control.
SelectedText. Cadena con el texto que hemos seleccionado en el control.
Mediante estas propiedades, no sólo averiguamos la selección que pueda tener
un control TextBox, sino que también podemos utilizarlas para establecer por
código una selección; teniendo el mismo efecto que si la hubiera efectuado el
usuario con el ratón o teclado.
Para comprobar el funcionamiento de las propiedades de selección del TextBox, crearemos un proyecto Windows, y en su formulario añadiremos varios controles para manipular la selección de texto que hagamos en un TextBox. La Figura muestra el formulario del ejemplo.
. Formulario para realizar selección en el control TextBox
El control de este formulario, que vamos a emplear para las operaciones de selección
76
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
es txtOrigen. En primer lugar, y aunque no se trata de una selección de texto, veremos su evento TextChanged, el cual se produce cada vez que cambia el contenido del cuadro de texto; lo usaremos por tanto, para contar lacantidad de caracteres escritos y mostrarlos en un Label. Ver Código fuente
' al cambiar el texto del control se produce este evento
Private Sub txtOrigen_TextChanged(ByVal sender As Object, ByVal e As
System.EventArgs) Handles txtOrigen.TextChanged
' calculamos la longitud del texto escrito
Me.lblContador.Text = Me.txtOrigen.TextLength
End Sub
Los eventos MouseMove y KeyDown del TextBox, se producen respectivamente, cuando movemos el ratón sobre el control, o cada vez que pulsamos una tecla para escribir texto. Detectaremos en este caso, si existen teclas o botones especiales presionados, que nos indiquen que se está realizando unaselección de texto, y mostraremos en el formulario el texto seleccionado, el número de caracteres y la posición del carácter de inicio de la selección. Veamos los procedimientos manipuladores de estos eventos en el Código fuente ' al mover el ratón por el TextBox se produce este evento
Private Sub txtOrigen_MouseMove(ByVal sender As Object, ByVal e As
System.Windows.Forms.MouseEventArgs) Handles txtOrigen.MouseMove
' comprobamos si al mover el ratón está pulsado su botón izquierdo
' en caso afirmativo es que se está seleccionando texto, por lo que obtenemos la
' información de selección con las ' propiedades de selección del TextBox
If e.Button.Left Then
Me.lblTextoSelec.Text = Me.txtOrigen.SelectedText
Me.lblLongitud.Text = Me.txtOrigen.SelectionLength
Me.lblPosicion.Text = Me.txtOrigen.SelectionStart
End If
End Sub
' este evento se produce cuando se pulsa una tecla en el TextBox
Private Sub txtOrigen_KeyDown(ByVal sender As Object, ByVal e As
System.Windows.Forms.KeyEventArgs) Handles txtOrigen.KeyDown
' comprobamos las teclas pulsadas si está pulsada la tecla mayúsculas,
' y además se está pulsando la tecla flecha derecha, quiere decir que se está
' seleccionando texto; obtener la información de las propiedades de
' selección del control TextBox
If e.Shift Then
If e.KeyCode.Right Then
Me.lblTextoSelec.Text = Me.txtOrigen.SelectedText
Me.lblLongitud.Text = Me.txtOrigen.SelectionLength
Me.lblPosicion.Text = Me.txtOrigen.SelectionStart
77
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
End If
End If
End Sub
Finalmente, tras introducir un valor en los controles txtPosicion y txtLongitud, pulsaremos el botón btnSeleccionar. Con ello conseguiremos realizar una selección de texto en el TextBox txtOrigen, y pasar el texto seleccionado al control txtDestino. El efecto será el mismo que si lo hubiera realizado el usuario, pero en este caso sin su intervención. Veamos en el Código fuente, el evento Click del botón btnSeleccionar. ' al pulsar este botón, seleccionar por código texto del control txtOrigen y
' pasarlo al control txtDestino
Private Sub btnSeleccionar_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnSeleccionar.Click
Me.txtOrigen.SelectionStart = Me.txtPosicion.Text
Me.txtOrigen.SelectionLength = Me.txtLongitud.Text
Me.txtDestino.Text = Me.txtOrigen.SelectedText
End Sub
La Figura muestra este ejemplo en ejecución.
Pruebas de selección de texto con el control TextBox
5.5.-Control Button
Este control representa un botón de pulsación, conocido en versiones anteriores de VB como CommandButton. Entre el nutrido conjunto de propiedades de este control, destacaremos las siguientes.
Text. Cadena con el título del botón.
TextAlign. Alineación o disposición del título dentro del área del botón; por defecto aparece centrado.
BackColor. Color de fondo para el botón.
Cursor. Permite modificar el cursor del ratón que por defecto tiene el botón.
78
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Image. Imagen que podemos mostrar en el botón como complemento a su título, o bien, en el caso de que no asignemos un texto al botón, nos permitirá describir su funcionalidad.
ImageAlign. Al igual que para el texto, esta propiedad nos permite situar la imagen en una zona del botón distinta de la central, que es en la que se ubica por defecto.
BackgroundImage. Imagen de fondo para el botón.
FlatStyle. Tipo de resaltado para el botón. Por defecto, el botón aparece con un cierto relieve, que al ser pulsado, proporciona el efecto de hundirse y recuperar nuevamente su estado, pero podemos, mediante esta propiedad, hacer que el botón se muestre en modo plano, con un ligero remarcado al pulsarse, etc.
Font. Cambia el tipo de letra y todas las características del tipo elegido, para el texto del botón.
La Figura muestra un ejemplo de control Button, sobre el que se han modificado algunos valores por defecto de sus propiedades.
5.6.-Foco de entrada
Para que las pulsaciones de teclado puedan ser recibidas por un determinado control, dicho control debe tener lo que se denomina el foco de entrada.
El modo de dar a un control el foco de entrada, consiste en hacer clic sobre él, o bien,
pulsar la tecla [TAB], pasando el foco hasta el control deseado. Cuando un control
recibe el foco, el sistema operativo lo remarca visualmente o en el caso de controles
de escritura, muestra el cursor de escritura en su interior.
Otra forma es realizar la codificación del foco de entrada, de la siguiente manera
Private Sub btnActivar_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnActivar.Click
' utilizando la propiedad focus para el control textbox1
79
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Textbox1.focus
End Sub
5.7.-Funciones para presentar mensajes
Visual Basic posee 2 tipos de funciones para presentar mensajes, ellas son MsgBox e InputBox.
5.8.-Función InputBox:
La función InputBox presenta un mensaje al usuario, permitiéndole ingresar un valor en una caja de texto:
Como se dijo la función InputBox presenta un cuadro de diálogo donde el usuario puede ingresar un texto y luego aceptar o cancelar dicho cuadro de diálogo.
Los parámetros principales de esta función son:
InputBox (Promt,Title, Default)
El parámetro Prompt específica la leyenda que mostrará la caja de mensajes. El parámetro Title especifica el título que llevará el cuadro de diálogo. El parámetro Default es el texto que mostrará la caja de texto.
El aspecto más importante de InputBox es que nos devuelve una cadena con lo que haya ingresado el usuario en la caja de texto. Luego podemos realizar una tarea específica dependiendo del valor devuelto.
Ejemplo:
Dim retorno As String
retorno = InputBox("Ingrese algo en la caja de texto", "Ejemplo")
MsgBox "Usted ingresó:" & retorno
En el ejemplo anterior, en la variable Retorno se almacenará el valor que haya ingresado el usuario cuando haga Click en el botón de Aceptar.
80
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Cuando el usuario presiona Candelar, el InputBox devuelve una cadena vacía. Esto es importante tenerlo en cuenta para realizar una o tal acción
Si quiseramos por ejemplo desplegar un InputBox, y que este no se cierre hasta que el usuario si o si haya ingresado un valor, podemos hacerlo de la siguiente forma, utilizando una condición en un bucle Do Loop
Código fuente en el formulario
Private Sub Form_Load()
Dim Dato As String
'Hasta que no se ingrese un dato, el InputBox no se cerrará
Do
Dato = InputBox("Ingresar algun dato", " Ejemplo ")
Loop Until Dato <> ""
'Muestra el valor
MsgBox Dato, vbInformation
End Sub
5.9.-Función MsgBox:
La función MsgBox, es muy fácil de usar y se utiliza para mostrar distintos tipos de mensajes. La sintaxis completa de la función MsgBox es:
MsgBox(mensaje[, botones][, título][, archivoAyuda, contexto])
Ejemplos de mensajes o cajas de texto con la función MsgBox que podemos mostrar:
Como se ve en los gráficos anteriores, con MsgBox podemos tener variedad a la hora de mostrar un determinado mensaje, utilizando para ello las diferentes constantes que incorpora la función. Los parámetros más importantes son:
Title : Es la leyenda que aparecerá en el título del mensaje.
81
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Texto : Es el Texto que mostrará el mensaje.
Botones: En este parámetro se colocan las constantes que determinarán si la
caja tiene uno o varios botones y el tipo de mensaje: informativo, de
exclamación de alerta etc... Cuando escribimos la coma dentro de la función en
el parámetro botones, Visual Basic despliega una lista con las opciones o
constantes que podemos utilizar.
Ejemplo de msgbox un poco más elaborado para entender un poco mejor esto; este
ejemplo envía un mensaje de alerta con dos botones como opciones: En vez de
utilizarse las palabras mensaje, estilo, etc se podrían utilizar otras, pero siempre hay
que respetar el orden
Private Sub Command1_Click() Dim Mensaje, Estilo, Título, Respuesta, MiCadena as String Mensaje = "¿Estas totalmente seguro de lo que vas a hacer?" ' cuerpo del mensaje. Estilo = vbYesNo + vbCritical ' Define el estilo, los botones, lo que está después del mas es el circulo rojo ' con la cruz. Título = "error grave (mentira)" ' es el título. Respuesta = MsgBox(Mensaje, Estilo, Título) 'el paréntesis se pone también If Respuesta = vbYes Then ' El usuario eligió el botón Sí. MiCadena = "Sí" ' Ejecuta una acción. Else ' El usuario eligió el botón No. MiCadena = "No" ' Ejecuta una acción. Form1.Visible = False 'Aca puse una acción que usted ya conoce End If End Sub En estilo podrían ir por ejemplo las siguientes opciones:
VbOKOnly: Sólo muestra el botón Aceptar.
VbOKCancel: Muestra los botones Aceptar y Cancelar.
VbAbortRetryIgnore: Muestra los botones Anular, Reintentar e Ignorar.
VbYesNoCancel: Muestra los botones Sí, No y Cancelar.
VbYesNo: Muestra los botones Sí y No.
VbRetryCancel: Muestra los botones Reintentar y Cancelar.
VbCritical: Muestra el icono Mensaje crítico.
VbQuestion: Muestra el icono Consulta de advertencia.
VbExclamation: Muestra el icono Mensaje de advertencia.
VbInformation: Muestra el icono Mensaje de información.
82
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
5.10.-Codificación de los eventos de controles
Windows es un sistema operativo orientado a eventos, por lo que cualquier mínima interacción que realicemos sobre un formulario o control, generará el oportuno evento, para el que si estamos interesados, deberemos responder.
Prosiguiendo con el control Button, cuando pulsamos sobre el mismo, se origina el
evento Click de dicho control. Si dibujamos un Button en un formulario y pulsamos
en él, no ocurrirá nada, ya que aunque el evento se produce, no existe código que
le proporcione respuesta.
Para dar oportuna respuesta a un evento emitido por un control, debemos escribir
un procedimiento manipulador del correspondiente evento. La creación de
manipuladores de evento es un aspecto que ya hemos visto en detalle en el tema
Delegación de código y eventos. De igual modo, los aspectos básicos de la escritura
de código para un evento se comentaron en el tema Una aplicación con
funcionalidad básica; sugerimos por lo tanto al lector, la consulta de estos temas
para cualquier referencia básica que necesite al respecto.
No obstante, en el presente apartado, y para reforzar conceptos, realizaremos un repaso del proceso de creación del manipulador de evento para un control.
Como ejemplo, insertaremos en un formulario un control Button, al que daremos el nombre btnMensaje, y en su propiedad Text asignaremos la cadena Mostrar mensaje.
Seguidamente haremos doble clic sobre el Button; esta acción abrirá la ventana del
editor de código, creando al mismo tiempo, la declaración o esqueleto del
procedimiento manipulador de evento Click del botón, listo para ser codificado.
Ya que necesitamos que se muestre un mensaje al ser pulsado este control,
utilizaremos el objeto MessageBox de la plataforma, llamando a su método
compartido Show( ), para visualizar el mensaje. En definitiva, el manipulador de este
evento quedaría como muestra el Código fuente
Private Sub btnMensaje_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnMensaje.Click
MessageBox.Show("Se acaba de pulsar el botón del formulario")
End Sub
El resultado en ejecución, sería el que muestra la Figura
Observando con más detalle el procedimiento del evento, vemos que al final
de su declaración, aparece la palabra clave Handles, que como vimos en el tema
sobre eventos, nos sirve para asociar esta rutina de código con un evento de un
objeto. En el ejemplo que nos ocupa, asociamos el procedimiento
83
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
btnMensaje_Click( ), con el evento Click del objeto btnMensaje, perteneciente a
la clase Button.
Resultado de la ejecución del evento Click de un control Button, al ser pulsado.
Como ya sabemos, el enlace procedimiento-evento de objeto mediante la palabra
Handles, se producede modo estático. Esto requiere que en el código, el identificador
que contenga el objeto del control, deba ser declarado con ámbito a nivel de clase,
y utilizando además la palabra clave WithEvents.
Dicha tarea es realizada automáticamente por el diseñador del formulario cuando genera el código del mismo. Veamos en el Código fuente , el fragmento de código generado por el diseñador que realiza esta labor.
' esta declaración es situada a nivel del código de la clase del formulario, es decir,
' fuera de cualquier método
Friend WithEvents btnMensaje As System.Windows.Forms.Button
5.11.-Codificando otros eventos de un control
En un control Button, el evento por defecto es Click; esto supone, como acabamos de ver, que al hacer doble clic sobre el control en el formulario, el procedimiento de evento sobre el que nos situará el editor será precisamente este. Sin embargo, un control Button, al igual que el resto de controles de los formularios Windows, disponen de un gran número de eventos que podemos codificar para adaptar a nuestras necesidades.
Por ejemplo, el evento MouseEnter, se produce cuando se detecta que el ratón
entra en el área de un control, en este caso Button. Como este no es el evento por
defecto, debemos buscar su declaración vacía manualmente en el editor. Para ello,
abriremos la lista desplegable Nombre de clase, situada en la parte superior
izquierda del editor de código, y seleccionaremos el nombre de nuestro control:
btnMensaje. Ver Figura
84
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Lista de clases del editor de código.
A continuación, abriremos la otra lista desplegable del editor de código: Nombre de método, situada en la parte superior derecha del editor. En ella aparecerán los nombres de todos los eventos de que dispone el control. Localizaremos el evento MouseEnter, y lo seleccionaremos. Ver Figura
Lista de eventos de una clase-control en el editor de código.
De igual modo que sucedió con el evento Click en el apartado anterior, el editor de código creará el procedimiento manipulador de evento vacío, para el evento que acabamos de seleccionar. Lo que vamos a hacer a continuación, es escribir el código que permita cambiar el color del botón cuando el ratón entre al mismo. Veamos el Código fuente
Private Sub btnMensaje_MouseEnter(ByVal sender As Object, ByVal e As
System.EventArgs) Handles btnMensaje.MouseEnter
Me.btnMensaje.BackColor = Color.Cyan
End Sub
Cuando al ejecutar, situemos el ratón en el botón, este cambiará su color, mostrando
el aspecto de la Figura
85
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Resultado de la ejecución del evento MouseEnter sobre un Button.
5.12.-Orden de tabulación de controles
Los controles disponen de la propiedad TabIndex, que contiene un número que será utilizado para pasar el foco entre ellos al pulsar la tecla [TAB] durante la ejecución del programa. Según vamos añadiendo nuevos controles, el IDE va asignando automáticamente nuevos números a esta propiedad; de forma que, cuando comencemos la ejecución, el primer control que tomará el foco será el que tiene el menor número en su TabIndex.
En el ejemplo anterior, el primer control que tomaba el foco era el TextBox de la contraseña, lo cual no era nada lógico, ya que dicho control era el último en el formulario para el que debíamos introducir datos.
Para solucionar este problema, simplemente tenemos que cambiar los valores de la propiedad TabIndex de los controles, de modo que el orden de tabulación sea el que mejor se adapte a nuestras necesidades.
Podemos obtener un mapa del orden de tabulación de los controles del formulario seleccionando el menú del IDE Ver + Orden de tabulación; esto mostrará los controles con el número de TabIndex que les hemos asignado. Como ventaja adicional, en esa situación, podemos hacer clic en los controles y cambiar también el número de tabulación. Ver Figura
Diseñador del formulario mostrando el orden de tabulación de controles.
Si por el contrario, no queremos dar el foco a un control pulsando [TAB],
debemos asignar a la propiedad TabStop de dicho control el valor False. Por
86
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
defecto, TabStop vale True, permitiendo de esta el paso de foco entre controles
mediante la tecla [TAB].
5.13.-Control ListBox
Un control ListBox contiene una lista de valores, de los cuales, el usuario puede
seleccionar uno o varios simultáneamente. Entre las principales propiedades de
este control, podemos resaltar las siguientes.
Items. Contiene la lista de valores que visualiza el control. Se trata
de un tipo ListBox.ObjectCollection, de manera que el contenido de la lista
puede ser tanto tipos carácter, como numéricos y objetos de distintas clases. Al
seleccionar esta propiedad en la ventana de propiedades del control, y pulsar el
botón que contiene, podemos introducir en una ventana elementos para el control.
Ver Figura
Introducción de valores para un ListBox en tiempo de diseño.
El control quedaría por lo tanto con valores asignados en la etapa de diseño,
como muestra la Figura
ListBox en diseño con valores en su lista.
Sorted. Cuando esta propiedad contiene el valor True, ordena el contenido de la
lista. Cuando contiene False, los elementos que hubiera previamente ordenados,
permanecen con dicho orden, mientras que los nuevos no serán ordenados.
87
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
IntegralHeight. Los valores de la lista son mostrados al completo cuando esta
propiedad contiene True. Sin embargo, al asignar el valor False, según el tamaño del
control, puede que el último valor de la lista se visualiza sólo en parte. La Figura 253
muestra un ListBox con esta propiedad a False.
ListBox mostrando parte del último elemento debido a la propiedad IntegralHeight.
MultiColumn. Visualiza el contenido de la lista en una o varias columnas en
función de si asignamos False o True respectivamente a esta propiedad.
SelectionMode. Establece el modo en el que vamos a poder seleccionar los elementos de la lista. Si esta propiedad contiene None, no se realizará selección; One, permite seleccionar los valores uno a uno; MultiSimple permite seleccionar múltiples valores de la lista pero debemos seleccionarlos independientemente; por último, MultiExtended nos posibilita la selección múltiple, con la ventaja de que podemos hacer clic en un valor, y arrastrar, seleccionando en la misma operación varios elementos de la lista.
SelectedItem. Devuelve el elemento de la lista actualmente seleccionado.
Selecteditems. Devuelve una colección ListBox.SelectedObjectCollection, que
contiene los elementos de la lista que han sido seleccionados.
SelectedIndex. Informa del elemento de la lista seleccionado, a través del
índice de la colección que contiene los elementos del ListBox.
PROPIEDAD ACCION O SIGNIFICADO
Items.Add(dato): Inserta un elemento al final del listbox.
Items.Clear(): Elimina todos los elementos de la lista.
Items.Count(): Regresa la cantidad de elementos en lista.
Items.Sorted = true; Ordena los elementos de la lista usada solo al tiempo de diseno.
Items.Contains(dato): Regresa true o false, si el dato se encuentra o no se encuentra en la lista.
Items.IndexOf(dato): Regresa el indice del objeto dentro del listbox.
88
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Items.Insert(indice,dato): Inserta el dato en la posicion indicada.
Items.Remove(dato): Elimina el dato de el listbox.
Items.RemoveAt(indice): Elimina el dato que esta en la posicion indicada.
Items[indice]: get or set el dato en la posicion indicada (ver primera nota abajo).
Observacion:
Como ya se indico anteriormente GET y SET son propiedades asociadas a todos los objetos o controles y sus propiedades en microsoft net, por ejemplo para un textbox, si en un programa se dice alfa = text5.text; se esta usando get, si se dice text5.text=500; se esta usando set.
Otro ejemplo alfa = listbox2.Items(2); se esta usando (get)
listbox2.Items(4 )= “mama”
Para mostrar algunas de las funcionalidades de este control, utilizaremos el
proyecto de ejemplo ListBoxPru. La Figura muestra esta aplicación en ejecución.
Ejemplo de uso del control ListBox.
El ejemplo, como puede comprobar el lector, consiste en un formulario que
contiene un ListBox principal, con el nombre lstValores, que dispone de una
serie de valores asignados en tiempo de diseño.
Cada vez que hacemos clic en alguno de los valores, se produce el evento SelectedIndexChanged, que utilizamos para mostrar en este caso, el nombre del elemento en el título del formulario, como muestra el Código fuente, de la clase frmListas, correspondiente al formulario.
' declaramos esta constante a nivel de clase, para poner como título
89
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
' del formulario junto al elemento seleccionado de la lista
Public Const TITULO As String = "Elemento seleccionado: "
' este evento se produce cada vez que se cambia el índice seleccionado del ListBox
Private Sub lstValores_SelectedIndexChanged(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles lstValores.SelectedIndexChanged
' mostrar en el título del formulario el valor actualmente seleccionado de la lista
Me.Text = TITULO & Me.lstValores.SelectedItem
End Sub
A través de los RadioButton, cambiamos el tipo de selección que podemos efectuar en el control lstValores. Ver Código fuente Private Sub rbtUno_CheckedChanged(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles rbtUno.CheckedChanged
' establecer tipo de selección en el ListBox a un elemento
Me.lstValores.SelectionMode = SelectionMode.One
End Sub
Private Sub rbtMultiple_CheckedChanged(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles rbtMultiple.CheckedChanged
' establecer tipo de selección en el ListBox a un múltiples elementos
Me.lstValores.SelectionMode = SelectionMode.MultiSimple
End Sub
Private Sub rbtExtendida_CheckedChanged(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles rbtExtendida.CheckedChanged
' establecer tipo de selección en el ListBox a múltiples
' elementos de modo extendido
Me.lstValores.SelectionMode = SelectionMode.MultiExtended
End Sub
Mediante los controles chkOrdenar y chkColumnas, ordenaremos y mostraremos en columnas respectivamente el ListBox. Ver Código fuente. Private Sub chkOrdenar_CheckedChanged(ByVal sender As System.Object, ByVal e
As, System.EventArgs) Handles chkOrdenar.CheckedChanged
' según el valor del CheckBox, ordenamos o quitamos
' la opción de ordenar del ListBox
Me.lstValores.Sorted = Me.chkOrdenar.Checked
End Sub
Private Sub chkColumnas_CheckedChanged(ByVal sender As System.Object, ByVal e
90
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
As System.EventArgs) Handles chkColumnas.CheckedChanged
' según el valor del CheckBox, mostramos el ListBox
' en varias columnas o en una
Me.lstValores.MultiColumn = Me.chkColumnas.Checked
End Sub
El TextBox de este formulario lo usaremos para añadir nuevos elementos al ListBox lstValores, y buscar también elementos existentes, pulsando los botones btnAgregar y btnBuscar en cada caso. Observemos el miembro NoMatches del ListBox, mediante el que averiguamos si la búsqueda tuvo éxito. Ver el Código fuente
Private Sub btnAgregar_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnAgregar.Click
' añadimos el contenido del TextBox como un elemento a la lista
Me.lstValores.Items.Add(Me.txtValor.Text)
End Sub
Private Sub btnBuscar_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnBuscar.Click
Dim iPosicion As Integer
' el método FindString() de la lista busca un valor
iPosicion = Me.lstValores.FindString(Me.txtValor.Text)
' el campo NoMatches indica si no existe el valor buscado
If iPosicion = Me.lstValores.NoMatches Then
MessageBox.Show("No existe el valor")
Else
' si encontramos el valor en la lista,lo seleccionamos por código
Me.lstValores.SelectedIndex = iPosicion
End If
End Sub
La selección de los elementos de un ListBox no es competencia exclusiva del usuario.
El programador puede también, si lo necesita, seleccionar valores de la lista
mediante el código del programa. Al pulsar el botón btnSelecCod, utilizaremos el
método SetSelected( ) del ListBox para realizar esta tarea.
En este método pasamos como parámetro el índice de la lista con el que vamos a
operar, y el valor True para seleccionarlo, o False para quitarle la selección. Ver el
Código fuente
Private Sub btnSelecCod_Click(ByVal sender As System.Object, ByVal e As
91
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
System.EventArgs) Handles btnSelecCod.Click
' para seleccionar elementos de un ListBox por código
' podemos utilizar el método SetSelected()
Me.rbtMultiple.Checked = True
Me.lstValores.SetSelected(1, True)
Me.lstValores.SetSelected(3, True)
Me.lstValores.SetSelected(5, True)
End Sub
El botón btnTraspasarSelec lo usaremos para tomar los elementos seleccionados
de lstValores, y pasarlos al otro ListBox del formulario. La propiedad SelectedItems
del control lstValores, devuelve una colección con sus elementos seleccionados. Por
otra parte, podemos eliminar los elementos de un ListBox llamando al método
Clear( ) de la colección de valores del control, cosa que hacemos pulsando el
botón btnLimpiar. Ver Código fuente
Private Sub btnTrapasarSelec_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnTrapasarSelec.Click
Dim oSeleccion As ListBox.SelectedObjectCollection
' obtenemos con SelectedItems los elementos seleccionados de un ListBox
oSeleccion = Me.lstValores.SelectedItems
' si existen elementos seleccionados, los traspasamos a otro ListBox del
' formulario
If oSeleccion.Count > 0 Then
Dim oEnumerador As IEnumerator
oEnumerador = oSeleccion.GetEnumerator()
While oEnumerador.MoveNext()
Me.lstTraspaso.Items.Add(oEnumerador.Current)
End While
End If
End Sub
Private Sub btnLimpiar_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnLimpiar.Click
' con el método Clear() de la colección de elementos
' de un ListBox, borramos los elementos del controls
Me.lstTraspaso.Items.Clear()
End Sub
Ejemplo programa
92
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click LISTA.Items.Add(DATO.Text) DATO.Text = "" End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim r, cant, meses As Integer cant = LISTA.Items.Count For r = 0 To cant - 1 meses = LISTA.Items(r) meses = meses * 12 LISTA.Items(r) = meses Next r End Sub
Recordar que el primer indice en un ListBox es el cero por eso el ciclo va desde el cero hasta la cantidad de elementos menos uno.
Corrida:
EJERCICIOS PROGRAMACION DE LISTBOX
1.- Capturar en una lista los sueldos de 6 empleados y desplegarlos en una segunda lista aumentados en un 30%
Actividades de reforzamiento de lo aprendido
93
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
2.- Capturar en una lista los pesos en kilogramos de 6 personas desplegarlos en una segunda lista convertidos a libras y ademas solo los mayores de 100 libras.
3.- Capturar en sus 4 listas respectivas matricula, nombre y dos calificaciones de 5 alumnos, despues calcular una lista de promedios de calificaciones.
4.- Capturar en sus listas respectivas numempleado, nomempleado, dias trabajados y sueldo diario de 5 empleados, desplegar en otra pantalla o panel la nomina pero solo de aquellos empleados que ganan mas de $300.00 a la semana.
5.14.-Control ComboBox
El ComboBox es un control basado en la combinación (de ahí su nombre) de dos controles que ya hemos tratado: TextBox y ListBox.
Un control ComboBox dispone de una zona de edición de texto y una lista de valores, que podemos desplegar desde el cuadro de edición.
El estilo de visualización por defecto de este control, muestra el cuadro de texto y la lista oculta, aunque mediante la propiedad DropDownStyle podemos cambiar dicho estilo. La Figura muestra un formulario con diversos ComboBox, cada uno con diferente estilo.
Controles ComboBox de distintos estilos.
La propiedad DropDownStyle también influye en una diferencia importante de
comportamiento entre el estilo DropDownList y los demás, dado que cuando
creamos un ComboBox con el mencionado estilo, el cuadro de texto sólo podrá
mostrar información, no permitiendo que esta sea modificada.
En el caso de que la lista desplegable sea muy grande, mediante la propiedad MaxDropDownItems, asignaremos el número de elementos máximo que mostrará la lista del control.
El resto de propiedades y métodos son comunes con los controles TextBox y ListBox. En el Código fuente se muestra el código del botón btnAgregar, mediante el que llenamos de valores los controles de este ejemplo.
94
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Private Sub btnAgregar_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnAgregar.Click
Me.cboColores.Items.AddRange(New String() {"AZUL", "VERDE", "AMARILLO",
"ROJO", "BLANCO", "MARRÓN", "GRANATE"})
Me.cboNombres.Items.AddRange(New String() {"ELENA", "JOSE", "ANA",
"ALFREDO", "LUIS", "ANGEL", "RAQUEL"})
Me.cboCiudades.Items.AddRange(New String() {"SEVILLA", "VALENCIA",
"ALICANTE", "TOLEDO", "SEGOVIA"})
End Sub
5.15.-Control CheckBox
Este control muestra una casilla de verificación, que podemos marcar para establecer un estado. Generalmente el estado de un CheckBox es marcado (verdadero) o
desmarcado (falso), sin embargo, podemos configurar el control para que sea
detectado un tercer estado, que se denomina indeterminado, en el cual, el control se muestra con la marca en la casilla pero en un color de tono gris.
Las propiedades remarcables de este control son las siguientes.
Checked. Valor lógico que devuelve True cuando la casilla está marcada, y False
cuando está desmarcada.
CheckState. Valor del tipo enumerado CheckState, que indica el estado del
control. Checked, marcado; Unchecked, desmarcado; e Indeterminate,
indeterminado.
ThreeState. Por defecto, un control de este tipo sólo tiene dos estados, pero
asignando True a esta propiedad, conseguimos que sea un control de tres
estados.
CheckAlign. Permite establecer de modo visual la ubicación de la casilla de
verificación dentro del área del control.
Como detalle destacable de las propiedades Checked y CheckState, si modificamos desde código sus valores, conseguiremos alterar el estado de la casilla del control.
El ejemplo CheckBoxPru, muestra un formulario con dos controles CheckBox. El control chkPonColor asigna un color de fondo al formulario o restablece el color original. Esto lo conseguimos codificando el evento CheckedChanged del control. Ver Código fuente.
' Este evento se produce cuando se hace clic en el CheckBox y cambia el contenido
' de la casilla
Private Sub chkPonColor_CheckedChanged(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles chkPonColor.CheckedChanged
If Me.chkPonColor.CheckState = CheckState.Checked Then
95
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Me.BackColor = Color.LightBlue
Else
Me.ResetBackColor()
End If
End Sub
Por su parte, el control chkMostrar, definido con tres estados, muestra, al estar
marcado, una cadena en un control Label; elimina la cadena al desmarcarlo; y
muestra la mitad al entrar en el estado indeterminado. El evento
CheckStateChanged es el que debemos de utilizar para detectar el estado del CheckBox
en cada ocasión. Para mantener el valor de la cadena a mostrar, utilizamos una
variable a nivel de la clase que inicializamos en el constructor del formulario. Ver
Código fuente
Public Class Form1
Inherits System.Windows.Forms.Form
Private sCadenaOriginal As String
Public Sub New()
'....
' inicializar la variable que contiene la cadena
' a mostrar en el label y asignarla
sCadenaOriginal = "Estamos visualizando una cadena"
Me.lblMuestra.Text = sCadenaOriginal
End Sub
'....
' este evento se produce cuando cambia el estado de la casilla
Private Sub chkMostrar_CheckStateChanged(ByVal sender As Object, ByVal e As
System.EventArgs) Handles chkMostrar.CheckStateChanged
Select Case Me.chkMostrar.CheckState
Case CheckState.Checked
Me.lblMuestra.Text = sCadenaOriginal
Case CheckState.Unchecked
Me.lblMuestra.Text = ""
Case CheckState.Indeterminate
Me.lblMuestra.Text = sCadenaOriginal.Substring(0,(sCadenaOriginal.Length / 2))
End Select
End Sub
La Figura muestra este ejemplo en ejecución.
96
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Controles CheckBox en ejecución.
5.16.-Controles RadioButton y GroupBox
Los controles RadioButton nos permiten definir conjuntos de opciones
autoexcluyentes, de modo que situando varios controles de este tipo en un
formulario, sólo podremos tener seleccionado uno en cada ocasión.
Vamos a crear un proyecto de ejemplo con el nombre RadioButtonPru, en el que
situaremos dentro de un formulario, una serie de controles RadioButton y un
TextBox, de modo que mediante los RadioButton cambiaremos el tipo de fuente y
color del cuadro de texto. La Figura 249 muestra un diseño inicial del formulario.
Pruebas con el control RadioButton.
Al ejecutar el proyecto, sin embargo, no podemos conseguir establecer
simultáneamente un tipo de letra y color, puesto que al pulsar cualquiera de
los botones de radio, se quita el que hubiera seleccionado previamente.
Para solucionar este problema, disponemos del control GroupBox, que nos permite, como indica su nombre, agrupar controles en su interior, tanto RadioButton como de otro tipo, ya que se trata de un control contenedor.
Una vez dibujado un GroupBox sobre un formulario, podemos arrastrar y soltar sobre él, controles ya existentes en el formulario, o crear nuevos controles dentro de dicho control. De esta forma, podremos ya, en este ejemplo, seleccionar más de un RadioButton del formulario, como vemos en la Figura .
97
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Selección de varios RadioButton en un formulario.
El evento CheckedChanged, al igual que ocurría con los controles CheckBox, será el
que tendremos que escribir para ejecutar el código en respuesta a la pulsación
sobre un control RadioButton. El Código fuente muestra los eventos
correspondientes a los controles de radio de este ejemplo. Para cambiar el tipo de
fuente, instanciamos un objeto Font y lo asignamos a la propiedad Font del
TextBox; mientras que para cambiar el color, utilizamos la estructura Color y la
propiedad BackColor, también del TextBox.
Private Sub rbtTahoma_CheckedChanged(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles rbtTahoma.CheckedChanged
Me.txtNombre.Font = New Font("Tahoma", 12)
End Sub
Private Sub rbtGaramond_CheckedChanged(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles rbtGaramond.CheckedChanged
Me.txtNombre.Font = New Font("Garamond", 8)
End Sub
Private Sub rbtComic_CheckedChanged(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles rbtComic.CheckedChanged
Me.txtNombre.Font = New Font("Comic Sans MS", 15)
End Sub
Private Sub rbtVerde_CheckedChanged(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles rbtVerde.CheckedChanged
Me.txtNombre.BackColor = Color.Green
End Sub
Private Sub rbtAzul_CheckedChanged(ByVal sender As System.Object, ByVal e As
98
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
System.EventArgs) Handles rbtAzul.CheckedChanged
Me.txtNombre.BackColor = Color.Blue
End Sub
Private Sub rbtAmarillo_CheckedChanged(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles rbtAmarillo.CheckedChanged
Me.txtNombre.BackColor = Color.Yellow
End Sub
5.17.-Controles de tipo menú
El menú es uno de los tipos de control más frecuentemente utilizados en los formularios Windows. Consiste en un conjunto de opciones, a través de las cuales, el usuario ejecutará algunos procesos de la aplicación. Disponemos de tres tipos de control menú: MainMenu, ContextMenu y MenuItem.
MainMenu y ContextMenu actúan como contenedores de grupos de controles MenuItem, representando este último control, la opción de menú sobre la que el usuario pulsa o hace clic.
El proyecto MenuPru que se acompaña como ejemplo, muestra los diferentes tipos de menú . A continuación, describiremos los principales pasos a dar en el proceso de su construcción.
Menú Principal. MainMenu
Un control MainMenu, consiste en un conjunto de opciones que se sitúan
horizontalmente debajo del título del formulario. A partir de cada opción, podemos
asociar a su vez, grupos de opciones que se mostraran verticalmente al hacer clic
en la opción principal o situada en la barra horizontal.
Para crear un menú principal, seleccionaremos del cuadro de herramientas el control MainMenu, y tras dibujarlo en el formulario, se añadirá una referencia del control al panel de controles especiales situado bajo el diseñador. La Figura muestra un control de este tipo al que le hemos dado el nombre mnuPrincipal.
Menú de tipo MainMenu añadido al diseñador del formulario.
99
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
La creación de las diferentes opciones que compondrán el menú es un proceso que se ha mejorado y simplificado al máximo respecto a versiones anteriores de VB. El proceso de edición del menú se realiza directamente en el formulario, en el mismo lugar en el que el menú aparecerá en tiempo de ejecución.
Al hacer clic en la primera opción del menú, podemos dar nombre y propiedades a esa opción. Al mismo tiempo, de un modo muy intuitivo, veremos las próximas opciones disponibles, tanto las desplegables a partir de dicho menú, como las de la barra principal. Sólo hemos de movernos en la dirección que necesitemos y dar nombre a las opciones, y valores a sus propiedades. Ver Figura
Creación de las opciones de un menú principal de formulario.
Cada una de las opciones que componen el menú es a su vez un control
MenuItem. Si durante su creación sólo proporcionamos el nombre, el IDE va
asignando a dicho control valores por defecto en sus propiedades.
Para modificar las propiedades de una opción de menú, sólo hemos de seleccionarlo en la estructura de menú que estamos creando en el diseñador del formulario, y pasar a la ventana de propiedades. Entre las propiedades disponibles para un MenuItem, podemos destacar las siguientes.
Text. Contiene una cadena con el literal o texto descriptivo de la opción de
menú.
Enabled. Permite habilitar/deshabilitar la opción de menú. Cuando se encuentra deshabilitada, se muestra su nombre en un tono gris, indicando que no puede ser seleccionada por el usuario.
DefaultItem. Permite establecer opciones por defecto. En una opción de menú
por defecto, su texto se resalta en negrita.
Checked. Marca/desmarca la opción. Cuando una opción está marcada,
muestra junto a su nombre un pequeño símbolo de verificación o punteo.
RadioCheck. En el caso de que la opción de menú se encuentre marcada, si
asignamos True a esta propiedad, en lugar de mostrar el símbolo de
verificación estándar, se muestra uno con forma de punto.
100
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
ShortCut. Se trata de un atajo de teclado, o combinación de teclas que nos van a permitir ejecutar la opción de menú sin tener que desplegarlo. Al elegir esta propiedad, aparecerá una lista con todos los atajos disponibles para asignar.
ShowShortCut. Permite mostrar u ocultar la combinación de teclas del atajo
de teclado que tenga asignado una opción de menú.
Visible. Muestra u oculta la opción de menú.
MdiList. Esta propiedad se utiliza habitualmente en opciones situadas en la
barra de menú, y permite establecer que dicha opción al desplegarse,
muestre, además de las opciones de menú que le hayamos asignado, la lista
de ventanas secundarias MDI, en el caso de que el menú principal esté
contenido en un formulario de tipo MDI. Los formularios MDI serán
tratados posteriormente.
Podemos adicionalmente, asignar una tecla de acceso rápido o hotkey a una
opción de menú, anteponiendo el carácter & a la letra que deseemos, de las que
se encuentran en la propiedad Text del control MenuItem. Al igual que sucede con
los demás tipos de controles, en el texto de la opción de menú, aparecerá
subrayada la mencionada letra. De este modo, cuando despleguemos un menú,
no será necesario posicionarnos en una de ellas para ejecutarla, sino que
simplemente pulsando la tecla rápida, se ejecutará el código de dicha opción.
También podemos establecer separadores entre las opciones de menú simplemente
creando una opción y asignando a su propiedad Text el carácter de guión ( - ).
En nuestro formulario de ejemplo, vamos pues a diseñar un menú con la estructura del esquema mostrado en la Figura
Para todas las opciones se ha asignado una tecla de acceso rápido, y adicionalmente, para las opciones que se indican a continuación, se han modificado algunas propiedades por defecto.
Guardar. Deshabilitada.
Salir. Atajo de teclado en Ctrl. + S.
Copiar. Opción por defecto.
Pegar. Marcada con símbolo normal.
Cortar. Marcada con símbolo de círculo.
Elipse. Opción no visible.
101
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Esquema del menú de ejemplo.
La Figura muestra el formulario en ejecución con una parte del menú abierta.
Menú desplegado a varios niveles, mostrando opciones.
Una vez finalizada la fase de diseño del menú, debemos proceder a escribir el
código para sus opciones. El evento Click es el que permite a un control MenuItem
ejecutar código cuando la opción de menú es seleccionada. Abriendo por tanto, el
menú desde el diseñador del formulario, y haciendo doble clic en la opción
correspondiente, nos situaremos en el editor de código, dentro del
procedimiento manipulador del evento Click para esa opción. El Código fuente
muestra el código que se ejecutará cuando seleccionemos las opciones de menú Abrir y
Salir de nuestro ejemplo.
Private Sub mnuAbrir_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles mnuAbrir.Click
MessageBox.Show("Opción Abrir del menú")
End Sub
Private Sub mnuSalir_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles mnuSalir.Click
Me.Close()
End Sub
102
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Puesto que muchas de las propiedades de un control MenuItem son
manipulables en tiempo de ejecución, añadiremos al formulario varios botones,
mediante los cuales realizaremos operaciones sobre las opciones del menú tales
como habilitar y deshabilitar, mostrar y ocultar, cambiar el nombre, etc. La Figura
muestra el formulario con estos nuevos botones.
Controles Button para manipular por código las propiedades de las opciones del menú.
En el Código fuente podemos ver los manipuladores de evento de estos botones.
Private Sub btnHabilitar_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnHabilitar.Click
Me.mnuGuardar.Enabled = Not Me.mnuGuardar.Enabled
End Sub
Private Sub btnMarcar_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnMarcar.Click
Me.mnuPegar.Checked = Not Me.mnuPegar.Checked
End Sub
Private Sub btnMostrar_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnMostrar.Click
Me.mnuElipse.Visible = Not Me.mnuElipse.Visible
End Sub
Private Sub btnNombre_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnNombre.Click
If Me.mnuAbrir.Text = "A&brir" Then
Me.mnuAbrir.Text = "HO&LA"
Else
Me.mnuAbrir.Text = "A&brir"
End If
End Sub
103
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Private Sub btnDefecto_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnDefecto.Click
Me.mnuCopiar.DefaultItem = Not Me.mnuCopiar.DefaultItem
End Sub
Menú Contextual. ContextMenu
El control ContextMenu representa un menú contextual o flotante. Este tipo de menú se asocia al formulario o a uno de sus controles, de modo que al hacer clic derecho, se mostrará sobre el elemento al que se haya asociado.
El modo de añadir un control ContextMenu y sus correspondientes opciones al
formulario, es el mismo que para un MainMenu; situándose también una
referencia del menú contextual en el panel de controles especiales del diseñador.
Antes de poder diseñar las opciones de un ContextMenu, debemos pulsar la
referencia de dicho menú que existe en el panel de controles especiales, ya que por
defecto, el formulario muestra el menú principal en caso de que tenga uno definido.
La Figura muestra el menú contextual mnuContexto, que hemos añadido al
formulario. Para asociar este menú con un control o formulario, utilizaremos la
propiedad ContextMenu de que disponen la mayoría de los controles Windows.
En este ejemplo, insertaremos el control txtValor, de tipo TextBox, y le asociaremos
el menú de contexto que acabamos de crear.
Como resultado, cuando ejecutemos la aplicación, al hacer clic derecho sobre el
TextBox, aparecerá el menú contextual que hemos asignado, mediante el que
cambiaremos el tipo de fuente de la caja de texto, transformaremos el texto a
mayúsculas y minúsculas. El Código fuente muestra el código de los eventos Click
correspondiente a las opciones del menú contextual.
Private Sub mnuFuente_Click(ByVal sender As System.Object, ByVal e As
104
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
System.EventArgs) Handles mnuFuente.Click
Dim oFuente As New Font("Comic", 15)
Me.txtValor.Font = oFuente
End Sub
Private Sub mnuMayusculas_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles mnuMayusculas.Click
Me.txtValor.Text = Me.txtValor.Text.ToUpper()
End Sub
Private Sub mnuMinusculas_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles mnuMinusculas.Click
Me.txtValor.Text = Me.txtValor.Text.ToLower()
End Sub
La Figura muestra el aspecto del menú contextual, cuando es utilizado desde el
control TextBox.
Control ContextMenu asociado a un TextBox.
5.18.- Controles avanzados de Visual Basic
Control Temporizadores (Timer) En VB.NET disponemos al igual que en anteriores versiones, del control Timer, que
nos permite la ejecución de código a intervalos de tiempo predeterminados.
Este control ha sufrido una importante reestructuración, ya que internamente
hace uso de la clase Timer, perteneciente al conjunto de clases del sistema. El
hecho de poder acceder a esta clase, nos proporciona una gran flexibilidad en
nuestros desarrollos, ya que, a partir de ahora también crearemos temporizadores
105
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
por código, sin necesidad de utilizar el control Timer.
En el ejemplo TimerPru que comentamos a continuación, vamos a construir un
formulario en el que utilizaremos ambos tipos de temporizadores, el propio control
Timer y un objeto de la clase. El primer proceso a codificar, consistirá en
traspasar a intervalos de tiempo, el contenido de un TextBox del formulario, a
otro control de este mismo tipo. El formulario del proyecto se muestra en la Figura
Figura Formulario para ejemplo con temporizadores.
Tras incluir los controles de usuario en el formulario, añadiremos un control Timer,
al que daremos el nombre tmrTemporizador. Esta acción abrirá, bajo el diseñador
del formulario, un panel para controles especiales, como es el caso de Timer, en el
que se mostrará dicho control.
En este panel se depositan los controles del formulario que no tienen una interacción directa con el usuario, o cuyo diseño es diferente al de los controles habituales.
Para especificar el espacio de tiempo en el que este control será ejecutado cuando lo activemos, utilizaremos la propiedad Interval, a la que tenemos que asignar un valor numérico, que establece dicho tiempo en milisegundos. En nuestro caso, asignaremos 500, con lo que el control se ejecutará cada medio segundo.
Panel para controles especiales del diseñador de formularios.
106
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
El control Timer lo activaremos llamando a su método Start( ), cosa que hacemos al
pulsar el botón btnTraspasar.
Private Sub btnTraspasar_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnTraspasar.Click
' iniciar el temporizador
Me.tmrTemporizador.Start()
End Sub
Una vez activado un temporizador, cada vez que transcurre el tiempo indicado en
Interval, genera un evento Tick. Es precisamente en este evento en el que debemos
escribir el código que necesitamos que se ejecute a intervalos regulares de tiempo.
Haremos, por consiguiente, doble clic en el control Timer del diseñador, para acceder
al procedimiento manipulador de este evento, cuyo contenido lo podemos ver
' Este evento se produce en el intervalo especificado en el control Timer
Private Sub tmrTemporizador_Tick(ByVal sender As Object, ByVal e As
System.EventArgs) Handles tmrTemporizador.Tick
' quitamos una letra del TextBox de origen...
Dim sLetra As String
sLetra = Me.txtOrigen.Text.Substring(0, 1)
Me.txtOrigen.Text = Me.txtOrigen.Text.Remove(0, 1)
' ...y lo pasamos al TextBox de destino
Me.txtDestino.Text &= sLetra
' cuando se haya traspaso todo el texto detener el temporizador
If Me.txtOrigen.Text.Length = 0 Then
Me.tmrTemporizador.Stop()
MessageBox.Show("Traspaso finalizado")
End If
End Sub
Control ImageList
Este control actúa como repositorio de imágenes, del que se alimentarán otros
controles del formulario que necesiten mostrar gráficos en su interior.
Una vez añadido este control en el formulario, se situará en el panel de
controles especiales del diseñador, y haciendo clic en su propiedad Images, se
abrirá la ventana de la Figura, en la que podremos añadir y quitar las imágenes que
van a formar parte de la lista del control, así como ver en el panel complementario,
la información sobre cada imagen asignada.
107
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Ventana de administración de imágenes del control ImageList.
Las imágenes que insertamos en el control tienen un tamaño por defecto, en
el caso de que necesitemos modificarlo, expandiremos la propiedad ImageSize
en la ventana de propiedades y asignaremos nuevos valores en Width y Height.
Otra ventaja de este control es que nos permite manipular las imágenes por código,
por ejemplo, para añadir nuevas imágenes, debemos usar el método Add( ) de su
propiedad Images, como muestra el Código fuente
Me.imlImagenes.Images.Add(New Bitmap("tutorias.gif"))
Control ToolBar
Este control representa la barra de herramientas o botones de acceso rápido que
facilitan al usuario la ejecución de los procesos principales del programa,
evitándole la navegación por el menú del formulario.
Al ser dibujado, este control queda acoplado a la parte superior del formulario.
Después de ponerle tbrBarra como nombre, asignaremos a su propiedad
ImageList, el control de ese mismo tipo que acabamos de crear; esto nos
permitirá asignar los gráficos de la lista a los botones que vayamos creando en
el ToolBar. Para establecer el tamaño de los botones de la barra utilizaremos la
propiedad ButtonSize de este control.
Seguidamente haremos clic en la propiedad Buttons, que abrirá una ventana con
la colección de botones de la barra, en la que podremos crear y configurar dichos
botones.
108
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Editor de botones del control ToolBar.
Cada botón en un ToolBar es un objeto de tipo ToolBarButton, del que
podemos destacar las siguientes propiedades.
Text. Cadena con el texto que muestra el botón.
ImageIndex. En el caso de asociar el ToolBar con un control ImageList, en
esta propiedad asignamos para un botón una de las imágenes del ImageList,
indicando el número de orden de la imagen.
Style. Permite establecer el estilo del botón: de pulsación; separador; o de
tipo desplegable, que abre un subconjunto de opciones.
DropDownMenu. Si asociamos el botón con una opción de la barra de menú
del formulario, y configuramos su estilo como DropDownButton, al pulsar el botón
desplegable, se mostrarán las opciones de menú; el efecto será el mismo que si
hubiéramos desplegado directamente el menú del formulario.
La Figura muestra la ventana principal de la aplicación con la barra de herramientas
109
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Formulario con ToolBar.
Una vez terminado el diseño del ToolBar, debemos codificar su evento
ButtonClick, que será provocado cada vez que se pulse un botón de la barra.
Dentro del procedimiento de este evento, comprobaremos qué botón ha sido
pulsado y ejecutaremos las acciones oportunas.
Tanto el botón Abrir como la opción de menú del mismo nombre realizan la misma
tarea, por lo que llaman al método AbrirArchivo( ), que es quien realmente
muestra el formulario necesario.
Private Sub tbrBarra_ButtonClick(ByVal sender As System.Object, ByVal e As
System.Windows.Forms.ToolBarButtonClickEventArgs) Handles
tbrBarra.ButtonClick
' comprobar qué botón de la barra se ha pulsado
If e.Button Is Me.btnAbrir Then
' llamamos al método que abre el formulario para abrir un archivo
Me.AbrirArchivo()
End If
If e.Button Is Me.btnSalir Then
' cerrar la aplicación
Me.Close()
End If
End Sub
Private Sub mnuAbrir_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles mnuAbrir.Click
' al seleccionar esta opción de menú llamar al método que
' abre el formulario que permite abrir un archivo
Me.AbrirArchivo()
End Sub
Private Sub AbrirArchivo()
Dim ofrmAbrirArchivo As New frmAbrirArchivo()
ofrmAbrirArchivo.MdiParent = Me
ofrmAbrirArchivo.Show()
End Sub
Al haber asignado al botón btnPersonal uno de los menús de la barra del formulario,
no será necesario escribir código para detectar este botón en el evento ButtonClick,
ya que se ejecutará directamente el código del evento Click de las opciones de
menú. El Código fuente 523 muestra el código perteneciente a la opción de
menú Personal + Datos.
110
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Private Sub mnuDatos_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles mnuDatos.Click
Dim ofrmPersonal As New frmDatosPersonal()
ofrmPersonal.MdiParent = Me
ofrmPersonal.Show()
End Sub
Control StatusBar
Para mostrar una barra informativa de estado recurriremos a este control, que
al dibujarse queda situado en la parte inferior del formulario; como nombre le
daremos sbrEstado. De forma similar al ToolBar, un control StatusBar está
compuesto de una colección de objetos Panel, que iremos añadiendo al control
mediante la propiedad Panels, la cual mostrará una ventana para la creación y
configuración de tales paneles.
Editor de paneles del control StatusBar.
Entre las propiedades destacables de un objeto Panel podemos mencionar las
siguientes.
BorderStyle. Muestra el panel con efecto resaltado, hundido o normal.
Icon. Permite asociar un icono al panel.
AutoSize. Con esta propiedad podemos conseguir que el panel se redimensione
ajustándose a su contenido o que tenga un tamaño fijo.
En este ejemplo, hemos añadido dos paneles a la barra de estado del formulario. En
uno mostramos un texto fijo; mientras que en el otro, visualizamos la hora
actual a través de un objeto Timer que ponemos en marcha en el evento Load
del formulario. Veamos los métodos implicados, en el Código fuente 524.
111
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Private Sub frmPrincipal_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles MyBase.Load
' al cargar el formulario, creamos un temporizador
' le asociamos un manejador para su evento Tick y lo iniciamos
Dim oTiempo As New Timer()
oTiempo.Interval = 1000
AddHandler oTiempo.Tick, AddressOf PonerHoraActual
oTiempo.Start()
End Sub
Private Sub PonerHoraActual(ByVal sender As Object, ByVal e As EventArgs)
' actualizamos a cada segundo la hora de un panel de la barra de estado
Me.sbrEstado.Panels(1).Text = DateTime.Now.ToString("HH:mm:ss")
End Sub
La Figura muestra el formulario con la barra de estado.
Formulario con StatusBar.
Finalizada la creación del StatusBar, añadiremos al proyecto un formulario
con el nombre frmDatosPersonal, en el dibujaremos un conjunto de nuevos
controles que iremos describiendo seguidamente.
Control DateTimePicker
Este control permite la selección e introducción de fechas en una caja de texto
con capacidades extendidas, o bien mediante un calendario desplegable que se
mostrará al pulsar el botón de expansión que contiene. Ver Figura
112
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Control DateTimePicker.
Para modificar la fecha en el cuadro de texto, debemos situarnos en la parte a
modificar de la fecha y teclear el nuevo valor, o bien, con las flechas de dirección
arriba-abajo, cambiar esa parte de la fecha. Si expandimos el calendario, podremos
realizar la selección de un modo más gráfico.
Por defecto el control muestra la fecha actual, pero con la propiedad Text
podemos cambiar la fecha por código, cosa que hacemos al cargar el formulario,
asignando una fecha distinta de la actual. Ver Código.
Private Sub frmDatosPersonal_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles MyBase.Load
' modificar fecha del DateTimePicker
Me.dtpFNacim.Text = "15/06/2002"
'....
End Sub
Podemos restringir el rango de fechas a mostrar por este control con las
propiedades MinDate y MaxDate. Si queremos, por otra parte, que la fecha se
muestre con un formato personalizado, aplicaremos dicho formato mediante la
propiedad CustomFormat, teniendo en cuenta que no se hará efectivo hasta que a
la propiedad Format no le asignemos el valor Custom.
El botón btnCambiosFecha del formulario realiza algunas modificaciones por código
sobre el control DateTimePicker dtpFNacim del formulario, que vemos en el Código
Private Sub btnCambiosFecha_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnCambiosFecha.Click
' configurar por código el control DateTimePicker
Me.dtpFNacim.MinDate = "1/4/2002"
Me.dtpFNacim.MaxDate = "1/10/2002"
Me.dtpFNacim.CustomFormat = "d-MMM-yy"
Me.dtpFNacim.Format = DateTimePickerFormat.Custom
113
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
End Sub
Control NumericUpDown Control que muestra una caja de texto con un valor numérico que podremos
ir aumentando- disminuyendo al pulsar los botones para esta labor de que dispone
el control. La Figura muestra este control en nuestro formulario de pruebas.
Control NumericUpDown.
Entre las propiedades de este control destacaremos las siguientes.
Increment. Número en el que se incrementará el valor del control cuando
pulsemos sus botones o teclas de dirección.
InterceptArrowKeys. Permite que las flechas de dirección arriba-abajo
tengan el mismo efecto que si pulsamos los botones para incrementar o
disminuir, de este control.
Maximum, Minimun. Contienen los límites superior e inferior en cuanto al
número que podrá contener el control.
TextAlign. Permite alinear el número dentro la caja de texto del control.
UpDownAlign. Permite situar los botones del control a la izquierda o derecha
de la caja de texto que contiene el valor.
Entre los eventos de que dispone este control, ValueChanged se produce cada vez
que cambia el valor del control, de modo que en este caso, vamos a cambiar el
color de fondo en función del número que contenga.
Private Sub nupEdad_ValueChanged(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles nupEdad.ValueChanged
Select Case Me.nupEdad.Value
Case 20 To 30
Me.nupEdad.BackColor = Color.Gold
Case 30 To 40
Me.nupEdad.BackColor = Color.LimeGreen
Case Else
Me.nupEdad.BackColor = Me.nupEdad.DefaultBackColor
End Select
End Sub
114
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Control DomainUpDown
Este control nos permite desplazarnos por una lista de valores, al mismo estilo que el
control anterior. Dicha lista de valores la crearemos mediante la propiedad Items, en
tiempo de diseño o ejecución. El Código muestra como al cargar el formulario
frmDatosPersonal, con la propiedad Items y su método AddRange( ), añadimos los
valores que seleccionaremos en el control en tiempo de ejecución.
Private Sub frmDatosPersonal_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles MyBase.Load
'....
' crear la lista del DomainUpDown
Me.dudCategoria.Items.AddRange(New String() {"Auxiliar", "Jefe
departamento","Coordinador"})
End Sub
La Figura muestra el control dudCategoría, de este tipo al ser utilizado en el
formulario. En el caso de que necesitemos los valores ordenados, asignaremos True a
su propiedad Sorted.
Control DomainUpDown.
Control MonthCalendar
Este control muestra en modo gráfico un calendario por el que podemos
desplazarnos para seleccionar una fecha. El control DateTimePicker utiliza
internamente un MonthCalendar para mostrar su calendario desplegable.
Por defecto se visualiza un mes, pero si asignamos a su propiedad
CalendarDimensions un objeto Size, podemos expandir el tamaño del calendario
para que muestre varios meses. El Código muestra el código de un botón del
formulario mediante el que cambiamos el tamaño del calendario.
Private Sub btnTamCalendario_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnTamCalendario.Click
Me.mclCalendario.CalendarDimensions = New Size(2, 2)
End Sub
En la Figura vemos el resultado de expandir el tamaño del control.
115
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Control MonthCalendar con el tamaño ampliado.
Para detectar la selección de una fecha utilizaremos el evento DateChanged.
Debido a que en un control MonthCalendar podemos seleccionar un rango de
fechas, las propiedades que tenemos que manipular para averiguar la
fechas seleccionadas son: SelectionStart, SelectionEnd y SelectionRange, aunque
en muchas ocasiones sólo será necesario utilizar una de ellas.
Private Sub mclCalendario_DateChanged(ByVal sender As System.Object, ByVal e As
System.Windows.Forms.DateRangeEventArgs) Handles mclCalendario.DateChanged
' mostrar en un Label la fecha seleccionada en el control MonthCalendar
Me.lblCalendario.Text = Me.mclCalendario.SelectionStart
End Sub
Control LinkLabel
Este control permite tener en un formulario Windows un enlace hacia una página de
Internet, con un comportamiento similar al que encontramos en un hiperenlace de una
página web.
Su propiedad Text muestra un literal, de modo que al hacer clic sobre el mismo, se
provocará el evento LinkClicked en el que escribiremos el código a ejecutar.
En nuestro formulario de ejemplo, hemos creado un control de este tipo con el
nombre lnkEidos, que tiene el aspecto de la Figura 322, ya que además del enlace, le
hemos asignado una imagen.
Control LinkLabel.
116
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Para conseguir que al hacer clic en este enlace, se abra Internet Explorer y
navegue hacia una determinada página, vamos a utilizar la clase Process, que
como su nombre indica, nos permite la gestión de procesos del sistema, tales como
su inicio y finalización.
En este caso, el método compartido Start( ), de Process, va a ejecutar el navegador
al pasarle como parámetro una dirección web en forma de cadena. Veamos el Código
Private Sub lnkEidos_LinkClicked(ByVal sender As System.Object, ByVal e As
System.Windows.Forms.LinkLabelLinkClickedEventArgs) Handles
lnkEidos.LinkClicked
' inicia Internet Explorer y navega hacia una página
Process.Start("http://www.eidos.es")
End Sub
Creación y manipulación de elementos en ejecución
El conjunto de controles que acabamos de ver, al igual que los básicos permiten
ser creados no sólo mediante el diseñador de formularios, sino también desde
código. Como muestra de ello, la opción de menú Varios + Añadir botón y panel,
añade dos imágenes al control ImageList del formulario frmPrincipal, creando un
nuevo botón para el ToolBar y un panel para el StatusBar Ver el Código
Private Sub mnuAgregaElementos(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles mnuAgregar.Click
' añadir por código imágenes a la lista
Me.imlImagenes.Images.Add(New Bitmap("tutorias.gif"))
Me.imlImagenes.Images.Add(New Bitmap("camera1.gif"))
Dim oBoton As New ToolBarButton()
oBoton.Text = "TUTORIAS"
oBoton.ImageIndex = 4
Me.tbrBarra.Buttons.Add(oBoton)
Dim oPanel As New StatusBarPanel()
oPanel.Text = "BUSCAR"
oPanel.BorderStyle = StatusBarPanelBorderStyle.Raised
oPanel.ToolTipText = "Información sobre búsquedas"
oPanel.Icon = New Icon("magnify.ico")
Me.sbrEstado.Panels.Add(oPanel)
End Sub
Para detectar la pulsación del nuevo botón de la barra de herramientas, añadimos el
siguiente código en su evento ButtonClick, que vemos en el Código
117
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Private Sub tbrBarra_ButtonClick(ByVal sender As System.Object, ByVal e As
System.Windows.Forms.ToolBarButtonClickEventArgs) Handles
tbrBarra.ButtonClick
'....
If e.Button.Text = "TUTORIAS" Then
MessageBox.Show("Se ha pulsado el botón de tutorías")
End If
End Sub
La Figura muestra este formulario en ejecución tras añadir los nuevos elementos.
Nuevos controles añadidos al formulario en tiempo de ejecución.
Control NotifyIcon
Este control permite añadir un icono asociado con nuestra aplicación en el panel de
iconos del sistema (Windows System Tray) situado en la parte derecha de la barra de
tareas de Windows. Tales iconos suelen utilizarse por aplicaciones que permanecen
ocultas, y al hacer clic derecho sobre su icono en este panel, aparece un menú
contextual que permite mostrar la aplicación.
En nuestro caso vamos a utilizar este control para ejecutar y parar la
calculadora del sistema empleando la clase Process, comentada en un apartado
anterior.
Después de agregar un control de este tipo al formulario, asignaremos un icono a su
propiedad Icon y una cadena a su propiedad Text, que será mostrada al situar el ratón
encima de este control en tiempo de ejecución.
Crearemos después un menú contextual con las opciones Abrir y Cerrar, que
asignaremos a la propiedad ContextMenu del control NotifyIcon.
Para poder controlar la calculadora de Windows cuando esté en ejecución,
declararemos una variable de tipo Process a nivel de la clase. Al ejecutar la
calculadora mediante el método Start( ) de la clase Process, obtendremos un objeto
de dicho tipo, que pasaremos a esta variable, y nos permitirá posteriormente,
118
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
cerrar el proceso en el que se está ejecutando la calculadora mediante el método Kill(
). Veamos esta parte en el Código
Public Class frmPrincipal
Inherits System.Windows.Forms.Form
Private oCalculadora As Process
'....
Private Sub mnuCalcAbrir_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles mnuCalcAbrir.Click
' iniciar la calculadora
oCalculadora = Process.Start("calc.exe")
End Sub
Private Sub mnuCalcCerrar_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles mnuCalcCerrar.Click
' cerrar la calculadora
oCalculadora.Kill()
End Sub
End Class
Al ejecutar el programa, se mostrará un nuevo icono en la lista del panel de iconos
del sistema de la barra de tareas, como muestra la Figura 324.
Control NotifyIcon en el panel de iconos del sistema de la barra de tareas.
Como se puede comprobar, la clase Process amplía enormemente nuestra
capacidad de manipulación de los procesos del sistema.
119
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
6.- PROGRAMACIÓN ORIENTADA A OBJETOS (POO) DE VISUAL BASIC.NET
Introducción:
Todo .NET Framework está basado en clases (u objetos). A diferencia de las versiones anteriores de Visual Basic, la versión .NET de este lenguaje basa su funcionamiento casi exclusivamente en las clases contenidas en .NET Framework, además casi sin ningún tipo de limitación.
La POO es una evolución de la programación por procedimientos llamada también estructurada. Se basaba en funciones y procedimientos y el código que controlaba el flujo de las llamadas a estos. En Visual Basic, sobre todo en versiones anteriores se sigue programando mucho así. A veces por desconocimiento y otras por "miedo" no se da el salto a la POO, aunque un programador con experiencia en VB puede hacer magníficas aplicaciones sin utilizar la POO (y sin aprovecharse de sus ventajas), y sobre todo, en un tiempo relativamente reducido.
6.1.-¿Qué es una clase?
Los programas de Visual Basic se generan con objetos como formularios y controles. Los objetos también se pueden utilizar para representar cosas reales como personas, equipos informáticos o incluso algo más abstracto, como una cuenta bancaria.
Una clase es simplemente una representación de un tipo de objeto. Se puede pensar en ella como un plano que describe el objeto. Así como un plano puede utilizarse para construir varios edificios, una clase podemos usarla para crear varias copias de un objeto.
Por ejemplo, el control TextBox lo define una clase TextBox, que define su aspecto y sus funciones. Cada vez que arrastramos un control TextBox a un formulario, realmente está creando una nueva instancia de la clase TextBox.
Cada control TextBox es una copia exacta, aunque distinta, de la clase que lo define, la clase TextBox. Puesto que cada objeto es una "instancia" independiente de una clase, la acción de crear una clase se denomina creación de instancias.
Hasta ahora hemos agregado los controles TextBox a su formulario arrastrándolos desde el Cuadro de herramientas, pero también puede crear instancias de un objeto TextBox en su código si utiliza la palabra clave New.
Dim Textbox1 As New TextBox
¿Qué hay dentro de una clase?
Todos los objetos tienen propiedades que describen sus atributos, métodos que definen sus acciones y eventos que definen sus respuestas. Igualmente, la clase que
120
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
define un objeto tiene sus propias propiedades, métodos y eventos (a veces llamados miembros) que se pasan a todas las instancias de esa clase.
Por ejemplo, una clase que representa una cuenta bancaria podría tener propiedades
como:
NumeroCuenta
BalanceCuenta
Métodos como:
CalculaInteres ()
Eventos :
CambioBalance.
Una vez creada la instancia de un objeto de cuenta bancaria, puede tener acceso a sus propiedades, métodos y eventos de igual manera que si se tratara de un objeto TextBox.
Algunos miembros de una clase son privados; sólo se tiene acceso a ellos mediante código dentro de la clase. Por ejemplo, una clase de cuenta bancaria puede tener un método para calcular un saldo. Lo lógico es permitir que un programa lea ese balance pero no que pueda cambiarlo directamente.
Puede ocultar los miembros de una clase si los declara como Private o exponerlos si los declara como Public. También puede permitir el acceso a una propiedad y a la vez impedir que el programa cambie su valor declarándolo como ReadOnly.
El código siguiente muestra cómo podría ser una clase CuentaBanco, por ejemplo:
'Declaramos la clase CuentaLimpia Class CuentaLimpia 'La hacemos privada Private NumeroCuenta As String Private BalanceCuenta As Decimal 'Y la ponemos publica para que calcule el balance Public Sub ActualizaBalance() End Sub ReadOnly Property Balance() As Decimal Get Return BalanceCuenta End Get End Property End Class
CtaBancaria
NumeroCuenta BalanceCuenta CalculaInteres()
CambioBalance
Hacer click
121
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
6.2.- Crear la primera clase
Una de las mejores razones para utilizar clases es que una vez que ha creado una clase para cierto tipo de objeto, se puede reutilizar esa clase en cualquier proyecto.
Por ejemplo, muchos de los programas que escribimos pueden involucrar personas: Un programa de administrador de contactos para los contactos comerciales o un programa para realizar un seguimiento de empleados. Aunque los programas pueden ser considerablemente diferentes, los atributos que se aplican a cada persona serían los mismos. Todas tienen nombre, edad, dirección, número de teléfono, etc.
Para empezar a ver mejor crear clases,y usarlas crearemos una clase que represente a una persona; Podemos guardar esta clase y utilizarla en otros programas que escribamos en el futuro.
Las clases se pueden crear de tres maneras: como parte del código en un módulo de formulario en un proyecto de aplicación para Windows, como un módulo de clase separado agregado a un proyecto de aplicación para Windows o como un proyecto de bibliotecas de clase independiente.
Crear clases
Al hacer doble clic en un formulario y abrir el Editor de código se ve algo parecido a lo siguiente:
Public Class Form1 Private Sub Form1_Load... … End Sub End Class
Podemos observar que el formulario realmente es una clase, marcada por instrucciones Class y End Class y cualquier código que se haya escrito entre las dos instrucciones es parte de la clase. Aunque de manera predeterminada un módulo de formulario contiene sólo una clase única, puede crear módulos adicionales agregando código debajo de la instrucción End Class, tal como se ilustra a continuación:
Public Class Form1 ' El código de vuestro Form AQUI End Class Public Class MyFirstClass ' El código de vuestra clase AQUI End Class
La desventaja de crear clases de esta manera es que sólo están disponibles dentro del proyecto donde se crearon. Si deseamos compartir una clase con otros proyectos, puede colocarla en un módulo de clase.
122
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Módulos de clase
Un módulo de clase es un archivo de código, separado del resto, que contiene una o más clases. Como es un archivo independiente, se puede reutilizar en otros proyectos.
Los módulos de clase se pueden crear de dos maneras:
Como un módulo agregado a un proyecto de aplicación para Windows. Como un proyecto de bibliotecas de clase independient
Puede agregar un nuevo módulo de clase a un proyecto existente seleccionando Clase en el cuadro de diálogo Agregar nuevo elemento, disponible en el menú Proyecto. Para trabajar en durante el tutorial, crearemos un proyecto de bibliotecas de clases independientes.
Vamos a ver cómo crear un proyecto de de biblioteca de clases:
En el menú Archivo, seleccionamos Nuevo proyecto. En el panel Plantillas, del cuadro de diálogo Nuevo proyecto, hacemos clic en
Biblioteca de clases.
En el cuadro Nombre, escribimos Persons y hacemos clic en Aceptar.
Se abrirá un nuevo proyecto de bibliotecas de clase y el Editor de código mostrará el módulo de clase Class1.vb.
123
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
En el Explorador de soluciones, hacemos clic con el botón secundario del ratón en Class1.vb y seleccionamos Cambiar nombre y, a continuación, cambiamos el nombre a "Persons.vb".
Observamos que el nombre en el Editor de código también cambia a Persons.vb.
En el menú Archivo, elegimos Guardar todo. En el cuadro de diálogo Guardar proyecto, hacemos clic en Guardar.
Nota: En lugar de guardar el proyecto en la ubicación predeterminada, podríamos crear un directorio en el cual podemos almacenar todas las clases para reutilizarlas mas tarde. se puede especificar esa carpeta en el campo Location del cuadro de diálogo Guardar proyecto antes de guardar.
De momento, mantendremos el proyecto abierto, porque lo utilizaremos durante todo el tutorial, e iremos ampliando la información.
Agregar propiedades a una clase
Ahora, aprenderemos a agregar propiedades a la clase que creamos en la sección anterior.
Todos los objetos tienen atributos y las propiedades representan atributos. Antes, hicimos la clase "Persons", que representa a una persona; las personas tienen atributos como el nombre y la edad, por lo que la clase Persons necesita propiedades que representen dichos atributos.
Se pueden agregar propiedades a una clase de dos maneras:
124
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Como campo. Como procedimiento de propiedad.
También podemos determinar cómo funciona una propiedad utilizando los modificadores Public, ReadOnly o WriteOnly.
Campos y procedimientos de propiedad
Los campos son variables públicas dentro de una clase que se pueden establecer o leer desde fuera de la clase. Resultan de utilidad para propiedades que no se tienen que validar, por ejemplo, un valor "Boolean" (True o False).
En el caso de la clase Personas, se puede tener una propiedad Boolean denominada Casado, que especifica si una persona está soltera o casada, puesto que hay sólo dos valores posibles.
Para agregar un campo a una clase, el código podría ser como el que sigue.
Public Casado As Boolean
La mayoría de las propiedades, sin embargo, son más complejas; en la mayor parte de los casos utilizaremos procedimientos de propiedad para agregar una propiedad a una clase.
Los procedimientos de propiedad tienen tres partes:
Una declaración de una variable privada para almacenar el valor de la propiedad.
Un procedimiento Get que expone el valor. Un procedimiento Set que, como indica su nombre, establece el valor en la
clase.
Por ejemplo, un procedimiento de propiedad para una propiedad Name, de la clase Personas, podría ser como el que sigue:
Private ValorNombre As String Public Property Nombre() As String Get Nombre = ValorNombre End Get Set(ByVal valor As String) ValorNombre = valor End Set End Property
Recibe el dato en la variable ValorNombre de La clase
Devuelve el contenido de la variable ValorNombre
125
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
La primera línea de código declara una variable String privada, ValorNombre que almacenará el valor de la propiedad. El procedimiento de propiedad en sí comienza con Public Property y termina con End Property.
El procedimiento Get contiene el código que se ejecutará cuando desee leer su valor; por ejemplo, si lee la propiedad Personas.Nombre, el código devolverá el valor almacenado en la variable ValorNombre
El procedimiento Set contiene código que se utiliza para asignar un nuevo valor a la variable ValorNombre usando un valor pasado como argumento Valor. Por ejemplo, si escribimos el código
Personas.Nombre = "Wyrm"
El valor String Wyrm se pasará como argumento Valor; el código del procedimiento Set lo asignará a la variable ValorNombre para su almacenamiento.
¿Por qué complicarnos tanto, en lugar de utilizar un campo que represente la propiedad Nombre? En el mundo real, hay ciertas reglas para los nombres: por ejemplo, los nombres normalmente no contienen números. Puede agregar código al procedimiento Set para comprobar el argumento Valor y devolver un error si contiene números.
Siguiendo con la Clase Personas, ahora agregaremos un campo y tres propiedades:
1. Abrimos el proyecto Personas que hicimos en la sección anterior. Si no lo guardaste, primero deberás regresar a la sección anterior, crear la primera clase, y realizar hasta el final los procedimientos de esa sección.
2. En el Explorador de soluciones, seleccionamos Personas.vb y en el menú Ver elegimos Código.
3. Agregamos el siguiente código de declaración debajo de la línea Public Class Personas.
126
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Private ValorPrimerNombre As String Private ValorSegundoNombre As String Private ValorApellido As String Public Casado As Boolean
4. Agregamos los siguientes procedimientos de propiedad debajo del código de declaración anterior.
Public Property PrimerNombre() As String Get PrimerNombre = ValorPrimerNombre End Get Set(ByVal valor As String) ValorPrimerNombre = Valor End Set End Property Public Property SegundoNombre() As String Get SegundoNombre = ValorSegundoNombre End Get Set(ByVal valor As String) ValorSegundoNombre = Valor End Set End Property
Public Property Apellido() As String Get Apellido = ValorApellido End Get Set(ByVal valor As String) ValorApellido = Valor End Set End Property
Quedará así:
5. En el menú Archivo, elegimos Guardar todo para guardar el trabajo.
Propiedades de sólo lectura y escritura
A veces una propiedad se establece una vez y no cambia nunca mas durante la ejecución del programa. Por ejemplo, una propiedad que representa un número de empleado nunca debe cambiar, de modo que otro programa si lo pueda leer, pero no se permitirá que ese programa cambie su valor.
La palabra clave ReadOnly se utiliza para especificar que un valor de propiedad se pueda leer pero no modificar.
127
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Nota: Si intentamos asignar un valor a una propiedad ReadOnly, aparecerá un error en el Editor de código.
Para crear una propiedad de sólo lectura, deberemos crear un procedimiento de propiedad con un procedimiento Get, pero sin procedimiento Set, como se muestra a continuación.
Private IDValue As Integer ReadOnly Property ID() As Integer Get ID = IDValue End Get End Property
De igual forma, la palabra clave WriteOnly permite establecer un valor de propiedad pero no permite que se lea; por ejemplo, no permite que otros programas lean una propiedad de contraseña. Podemos utilizar ese valor para realizar acciones dentro de la clase, pero deseará que sigan siendo privadas.
Para crear una propiedad de sólo escritura, se creará una propiedad con un procedimiento Set pero sin procedimiento Get, como a continuación:
Private passwordValue As String WriteOnly Property Password() As String Set(ByVal value As String) passwordValue = value End Set End Property
Los procedimientos de propiedad ReadOnly y WriteOnly también son útiles cuando deseamos tomar un valor de propiedad y convertirlo en un valor diferente. Por ejemplo, pensemos en la edad de una persona. A diferencia del nombre, la edad cambia con el tiempo, si ha asignado la edad a una clase y la lee de nuevo un año después, sería incorrecta.
En la clase Persons, podemos evitarlo agregando dos propiedades: una propiedad "WriteOnly BirthYear" que representa el año de nacimiento, que nunca cambia, y una propiedad "ReadOnly Age" que devuelve un valor calculando la diferencia entre el año en curso y el año de nacimiento.
Siguiendo con la Clase Persons, ahora agregaremos propiedades ReadOnly y WriteOnly a la clase:
1. Agregamos el siguiente código de declaración debajo de las otras declaraciones en la parte superior del módulo de clase.
Private birthYearValue As Integer
128
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
2. Introducimos los siguientes procedimientos de propiedad debajo del código de declaración.
WriteOnly Property BirthYear() As Integer Set(ByVal value As Integer) birthYearValue = value End Set End Property ReadOnly Property Age() As String Get Age = My.Computer.Clock.LocalTime.Year – birthYearValue End Get End Property
3. En el menú Archivo, elegimos Guardar todo para guardar el trabajo.
6.4.- Agregar métodos a una clase
Agregaremos métodos a una clase, para que puedan realizar acciones. Vimos que la mayoría de los objetos tienen acciones que pueden realizar; estas acciones se conocen como métodos.
La clase Persons que creamos en la sección anterior,tiene muchas acciones que pueden realizar las personas y, estas acciones se pueden expresar como métodos de clase.
Métodos de una clase
Los métodos de una clase son simplemente procedimientos Sub o Function, declarados en la clase.
Por ejemplo, una clase Cuenta puede tener un procedimiento Sub denominado Recalcular, que actualizará el balance o un procedimiento Function denominado CurrentBalance para devolver el último balance.
El código para declarar esos métodos puede ser similar al siguiente:
Public Sub Recalcular() 'Aqui el codigo para recalcular Cuenta. End Sub Ejemplo: Public Function BalanceCuenta(ByVal AccountNumber As Integer) As Double 'Codigo para volver a Balance End Function
129
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Si bien la mayoría de los métodos de clase son públicos, también se pueden agregar métodos que sólo la clase en sí puede utilizar. Por ejemplo, la clase Personas puede tener su propia función para calcular la edad de una persona. Si declara la función como Private, no se puede ver o llamar desde fuera de la clase.
El código para una función privada puede ser similar a éste otro:
Private Function CalcuEdad(ByVal year As Integer) As Integer CalcuAge = My.Computer.Clock.LocalTime.Year - year End Function
Más tarde podremos cambiar el código que calcula el valor CalcAge y el método seguirá funcionando bien sin cambiar ningún código que utilice el método. Ocultar el código que realiza el método, se conoce como la "encapsulación", ya explicada al comienzo.
Ahora, para agregar un método a la clase Persons, hacemos lo siguiente:
Abrimos el proyecto Personas (si no lo tenemos abierto ya de antes) que hicimos en las secciones anteriores. Si no lo guardaste, o no lo creaste, primero deberás volver a las secciones anteriores, agregar propiedades a la clase, y completar los procedimientos.
En el Explorador de soluciones, seleccionamos Personas.vb y, en el menú Ver, hacemos clic en Código. Agregamos el siguiente código bajo los procedimientos de propiedad.
Public Function NombreComplet() As String If ValorSegundoNombre <> "" Then NombreCompleto = ValorPrimerNombre & " " & ValorSegundoNombre & " " & ValorApellido Else NombreCompleto = ValorPrimerNombre & " " & ValorApellido End If End Function Private Function CalcuEdad(ByVal year As Integer) As Integer CalcuEdad = My.Computer.Clock.LocalTime.Year - year End Function
Modificamos el código en el procedimiento de la propiedad Age para utilizar la función privada:
ReadOnly Property Age() As String Get 'Age = My.Computer.Clock.LocalTime.Year – birthDateValue
130
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Age = CalcuEdad(birthYearValue) End Get End Property
Antes, el código era así:
ReadOnly Property Age() As String Get Age = My.Computer.Clock.LocalTime.Year – birthYearValue End Get End Property
En el menú Archivo, hacemos clic en Guardar todo para guardar el trabajo.
6.5.- Agregar eventos a una clase
Un programa puede responder a eventos externos, como por ejemplo, un usuario que hace clic en un botón. En esta sección, obtendremos información sobre cómo agregar eventos a una clase.
Primero, debemos declarar el evento. A continuación, debemos provocarlo.
Provocar un evento significa que estamos señalizando la aparición del evento. Para agregar un evento a una clase, lo declaramos con la instrucción Event. Ésto indica que el objeto puede provocar el evento que especificamos.
Por ejemplo, quizás deseemos agregar un evento AgeCalculated a la clase Persons que hicimos. Podemos provocar a continuación el evento en el método CalcAge. Después de hacer esto, cuando se llama al método, podemos ejecutar algún código adicional en cuanto se haya calculado la edad de la persona.
Para agregar un evento a la clase Persons
Abrimos el proyecto Persons. En el Explorador de soluciones, seleccione Persons.vb y, en el menú Ver,
hacemos clic en Código. Agregamos el siguiente código encima de los procedimientos de propiedad.
131
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Public Event AgeCalculated(ByVal Age As Single)
En el método CalcAge, reemplazamos el código existente por el siguiente código para provocar el evento.
Private Function CalcAge(ByVal year As Integer) As Integer Dim Age = My.Computer.Clock.LocalTime.Year - year RaiseEvent AgeCalculated(Age) CalcAge = My.Computer.Clock.LocalTime.Year - year End Function
En el menú Archivo, hacemos clic en Guardar todo para guardar el trabajo.
Probar una clase
Creamos una clase llamada "Persons" y le proporcionamos propiedades, métodos y eventos. Lo que hemos hecho hasta ahora es agregar código, ahora es el momento de utilizar la clase Persons y asegurarse de que funciona según lo esperado.
6.6.- Crear una instancia de una clase
Los formularios y controles son en realidad clases; cuando arrastramos un control Button a un formulario, estamos creando realmente una instancia de la clase Button.
También podemos crear instancias de cualquier clase en el código utilizando una declaración con la palabra clave New. Por ejemplo, para crear una nueva instancia de la clase Button, agregaremos el código siguiente.
Dim aButton As New Button
Para utilizar y probar la clase Persons, debemos crear primero un proyecto de prueba y agregar una referencia al módulo de clase.
Para crear un proyecto de prueba para la clase Persons
Abrimos el proyecto Persons que creamos en las secciones anteriores. En el menú Archivo, elegimos Agregar y, a continuación, hacemos clic en Nuevo
proyecto.
132
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
En el panel Plantillas, en el cuadro de diálogo Nuevo proyecto, hacemos clic en Aplicación de Windows Forms.
En el cuadro Nombre, escribimos PersonsTest y hacemos clic en Aceptar.
Se agregará un nuevo proyecto de Windows Forms al Explorador de soluciones y aparecerá un nuevo formulario.
133
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
En el Explorador de soluciones, seleccionamos el proyecto PersonsTest y, en el menú Proyecto, hacemos clic en Establecer como proyecto de inicio.
En el Explorador de soluciones, seleccionamos el proyecto PersonsTest y, en el menú Proyecto, hacemos clic en Agregar referencia.
Aparecerá el cuadro de diálogo Agregar referencia.
Hacemos clic en la ficha Proyectos, seleccionamos Personas y hacemos clic en Aceptar.
134
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Hacemos doble clic en el formulario para abrir el editor de código y escribimos la siguiente declaración justo debajo de la línea Public Class Form1.
Dim person1 As New Persons.Persons
Esto declara una nueva instancia de la clase Persons.
Quizás os preguntéis por qué tuvimos que escribir dos veces Persons, pues porque la primera instancia es el módulo de clase Persons.vb y la segunda instancia es la clase Persons de ese módulo.
En el menú Archivo, hacemos clic en Guardar todo.
El siguiente paso es agregar una interfaz de usuario y un código que utilice la clase Persons.
Agregaremos cuadros de texto donde el usuario especificará los valores para cada una de las propiedades (excepto la propiedad de sólo lectura "Age"), una casilla para el campo "Married" y botones para probar cada uno de los métodos públicos.
Para probar la clase Persons:
En el Explorador de soluciones, seleccionamos Form1 y, en el menú Ver, hacemos clic en Diseñador.
En el Cuadro de herramientas, arrastramos cuatro controles TextBox, un control CheckBox y dos controles Button al formulario.
135
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Seleccionamos el primer control Button y, a continuación, en la ventana Propiedades establecemos la propiedad Text en Update.
Seleccionamos el segundo control Button y en la ventana Propiedades establecemos la propiedad Text en Full Name.
Hacemos doble clic en el primer botón (Update) para abrir el Editor de código y en el controlador de eventos Button1_Click, agregamos el siguiente código:
With person1 .FirstName = Textbox1.Text .MiddleName = Textbox2.Text .LastName = Textbox3.Text .BirthYear = Textbox4.Text .Married = CheckBox1.Checked End With
En el controlador de eventos Button2_Click, agregamos lo siguiente:
MsgBox(person1.NombreCompleto) MsgBox(CStr(person1.Edad) & " años") If person1.Casado = True Then MsgBox(person1.PrimerNombre & " es casado") Else MsgBox(person1.Primernombre & " es soltero") End If
Presionamos F5 para ejecutar el proyecto y mostrar el formulario:
-En el primer cuadro de texto, escribimos nuestro nombre.
-En el segundo cuadro de texto, escribimos nuestro segundo nombre.
-En el tercer cuadro de texto, escribimos nuestro apellido.
-En el cuarto cuadro de texto, escribimos el año de nuestro nacimiento con
cuatro dígitos (por ejemplo, 1983).
-Activamos la casilla de si estamos casados/as.
136
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Hacemos clic en el botón "Update" para establecer las propiedades de la clase y clic en el botón "Full Name".
Se muestran tres cuadros de mensaje. Estos cuadros de mensaje muestran su nombre completo, edad y estado civil.
En el menú Archivo, hacemos clic en Guardar todo.
6.7.-Cómo utilizar los constructores
Introducción
En Visual Basic .NET, la inicialización de nuevos objetos se controla utilizando
constructores. Para crear un constructor para una clase, se crea un procedimiento
denominado Sub New en cualquier lugar de la definición de la clase.
Características de Sub New
El constructor Sub New tiene las siguientes características:
El código del bloque Sub New siempre se ejecutará antes de cualquier otro código de
una clase.
137
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
El constructor Sub New solo se ejecutará una vez, cuando se cree un objeto.
Ejemplo de Sub New
El siguiente ejemplo muestra cómo utilizar el constructor Sub New:
Public Sub New( )
' Perform simple inicialización
intValue = 1
End Sub
La siguiente línea de código crea un objeto desde una clase denominada BankAccount,
ya definida en la aplicación.
Dim myAccount As New BankAccount( )
Podemos sobrecargar New y crear tantos constructores de clases como sean necesarios.
Esto resulta útil si deseamos inicializar nuestro objeto cuando lo creemos.
Sobrecarga de constructores
Podemos sobrecargar constructores del mismo modo que se sobrecarga cualquier otro
método de una clase. No obstante, no podemos utilizar la palabra clave Overloads
cuando sobrecargamos constructores. El siguiente ejemplo muestra cómo sobrecargar
New y crear múltiples constructores de clase:
Class BankAccount
Private balance as Double
Sub New( )
' Initialize balance
balance = 0.0
End Sub
Sub New(ByVal amount As Double)
balance = amount
End Sub
End Class
Uno de los constructores del ejemplo anterior toma un parámetro. Si estamos creando
un objeto desde tal clase, podemos incluir sus parámetros en la declaración. El siguiente
ejemplo muestra cómo invocar el método New que toma un parámetro.
Dim myAccount As New BankAccount(120.00)
Para escribir nuestros propios constructores de clase, crearemos un método con el
nombre New( ), como vemos en el Código. En dicho ejemplo, al instanciarse un
objeto de la clase Empleado, se asignará a una de sus propiedades la fecha actual.
Interfase grafica cliente
Public class form1…..
Private Sub Botton_Click … Dim loEmp As Empleado
loEmp = New Empleado()
138
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
MsgBox("El objeto se ha creado el día "& loEmp.FechaCrea)
End Sub
End class
Public Class Empleado Private mdtFechaCrea As Date
Public Property FechaCrea() As Date Get
Return mdtFechaCrea
End Get Set(ByVal Value As Date)
mdtFechaCrea = Value End Set
End Property
' método constructor Public Sub New()
' asignamos un valor inicial a una variable de propiedad Me.FechaCrea = Now
End Sub End Class
Al igual que ocurre en un método normal, New( ) admite parámetros; esto nos
sirve para asignar valores de inicio al objeto en el momento de su instanciación.
La denominación para este tipo de métodos es constructor parametrizado. El
Código nos muestra una variación del fuente anterior, utilizando un constructor de
este tipo.
Interfase grafica cliente
Public class form1…..
Private Sub Botton_Click …
Dim loEmp As Empleado
loEmp = New Empleado("5/7/2002")
MsgBox("El objeto se ha creado el día "& loEmp.FechaCrea)
' este es otro modo de instanciar
' un objeto con un constructor parametrizado
Dim loEmp2 As New Empleado("08/4/2002")
End Sub
End Class
Public Class Empleado
Private mdtFechaCrea
Public Property FechaCrea() As Date
Get
Return mdtFechaCrea
End Get
Set(ByVal Value As Date)
139
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
mdtFechaCrea = Value
End Set
End Property
' método constructor con parámetro
Public Sub New(ByVal ldtFecha As Date)
' asignamos el valor del parámetro a una variable de propiedad
Me.FechaCrea = ldtFecha
End Sub
End Class
Combinando las características de métodos constructores junto a las de sobrecarga, podemos crear un conjunto de constructores sobrecargados para la clase.
Public Class Empleado
Public psNombre
Public psApellidos
Public psCiudad
Private mdtFechaCre
' en este constructor sin parámetros, asignamos la fecha actual
Public Sub New()
mdtFechaCrea = Now()
End Sub
' en este constructor, asignamos valores a todos los campos de la clase
Public Sub New(ByVal lsNombre As String, ByVal lsApellidos As String, ByVal
lsCiudad As String)
psNombre = lsNombre
psApellidos = lsApellidos
psCiudad = lsCiudad
End Sub
End Class
6.8.-Cómo utilizar los destructores
Introducción
En Visual Basic .NET, podemos controlar qué ocurre durante la destrucción de objetos
utilizando procedimientos denominados destructores.
Finalize y Dispose
El sistema invoca al destructor Finalize antes de liberar el objeto. Puede utilizarse para
limpiar recursos abiertos, como conexiones a bases de datos, o para liberar otros
140
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
recursos. Sin embargo, existe una demora entre el momento en que un objeto pierde su
alcance y el momento en que se invoca al destructor Finalize.
La ejecución de Sub Finalize provoca una ligera pérdida en el rendimiento, por ello
únicamente debería definirse un método Sub Finalize cuando sea necesario liberar
objetos explícitamente.
Visual Basic .NET permite un segundo tipo de destructor, denominado Dispose, que
puede ser invocado explícitamente en cualquier momento para liberar recursos de forma
inmediata. Dispose no se incluye en el ámbito de este curso. Si desea más información
sobre Dispose, puede consultar “Duración de los objetos: cómo se crean y destruyen”
en la documentación de Visual Studio .NET.
Nota
Ejemplo de Sub Finalize
El siguiente ejemplo muestra cómo utilizar el destructor Finalize:
Protected Overrides Sub Finalize( )
' Can close connections or other resources
conn.Close
End Sub
Protected es un modificador de acceso que establece el nivel de accesibilidad.
6.9.-Cómo utilizar miembros de datos compartidos
Introducción
En Visual Basic .NET, los miembros de datos compartidos pueden utilizarse para
permitir que múltiples instancias de una clase hagan referencia a una única variable a
nivel de clase.
Sintaxis
Utilizaremos la siguiente sintaxis para declarar miembros de datos compartidos:
NiveldeAcceso Shared MiembrodeDatos As TipodeDatos
Niveles de acceso
Los miembros de datos compartidos están directamente enlazados a la clase, y podemos
declararlos como públicos o privados. Si declaramos los miembros de datos como
públicos, estarán accesibles para cualquier código que pueda acceder a la clase. Si
declaramos los miembros de datos como privados, proporcionaremos propiedades
compartidas públicas para acceder a la propiedad compartida privada.
Ejemplo
El siguiente ejemplo muestra cómo crear una clase de cuenta de ahorro
(SavingsAccount) que utilice un miembro de datos compartido público para mantener
los tipos de interés para una cuenta de ahorro:
141
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Class SavingsAccount
Public Shared InterestRate As Double
Public Function CalculateInterest( ) As Double
...
End Function
End Class
El valor del miembro de datos InterestRate de la clase SavingsAccount puede
establecerse globalmente con independencia del número de instancias de la clase que
estén en uso. El valor se utiliza para calcular el interés del saldo actual.
Invocar miembros de datos compartidos desde un cliente
Después de crear una clase que utilice miembros de datos compartidos públicos,
podemos invocar los miembros de datos de esa clase desde una aplicación cliente. El
siguiente código muestra cómo invocar la clase SavingsAccount y sus miembros de
datos desde una aplicación cliente:
Sub Test( )
SavingsAccount.InterestRate = 0.03
Dim myAccount As New SavingsAccount( )
Dim yourAccount As New SavingsAccount( )
MessageBox.Show(myAccount.CalculateInterest( ))
MessageBox.Show(yourAccount.CalculateInterest( ))
End Sub
En el examen de este código, se observa lo siguiente:
InterestRate puede establecerse antes y después de la creación de cualquier instancia de
la clase SavingsAccount.
Cualquier modificación a InterestRate se aplicará a todas las instancias de la clase
SavingsAccount.
Propiedades compartidas
También pueden crearse propiedades compartidas en las clases. El siguiente ejemplo
muestra cómo declarar una propiedad compartida denominada Rate en la clase
SavingsAccount:
Class SavingsAccount
Private Shared interestRate As Double
Shared Property Rate( ) As Double
Get
Return interestRate
End Get
Set(ByVal Value As Double)
interestRate = Value
End Set
End Property
End Class
142
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Invocar propiedades compartidas desde un cliente
Una vez declarada la propiedad compartida Rate, puede utilizarse en una aplicación
cliente en lugar de acceder directamente al miembro de datos compartido interestRate.
Podemos invocar una propiedad compartida cualificándola con el nombre de clase o con
el nombre de variable de una instancia específica de la clase.
El siguiente código muestra cómo invocar una propiedad compartida cualificándola con
el nombre de la clase:
SavingsAccount.Rate = 0.03
El siguiente código muestra cómo invocar una propiedad compartida utilizando el
nombre de variable de una instancia específica de la clase:
6.10.-Cómo utilizar los métodos compartidos
Introducción
Podemos utilizar los miembros de procedimiento compartidos para diseñar funciones
que pueden ser invocadas sin crear una instancia de la clase. Los procedimientos
compartidos son métodos de una clase que no están asociados a una instancia específica
de una clase. Los miembros de procedimiento compartidos únicamente pueden acceder
a datos marcados con la palabra clave Shared. Por ejemplo, un método compartido no
puede hacer referencia a un miembro de la instancia de una clase.
Ejemplo del uso de un miembro de procedimiento compartido
El siguiente ejemplo muestra cómo una función utilizada habitualmente, como
GetComputerName, puede crearse como un miembro de procedimiento compartido de
forma que una aplicación cliente puede utilizarla fácilmente. El cliente únicamente
necesita hacer referencia al método prefijado por el nombre de la clase, ya que no se
requiere ninguna instancia de la clase.
' TestClass code
Public Shared Function GetComputerName( ) As String
...
End Function
' Client code
MessageBox.Show(TestClass.GetComputerName( ))
Observaremos también que, en el código anterior, Show es un método compartido de la
clase MessageBox.
143
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
6.11.-¿Qué es el polimorfismo?
Introducción
La mayoría de sistemas de programación orientada a objetos proporcionan
polimorfismo mediante herencia. El polimorfismo basado en herencia implica la
definición de métodos en una clase base y sobrecargarlos con nuevas implementaciones
en clases derivadas.
Definición
Polimorfismo hace referencia a la capacidad de definir múltiples clases con diferentes
funcionalidades pero con métodos o propiedades de nombres idénticos que pueden
utilizarse de forma intercambiable por el código cliente en tiempo de ejecución. El
nombre del método reside en la clase base. Las implementaciones de métodos residen
en las clases derivadas. Para gestionar esto, únicamente puede declararse en la clase
base el nombre del método (no el código que proporciona la funcionalidad del método).
Ejemplo de polimorfismo
Supongamos que definimos una clase denominada BaseTax que proporciona
funcionalidad básica para calcular el impuesto sobre las ventas de un estado. Las clases
derivadas de BaseTax, como CountyTax o CityTax, podrían implementar métodos
como CalculateTax.
Polimorfismo hace referencia al hecho de que la implementación del método
CalculateTax podría ser distinta en cada una de las clases derivadas. Por ejemplo, el
tipo impositivo de un condado (county tax rate) podría ser distinto del tipo impositivo
de una ciudad (city tax rate). Las clases que hereden de BaseTax tendrán un método
CalculateTax, pero el modo como se calcule realmente el impuesto podría variar en
cada una de las clases derivadas.
Sobrecarga de métodos o polimorfismo, en una misma clase
La sobrecarga de métodos, es una técnica que consiste en crear varios métodos con
idéntico nombre dentro de la misma clase, distinguiéndose entre sí por su lista de
parámetros. Analicemos el siguiente ejemplo:
Interfase grafica cliente
Public class form1…..
Private Sub Botton_Click …
Dim loEmpleado As New Empleado()
Dim ldbResultadoIncent As Double
loEmpleado.Salario = 1020.82
'llamada al primer método sobrecargado
loEmpleado.Sueldo()
144
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
'llamada al segundo método sobrecargado
MsgBox("El sueldo se transferirá el día " & loEmpleado.Sueldo(29))
'llamada al tercer método sobrecargado
ldbResultadoIncent = loEmpleado.Sueldo(50.75, "Extras")
MsgBox(“El incentivo a pagar será " & ldbResultadoIncent)
End Sub
End Class
Public Class Empleado
Private mdbSalario As Double
Public Property Salario() As Double
Get
Return mdbSalario
End Get
Set(ByVal Value As Double)
mdbSalario = Value
End Set
End Property
' Métodos sobrecargados
Public Overloads Sub Sueldo()
' aquí mostramos en consola el importe del sueldo formateado
MsgBox("El sueldo es " & Format(Me.Salario, "#,#.##"))
End Sub
Public Overloads Function Sueldo(ByVal liDia As Integer) As String
' Aquí mostramos la fecha del mes actual en la que se
' realizará la transferencia del sueldo al banco del empleado
Dim ldtFechaActual As Date
Dim lsFechaCobro As String
ldtFechaActual = Now()
lsFechaCobro = CStr(liDia) & "/" & _
CStr(Month(ldtFechaActual)) & "/" & _
CStr(Year(ldtFechaActual))
Return lsFechaCobro
End Function
Public Overloads Function Sueldo(ByVal ldbImporteIncentivo As Double,ByVal
lsTipoIncentivo As String) As Double
' aquí calculamos la cantidad de incentivo que se añadirá al
' sueldo del empleado,en función del tipo de incentivo
Dim ldbIncentivo As Double
145
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
' según el tipo de incentivo, se descuenta un importe de la cantidad del
‘ incentivo
Select Case lsTipoIncentivo
Case "Viajes"
ldbIncentivo = ldbImporteIncentivo - 30
Case "Extras"
ldbIncentivo = ldbImporteIncentivo - 15
End Select
Return ldbIncentivo
End Function
End Class
Métodos sobrecargados
Para crear un método sobrecargado, agregamos dos o más procedimientos Sub o Function a la clase, cada uno con el mismo nombre.
En las declaraciones de procedimiento, el conjunto de argumentos para cada procedimiento debe ser distinto o se producirá un error.
El siguiente ejemplo muestra un método con dos sobrecargas, una que acepta una String y la otra que acepta un Integer como argumentos.
Public Sub TestFunction(ByVal input As String) MsgBox(input) End Sub Public Sub TestFunction(ByVal input As Integer) MsgBox(CStr(input)) End Sub
Si se debe llamar a este método desde el código y pesarle una cadena, se ejecutaría la primera sobrecarga y un cuadro de mensaje mostraría la cadena; si se le pasó un número, se ejecutaría la segunda sobrecarga y el número se convertiría en una cadena y aparecería en el cuadro de mensaje.
Podemos crear tantas sobrecargas como sean necesarias y cada una de ellas puede contener un número diferente de argumentos.
En la clase Persons, agregaremos un método con dos sobrecargas para devolver la inicial del segundo nombre de una persona; una sólo con la inicial y la otra con la inicial seguida por un punto.
Probar los métodos sobrecargados en la clase Persons
Abrimos el proyecto Persons que creamos en la secciones anteriores. En el Explorador de soluciones, seleccionamos Persons.vb y, en el menú Ver,
elegimos Código.
146
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Agregamos el siguiente código debajo de los métodos existentes.
Public Function MiddleInitial() As String MiddleInitial = Left$(middleNameValue, 1) End Function Public Function MiddleInitial(ByVal period As Boolean) As String MiddleInitial = Left$(middleNameValue, 1) & "." End Function
En el Explorador de soluciones, seleccionamos Form1 y, en el menú Ver, hacemos clic en Diseñador.
En el Cuadro de herramientas, arrastramos dos controles más de Button al formulario.
Seleccionamos el tercer control Button y en la ventana Propiedades establecemos su propiedad Text en With.
Seleccionamos el cuarto control Button y en la ventana Propiedades establecemos su propiedad Text en Without.
Hacemos doble clic en el primer botón (With) para abrir el Editor de código y escribimos el siguiente código en el controlador de eventos Button3_Click.
En el controlador de eventos Button4_Click, agregamos el siguiente código.
MsgBox(person1.FirstName & " " & person1.MiddleInitial & _ " " & person1.LastName)
Presionamos F5 para ejecutar el proyecto y mostrar el formulario.
-En el primer cuadro de texto, escribimos nuestro nombre.
-En el segundo cuadro de texto, escribimos nuestro segundo apellido.
-En el tercer cuadro de texto, escribimos nuestro tercer apellido.
-En el cuarto cuadro de texto, escribimos el año de nuestro nacimiento con
cuatro dígitos (por ejemplo, 1983).
-Activamos la casilla si está casado/a.
147
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Hacemos clic en el botón Actualizar para establecer las propiedades de la clase y hacemos clic en el botón With.
Se abrirá un cuadro de mensaje. Muestra nuestro nombre con un punto tras la inicial del primer apellido.
Hacemos clic en el botón Without.
Se abrirá un cuadro de mensaje. Muestra nuestro nombre sin el punto tras la inicial del primer apellido.
148
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
En el menú Archivo, hacemos clic en Guardar todo.
6.12.-Probar controladores de eventos
Si deseamos escribir código que responda a un evento (o que controle un evento), debemos asociar ese evento a un controlador de eventos. Podemos hacerlo mediante la instrucción Handles o Add Handler.
La instrucción Add Handler permite asociar los eventos a los controladores en tiempo de ejecución, mientras que la instrucción Handles sólo asocia los eventos a los controladores en tiempo de compilación. La instrucción Handles se puede agregar al final de cualquier subrutina que tenga la misma firma que el evento.
Por ejemplo, antes, agregamos un evento denominado "AgeCalculated" que toma un parámetro de tipo "Integer". La subrutina que crea para controlar el evento también debe tomar un parámetro Integer, como se observa en el código siguiente.
Private Sub person1_AgeCalculated(ByVal Age As Integer) _ Handles person1.AgeCalculated
El objeto person1 se debe crear con la instrucción WithEvents para que se pueda tener acceso al evento AgeCalculated. Al usar la instrucción Add Handler, puede asociar dinámicamente los eventos a controladores en tiempo de ejecución.
Probamos el controlador de eventos en la clase Person
En el Explorador de soluciones, seleccionamos Form1 y, en el menú Ver, hacemos clic en Código.
Agregamos la instrucción WithEvents antes de la declaración person1, como se muestra en el código siguiente:
WithEvents person1 As New Persons.Persons
149
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Agregamos el procedimiento siguiente a Form1. Este código comprueba la edad calculada y muestra un mensaje basado en el resultado.
Private Sub person1_AgeCalculated(ByVal Age As Integer) _ Handles person1.AgeCalculated If Age > 18 Then MsgBox("You have been over 18 for " & Age - 18 _ & " years.") Else MsgBox("You will be 18 in " & 18 - Age & " years") End If End Sub
Presionamos F5 para ejecutar el proyecto y mostrar el formulario.
-En el primer cuadro de texto, escribimos nuestro nombre.
-En el segundo cuadro de texto, escribimos nuestro segundo apellido.
-En el tercer cuadro de texto, escribimos nuestro tercer apellido.
-En el cuarto cuadro de texto, escribimos el año de nuestro nacimiento con
cuatro dígitos (por ejemplo, 1983).
-Activamos la casilla si está casado/a.
Hacemos clic en el botón Actualizar para establecer las propiedades de la clase y haga clic en el botón Full Name.
Un cuadro de mensaje muestra su nombre completo. Si tiene más de 18 años, otro cuadro de mensaje muestra información sobre cuánto tiempo hace que cumplió los 18 años. Si tiene menos de 18 años, aparece un cuadro de mensaje que muestra información sobre cuánto tiempo queda hasta que cumpla los 18 años. A continuación, otro cuadro de mensaje muestra su edad.
150
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
En el menú Archivo, hacemos clic en Guardar todo.
6.13.- Herencia en Visual Basic NET
La Herencia especifica una relación “es un tipo de”
Múltiples clases comparten los mismos atributos y operaciones, permitiendo una eficaz
reutilización del código
Introducción
En la programación orientada a objetos, podemos compartir las características de una
clase base en otras clases derivadas de la clase base. Esto se denomina herencia.
Definición
Herencia es el concepto de reutilizar atributos y operaciones comunes de una clase base
en una clase derivada.
Cómo heredar de una clase
Una clase derivada hereda de una clase base
Pueden heredarse propiedades, métodos, miembros de datos, eventos y controladores de
eventos (dependiendo del ámbito)
Palabras clave
Inherits: hereda de una clase base
NotInheritable: no es heredable
MustInherit: no pueden crearse instancias de la clase; deben heredarse como una clase
base
Introducción
Persona
Cliente Empleado
Clase base
Clase Derivada
151
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
En Visual Basic .NET, la herencia puede utilizarse para derivar una clase de una clase
existente. La clase derivada puede heredar todas las propiedades, métodos, miembros de
datos, eventos y controladores de eventos de la clase base, facilitando la reutilización de
la clase base por toda la aplicación.
La palabra clave Inherits La palabra clave Inherits se utiliza para definir una clase derivada que heredará de una
clase base existente.
Ejemplo: El siguiente ejemplo muestra cómo utilizar la palabra clave Inherits:
Public Class CheckingAccount
Inherits BankAccount
Private Sub ProcessCheck( )
' Add code to process a check drawn on this account
End Sub
End Class
Observacion Podemos utilizar la palabra clave MyBase para invocar métodos en una
clase base cuando invalidan métodos en una clase derivada. También podemos utilizar
la palabra clave MyBase para invocar el constructor y el destructor de la clase base en
nuestra clase derivada.
Observemos el siguiente ejemplo:
'Crear clase derivada en dos líneas
Public Class Administrativo
Inherits Empleado
' Crear clase derivada en la misma línea
Public Class Administrativo : Inherits Empleado
La palabra clave NotInheritable
La palabra clave NotInheritable se utiliza para definir una clase que no puede utilizarse
como clase base para herencia. Si otra clase intenta heredar de esta clase, se generará un
error de compilación.
Ejemplo: El siguiente ejemplo muestra cómo utilizar la palabra clave NotInheritable:
Public NotInheritable Class TestClass
...
End Class
Public Class DerivedClass
' The following line generates a compiler error
Inherits TestClass
152
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
...
End Class
La palabra clave MustInherit La palabra clave MustInherit se utiliza para definir clases que no están pensados para
ser utilizados directamente como objetos instanciados. La clase resultante debe ser
heredada como una clase base para utilizarla en el objeto de una clase derivada
instanciada.
Ejemplo: El siguiente ejemplo muestra cómo utilizar la palabra clave MustInherit:
Public MustInherit Class BaseClass
...
End Class
...
Si el código cliente intenta crear una instancia de este tipo de clase, se generará un error
de compilación, como se muestra en el siguiente ejemplo:
' Client code
' The following line generates a compiler error
Dim x As New BaseClass( )
La palabra clave Protected Utilizamos el acceso Protected para limitar el ámbito de una propiedad, método,
miembro de datos, evento o controlador de eventos a la clase que los define y cualquier
clase derivada basada en esa clase base.
Ejemplo
El siguiente ejemplo muestra cómo utilizar la palabra clave Protected:
Public Class BaseClass
' Accessible anywhere
Public counter As Integer
' Accessible only in this class or a derived class
Protected name As String
...
End Class
Generar una clase a partir de una clase existente: Herencia de clases
Ahora veremos cómo utilizar la herencia de clases para crear una clase basada en una
clase existente.
Muchos objetos de la vida real tienen atributos y comportamientos en común, por
ejemplo, todos los coches tienen ruedas y motores, y pueden avanzar y detenerse. Sin
embargo, algunos automóviles tienen atributos que no son comunes, por ejemplo, un
153
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
descapotable tiene una parte superior que se puede subir/bajar electrónica o
manualmente.
Si se creó un objeto para representar un automóvil, se pueden incluir propiedades y
métodos para todos los atributos y comportamientos comunes, pero no se podrían
agregar atributos como la cubierta de un descapotable, puesto que dicho atributo no
es generalizable a todos los automóviles.
Mediante el uso de la herencia, se puede crear una clase "descapotable" que deriva de
la clase "automóvil". Ésta hereda todos los atributos de la clase automóvil y puede
agregar los atributos y comportamientos que son únicos de un auto descapotable.
Heredar a partir de una clase existente
La instrucción Inherits se utiliza para declarar una nueva clase, denominada clase derivada, basada en una clase existente conocida como clase base. Las clases derivadas heredan todas las propiedades, los métodos, los eventos, los campos y las constantes definidos en la clase base.
El siguiente código muestra la declaración de una clase derivada.
Class DerivedClass Inherits BaseClass … End Class
Se pueden crear instancias de la nueva clase DerivedClass, se puede tener acceso a sus propiedades y métodos como BaseClass y se pueden agregar nuevas propiedades y métodos que son específicos de la nueva clase. Para ver un ejemplo, nos fijaremos en la clase Persons que tenemos creada.
Supongamos que deseamos tener una clase que represente jugadores de béisbol: los jugadores del béisbol tienen todos los atributos definidos en la clase Persons, pero también tienen atributos únicos, como su número y posición. En lugar de agregar esas propiedades a la clase Persons, se creará una nueva clase derivada que se hereda de Persons, a la que se agregaran las nuevas propiedades.
Para crear una clase derivada de la clase Persons:
Abrimos el proyecto Persons que llevamos todo el tutorial usando. En el Explorador de soluciones, seleccionamos el nodo del proyecto Persons. En el menú Proyecto, elegimos Agregar clase.
154
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
En el cuadro de diálogo Agregar nuevo elemento, escribimos Players en el cuadro Nombre, a continuación, hacemos clic en Agregar.
Se agregará un nuevo módulo de clase al proyecto.
En el Editor de código, agregamos lo siguiente justo debajo de la línea Public
Class Players.
Inherits Persons
Agregamos también el siguiente código para definir las dos nuevas
propiedades.
Private numberValue As Integer Private positionValue As String Public Property Number() As Integer Get Number = numberValue End Get Set(ByVal value As Integer)
155
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
numberValue = value End Set End Property Public Property Position() As String Get Position = positionValue End Get Set(ByVal value As String) positionValue = value End Set End Property
En el menú Archivo, hacemos clic en Guardar todo.
Probar la clase Players
Hemos creado una clase Players, derivada de la clase Persons.Ahora haremos una nueva aplicación para probar la clase Players.
Para crear un proyecto de prueba para la clase:
1. En el menú Archivo, elegimos Agregar y, a continuación, hacemos clic en Nuevo proyecto.
2. En el cuadro de diálogo Agregar nuevo proyecto, en el panel Plantillas, seleccionamos una Aplicación de Windows Forms.
3. En el cuadro Nombre, escribimos PlayerTest y hacemos clic en Aceptar.
4. Se agregará un nuevo proyecto de Windows Forms al Explorador de soluciones y aparecerá un nuevo formulario.
156
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
5. En el Explorador de soluciones, seleccionamos el proyecto PlayerTest y, en el menú Proyecto, hacemos clic en Establecer como proyecto de inicio.
6. En el Explorador de soluciones, seleccionamos el proyecto PlayerTest y, en el menú Proyecto, haga clic en Agregar referencia.
7. Se abrirá el cuadro de diálogo Agregar referencia. 8. Hacemos clic en la ficha Proyectos, elegimos Persons y hacemos clic en Aceptar.
9. Hacemos doble clic en el formulario para abrir el Editor de código y escribimos la siguiente declaración justo debajo de la línea Public Class Form1.
Dim player1 As New Persons.Players Dim player2 As New Persons.Players
Esto declara dos nuevas instancias de la clase Players.
10. En el menú Archivo, hacemos clic en Guardar todo.
Para probar la clase derivada:
1. En el Explorador de soluciones, seleccionamos Form1 en el proyecto PlayerTest y, a continuación, en el menú Ver, hacemos clic en Código.
157
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
2. En el Editor de código, agregamos el siguiente código al procedimiento de evento Form1_Load.
With player1
.FirstName = "Wyrm"
.LastName = "Garcia"
.Number = 13
.Position = "Shortstop"
End With
With player2
.FirstName = "Joe"
.LastName = "Black"
.Number = 51
.Position = "Catcher"
End With
3. En el Explorador de soluciones, seleccionamos Form1 en el proyecto PlayerTest y, a continuación, en el menú Ver, hacemos clic en Diseñador.
158
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
4. En el Cuadro de herramientas, arrastramos dos controles Button al formulario.
5. Seleccionamos el primer control Button y en la ventana Propiedades establecemos su propiedad Text en At Bat.
6. Seleccionamos el segundo control Button y en la ventana Propiedades establecemos su propiedad Text en On Deck.
7. Hacemos doble clic en el primer botón (At Bat) para abrir el Editor de código y escribimos el siguiente código en el controlador de eventos Button1_Click.
MsgBox(player1.Position & " " & player1.FullName & ", #" & CStr(player1.Number) & " is now at bat.")
Observamos que estamos utilizando el método FullName que se heredó de la clase base Persons.
8. En el controlador de eventos Button2_Click, agregamos el siguiente código.
MsgBox(player2.Position & " " & player2.FullName & ", #" & CStr(player2.Number) & " is on deck.")
9. Presionamos F5 para ejecutar el programa. Hacemos clic en cada botón para ver los resultados.
Clic al Boton1(At Bat):
159
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Clic al Boton2 (on Deck):
10. En el menú Archivo, elegimos Guardar todo.
Hemos visto, qué son y cómo crear clases, agregarle propiedades, métodos y eventos, las hemos heredado, etc. la mejor forma de aprender y de que las cosas se entiendan, es haciéndolo uno mismo...
160
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
7.- Impresión en Visual Basic .NET
Introducción
Muchos de los usuarios de Visual Basic 6 que han migrado a .NET han sufrido (incluso están sufriendo) la carencia de este "nuevo" entorno de programación de un objeto que les permita imprimir de forma tan fácil como lo era el objeto Printer o de una colección que les permita saber las impresoras disponibles en el sistema. En este artículo explicaremos cómo imprimir en .NET y comprobaremos que aunque parezca complicado, a la larga, imprimir en .NET es igual o más fácil que con VB6, aunque tratándose de un lenguaje orientado a objetos, debemos cambiar un poco el chip.
Los precedentes
Lo primero que debemos tener en cuenta es que todo lo que queramos hacer en .NET debemos hacerlo usando las clases que este entorno nos ofrece y el tema de imprimir no es una excepción.
En Visual Basic 6 solamente disponíamos del objeto Printer, que era el que realmente nos permitía imprimir, de la colección Printers, la cual podíamos usar para saber las impresoras que teníamos disponibles, además del control para diálogos comunes, el cual nos permitía seleccionar y configurar la impresora que queríamos usar, además de permitirnos indicar el número de páginas a imprimir, etc., aunque no siempre funcionara como a nosotros nos hubiera gustado y en ocasiones tuviésemos que acudir a las funciones del API de Windows si realmente queríamos hacer algo verdaderamente práctico.
En .NET ha cambiado un poco la forma de hacer todo lo que hacíamos en VB6, ya no existen "objetos" que nos permitan imprimir ni colecciones que nos permitan saber las impresoras disponibles, bueno, un poco sí, pero como veremos de una forma más ordenada y algo diferente. Esa diferencia es la que a muchos les ha causado desesperación e incluso les ha llevado a un consumo excesivo de Aspirinas. En los siguientes puntos veremos que nuestra vida puede ser más soportable e incluso más fácil si aprendemos a manejar las clases de .NET que nos permiten imprimir y configurar las opciones de impresión.
7.1.-La solución: Cómo imprimir en .NET
Básicamente para imprimir en .NET solamente necesitamos una clase: PrintDocument la cual está definida en el espacio de nombres System.Drawing.Printing. Con esta clase tenemos todo lo necesario para imprimir (en la impresora predeterminada) cualquier tipo de documento.
Simplemente necesitamos llamar al método Print y asunto arreglado. Seguramente el lector se preguntará que si esto es así, ¿dónde está el problema? Problema, lo que se dice problema, realmente no hay ninguno, lo que ocurre es que esta clase, particularmente el método Print, se utiliza sin tener que indicar qué es lo que
161
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
queremos imprimir, y aquí es donde podría estar ese problema. El método Print de la clase PrintDocument lo que realmente hace es "despertar a la bestia", es decir, dar las instrucciones pertinentes al motor de .NET para que se inicie el proceso de impresión, dicho proceso se lleva a cabo básicamente utilizando el evento PrintPage de la clase PrintDocument, en este evento es donde tendremos que hacer todo lo necesario para que se imprima lo que queramos imprimir.
Por tanto, para poder controlar lo que se va a imprimir, debemos escribir todo nuestro código en ese evento, el cual se produce para cada página que deba imprimirse; posiblemente este sea el punto problemático, al menos desde el punto de vista del programador de VB6, ya que antes para controlar lo que debía imprimirse simplemente usábamos el método Print del objeto Printer, (o de cualquier objeto del tipo Printer que hubiésemos obtenido de la colección Printers), al que le indicábamos qué es lo que debía imprimirse, aunque en VB6 éramos nosotros los que debíamos comprobar cuando cambiar de página, cuando imprimir la cabecera, etc.
En .NET todo esto se hace en un solo sitio: el evento PrintPage, por tanto podemos decir que en .NET es más fácil imprimir y sobre todo controlar cómo y dónde se imprime cada cosa, ya que, si lo simplificamos al máximo, todo se hace en un solo sitio: el evento PrintPage de la clase PrintDocument.
Para muestra, un botón
En el listado podemos ver un ejemplo de la forma más simple de imprimir en .NET, en este ejemplo mostramos la cadena "Hola, Mundo" en la parte superior de la página usando una fuente Arial de 24 puntos en negrita.
Private Sub btnImprimirSimple_Click(ByVal sender As Object, _ ByVal e As EventArgs)Handles btnImprimirSimple.Click ' ejemplo simple para imprimir en .NET ' Usamos una clase del tipo PrintDocument Dim printDoc As New PrintDocument ' asignamos el método de evento para cada página a imprimir AddHandler printDoc.PrintPage, AddressOf print_PrintPage ' indicamos que queremos imprimir printDoc.Print() End Sub Private Sub print_PrintPage(ByVal sender As Object, _ ByVal e As PrintPageEventArgs) 'Este evento se producirá cada vez que se imprima una nueva página ' imprimir HOLA MUNDO en Arial tamaño 24 y negrita ' imprimimos la cadena en el margen izquierdo Dim xPos As Single = e.MarginBounds.Left ' La fuente a usar Dim prFont As New Font("Arial", 24, FontStyle.Bold)
162
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
' la posición superior Dim yPos As Single = prFont.GetHeight(e.Graphics) ' imprimimos la cadena e.Graphics.DrawString("Hola, Mundo", prFont, Brushes.Black, xPos, yPos) ' indicamos que ya no hay nada más que imprimir ' (el valor predeterminado de esta propiedad es False) e.HasMorePages = False End Sub
Ejemplo simple de impresión
Como podemos comprobar el proceso es bien simple:
Primero tenemos el código usado para dar la orden de imprimir, (este código puede estar en el evento Click de un botón), en el que creamos un nuevo objeto del tipo PrintDocument al que asignamos el procedimiento de evento a usar cuando se vaya a imprimir cada página, cosa que ocurrirá después de llamar al método Print de esta clase.
En el evento PrintPage le indicamos a .NET que es lo que queremos imprimir, en nuestro caso sólo la cadena "Hola, Mundo", para imprimir dicho texto utilizamos el método DrawString del objeto Graphics, (una propiedad del segundo parámetro pasado al evento).
Esta simpleza es en parte porque tampoco hacemos demasiadas cosas en el código del evento PrintPage, aunque aquí mostramos algunas de las cosas necesarias, como por ejemplo indicar el tipo de fuente a usar para la impresión, la cual se puede cambiar en cada una de las líneas a imprimir (e incluso en distintas partes de esa línea), ya que cada línea se "dibuja" por medio del método DrawString del objeto Graphics obtenido del segundo parámetro pasado a este método.
Como vemos en DrawString debemos indicarle que es lo que queremos imprimir, con qué tipo de fuente y en qué posición. Por último indicaremos si quedan más páginas a imprimir, esto lo haremos asignado un valor verdadero o falso a la propiedad HasMorePages del objeto recibido como segundo parámetro del evento, si el valor asignado es True estaremos indicando que queremos seguir imprimiendo, por el contrario, asignando un valor False terminaremos la impresión, cosa que también ocurrirá si no le asignamos expresamente nada a esa propiedad.
7.2.-Configurar la impresión
Pero para ser claros esta no será la forma "habitual" de usar este evento, ya que en la mayoría de los casos imprimiremos más de una página y seguramente querremos asignar otros valores a la impresora, como los márgenes, el número de copias, el tamaño del papel, la orientación de la impresión (vertical o apaisada) e incluso, lo más importante, qué impresora usar.
163
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Todos estos valores los podremos indicar usando un objeto del tipo PrinterSettings, el cual, entre otras cosas, nos permite saber cuáles son las impresoras que tenemos disponibles en el equipo actual. Por tanto, lo habitual será que usemos un objeto de esta clase en conjunto con el de la clase principal para imprimir: PrintDocument.
Seleccionar la impresora a usar
Otra de las tareas que seguramente nos veremos en la necesidad de ofrecer a los usuarios de nuestras aplicaciones es que puedan seleccionar de una manera fácil qué impresora usar y darles la posibilidad de que ajusten sus preferencias de impresión.
Todo esto lo podríamos hacer manualmente creando un formulario que utilice un objeto del tipo PrinterSettings y que le ofrezca a los usuarios las opciones que creamos conveniente, pero para que todo sea, digamos, más homogéneo y no tengamos que reinventar la rueda, podemos hacer que toda esta configuración y selección de la impresora a usar la ofrezcamos mediante los mismos cuadros de diálogo que utiliza el resto de aplicaciones, los cuales se basan en los cuadros de diálogos comunes del sistema operativo, si esta es nuestra elección, nos resultará fácil, ya que podemos usar la clase PrintDialog.
Con un objeto de esta clase, tal como hemos comentado, podemos mostrar el mismo cuadro de diálogo que utilizan el resto de aplicaciones de Windows, con la ventaja añadida de que podemos configurar las opciones que se mostrarán, de forma que lo configuremos para que se adapte, en la medida de lo posible, a las preferencias de nuestra aplicación.
En breve veremos cuáles son las opciones que podemos usar para ajustar este cuadro de diálogo a nuestras preferencias o a la de nuestra aplicación.
7.3.-Las clases para imprimir en .NET
Como hemos comentado en los párrafos anteriores, existen varias clases que nos permitirán tanto imprimir como configurar la impresión. Todo esto es posible gracias a las clases que .NET Framework pone a nuestra disposición para poder realizar esta tarea.
Echando mano del comodín que los que nos dedicamos a escribir artículos o libros, tenemos que decir que en este artículo no disponemos del espacio suficiente para enumerar en detalle todas las clases, delegados y enumeraciones que tanto el espacio de nombres System.Drawing.Printing como System.Windows.Forms pone a nuestra disposición para realizar tareas relacionadas con la impresión, por tanto haremos una pequeña criba para mostrar solamente los tipos que desde nuestro punto de vista pueden resultarnos más útiles, particularmente porque serán los que utilicemos en la mayoría de los casos.
164
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
La clase PrintDocument
Esta es la clase elemental o principal si queremos imprimir en .NET, como hemos comentado anteriormente, de los miembros que esta clase ofrece principalmente usaremos tres:
El método Print es el que iniciará el proceso de impresión, haciendo que se produzcan los eventos necesarios para controlar lo que queremos imprimir.
El evento PrintPage, el cual se producirá cada vez que tengamos que imprimir una página. Dentro de este evento es donde haremos todo lo que tengamos que hacer para imprimir cada una de las páginas, desde aquí podemos controlar si quedan más páginas por imprimir, etc.
La propiedad PrinterSettings a la que podemos asignarle un objeto del mismo nombre en el que indicamos la impresora a usar y otros valores como el rango de página, el número de copias, el tamaño del papel, la orientación, etc.
Del resto de miembros de esta clase podemos destacar la propiedad DocumentName a la que podemos asignar el nombre del documento que estamos imprimiendo y que será el que se muestre en el estado de la impresión. También tenemos el evento QueryPageSettings el cual se produce justo antes del evento PrintPage y que nos permite asignar valores "particulares" a cada una de las páginas a imprimir antes de que se produzca el evento PrintPage.
La clase PrinterSettings
Tal y como hemos estado indicando en los párrafos anteriores, esta clase nos permite especificar características de impresión como la impresora a usar, el número de copias a imprimir, el rango de páginas, etc. Realmente no necesitamos indicar nada, al menos de forma explícita para usar un objeto de esta clase, ya que al crear una nueva instancia los valores predeterminados serán los que tengamos asignado en la impresora, valga la redundancia, predeterminada de nuestro sistema. Pero si queremos modificar esos valores, tendremos que asignarlos a las propiedades de esta clase, entre las que podemos destacar las siguientes:
Copies indica el número de copias a imprimir. FromPage indica la página a partir de la que queremos imprimir. MaximunPage indica el número máximo de copias que se pueden indicar. MinimunPage es el número mínimo de copias que podemos indicar. ToPage indica la página hasta la que queremos imprimir.
Tanto MaximunPage como MinimunPage se utilizarán para indicar los valores máximo y mínimo de las páginas disponibles y se usarán con una clase del tipo PrintDialog.
Del resto de propiedades también podemos destacar las colecciones:
InstalledPrinters es una propiedad compartida y por tanto podemos usarla sin necesidad de crear una instancia de la clase PrinterSettings, esta colección
165
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
devuelve un array de tipo String con el nombre de cada una de las impresoras instaladas en el sistema.
PaperSizes es una colección con elementos del tipo PaperSize que nos permite saber los tamaños de papel que la impresora soporta. Cada elemento del tipo PaperSize nos proporciona información sobre el tamaño (ancho y alto), el nombre y la "clase" de papel, que no es ni más que una enumeración del tipo PaperKind.
PrinterResolutions es una colección con elementos del tipo PrinterResolution, de forma que podamos averiguar las resoluciones (y calidades) permitidas por la impresora. Cada uno de estos elementos nos indicará tanto la resolución horizontal como la vertical, además de la calidad de impresión, especificada con uno de los valores de la enumeración PrinterResolutionKind, cuyos valores pueden ser: Custom, Draft, High, Low y Medium.
De los métodos, posiblemente el que más nos puede interesar es:
CreateMeasurementGraphics el cual nos permite conseguir un objeto del tipo Graphics con el cual podemos averiguar ciertas características de la impresora sin necesidad de tener que imprimir, ya que el objeto devuelto por este método es igual al que se incluye en la clase PrintPageEventArgs, usada como segundo parámetro en los eventos producidos por la clase PrintDocument.
Como regla general deberíamos tener una variable del tipo PrinterSettings para usarla como almacenamiento de las preferencias de impresión de nuestros usuarios, ya que esta clase se utiliza tanto con PrintDocument como con PrintDialog.
La clase PrintDialog
Esta clase nos servirá para que nuestros usuarios seleccionen la impresora a usar así como para que indiquen ciertas características relacionadas con la impresión, como la calidad del papel, el número de copias, etc., con la ventaja de que todo esto lo haremos usando el mismo cuadro de diálogo común incluido en Windows y que es el que la práctica totalidad de aplicaciones de este sistema operativo utilizarán, tal como podemos comprobar en la figura 1.
166
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Figura 1. El cuadro de diálogo para seleccionar la impresora
En la figura 1 podemos comprobar que hay ciertos elementos que puede que no nos interese mostrar o dejar habilitados, por ejemplo, si nuestra aplicación no permite imprimir el código seleccionado no tiene mucho significado ofrecerle la opción "Selección", (la figura está capturada de un Windows XP en inglés, por eso se muestran las opciones en inglés), lo mismo ocurre con el botón de ayuda o con las cajas de texto que permiten indicar el rango de páginas a imprimir. Todas estas características las podemos habilitar o deshabilitar mediante algunas de las propiedades de la clase PrintDialog, tales como: AllowPrintToFile, AllowSelection, AllowSomePages, PrintToFile, ShowHelp y ShowNetwork.
La ayuda del cuadro de diálogo de imprimir
Como curiosidad, decir que la propiedad ShowHelp nos permite indicar si se debe mostrar o no el botón de ayuda, (no la interrogación de la barra de títulos que siempre estará funcional), pero entre las propiedades de esta clase no tenemos ninguna a la que indicarle que ayuda se debe mostrar si pulsamos en ese botón, en lugar de eso, de lo que disponemos es de un evento: HelpRequest el cual se producirá cuando el usuario pulse en dicho botón, por tanto si queremos mostrar algún tipo de ayuda, tendremos que usar ese evento para mostrar la información que creamos conveniente para nuestro cuadro de diálogo.
Al igual que en el resto de cuadros de diálogos de .NET, tenemos el método ShowDialog que será el que nos permita mostrar el cuadro de diálogo y saber si el usuario ha pulsado en el botón OK (Aceptar) o Cancelar, para que de esta forma sepamos si debemos seguir con el proceso de impresión o no.
La propiedad PrinterSettings será la que nos permita saber lo que el usuario ha seleccionado, además de ser la que usemos para asignar los valores predeterminados o bien los que tengamos almacenado de ocasiones anteriores; tal como indicamos anteriormente, lo habitual será que tengamos una variable del tipo de esta propiedad
167
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
con las preferencias del usuario, por tanto antes de llamar al método ShowDialog deberíamos asignar a esta propiedad la variable que tengamos con las preferencias del usuario y si no se ha cancelado, debemos asignar nuevamente el resultado de dichas preferencias, tal como mostramos en el listado 2.
Private Function seleccionarImpresora() As Boolean Dim prtDialog As New PrintDialog If prtSettings Is Nothing Then prtSettings = New PrinterSettings End If With prtDialog .AllowPrintToFile = False .AllowSelection = False .AllowSomePages = False .PrintToFile = False .ShowHelp = False .ShowNetwork = True .PrinterSettings = prtSettings If .ShowDialog() = DialogResult.OK Then prtSettings = .PrinterSettings Else Return False End If End With Return True End Function
La clase PrintPreviewDialog
Esta clase nos permitirá mostrar una ventana con la vista preliminar del documento que queremos imprimir, de forma que los usuarios de nuestra aplicación pueden ver lo que se imprimirá. Debido a que esta clase al estar derivada de Form tiene todas las propiedades, métodos y eventos de cualquier formulario además de los relacionados con la previsualización del documento a imprimir, veamos solamente los dos miembros que nos interesarán más:
El método ShowDialog será el que se encargue de mostrar el formulario con la vista preliminar.
A la propiedad Document le asignaremos un objeto del tipo PrintDocument que será el que utilicemos para saber qué es lo que queremos imprimir.
168
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Tal como hemos resaltado en la nota, tanto el método Print de la clase PrintDocument como la clase PrintPreviewDialog utilizan los mismos eventos del objeto PrintDocument, por tanto podríamos usar un método genérico que sea el encargado de mostrar una vista preliminar de lo que queremos imprimir o de mandarlo a la impresora, de esta forma podemos usar de forma común las opciones ofrecidas al usuario, como por ejemplo permitir la selección de la impresora antes de imprimir, etc.
En el listado podemos ver cómo podría ser ese método genérico para elegir entre imprimir o previsualizar lo que deseamos imprimir.
Private Sub imprimir(ByVal esPreview As Boolean) ' imprimir o mostrar el PrintPreview If prtSettings Is Nothing Then prtSettings = New PrinterSettings End If If chkSelAntes.Checked Then If seleccionarImpresora() = False Then Return End If If prtDoc Is Nothing Then prtDoc = New System.Drawing.Printing.PrintDocument AddHandler prtDoc.PrintPage, AddressOf prt_PrintPage End If ' la línea actual lineaActual = 0 ' la configuración a usar en la impresión prtDoc.PrinterSettings = prtSettings If esPreview Then Dim prtPrev As New PrintPreviewDialog prtPrev.Document = prtDoc prtPrev.Text = "Previsualizar documento" prtPrev.ShowDialog()
NOTA: Por regla general deberíamos asignar a la propiedad Document de la clase PrintPreviewDialog el mismo objeto PrintDocument usado para imprimir, ya que la clase PrintPreviewDialog se encargará de que se produzcan los mismos eventos que si hubiésemos llamado al método Print del objeto PrintDocument asignado, de forma que lo que se muestre mediante este diálogo sea lo mismo que se imprima, que es al fin y al cabo lo que queremos conseguir.
169
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Else prtDoc.Print() End If End Sub
Tal como podemos ver en la figura, el formulario (o cuadro de diálogo) de previsualización nos permite seleccionar el número de página a mostrar, si queremos ver una o más páginas a un mismo tiempo, el porcentaje de ampliación e incluso imprimir lo que estamos viendo, todos estas características ya están incluidas en ese formulario.
El formulario de previsualización
La clase PrintPreviewControl
Si nuestra intención es crear nuestro propio formulario de previsualización, también podemos hacerlo si usamos el control PrintPreviewControl que es el que la clase PrintPreviewDialog utiliza, si bien todos los botones y opciones tendremos que crearlos nosotros, para ello podemos usar los miembros específicos de este control, tales como:
AutoZoom lo usaremos para que al cambiar el tamaño del control se cambie también la página mostrada.
Columns indica el número de páginas a mostrar cuando se elija la orientación horizontal (apaisada).
Document es donde asignaremos el objeto PrintDocument a imprimir. Rows indica el número de páginas a mostrar cuando elijamos la orientación
vertical. Zoom para indicar la ampliación con la que queremos mostrar los documentos. StartPageChanged en un evento que se producirá cada vez que cambiemos la
página de inicio (este evento nos servirá para crear un equivalente al NumericDropDown usado en la clase PrintPreviewDialog).
170
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Si también quisiéramos implementar un botón para imprimir, tendremos que manejar nosotros mismos la impresión, pero realmente resultaría fácil, ya que lo único que tendríamos que hacer es llamar al método Print del objeto PrintDocument asignado a la propiedad Document.
Como siempre la última palabra la tendremos nosotros y dependiendo de lo que queramos hacer usaremos una clase u otra.
7.4.- Conclusión: Imprimir en .NET es fácil
Tal como hemos podido comprobar, imprimir en .NET no es tan complicado como en un principio pudiera parecer, además de que tenemos valores añadidos que nos permiten un mayor control sobre la impresión y, especialmente, sobre las opciones que podemos ofrecer a los usuarios de nuestras aplicaciones, ya que como hemos visto, hacer algo como la presentación preliminar, que en otros lenguajes nos obligaría a escribir bastante código, es tan sencillo como crear un nuevo objeto en la memoria y asignar un par de propiedades.
Por supuesto, lo que no es totalmente sencillo ni automático es la presentación o impresión de los datos que necesitamos mostrar, al menos si queremos darle un toque, digamos, profesional a nuestra impresión, ya que seremos nosotros los que debamos "afinar" en la forma de mostrar esos resultados; pero de todas formas eso es algo que siempre nos tocará hacer, utilicemos el entorno de programación que utilicemos, la ventaja de usar lo que .NET nos ofrece es que tenemos ciertas posibilidades de hacerlo de una forma más o menos fácil y que de alguna forma nos facilita bastante la tarea, aunque para la mayoría de situaciones será más que suficiente e incluso podemos automatizar, principalmente porque podemos aprovechar las posibilidades que nos da la programación orientada a objetos de crear nuestras propias clases e implementar métodos de impresión que se adapten a los datos que tengamos que mostrar, ya que una de las claves de la POO es la abstracción y que mejor forma de abstracción que crear un método que se encargue de manejar los datos que la propia clase mantiene y que "sepa" cómo mostrar esos datos e incluso qué formato deben aplicarse a la hora de presentar esos datos por la impresora. Posiblemente tengamos que quemar unas cuantas neuronas más a la hora de "concebir" esa clase, pero a la larga ese esfuerzo habrá valido la pena ya que puede suponernos una forma de "olvidarnos" de esos pequeños detalles de ajustar cada una de las líneas que vamos a imprimir.
De seguro que el lector puede pensar que tampoco es necesario ese "esfuerzo" extra para imprimir una línea, y seguramente tenga razón, pero precisamente si cuando diseñamos nuestras clases para manejar datos tenemos en cuenta estos detalles, seguramente nos resultará más fácil realizar cambios en ocasiones futuras. Por ejemplo, si tenemos una clase en la que hay datos de cadena y de tipo numérico y queremos mostrar esos datos, la forma de tratar cada uno de esos datos será diferente, ya que con toda seguridad los datos numéricos querremos ajustarlos a la derecha y los de cadena a la izquierda, además de que si debemos recortar la
171
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
información que tenemos que mostrar, con total seguridad preferiremos "truncar" los datos de cadena antes que los numéricos.
En este tipo de situaciones si dejamos que el código de la clase sea el que decida estos truncamientos, (realmente el código de la clase no va a decidir nada, ya que tendremos que ser nosotros los que hagamos esa decisión), siempre será preferible que tener que hacerlo en el propio evento de impresión, sobre todo si ese mismo evento es el que usaremos para imprimir datos de diferentes tipos, que pueden proceder de diferentes clases, pero si las clases usadas para contener los datos están "preparadas" para imprimir el contenido de cada línea, entonces resultará tan sencillo como llamar a un método de cada una de esas clases... En el listado podemos ver cómo quedaría el evento PrintPage si hiciéramos algo de lo que acabamos de comentar.
' El evento usado mientras se imprime el documento Private Sub prt_PrintPage(ByVal sender As Object, ByVal e As PrintPageEventArgs) ' Este evento se produce cada vez que se va a imprimir una página Dim lineHeight As Single Dim yPos As Single = e.MarginBounds.Top Dim leftMargin As Single = e.MarginBounds.Left Dim printFont As System.Drawing.Font ' Asignar el tipo de letra printFont = prtFont lineHeight = printFont.GetHeight(e.Graphics) Dim fontTitulo As New Font("Arial", 20, FontStyle.Bold) e.Graphics.DrawString("Listado de " & Título, fontTitulo, _ Brushes.Black, leftMargin, yPos) yPos += fontTitulo.GetHeight(e.Graphics) ' imprimir la cabecera de la página yPos = Datos(0).CabeceraImpresión(e, printFont, yPos) ' imprimir cada una de las líneas de esta página Do yPos += lineHeight e.Graphics.DrawString(Datos(lineaActual).LineaImpresión, _ printFont, Brushes.Black, leftMargin, yPos) lineaActual += 1 Loop Until yPos >= e.MarginBounds.Bottom _ OrElse lineaActual >= Datos.Count If lineaActual < Datos.Count Then e.HasMorePages = True Else e.HasMorePages = False End If End Sub
172
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
7.5.-Hacer Crystal Report con DataSet en Visual Basic.NET
La mayoría de las veces que trabajamos con Visual Basic .Net y Crystal Report, solemos conectarnos a SQL Server u Oracle como fuente de datos, debido a que tienen integración con el IDE de Visual Studio, para facilitar la creación de los mismos.
Cuando hablamos de motores como PostgreSQL, MySQL, Firebird, Teradata y otros, no tenemos la integración del IDE con el servidor de base de datos, esto hace que no podamos crear tan sencillamente los reportes como los hacemos como con los otros motores, pero no lo hace imposible, sólo se debe seguir unos pasos distintos, que también sirve para los 2 primeros motores mencionados anteriormente.
Lo siguiente sirve en muchos casos para proyectos pequeños de la universidad, a pesar
de que utlizaré Visual Studio 2008 esto sirve muy bien para Visual Studio 2005
también, asi que comencemos:
1.- Procederé a crear un proyecto en Visual Basic 2008, con el Framework 2.0, y le
pondré de nombre EjemploReporteCrystal, obviamente si ya tienen el proyecto creado
no deben de hacerlo.
2.- Después lo que hacemos es insertar un DataSet de nuestra base de datos, si no sabes
como hacerlo da clic aquí.
173
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
3.- Luego de eso agregamos un nuevo elemento, para esto damos clic derecho en
nuestro proyecto –> Agregar –> Nuevo
Elemento.
4.- Tendremos un formulario como el siguiente en donde escogeremos la opción de la
izquierda, seleccionamos Reporting –> Seleccionamos ahora Crystal Report –> Le
ponemos un nombre –> y damos clic en Adjuntar.
174
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
5.- Ahora lo que veremos será un wizard o ayudante que nos permitirá crear un reporte
de manera sencilla, deberán entonces de ver una imagen como la siguiente y darle clic
en ok. Dejen las opciones tal como las tengo en mi imagen.
6.- Lo siguiente es escoger de donde sacaremos los datos que mostraremos, para esto en
la siguiente pantalla que se les mostrará que deberá ser como la imagen que coloco
abajo, ustedes deberán escoger Datos del Proyecto –> ADO.NET DataSets –>
EjemploReporteCrystal.BD_EjemploProcedimientosDataSet (Este es mi dataset que
puse enante, entonces aquí colocan el de ustedes) –> y escogen las tablas que utilizarán
en su reporte, en mi caso escogí 2, ya que utilizaré datos de las 2 tablas –> Presionamos
el boton “>” para cada tabla que queramos utilizar en el reporte y una vez hecho esto
damos en siguiente.
175
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
7.- En la siguiente pantalla veremos como están relacionadas las tablas, no hay
practicamente nada que explicar asi que damos clic en siguiente.
8.- Ahora en esta pantalla siguiente si hay que poner asunto, porque es aquí en donde
diremos que campos de que tablas y en qué lugar los queremos en nuestro reporte,
entonces vemos como tengo mis 2 tablas y escojo los datos que necesito de las 2, sin
preocuparme de como estén relacionadas ni nada por el estilo, como ven en esta parte lo
que hago es darle sentido a la forma de presentar mis datos.
176
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
9.- Luego de esto vendrán ciertas opciones como la que utilizaré a continuación que es
de agrupar los datos en un cierto orden, y la forma que escogi de agruparlos es por
géneros iguales, esto lo hago especificando en la parte de agrupamiento qué campo es el
que quiero agrupar.
10.- Lo que sigue son más opciones como les dije, pero en este momento yo ya le di en
finalizar, ya que no necesito hacerle más cosas a mi reporte, por ahora. Luego de dar
clic en finalizar tendré una imagen como la que está abajo, la parte que tengo tachada es
una parte que no quiero mostrar en ejecución por tanto para ocultarlas les damos clic
derecho en la parte gris y al desplegarse un menú de opciones seleccionamos ocultar.
177
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
11.- Bien ahora regresamos y abrimos nuestro form, y buscamos nuestro origen de
datos, si no lo vemos por ahi, damos clic en el menú de Visual Studio en la opción de
Datos –> Seleccionamos ver Origenes de Datos y listo, tendrán que poder ver su dataset
con las tablas al lado como en la imagen. Pero bueno lo que debemos hacer con esto es
arrastrar esas 2 tablas a mi formulario, y esto para qué es? pues es para colocar esos
controles que ven abajo junto con el dataset que están encerrados en el rectángulo verde,
son controles que ya vienen cargados con datos necesarios y que no tendremos que
ponerlos nosotros, por ejemplo ruta de la base de datos o metodos de conexión y
desconexión, etc.
12.- Después de poner esas tablas las sacamos junto con la barra que se pone en la parte
superior, y deberá quedarnos tener algo como lo que sigue.
178
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
13.- Luego de lo que hicimos vamos a la caja de herramientas y buscamos un control
llamado CrystalReportViewer, lo arrastramos y colocamos en el formulario, este control
será el que nos permita vizualizar nuestro reporte hecho anteriormente.
14.- Entonces una vez hecho esto damos doble clic en el borde del form para entrar al
metodo load del mismo y poner el codigo que sigue a continuación. Aclarando un poco
sobre ese código, lo que hacen las 2 primeras líneas es filtrar los datos de las tablas
indistintamente si están relacionadas, las otras 3 líneas sirven para cargar nuestro
reporte en el reportviewer que pusimos en el form, para esto cree un objeto llamado rpt
del reporte(), que fue mi reporte que creamos hace rato, y en su propiedad
SetDataSource le envie el dataset del proyecto que obviamente ya tiene los datos
filtrado gracias a las 2 líneas primeras, por último mande a cargar este reporte al control
del form con su propiedad ReportSource.
179
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
15.- Luego de esto si lo ejecutan deberán ver algo como esto.
16.- Ahora abramos el DataSet para crear algo extra, a continuación lo que haremos es
crear un método que nos filtree solo los datos de las personas de género masculino. Para
esto demos doble clic sobre el dataset o clic derecho y Open.
17.- Damos clic derecho sobre la tabla en la que crearemos el filtro –> Adjuntar –>
Query.
180
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
18.- Lo que haremos a las siguientes 2 pantallas es simplemente darles clic en siguiente.
181
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
19.- Luego tendremos esto y lo que haremos es agregar otra tabla para relacionarla con
la actual, para esto damos clic derecho en la parte blanca al lado de la tabla y en las
opciones que se despliegan seleccionamos Adjuntar Tabla.
20.- Ya que nuestra Base de Datos solo posee 2 tablas solo podremos escoger 1, que es
la tabla TGenero que es la que no tenemos puesta, la seleccionamos y damos clic en
Adjuntar y luego en Cerrar.
21.- Como vemos a continuación ya nos aparece la tabla que agregamos relacionada con
la primera que teniamos, esto es debido a que ya desde que las creamos hicimos esta
relación; lo que sigue el como se ve en la imagen poner en la parte del medio o
directamente en el query que necesitamos de la tabla TGenero el campo nombre_genero
y que este nos servirá como filtro, por eso colocamos en la parte de filtro la palabra
=@nombre_genero además debemos de sacar este campo de área Select, ya que si lo
dejamos ahí no nos mostrará datos en nuestro reporte, o por lo menos eso es lo que me
ha sucedido en la práctica, porque si lo ejecutamos en ese instante con el botón Execue
Query si funciona normalmente pero con el Crystal Report encontre esa falla.
182
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
22.- Ya al haberle dado clic en OK debe de presentarnos la siguiente imagen en la
cual veremos ya hecha nuestra sentencia query de consulta, damos clic en siguiente para
continuar.
23.- Ahora le pondremos un nombre tanto en la parte donde dice Fill a DataTable como
en Return a DataTable, damos clic en siguiente.
183
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
24.- Lo que viene es que ejecutará lo que hicimos en el DataSet y guardará los cambios,
solo le damos clic en Finalizar.
25.- Ahora en el código modificaremos la línea que hacia el filtro en la tabla TPersona,
en mi caso la puse como comentario, y coloqué la que cree recién, pueden ver que
después del DataSet le pongo una coma y le envio un parámetro, esto es debido a que en
mi query le puse el @nombre_genero, entonces por cada parámetro así que pongamos
en el query que hicimos debemos enviarlo aquí es esa línea después del DataSet en el
orden que nos lo pide la instrucción; en ese código yo puse la opción masculino
directamente, si nosotros la colocaramos o escogieramos desde un textbox o un
combobox este sería el que pondríamos ahí con su propiedad text.
26.- Ya lo que queda es ejecutar la aplicación y podremos ver que solo nos filtrará los
datos de las personas de género masculino.
184
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
8.- Acceso a datos con ADO.NET en Visual Basic
8.1. Acercándonos a ADO.NET En este módulo, aprenderemos a trabajar con datos y fuentes de datos en Visual Basic
ADO.NET es la tecnología principal para conectarse a una base de datos, nos ofrece un alto nivel de abstracción, ocultando los detalles de bajo nivel de la implementación de la base de datos de un fabricante. En este tutorial, encontrará las cosas más importantes que debe saber, para trabajar con fuentes de datos con Visual Basic. De esta manera, aprenderá en poco tiempo, a encontrarse cómodo en el entorno de clases de ADO.NET y podrá así, sacar el máximo provecho a sus desarrollos. Las partes que forman parte de este módulo son las siguientes:
ADO.NET ha sufrido a lo largo de los últimos años diferentes mejoras y actualizaciones, desde que .NET apareció.El resumen de las diferentes versiones de ADO.NET podría quedar de la siguiente forma.
ADO.NET 1.0 apareció con Microsoft .NET Framework 1.0. Posteriormente, ADO.NET 1.1 sufrió una pequeñas y casi inapreciables actualizaciones con la aparición de Microsoft .NET Framework 1.1. En el caso del entorno Visual Studio, éste trabaja con Microsoft .NET Framework 2.0 y por lo tanto, utiliza ADO.NET 2.0, el cuál añade algunas características nuevas adicionales.
En nuestro caso, nos centraremos única y exclusivamente en ADO.NET como modelo de objetos de acceso a datos para la plataforma .NET de Microsoft, ya que es el mismo para cualquier tipo de versión de ADO.NET.
¿Qué es ADO.NET? ADO.NET es la tecnología principal para conectarse aun gestor de bases de datos, con un alto
nivel de abstracción, lo que nos permite olvidarnos de los detalles de bajo nivel de las bases de
datos. Además ADO.NET es una tecnología inter operativa. Aparte del almacenamiento y
recuperación de datos, ADO.NET introduce la posibilidad de integrarse con el estándar XML,
los datos pueden 'Serializarse' directamente a y desde XML lo que favorece el intercambio de
información.
ADO.NET proporciona diferentes clases del nombre de espacio System.Data dentro de las
cuáles, destacaremos por encima de todas, la clase DataView, la clase DataSet y la clase
DataTable.
Este conjunto de clases de carácter armónico, funcionan de igual forma con la capa inferior que es la que corresponde a los proveedores de acceso a datos con los que podemos trabajar. Esto facilita el trabajo en n-capas y la posible migración de aplicaciones que utilicen una determinada fuente de datos y deseemos en un momento dado, hacer uso de otra fuente de datos.
¿Qué capas o qué partes hay dentro de ADO.NET?
185
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Dentro de ADO.NET tenemos dos partes importantes.
La primera de ellas es la que corresponde con el nombre de espacio System.Data y que constituye los objetos y clases globales de ADO.NET.
La otra parte es la que corresponde con los objetos que permiten el acceso a datos a una determinada fuente de datos desde ADO.NET y que utilizan así mismo, las clases del nombre de espacio System.Data.
Esta última parte, queda constituida por las clases y objetos de los diferentes proveedores de acceso a datos como se muestra en la figura 1.
Visión general de las clases de ADO.NET
Para resumir de alguna forma lo que estamos comentando, diremos que el trabajo de conexión con la base de datos, la ejecución de una instrucción SQL determinada, una vista, etc., la realiza el proveedor de acceso a datos.
Recuperar esos datos para tratarlos, manipularlos o volcarlos a un determinado control o dispositivo, es acción de la capa superior que corresponde con el nombre de espacio System.Data.
A continuación veremos todo esto con más detalle y comprenderemos de una forma más clara cada una de las partes que componen el modelo de trabajo con ADO.NET.
¿Qué nos permite realmente ADO.NET cuando trabajamos con XML? El entorno de Microsoft .NET Framework nos proporciona el trabajo con estándares y con ello, la posibilidad de trabajar con diferentes tipos de aplicaciones, entornos, sistemas operativos y lenguajes sin necesidad de conocer lo que hay al otro lado de nuestra aplicación.
XML es sin lugar a dudas, el lenguaje de etiquetas por excelencia, válido para llevar a cabo esta tarea sin tener un impacto relevante cuando trabajamos con diferentes soluciones en entornos dispares.
Tanto la posibilidad de trabajar con Servicios Web XML como con documentos e información en XML, sobre todo al trabajar con fuentes de datos en ADO.NET, nos proporciona a los desarrolladores las posibilidades necesarias que nos permite hacer que la información con la que trabajamos, pueda ser tratada entre diferentes sistemas o entornos, sin que por ello nos
186
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
preocupemos de lo que hay al otro lado.
8.2. System.Data Las clases del nombre de espacio System.Data son bastantes extensas y variadas. Quizás las clases más importantes son la clase DataView, la clase DataSet y la clase DataTable.
La clase DataSet El DataSet es una representación de datos residente en memoria que proporciona una modelo de programación relacional coherente independientemente del origen de datos que contiene. El DataSet contiene en sí, un conjunto de datos que han sido volcados desde el proveedor de datos.
Debemos tener en cuenta que cuando trabajamos con DataSets, el origen de datos no es lo más importante, ya que éste, puede ser cualquier tipo de origen de datos. No tiene porqué ser una base de datos.
Un DataSet contiene colecciones de DataTables y DataRelations.
El DataTable contiene una tabla o tablas, mientras que la DataRelation contiene las relaciones entre las DataTables. Sin embargo, no es necesario especificar todo esto hasta el último detalle como veremos más adelante.
La clase DataView
Este objeto nos permite crear múltiples vistas de nuestros datos, además de permitirnos presentar los datos. Es la clase que nos permite representar los datos de la clase DataTable, permitiéndonos editar, ordenar y filtrar, buscar y navegar por un conjunto de datos determinado.
La clase DataTable
Este objeto nos permite representar una determinada tabla en memoria, de modo que podamos interactuar con ella.
A la hora de trabajar con este objeto, debemos tener en cuenta el nombre con el cuál definamos una determinada tabla, ya que los objetos declarados en el DataTable es sensitivo a mayúsculas y minúsculas.
Un pequeño ejemplo práctico El siguiente ejemplo práctico, nos enseña a utilizar un DataSet y nos muestra cómo podemos acceder a los objetos que dependen de un DataSet para recuperar por ejemplo, los campos y propiedades de una determinada tabla o tablas.
187
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Imports System.Data Imports System.Data.SqlClient Imports System.Xml Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim Conexion As String = "server=.;uid=sa;password=VisualBasic;database=MSDNVideo" Dim MiTabla As DataTable Dim MiColumna As DataColumn Dim MiDataSet As New DataSet() Dim Comando As New SqlDataAdapter("SELECT * FROM ALQUILERES", Conexion) Comando.Fill(MiDataSet, "ALQUILERES") ' Recorremos las tablas For Each MiTabla In MiDataSet.Tables
TextBox1.Text += "Tabla: " & MiTabla.TableName & vbCrLf ' Recorremos las Columnas de cada Tabla For Each MiColumna In MiTabla.Columns
TextBox1.Text += MiColumna.ColumnName & vbTab & "(" & MiColumna.DataType.Name & ")" & & vbCrLf
Next Next Comando = Nothing End Sub End Class
Nuestro ejemplo en ejecución es el que se muestra en la figura 1.
Ejemplo en ejecución del uso de DataSet, DataTable y DataColumn
8.3. Los proveedores de acceso a datos Los proveedores de acceso a datos es la capa inferior de la parte correspondiente al
188
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
acceso de datos y es la responsable de establecer la comunicación con las fuentes de
datos. En este conjunto de nombres de espacio, encontraremos casi siempre las clases
Connection, Command, DataAdapter y DataReader como las clases más generales, las
cuales nos permiten establecer la conexión con la fuente de datos.
Proveedores de acceso a datos de .NET Framework Dentro del entorno .NET Framework, encontramos un nutrido conjunto de
proveedores de acceso a datos. Estos son los siguientes:
● ODBC .NET Data Provider
● OLE DB .NET Data Provider
● Oracle Client .NET Data Provider
● SQL Server .NET Data Provider
Estos proveedores de acceso a datos incluidos en Microsoft .NET Framework, los
podemos encontrar en los nombres de espacio:
● System.Data.Odbc
● System.Data.OleDb
● System.Data.OracleClient
● System.Data.SqlClient
El proveedor ODBC .NET permite conectar nuestras aplicaciones a fuentes de datos a través
de ODBC.
El proveedor OLE DB .NET permite conectar nuestras aplicaciones a fuentes de datos a través
de OLE DB.
El proveedor Oracle Client .NET es un proveedor de acceso a datos especialmente
diseñado para bases de datos Oracle.
Por último, el proveedor SQL Server .NET es un proveedor de acceso a datos nativo, que
nos permite conectar nuestras aplicaciones a fuentes de datos Microsoft SQL Server 7 o
posterior. Se trata de un proveedor específico para bases de datos Microsoft SQL Server
7.0, Microsoft SQL Server 2000 y Microsoft SQL Server 2005; 2008
Los proveedores de acceso a datos que distribuye Microsoft en ADO.NET y algunos desarrollados por otras empresas o terceros, contienen los mismos objetos, aunque los
Nota:
Siempre que pueda, utilice para acceder a fuentes de datos, un proveedor de
acceso a datos nativo. Esto le permitirá aumentar considerablemente el
rendimiento a la hora de establecer la conexión con una determinada fuente
de datos
189
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
nombres de éstos, sus propiedades y métodos, pueden ser diferentes.
Más adelante veremos algún ejemplo, y observará en la práctica cuáles son estas diferencias más destacables.
Otros proveedores de acceso a datos Si bien el proveedor de acceso a datos es el mecanismo a través del cuál podemos establecer una comunicación nativa con una determinada fuente de datos, y dado que Microsoft proporciona los proveedores de acceso a datos más corrientes, es cierto que no los proporciona todos, si bien, con OLE DB y ODBC, podemos acceder a la inmensa totalidad de ellos.
Sin embargo, hay muchos motores de bases de datos de igual importancia como Oracle, MySql, AS/400, etc. En estos casos, si queremos utilizar un proveedor de acceso a datos nativo, deberemos acudir al fabricante o a empresas o iniciativas particulares para que nos proporcionen el conjunto de clases necesarias que nos permitan abordar esta acción.
El objeto Connection Este objeto es el encargado de establecer una conexión física con una base de datos determinada. Para establecer la conexión con una determinada fuente de datos, no sólo debemos establecer la cadena de conexión correctamente, sino que además deberemos usar los parámetros de conexión y el proveedor de acceso a datos adecuado. Con este objeto, podremos además abrir y cerrar una conexión.
El objeto Command Este objeto es el que representa una determinada sentencia SQL o un Stored
Procedure. Aunque no es obligatorio su uso, en caso de necesitarlo, lo utilizaremos conjuntamente con el objeto DataAdapter que es el encargado de ejecutar la instrucción indicada.
El objeto DataAdapter Este objeto es quizás el objeto más complejo y a la vez complicado de todos los que forman parte de un proveedor de acceso a datos en .NET. Cuando deseamos establecer una comunicación entre una fuente de datos y un DataSet, utilizamos como intermediario a un objeto DataAdapter. A su vez, un DataAdapter contiene 4 objetos que debemos conocer:
● SelectCommand es el objeto encargado de realizar los trabajos de selección de datos con una fuente de datos dada. En sí, es el que se encarga de devolver y rellenar los datos de una fuente deb datos a un DataSet.
● DeleteCommand es el objeto encargado de realizar las acciones de borrado de datos.
● InsertCommand es el objeto encargado de realizar las acciones de inserción de datos.
● UpdateCommand es el objeto encargado de realizar las acciones de actualización de datos.
Los objetos DeleteCommand, InsertCommand y UpdateCommand son los objetos que se
190
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
utilizan para manipular y transmitir datos de una fuente de datos determinada, al contrario del objeto SelectCommand que tan sólo interactúa con la fuente de datos para recuperar una porción o todos los datos indicados en el objeto Command anteriormente comentado.
El objeto DataReader Este objeto es el utilizado en una sola dirección de datos. Se trata de un objeto de acceso a datos muy rápido. Este objeto puede usar a su vez el objeto Command o el método ExecuteReader.
8.4.- El concepto DataBinding DataBinding es una expresión de enlace a datos. Como veremos a continuación es una forma rápida y sencilla de manejar la fuentes de datos mediante su enlace con controles o clases..
El uso de DataBind El método DataBind se utiliza para rellenar de datos un determinado control o clase. Muchos controles y clases, posee este método al que le asignaremos un conjunto de datos para que se rellene con ellos, pudiendo después interactuar con los datos de forma directa.
En sí, un DataBinding es un enlace a datos que se encarga de rellenar de datos a un determinado control o clase. Como ejemplo de esto, veremos como rellenar un control TextBox con un dato utilizando este método.
Iniciaremos una nueva aplicación Windows y escribiremos el siguiente código fuente:
Imports System.Data Imports System.Data.SqlClient Imports System.Xml
Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim Conexion As String = "server=.;uid=sa;password=VisualBasic;database=MSDNVideo" Dim MiDataSet As New DataSet() Dim Comando As New SqlDataAdapter("SELECT TITULO FROM ALQUILERES, PELICULAS WHERE PELICULACODBARRAS = CODBARRAS AND SOCIONIF = '111111'", Conexion) ' Rellenamos el DataSet con el contenido de la sentencia SELECT Comando.Fill(MiDataSet, "PELIS") ' Rellenamos el control TextBox1 con el dato correspondiente a la primera fila ' de la sentencia SELECT ejecutada TextBox1.DataBindings.Add("Text", MiDataSet,"PELIS.TITULO") Comando = Nothing End Sub End Class
Nuestro ejemplo en ejecución es el que se muestra en la figura.
191
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Ejemplo en ejecución del uso de DataBinding
8.5.- Otras consideraciones Dentro de las conexiones a fuentes de datos, hay algunas partes de éstas que permanecen a veces en el olvido y su importancia sin embargo, es bastante grande. La acción más pesada cuando realizamos un acceso a una fuente de datos, se encuentra en la conexión con la fuente de datos. Esa tarea, simple tarea, es la que más recursos del sistema consume cuando Accedemos a fuentes de datos.
Esto lo debemos tener en cuenta, y por lo tanto, variante de esto que comentamos son las siguientes premisas:
● La conexión debe realizarse siempre que se pueda, con los proveedores de acceso a datos nativos, que por lo general salvo raras excepciones, serán más rápidos que los accesos a fuentes de datos a través de proveedores del tipo OLE DB y ODBC.
● La conexión con la fuente de datos (apertura de la conexión), debe realizarse lo más tarde posible. Es recomendable definir todas las variables que podamos, antes de realizar la conexión.
● La conexión debe cerrarse lo antes posible, siempre y cuando no tengamos la necesidad de utilizar la conexión previamente abierta.
Hay más particularidades a tener en cuenta cuando trabajamos con fuentes de datos. El hecho de que con un DataSet podamos trabajar con datos desconectados, no significa que dentro de él, podamos abrir una tabla con una cantidad de registros enormes, y trabajemos sobre ella creyendo que esto nos beneficiará. Todo lo contrario.
8.6.- El paradigma de la conexión Cuando abordamos un proyecto de acceso a fuentes de datos, siempre nos encontramos con una duda existencial.
¿Debemos crear una conexión con la base de datos al principio de nuestra aplicación y cerrarla cuando la aplicación se cierre?, ¿o debemos crear una conexión con la base de datos sólo cuando vayamos a trabajar con la fuente de datos?. ¿Y si estamos trabajando continuamente con una fuente de datos?, ¿cómo penalizarían todas estas acciones?.
Es difícil de asumir que acción tomar en cada caso, y es que dependiendo de lo que vayamos a realizar, a veces es más efectiva una acción que otra, y en otras ocasiones, no está del todo claro, ya que no existe en sí una regla clara que especifique qué acción tomar en un momento
192
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
dado.
Lo que sí está claro es que el modelo de datos de ADO.NET que hemos visto, quedaría resumido en cuanto a la conectividad de la manera en la que se representa en la figura
Visión general de ADO.NET respecto a la conectividad con bases de datos
El objeto DataSet nos ofrece la posibilidad de almacenar datos, tablas y bases de datos de una determinada fuente de datos. De esta manera, podemos trabajar con las aplicaciones estando desconectados de la fuente de datos.
Sin embargo, a veces necesitamos trabajar con la fuente de datos estando conectados a ella. El objeto DataReader nos ofrece precisamente la posibilidad de trabajar con fuentes de datos conectadas.
Por otro lado, el objeto DataReader tiene algunas particularidades que conviene conocer y que veremos a continuación.
8.7.- Conociendo el objeto DataReader El objeto DataReader nos permite como hemos indicado anteriormente, establecer una conexión con una fuente de datos y trabajar con esta fuente de datos sin desconectarnos de ella, sin embargo, hay diferentes cualidades y particularidades que conviene conocer.
DataReader es de solo lectura Lo que hemos dicho anteriormente, requiere sin embargo, que esta conexión se establezca en un modo de sólo lectura, al contrario de lo que se puede hacer con el objeto DataSet, con el que podemos interactuar con la fuente de datos en modo lectura y modo escritura.
DataReader se maneja en una sola dirección El objeto DataReader sólo permite que nos desplacemos por los datos en una sola dirección, sin vuelta atrás. Por el contrario, el objeto DataSet nos permite movernos por los registros para adelante y para atrás.
Además, sólo podemos utilizar el objeto DataReader con conexiones establecidas en una sentencia SQL por ejemplo, pero no podemos variar esta. Para hacerlo, debemos entonces
193
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
modificar la conexión con el comando establecido.
DataReader es rápido
Debido a su naturaleza y características, este objeto es bastante rápido a la hora de trabajar con datos. Como es lógico, consume además menos memoria y recursos que un objeto DataSet por ejemplo. Sin embargo, dependiendo de las necesidades con las que nos encontremos, puede que este método de acceso y trabajo no sea el más idóneo.
Analizando el flujo de trabajo de DataReader
Cuando trabajamos con fuentes de datos conectadas, trabajaremos con el objeto DataReader.
Para trabajar con este objeto, utilizaremos los objetos siguientes del proveedor de acceso a datos:
● Connection
● Command
● DataReader
Un resumen gráfico de esto es lo que podemos ver en la figura 1.
El flujo de conectividad de DataReader
8.8.- Un primer contacto con el objeto DataReader A continuación veremos un ejemplo sencillo sobre la forma de trabajar con DataReader
Un ejemplo simple para entenderlo mejor Tenga en cuenta que en el siguiente ejemplo nos conectaremos a Microsoft SQL Server y recorreremos los registros uno a uno en un ambiente conectado y volcaremos estos registros en un control TextBox.
Imports System.Data
194
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Imports System.Data.SqlClient Imports System.Xml Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim Conexion As String =
"server=.;uid=sa;password=VisualBasic;database=MSDNVideo"
Dim MiConexion As New SqlConnection(Conexion) Dim MiDataReader As SqlDataReader Dim Comando As New SqlCommand("SELECT TITULO FROM ALQUILERES, PELICULAS WHERE PELICULACODBARRAS = CODBARRAS AND SOCIONIF = '111111'", MiConexion) MiConexion.Open() MiDataReader = Comando.ExecuteReader() While MiDataReader.Read() TextBox1.Text += MiDataReader("TITULO") & vbCrLf End While Comando = Nothing MiConexion.Close() End Sub End Class
El código de ejemplo en ejecución es el que se muestra en la figura 1.
Ejemplo en ejecución del uso simple de DataReader
Este es un ejemplo simple del uso de DataReader.
Sin embargo, el objeto DataReader contiene un conjunto de propiedades y métodos que nos proporcionan acciones determinadas. Por ejemplo, en el ejemplo anterior, hemos dado por hecho que la ejecución de la instrucción Select nos devolverá uno o más valores, pero podríamos también saber antes de manipular y trabajar con los posibles datos, si hay o no información. Esto lo conseguimos con el método HasRows.
195
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
8.9.- ¿Trabaja DataReader en un ambiente conectado realmente? Pese a todo esto, ¿que ocurre si trabajando en un ambiente conectado se desconecta el servidor de acceso a datos?. Imaginemos por un instante, que la conexión con SQL Server se establece correctamente y que en un momento dado se detiene el servicio del servidor de base de datos. Esto es lo que veremos en el siguiente ejemplo.
Desenchufando la fuente de datos usando DataReader Inicie un nuevo proyecto, inserte en el formulario de la aplicación un control TextBox y un control Button, y escriba el código que se detalla a continuación:
Imports System.Data Imports System.Data.SqlClient Imports System.Xml Public Class Form1
Private Conexion As String = "server=.;uid=sa;password=VisualBasic;database=MSDNVideo" Private strSQL As String = "SELECT TITULO FROM ALQUILERES, PELICULAS WHERE PELICULACODBARRAS = CODBARRAS AND SOCIONIF = '111111'" Private MiConexion As New SqlConnection(Conexion) Private MiDataReader As SqlDataReader Private Contador As Long = 0 Private Posicion As Long = 0 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Establecemos la Conexión con la base de datos Establecer_Conexion(True) ' Si hay datos los mostramos, sino deshabilitamos la opción (botón) para recorrerlos If Not MiDataReader.HasRows Then Button1.Enabled = False Else Button1_Click(sender, e) End If End Sub Private Sub Establecer_Conexion(ByVal bolAccion As Boolean) Dim Comando As SqlCommand If bolAccion Then ' True => Establecemos la conexión Comando = New SqlCommand(strSQL, MiConexion) ' Abrimos la Conexión MiConexion.Open() ' Ejecutamos la sentencia SQL MiDataReader = Comando.ExecuteReader() ' Obtenemos la cantidad de registros obtenidos
Contador = MiDataReader.VisibleFieldCount() + 1
196
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Else ' False => Finalizamos la conexión Button1.Enabled = False ' Cerramos la Conexión Comando = Nothing MiConexion.Close() End If End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' Recorremos los registros y los mostramos Posicion += 1 MiDataReader.Read() TextBox1.Text = MiDataReader("TITULO") ' Si hemos recorrido el objeto por completo, finalizamos la Conexión y ' deshabilitamos el control Button que nos permite recuperar los registros If Posicion = Contador Then Establecer_Conexion(False) End If End Sub End Class Suponiendo que tenemos en nuestra base de datos varios registros, ejecute la aplicación. Si todo ha ido como se esperaba, observaremos que nuestra aplicación tiene un aspecto como el que se muestra en la figura
.
Ejemplo en ejecución del uso de DataReader en un ambiente conectado, forzando la desconexión de la fuente de datos
En este punto, detenga el servicio de SQL Server y pulse el botón Siguiente >>. Observará que la aplicación sigue funcionando. En este punto se hará la pregunta que todos nos hemos hecho, ¿no es el objeto DataReader un objeto conectado?, ¿cómo es posible que funcione si hemos detenido el servicio de SQL Server?. La respuesta es sencilla. El objeto DataReader recupera un nutrido conjunto de valores llenando un pequeño buffer de datos e información.
197
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Si el número de registros que hay en el buffer se acaban, el objeto DataReader regresará a la fuente de datos para recuperar más registros. Si el servicio de SQL Server está detenido en ese momento o en su caso, la fuente de datos está parada, la aplicación generará un error a la hora de leer el siguiente registro.
En sí, DataReader es un objeto conectado, pero trabaja en background con un conjunto de datos, por lo que a veces nos puede resultar chocante su comportamiento como el ejemplo que comento.
8.10.- Usando DataSource con DataReader ¿Podemos usar el método DataSource con el objeto DataReader?.
Demostración del uso de DataSource con DataReader La respuesta es sí, en ADO.NET 2.0, se ha incorporado un nuevo método al objeto DataTable que le permite tener mayor independencia respecto al modo en el que nos conectemos y recuperemos datos de una fuente de datos. Recuerde que podemos recuperar datos en modo conectado DataReader o en modo desconectado DataSet.
Este método que se ha incorporado a ADO.NET y que tiene por nombre Load, nos permite cargar un DataReader para volcarlo a continuación dentro de un control como por ejemplo el control DataGridView. Lo mejor es que veamos como funciona esto con un ejemplo que nos ayude a comprender mejor la teoría. Inserte en un formulario un control DataGridView y escriba el siguiente código:
Imports System.Data Imports System.Data.SqlClient Imports System.Xml
Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Declaramos las variables a utilizar Dim Conexion As String = "server=.;uid=sa;password=VisualBasic;database=MSDNVideo" Dim strSQL As String = "SELECT TITULO FROM ALQUILERES, PELICULAS WHERE PELICULACODBARRAS = CODBARRAS AND SOCIONIF = '111111'" Dim MiConexion As New SqlConnection(Conexion) Dim MiDataReader As SqlDataReader Dim MiDataTable As New DataTable Dim Comando As SqlCommand ' Establecemos la Conexión con la base de datos Comando = New SqlCommand(strSQL, MiConexion) ' Abrimos la Conexión MiConexion.Open() ' Ejecutamos la sentencia SQL MiDataReader = Comando.ExecuteReader()
198
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
' Cargamos los resultados en el objeto DataTable MiDataTable.Load(MiDataReader, LoadOption.OverwriteChanges) ' Volcamos los datos en el control DataGridView DataGridView1.DataSource = MiDataTable ' Cerramos la Conexión Comando = Nothing MiConexion.Close() End Sub End Class
Nuestro ejemplo en ejecución es el que podemos ver en la figura
Ejemplo en ejecución del uso de DataReader y DataSource en un control DataGridView
Con todo y con esto, lo que realmente es curioso, es que hemos olvidado por un instante que el objeto DataReader es un objeto de sólo lectura que funciona en una única dirección, hacia delante. ¿Qué significa esto o como puede influir o como podemos aprovechar esta circunstancia en nuestros desarrollos?.
Carga segmentada de datos con DataSource y DataReader
Si recuperamos los datos de una fuente de datos con DataReader y leemos algunos de sus datos y posteriormente, ejecutamos el método DataSource, el resto de datos, aquellos datos que quedan en el DataReader, serán los que se vuelquen en el control que definamos como destino de los datos. Imaginemos el ejemplo anterior, y el siguiente código fuente.
Imports System.Data Imports System.Data.SqlClient Imports System.Xml Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Declaramos las variables a utilizar
Dim Conexion As String =
199
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
"server=.;uid=sa;password=VisualBasic;database=MSDNVideo" Dim strSQL As String = "SELECT TITULO FROM ALQUILERES, PELICULAS WHERE PELICULACODBARRAS = CODBARRAS AND SOCIONIF = '111111'" Dim MiConexion As New SqlConnection(Conexion) Dim MiDataReader As SqlDataReader Dim MiDataTable As New DataTable Dim Comando As SqlCommand ' Establecemos la Conexión con la base de datos Comando = New SqlCommand(strSQL, MiConexion)
' Abrimos la Conexión MiConexion.Open() ' Ejecutamos la sentencia SQL MiDataReader = Comando.ExecuteReader() ' Leemos el primer registro y así nos posicionamos a partir del segundo de ellos MiDataReader.Read() ' Cargamos los resultados en el objeto DataTable MiDataTable.Load(MiDataReader, LoadOption.OverwriteChanges) ' Volcamos los datos en el control DataGridView DataGridView1.DataSource = MiDataTable ' Cerramos la Conexión Comando = Nothing MiConexion.Close() End Sub End Class En este caso, lo que ocurre como ya hemos comentado, es que los datos que se cargan son los que aún no han sido leídos en el objeto DataReader, por lo que se mostrarán todos los datos desde el último leído hasta llegar al final del objeto.
8.11.- Usando los componentes de acceso a datos de .NET Los componentes del entorno .NET nos proporcionan las características necesarias para poder acceder a fuentes de datos de forma rápida y sencilla.
El mejor ejemplo de esto que comento es el que veremos a continuación.
Demostración del uso de BindingSource y BindingNavigator Para ello, crearemos un proyecto nuevo e insertaremos un control BindingSource y un control BindingNavigator dentro del formulario.
También insertaremos un control TextBox al formulario, dónde presentaremos la información sobre la que navegaremos. Nuestro formulario con los controles insertados en él, tendrá un aspecto similar al que se presenta en la figura 1.
200
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Controles de navegación y acceso a datos dispuestos en el formulario Figura 1
Una vez llegado a este punto, lo que tendremos que hacer a continuación será escribir el código fuente necesario para poder representar los datos de la sentencia SQL en el control BingindNavigator, para que a su vez los presente en el control TextBox. A continuación se indica el código fuente de esta parte de demostración de la aplicación.
Imports System.Data Imports System.Data.SqlClient Imports System.Xml Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal eAs System.EventArgs) Handles MyBase.Load ' Declaramos las variables a utilizar
Dim Conexion As String = "server=.;uid=sa;password=VisualBasic;database=MSDNVideo" Dim strSQL As String = "SELECT TITULO FROM ALQUILERES, PELICULAS WHERE PELICULACODBARRAS = CODBARRAS AND SOCIONIF = '111111'" Dim MiConexion As New SqlConnection(Conexion) Dim MiDataReader As SqlDataReader Dim MiDataTable As New DataTable Dim Comando As SqlCommand ' Establecemos la Conexión con la base de datos Comando = New SqlCommand(strSQL, MiConexion) ' Abrimos la Conexión MiConexion.Open() ' Ejecutamos la sentencia SQL MiDataReader = Comando.ExecuteReader() ' Cargamos los resultados en el objeto DataTable MiDataTable.Load(MiDataReader, LoadOption.OverwriteChanges) ' Volcamos los datos en el control TextBox BindingSource1.DataSource = MiDataTable BindingNavigator1.BindingSource = BindingSource1
201
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
TextBox1.DataBindings.Add(New Binding("Text", BindingSource1, "TITULO", True)) ' Cerramos la Conexión Comando = Nothing MiConexion.Close() End Sub End Class
8.12.- Esquema general de la estructura desconectada de acceso a datos En los capítulos anteriores de este módulo, hemos visto ya el uso de la clase DataSet. Incluso lo hemos visto con algún ejemplo.
La clase DataSet está pensada y diseñada para trabajar con fuentes de datos desconectadas. Indudablemente, en este punto, debemos tener clara la estructura general de cómo funciona el acceso desconectado con fuentes de datos. En la figura, podemos observar el diagrama general de esta parte
Estructura general del uso de DataSet en el acceso desconectado a datos
Connection, DataAdapter y DataSet Como podemos observar en la figura 1, para comunicarnos con una fuente de datos, siempre deberemos establecer una conexión, independientemente de si la conexión con la fuente de datos va a permanecer a lo largo del tiempo o no.
El objeto Connection nos permite por lo tanto, establecer la conexión con la fuente de datos. El objeto DataSet nos permite por otro lado, recoger los datos de la fuente de datos y mandárselos a la aplicación.
Entre medias de estos dos objetos, encontramos el objeto DataAdapter que hace las funciones de puente o nexo de unión entre la conexión y el objeto DataSet.
Esto es lo que veremos a continuación, como funciona el objeto DataAdapter, y como encaja todo esto en el acceso a fuentes de datos desconectadas.
8.13.- Conociendo el objeto DataAdapter
202
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
El objeto DataAdapter forma parte del proveedor de acceso a datos, tal y como se muestra en la figura
Visión general de las clases de ADO.NET
Cada proveedor de acceso a datos posee su propio objeto DataAdapter. Cuando realizamos alguna modificación o acción sobre la fuente de datos, utilizaremos siempre el objeto DataAdapter a caballo entre el objeto DataSet y la fuente de datos establecida a través de la conexión con el objeto Connection.Con el objeto DataAdapter, podremos además realizar diferentes acciones sobre nuestras bases de datos, acciones como la ejecución general de sentencias de SQL no sólo para seleccionar un conjunto de datos, sino para alterar el contenido de una base de datos o de sus tablas.
Connection, DataAdapter y DataSet Antes de entrar en materia más profundamente, diremos que en lo que respecta a los proveedores de acceso a datos que vienen integrados con .NET, encontramos dos formas de usar un DataAdapter.
La primera de ellas es utilizando los componentes del proveedor de acceso a datos. La segunda de ellas es utilizando las clases del nombre de espacio del proveedor de acceso a datos. La mejor forma de entender todo esto que comentamos, es trabajando con un ejemplo práctico que nos enseñe a usar el objeto DataAdapter en Visual Studio
Utilizando las clases de .NET En este primer ejemplo de demostración del uso de DataAdapter a través de código usando para ello las clases de .NET, estableceremos una conexión con SQL Server y mostraremos los datos recogidos en un control TextBox.
niciaremos Visual Studio 2005 y seleccionaremos un proyecto de formulario de Windows. Dentro del formulario, insertaremos un control TextBox y añadiremos dos referencias al proyecto. Las referencias añadidas serán a las librerías System.Data y System.XML, como se muestra en la figura
203
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Referencias a las clases de acceso a datos de .NET Una vez que hemos añadido las referencias necesarias para utilizar las clases que queremos en
nuestro proyecto, iremos al código y escribiremos las siguientes instrucciones:
Imports System.Data Imports System.Data.SqlClient Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Establecemos la cadena de conexión con la BBDD Dim Conexion As String = "server=.;uid=sa;password=VisualBasic;database=MSDNVideo" ' Declaramos el DataSet dónde volcaremos los datos Dim MiDataSet As New DataSet() ' Declaramos el DataAdapter estableciendo ' la conexión con la fuente de datos SQL Dim Comando As New SqlDataAdapter("SELECT SocioNIF, FechaAlquiler FROM ALQUILERES", Conexion) ' Rellenamos el DataSet con el contenido de la instrucción Comando.Fill(MiDataSet) ' Cerramos la conexión con la BBDD Comando = Nothing ' Declaramos la propiedad Row para recorrer ' las filas contenidas en el DataSet Dim Row ' Recorremos todas las filas y las tratamos For Each Row In MiDataSet.Tables(0).Rows TextBox1.Text += Row("SocioNIF").ToString & vbTab &
204
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Row("FechaAlquiler") & vbCrLf Next ' Vaciamos el DataSet para liberar memoria MiDataSet = Nothing End Sub End Class
El ejemplo en ejecución del uso de DataAdapter junto con las clases de .NET es el que se muestra en la figura
Ejemplo del acceso a datos con DataAdapter a través de las clases de .NET
Utilizando los componentes de .NET Sin embargo y como ya hemos comentado, existe otro método de acceso a fuentes de datos diferente a las clases de .NET, el acceso a través de componentes que nos faciliten esa tarea. Sin embargo, los componentes de acceso a datos, utilizan por detrás las clases de .NET que hemos visto, lo que ocurre, es que simplifica enormemente el trabajo y ahorra tiempo a la hora de desarrollar aplicaciones. De todos los modos, todo depende de la utilidad o necesidades con las que nos encontremos en un momento dado. Iniciaremos un proyecto Windows nuevamente, e insertaremos en él un control TextBox como hicimos en el caso anterior.
A continuación, añadiremos los componentes de acceso a fuentes de datos SQL Server que es la fuente de datos origen. Como hemos visto, para conectar a fuentes de datos SQL Server, hemos utilizado el nombre de espacio System.Data y hemos importado en el proyecto los nombres de espacio System.Data y System.Data.SqlClient.
Los componentes .NET de acceso a fuentes de datos de SQL Server, se identifican por el nombre Sqlxxx, siendo xxx el tipo de componente a utilizar. Para poder utilizarlos, deberemos añadirlo a la barra de herramientas.
Para añadir los componentes a nuestro proyecto, haremos soble clic sobre el formulario y posteriormente haremos clic con el botón secundario del mouse sobre la barra de herramientas y seleccionaremos la opción Elegir elementos... como se muestra en la figura
205
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Opción de la barra de herramientas para añadir componentes al entorno
Una vez que hemos hecho esto, seleccionaremos los componentes SqlCommand, SqlCommandBuilder, SqlConnection, SqlDataAdapter y SqlDataSource, tal y como se muestra en la figura
Componentes a añadir al entorno
Una vez que hemos añadido los componentes al entorno, estos quedarán dispuestos dentro de la barra de herramientas como se indica en la figura
206
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Componentes añadidos en la barra de herramientas Lo primero que haremos será insertar un componente SqlConnection dentro del formulario. Acudiremos a la ventana de propiedades del componente y modificaremos la propiedad ConnectionString dentro de la cuál escribiremos la instrucción:
server=.;uid=sa;password=VisualBasic;database=MSDNVideo
Entendiendo que ésta, es la cadena de conexión válida con nuestra base de datos. A continuación añadiremos el componente SqlDataAdapter a nuestro formulario. Si se abre alguna ventana, ciérrela.
Vamos a configurar el control con la ventana Propiedades. Podríamos haberlo hecho desde el asistente que se nos ha abierto, pero lo vamos a hacer de otra forma menos sencilla.
Sitúese sobre la propiedad SelectCommand, y dentro de ésta, en la propiedad Connection. Lo que vamos a hacer, es asignar al componente SqlDataAdapter el componente de conexión que vamos a usar para establecer la comunicación entre la fuente de datos y nuestra aplicación.
Despliegue la propiedad Connection indicada, y seleccione el componente de conexión SqlConnection1 anteriormente configurado, tal y como se muestra en la figura.
207
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Componente SqlDataAdapter con la conexión establecida para ser usada en la ejecución de nuestra aplicación
Por último, inserte un componente DataSet al formulario. Todos los componentes quedarán por lo tanto insertados, tal y como se indica en la figura
Componentes añadidos en el formulario de nuestra aplicación
Una vez que tenemos todo preparado, tan sólo nos queda escribir la parte de código fuente necesario para poder realizar todas las operaciones y acciones que necesitamos. A continuación, se expone el código fuente de nuestra aplicación de demostración: Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Establecemos la cadena SQL a utilizar SqlDataAdapter1.SelectCommand.CommandText = "SELECT
208
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
SocioNIF, FechaAlquiler FROM ALQUILERES" ' Abrimos la Conexión SqlConnection1.Open() ' Rellenamos el DataSet con el contenido de la instrucción SQL SqlDataAdapter1.Fill(DataSet1) ' Cerramos la Conexión SqlConnection1.Close() ' Declaramos la propiedad Row para recorrer las filas contenidas en el DataSet Dim Row ' Recorremos todas las filas y las tratamos For Each Row In DataSet1.Tables(0).Rows TextBox1.Text += Row("SocioNIF").ToString & vbTab & Row("FechaAlquiler") & vbCrLf Next End Sub End Class Ahora nos queda únicamente ejecutar nuestra aplicación para estudiar el resultado final. Este es el que se puede ver en la figura
Ejemplo en ejecución del uso de componentes Pese a todo lo que hemos visto, quizás se pregunte como es que en el caso del primer ejemplo que hemos visto y en el que hemos declarado el uso de un DataAdapter sin usar componentes, hemos tenido la obligatoriedad de añadir las referencias a los nombres de espacio System.Data y System.Xml, mientras que en este segundo ejemplo, no hemos hecho referencia a ellos.
En realidad nosotros no hemos hecho referencia a ellos, pero al insertar los componentes dentro del formulario, el entorno Visual Studio 2005 se ha encargado por nosotros de añadir esas referencias al proyecto, tal y como puede verse en la figura.
209
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Referencias añadidas automáticamente al trabajar con componentes de acceso a datos
8.14.- Insertando datos a través del objeto DataAdapter
Hasta ahora, todos los ejemplos que hemos visto del objeto DataAdapter, han sido ejemplos del uso de selección de datos, pero aún no hemos visto como debemos trabajar cuando realicemos otras acciones sobre la fuente de datos.
A continuación, veremos como realizar acciones de actualización de datos, utilizando para ello el objeto DataAdapter.
¿Cómo se insertan datos con el objeto DataAdapter
Suponiendo que hemos recogido un conjunto de datos y que trabajando con el objeto
DataSet hemos realizado una inserción de datos y que a continuación, queremos propagar
dicha inserción a la base de datos, deberemos hacer uso del método Insert del objeto
DataAdapter.
El objeto DataAdapter se encargará de llamar al comando apropiado para cada una de las filas
Nota:
El DataSet permanece desconectado de la fuente de datos y si realizamos una
modificación o alteración de los datos de un DataSet, estos no son propagados a la
fuente de datos. Para ello, el DataAdapter debe recibir la orden que queramos
ejecutar.
210
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
que han sido modificadas en un determinado DataSet.
Esto lo realizará siempre a través del método Update.
Trabajando con un ejemplo
La mejor manera de ver esto es con un ejemplo que nos ayude a entender mejor como funciona la inserción de datos a través del objeto DataAdapter.
Tenga en cuenta además, que la actualización y el borrado de datos funciona de la misma
manera. Iniciaremos un nuevo proyecto de formulario Windows y en él insertamos los
componentes SqlConnection, SqlDataAdapter, DataSet y SqlCommand. Para el
componente SqlConnection, estableceremos la propiedad ConnectionString con el valor:
server=.;uid=sa;password=VisualBasic;database=MSDNVideo A continuación seleccionaremos el componente SqlDataAdapter y modificaremos la propiedad SelectCommand > Connection como vimos en el capítulo anterior.
De la lista de posibles conexiones que le aparezca, seleccione la conexión SqlConnection1. Finalmente, inserte un control Button y un control DataGridView en el formulario. Éste quedará como se indica en la figura.
Formulario con los componentes y controles insertados en él Figura 1 Finalmente, escribiremos el código necesario para ejecutar nuestra aplicación tal y como queremos. Este es el que se detalla a continuación:
Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' Establecemos la cadena SQL a utilizar SqlDataAdapter1.SelectCommand.CommandText = "SELECT NIF, Nombre, Apellido1,
211
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Apellido2, Telefono, Email, Direccion, Ciudad, Provincia, CP FROM SOCIOS" ' Abrimos la Conexión SqlConnection1.Open()
' Rellenamos el DataSet con el contenido de la instrucción sql
SqlDataAdapter1.Fill(DataSet1, "Ejemplo") ' Cerramos la Conexión SqlConnection1.Close() ' Asociamos el control DataGridView al DataSet DataGridView1.DataSource = DataSet1.Tables("Ejemplo") End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' Declaramos un objeto DataRow para insertar en él los nuevos datos Dim MiDataRow As Data.DataRow ' Creamos una nueva fila en el DataSet MiDataRow = DataSet1.Tables("Ejemplo").NewRow() ' Insertamos los datos en el DataSet MiDataRow("NIF") = "222222" MiDataRow("Nombre") = "María" MiDataRow("Apellido1") = "Juárez" MiDataRow("Apellido2") = "Fernández" MiDataRow("Telefono") = "1112233" MiDataRow("Email") = "maría@cuentademail.com" MiDataRow("Direccion") = "C\ Fernández de los Ríos, 77" MiDataRow("Ciudad") = "Valladolid" MiDataRow("Provincia") = "Valladolid" MiDataRow("CP") = "11111"
DataSet1.Tables("Ejemplo").Rows.Add(MiDataRow) ' Si el DataSet tiene cambios ? If DataSet1.HasChanges Then ' Indicamos la instrucción SQL correspondiente SqlCommand1.CommandText = "INSERT INTO SOCIOS(NIF, Nombre, Apellido1, Apellido2, Telefono, Email, Direccion, Ciudad, Provincia, CP) VALUES(@NIF, @Nombre, @Apellido1, @Apellido2, @Telefono, @Email, @Direccion, @Ciudad, @Provincia, @CP)" ' Establecemos para el comando, la (conexión) que utilizaremos SqlCommand1.Connection = SqlConnection1 ' Le indicamos al DataAdapter, cuál es el comando de inserción que usaremos SqlDataAdapter1.InsertCommand = SqlCommand1 ' Añadimos los parámetros y comandos correspondientes ' para cada campo a añadir en la base de datos
212
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
SqlCommand1.Parameters.Add("@NIF", Data.SqlDbType.NChar, 10, "NIF") SqlCommand1.Parameters.Add("@Nombre", Data.SqlDbType.NVarChar, 50, "Nombre") SqlCommand1.Parameters.Add("@Apellido1", Data.SqlDbType.NVarChar, 50, "Apellido1") SqlCommand1.Parameters.Add("@Apellido2", Data.SqlDbType.NVarChar, 50, "Apellido2") SqlCommand1.Parameters.Add("@Telefono", Data.SqlDbType.NVarChar, 13, "Telefono") SqlCommand1.Parameters.Add("@Email", Data.SqlDbType.NVarChar, 50, "Email") sqlCommand1.Parameters.Add("@Direccion", Data.SqlDbType.NVarChar, 100, "Direccion") SqlCommand1.Parameters.Add("@Ciudad", Data.SqlDbType.NVarChar, 50, "Ciudad") SqlCommand1.Parameters.Add("@Provincia", Data.SqlDbType.NVarChar, 50, "Provincia") SqlCommand1.Parameters.Add("@CP", Data.SqlDbType.NChar, 5,"CP") ' Abrimos la conexión SqlConnection1.Open()
' Realizamos la inserción de datos desde el DataSet a través del DataAdapter SqlDataAdapter1.Update(DataSet1, "Ejemplo") ' Cerramos la conexión SqlConnection1.Close() ' Indicamos con un mensaje que la inserción de datos se ha realizado con éxito MessageBox.Show("Datos insertados correctamente") End If End Sub End Class Por último, ejecute la aplicación. Si todo ha ido correctamente, los datos habrán quedado correctamente insertados en la base de datos. Un ejemplo de nuestra aplicación en ejecución es la que puede verse en la figura
213
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Aplicación de ejemplo de inserción de datos con DataAdapter y DataSet en ejecución
Como vemos, el uso de DataAdapter en el caso de manipular datos, varía ligeramente. Sin embargo, no es mucho más complicado con la actualización y borrado de datos. De hecho, la forma de actuar es la misma como veremos a continuación.
8.15.- Actualizando datos a través del objeto DataAdapter De la misma manera que hemos insertado datos en nuestra base de datos, debemos hacer a la hora de actualizar los mismos. Sobre la base del ejemplo anterior (componentes y controles), escriba o modifique el siguiente código:
Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Establecemos la cadena SQL a utilizar SqlDataAdapter1.SelectCommand.CommandText = "SELECT NIF, Nombre, Apellido1, Apellido2, Telefono, Email, Direccion, Ciudad, Provincia, CP FROM SOCIOS" ' Abrimos la Conexión SQL SqlConnection1.Open() SqlDataAdapter1.Fill(DataSet1, "Ejemplo")
' Cerramos la Conexión SqlConnection1.Close() ' Asociamos el control DataGridView al DataSet DataGridView1.DataSource = DataSet1.Tables("Ejemplo") End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' En nuestro ejemplo, sabemos que queremos modificar ' la fila 2, columna 4 (todos los elementos empiezan por 0) DataSet1.Tables("Ejemplo").Rows(1)(4) = "1112234" ' Si el DataSet tiene cambios ?
214
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
If DataSet1.HasChanges Then ' Indicamos la instrucción SQL correspondiente SqlCommand1.CommandText = "UPDATE SOCIOS SET Telefono=@Telefono WHERE NIF=@NIF" ' Establecemos para el comando, la (conexión) que utilizaremos SqlCommand1.Connection = SqlConnection1 ' Le indicamos al DataAdapter, cuál es el comando de actualización que usaremos SqlDataAdapter1.UpdateCommand = SqlCommand1 ' Añadimos los parámetros y comandos orrespondientes ' para cada campo a actualizar en la base de datos SqlCommand1.Parameters.Add("@NIF", Data.SqlDbType.NChar,10, "NIF") SqlCommand1.Parameters.Add("@Nombre", Data.SqlDbType.NVarChar, 50, "Nombre")
SqlCommand1.Parameters.Add("@Apellido1", Data.SqlDbType.NVarChar, 50, "Apellido1") SqlCommand1.Parameters.Add("@Apellido2", Data.SqlDbType.NVarChar, 50, "Apellido2") SqlCommand1.Parameters.Add("@Telefono", Data.SqlDbType.NVarChar, 13, "Telefono") SqlCommand1.Parameters.Add("@Email", Data.SqlDbType.NVarChar, 50, "Email")
SqlCommand1.Parameters.Add("@Direccion", Data.SqlDbType.NVarChar, 100, "Direccion") SqlCommand1.Parameters.Add("@Ciudad", Data.SqlDbType.NVarChar, 50, "Ciudad") SqlCommand1.Parameters.Add("@Provincia", Data.SqlDbType.NVarChar, 50, "Provincia") SqlCommand1.Parameters.Add("@CP", Data.SqlDbType.NChar, 5, "CP")
' Abrimos la conexión SqlConnection1.Open() ' Realizamos la actualización de datos desde el DataSet a través del DataAdapter SqlDataAdapter1.Update(DataSet1, "Ejemplo") ' Cerramos la conexión SqlConnection1.Close() ' Indicamos con un mensaje que la actualización de datos se ha realizado con éxito MessageBox.Show("Datos actualizados correctamente") End If End Sub End Class
Nuestro ejemplo en ejecución es el que se puede ver en la figura 1.
215
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Aplicación de ejemplo de actualización de datos con DataAdapter y DataSet
8.16.- Eliminando datos a través del objeto DataAdapter
De igual forma sucede con la eliminación de datos utilizando para ello el objeto DataAdapter junto al objeto DataSet.
Utilizaremos nuevamente en este caso, la base del ejemplo anterior (componentes y controles), y escribiremos el siguiente código:
Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Establecemos la cadena SQL a utilizar SqlDataAdapter1.SelectCommand.CommandText = "SELECT NIF,Nombre, Apellido1, Apellido2, Telefono, Email, Direccion, Ciudad,Provincia, CP FROM SOCIOS" ' Abrimos la Conexión SqlConnection1.Open() ' Rellenamos el DataSet con el contenido de la instrucción SQL SqlDataAdapter1.Fill(DataSet1, "Ejemplo") ' Cerramos la Conexión
SqlConnection1.Close() ' Asociamos el control DataGridView al DataSet DataGridView1.DataSource = DataSet1.Tables("Ejemplo") End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' En nuestro ejemplo, sabemos que queremos eliminar ' la fila 2 (todos los elementos empiezan por 0) por lo que la fila 2 es aquí la 1 DataSet1.Tables("Ejemplo").Rows(1).Delete()
216
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
' Si el DataSet tiene cambios ? If DataSet1.HasChanges Then ' Indicamos la instrucción SQL correspondiente SqlCommand1.CommandText = "DELETE SOCIOS WHERE NIF=@NIF" ' Establecemos para el comando, la (conexión) que utilizaremos SqlCommand1.Connection = SqlConnection1 ' Le indicamos al DataAdapter, cuál es el comando de eliminación que usaremos SqlDataAdapter1.DeleteCommand = SqlCommand1 ' Añadimos los parámetros y comandos correspondientes ' para cada campo a actualizar en la base de datos SqlCommand1.Parameters.Add("@NIF", Data.SqlDbType.NChar,10, "NIF") SqlCommand1.Parameters.Add("@Nombre", Data.SqlDbType.NVarChar, 50, "Nombre") SqlCommand1.Parameters.Add("@Apellido1", Data.SqlDbType.NVarChar, 50, "Apellido1") SqlCommand1.Parameters.Add("@Apellido2", Data.SqlDbType.NVarChar, 50, "Apellido2") SqlCommand1.Parameters.Add("@Telefono", Data.SqlDbType.NVarChar, 13, "Telefono") SqlCommand1.Parameters.Add("@Email", Data.SqlDbType.NVarChar, 50, "Email")
SqlCommand1.Parameters.Add("@Direccion", Data.SqlDbType.NVarChar, 100, "Direccion") SqlCommand1.Parameters.Add("@Ciudad", Data.SqlDbType.NVarChar, 50, "Ciudad") SqlCommand1.Parameters.Add("@Provincia", Data.SqlDbType.NVarChar, 50, "Provincia") SqlCommand1.Parameters.Add("@CP", Data.SqlDbType.NChar, 5,"CP") ' Abrimos la conexión SqlConnection1.Open() ' Realizamos la eliminación de datos desde el DataSet a través del DataAdapter SqlDataAdapter1.Update(DataSet1, "Ejemplo") ' Cerramos la conexión SqlConnection1.Close() ' Indicamos con un mensaje que la eliminación de datos se ha realizado con éxito MessageBox.Show("Datos eliminados correctamente") End If End Sub End Class
217
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Nuestro ejemplo en ejecución es el que se puede ver en la figura .
Aplicación de ejemplo de eliminación de datos con DataAdapter y DataSet
8.17.- ¿Qué son los datos Maestro Detalle? El desarrollador de aplicaciones que debe trabajar con datos y fuentes de datos relacionadas entre sí, encuentra con frecuencia problemas de desarrollo en aplicaciones con datos interrelacionados. Además, este tipo de aplicaciones, consumen gran parte del tiempo de desarrollo y son por lo general, acciones repetitivas.
Supongamos como ejemplo general, la tabla Socios de un videoclub. Además, relacionemos los socios del videoclub, con una tabla Alquileres, para saber si un socio determinado tiene películas alquiladas, y en ese caso, saber cuáles.
Este sencillo ejemplo, es un claro exponente de una aplicación que relaciona datos maestro detalle. Ambas tablas deben estar relacionadas para recopilar la información que se necesite en un momento dado.
Los datos maestros serían expuestos por los socios del videoclub, mientras que los datos detalle estarían relacionados con los datos de los alquileres de los socios.
En nuestro caso, vamos a cambiar las palabras maestro y detalle por padre e hijo, y a partir de ahora, nos referiremos a padre como la tabla Socios, e hijo como la tabla Alquileres. De esta forma, ubicaremos sin problemas ambos conceptos dentro del entorno de Visual Studio 2008, ya que éste tiene alguna ligera connotación que podría infundirnos a error como observará más adelante.
Por suerte, Visual Studio nos proporciona un conjunto de herramientas, que hace que realizar una aplicación Windows con todas las características de una aplicación maestro detalle, sea un auténtico juego de niños, que nos llevará aproximadamente un minuto de nuestro tiempo como mucho. ¿No me cree?. Continúe el capítulo, y se sorprenderá de lo que Visual Studio 2008 puede hacer por usted.
8.18.- Configurando la fuente de datos Trabajar con fuentes de datos requiere como tarea inicial, que tengamos listo y preparado un
218
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
origen de fuentes de datos válido. Para esta tarea, deberemos configurar la fuente de datos que vamos a utilizar, algo que vamos a aprender a hacer a continuación.
Configurando el origen de la fuente de datos Iniciaremos una nueva aplicación Windows con Visual Studio y seleccionaremos el menú Datos > Mostrar orígenes de datos como se indica en la figura
Menú para mostrar los orígenes de datos En este punto, aparecerá una ventana como la que se muestra en la figura.
Ventana de orígenes de datos
Como podemos apreciar, la ventana no tiene por defecto ningún origen de datos asignado, además, esta ventana inicialmente, no está anclada a ningún sitio del entorno. Para situarla en un lugar específico del entorno, haga clic sobre la ventana y arrástrela sobre la parte en la que desee situarla, como se indica por ejemplo, en la figura
219
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
La ventana orígenes de datos podemos situarla dónde deseemos dentro de Visual Studio En este punto, la ventana de orígenes de datos, quedará anclada en el entorno de desarrollo, como se muestra en la figura
La ventana orígenes de datos anclada en Visual Studio Cada uno, puede situar esta ventana dónde considere oportuno. En mi caso la he situado entre las ventanas del Explorador de soluciones y de Propiedades, pero podemos situarla dónde consideremos oportuno. Sobre la configuración del origen de datos, haga clic sobre la opción Agregar nuevo origen de datos... como se indica en la figura
220
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Opción para agregar un nuevo origen de datos Aparecerá una ventana como la que se muestra en la figura 6 en la cuál indicaremos el lugar de dónde la aplicación obtendrá los datos, y que en nuestro caso será de una Base de datos.
Como tipo de origen de datos elegiremos una Base de datos Una vez seleccionado la opción de Base de datos como tipo de origen de datos, presionaremos el botón Siguiente.
En la siguiente ventana, elegiremos la conexión de la base de datos que vamos a utilizar, o presionaremos sobre el botón Nueva conexión... sino tenemos seleccionada la conexión que queremos utilizar.
En la figura podemos ver como hemos establecido la conexión con nuestra fuente de datos, que utilizaremos en nuestro ejemplo de creación de la aplicación de acceso a datos maestro detalle.
221
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Ventana dónde elegimos la conexión de datos A continuación, haremos clic en el botón Siguiente.
En la nueva ventana que aparece ahora dentro del asistente para la creación del origen de datos, indicaremos el nombre de la cadena de conexión que crearemos. En nuestro caso, no modificaremos el nombre de la cadena de conexión, dejándola por defecto como se muestra en la figura
Asignamos un nombre para el nombre de la cadena de conexión A continuación, haremos clic sobre el botón Siguiente.
En este punto, el asistente se conecta a la base de datos para recuperar la información de la base de datos y mostrarla en la ventana del asistente como se muestra en la figura
222
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Ventana con los objetos de la base de datos seleccionada A continuación, despliegue el objeto Tablas y seleccione las tablas Alquileres y Socios como se indica en la figura
Selección de los objetos de la base de datos seleccionada Una vez que hemos seleccionado los objetos de la base de datos, haremos clic sobre el botón Finalizar para que el asistente concluya las opciones añadidas al asistente. La ventana del origen de datos, quedará ahora configurado de una forma similar a la que se presenta en la figura
223
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Ventana de origen de datos con la configuración añadida A partir de aquí, deberemos preparar las tablas del origen de datos para que se comporten como auténticos datos e informaciones maestro detalle. Esto es lo que veremos en el siguiente módulo.
8.19.- Preparando el origen de datos Ya hemos aprendido a añadir nuestro origen de datos, y ahora aprenderemos a prepararlo para poder utilizarlo posteriormente en la aplicación Windows.
La preparación del origen de datos, nos permitirá seleccionar que tabla o datos queremos que actúen como maestro y cuales como detalle, o dicho de otra forma, que datos queremos que sean padre y cuales hijo.
Nuestro objetivo principal es mostrar la tabla Alquileres como tabla hijo y la tabla Socios como padre de la tabla anterior.
Prepararemos e incrustaremos primero la tabla Socios dentro del formulario Windows como Detalle de la información, y posteriormente insertaremos la tabla Alquileres dentro del formulario.
Por último, asignaremos alguna relación que permita trabajar con las dos tablas en nuestro formulario Windows sin perder la conexión entre ambas tablas y permitiéndonos acceder a la información que nos proporciona dicha relación.
Preparando la tabla padre Lo primero que haremos será preparar la tabla padre para poderla añadir al formulario Windows. Por esa razón, haremos clic sobre la tabla Socios de la ventana de Orígenes de datos como se indica en la figura
Tabla Socios de la ventana de orígenes de datos
224
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
En la ventana de Orígenes de datos y en concreto con la tabla Socios desplegada, centraremos nuestra atención en el campo NIF como se indica en la figura
Campo NIF de la tabla Socios
Pulse sobre la lista desplegable que aparece a la derecha del campo NIF y seleccione la opción Label como se indica en la figura
Lista desplegable con la opción Label seleccionada como campo de la tabla desplegada
En este caso, la ventana de Orígenes de datos quedará informada tal y como se indica en la figura
Campo NIF modificado en la ventana de Orígenes de datos
A continuación, haremos clic sobre la tabla Socios como se indica en la figura, y posteriormente presionaremos sobre la lista desplegable que aparece a la derecha de la tabla.
225
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Tabla Socios seleccionada en la ventana de Orígenes de datos
Si hacemos clic sobre la lista desplegable, aparecerá una lista de opciones o posibilidades, para indicar cómo queremos que sean los campos de la tabla seleccionada con respecto a que tipo de controles queremos que sean. Esto es lo que se indica en la figura
Lista desplegable de la tabla Socios de la ventana de Orígenes de datos
Por defecto, una tabla queda determinada con un icono que representa el control DataGridView, aunque se puede modificar la representación que deseamos tengan los datos dentro de un formulario seleccionando cualquiera de las opciones que tenemos de la lista desplegable. Estas opciones pueden ser cualquiera de las siguientes:
Representa los datos volcados dentro de un control DataGridView
Representa los datos volcados dentro de controles estándar como TextBox u otros controles para reflejarla como Detalle de la información
No representa ningún control como tipo de control de volcado de datos
En el caso de la tabla Socios que usaremos como tabla padre, cambiaremos la representación por defecto de DataGridView para indicarle que nos represente la información en controles, tal y como se indica en la figura
226
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Tabla Socios seleccionada en la ventana de Orígenes de datos como Detalle Ahora que tenemos la tabla maestra ya preparada, pasaremos a preparar la tabla hija.
Preparando la tabla hija Ahora que ya tenemos preparada la tabla tabla padre, prepararemos la tabla hija de los alquileres de las películas de video, para poder usar su información dentro del formulario Windows. Por esa razón, haga clic sobre la tabla Alquileres de la ventana de Orígenes de datos como se indica en la figura
Tabla Alquileres de la ventana de orígenes de datos Dentro de la ventana de Orígenes de datos y en concreto de la tabla Alquileres desplegada, centraremos nuestra atención en el campo AlquilerID y SocioNIF como se indica en la figura
Campos AlquilerID y SocioNIF de la tabla Alquileres Sobre el campo AlquilerID y SocioNIF, haremos una pequeña modificación. Pulse sobre la lista desplegable que aparece a la derecha del campo AlquilerID y SocioNIF y seleccione la opción Label como se indica en la figura
227
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Lista desplegable de opciones de un campo de la tabla desplegada
De esta manera, el campo AlquilerID y SocioNIF quedarán modificados en la ventana Orígenes de datos como se indica en la figura
Campo AlquilerID y SocioNIF modificados en la ventana de Orígenes de datos A continuación, haremos clic sobre la tabla Alquileres como se indica en la figura, y posteriormente presionaremos sobre la lista desplegable que aparece a la derecha de la tabla.
Tabla Alquileres seleccionada en la ventana de Orígenes de datos
Nos aseguraremos que está seleccionada la opción DataGridView que es la que aparece por defecto. Esto es lo que se indica en la figura
228
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
En la tabla Alquileres, nos aseguraremos de seleccionar la opción DataGridView Una vez que tenemos las tabla maestra y detalle preparadas para utilizarlas, las añadiremos al formulario Windows para que tengan el funcionamiento esperado.
8.20.- Incrustando los datos maestro detalle Ya sabemos como crear un origen de datos, también sabemos como preparar los datos maestro y detalle, y por último, lo que nos queda es insertar esos datos en el formulario, y relacionar todos sus datos para que funcionen de la forma esperada. A continuación, veremos como llevar a cabo esta tarea y aprenderemos a hacerlo posible de forma muy rápida y sencilla.
Incrustando la tabla padre en el formulario Nuestra primera acción, será incrustar en el formulario los datos o tabla padre, que en nuestro caso es la formada por la tabla Socios.
Para situar los datos de la tabla Socios dentro de un formulario y en concreto como una información de detalle, bastará con arrastrar y soltar la tabla Socios sobre el formulario como se indica en la figura
Para presentar la información como detalle, arrastraremos la tabla Socios de la ventana Orígenes de datos sobre el formulario Windows
Observaremos que Visual Studio, generará por nosotros un conjunto de componentes y controles, que por defecto tendrá una apariencia similar a la que se presenta en la figura
229
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Controles y Componentes de la tabla maestra añadidos al formulario Windows Observe por un momento, que el campo NIF que declaramos como Label en la ventana de Orígenes de datos, aparece como tal en el formulario, tal y como se indica en la figura
Campo NIF de la tabla, representado como un control Label en el formulario Windows
Si ejecutamos nuestra aplicación, observaremos que esta actúa como una típica aplicación de acceso a datos que nos permite navegar a través de los campos de la tabla Socios, tal y como se indica en la figura
230
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Aplicación en ejecución de la tabla de detalle incrustada en el formulario Windows A continuación, insertaremos en el formulario la tabla Alquileres y relacionaremos ambas tablas para que se muestren los datos relacionados, dentro del formulario Windows.
Incrustando la tabla hija en el formulario Ya tenemos la tabla padre insertada en nuestro formulario Windows. Nuestra segunda acción, será la de incrustar en el formulario los datos o tabla hoja, que en nuestro caso es la formada por la tabla Alquileres, la cuál además, posee una relación entre campos con la tabla Socios insertada anteriormente.
Para llevar a cabo esta acción arrastraremos y soltaremos la tabla Alquileres sobre el formulario como se indica en la figura
Para presentar la información de la tabla Alquileres, arrastraremos la tabla de la ventana Orígenes de datos sobre el formulario Windows
Como podemos observar, el entorno de trabajo ha hecho por nosotros el trabajo más complejo para representar los datos de forma rápida y sencilla.
El esquema de datos tipados, aparecía ya en nuestro proyecto cuando asignamos el correspondiente origen de datos. Ahora lo que ha ocurrido, es que al arrastrar y soltar la tabla padre Socios de la ventana de Orígenes de datos, en el entorno se ha añadido un componente de nombre MSDNVideoDataSet que es el que permitirá relacionar el DataSet tipado con nuestros datos.
Este componente será usado por la relación maestro detalle de las dos tablas añadidas al formulario.
En la figura, podemos ver el esquema añadido a nuestro proyecto, y el componente del que estamos hablando.
231
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Esquema del DataSet tipado añadido al proyecto y su componente de relación Ejecute la aplicación y observe el comportamiento de la misma.
Observará por lo tanto, que los datos entre detalle y maestra, no están relacionados. Si navegamos a través de los datos de detalle a través del objeto SociosBindingNavigator, el control DataGridView no representa la relación de los datos seleccionados.
Esto es lo que se muestra en la figura.
Ejecución de la aplicación confirmando que los datos mostrados no están relacionados A continuación, la tarea que nos queda para completar el correcto funcionamiento de nuestra aplicación, es la de relacionar la tabla detalle y la tabla maestra entre sí, para que los datos que se muestran en la aplicación, estén relacionados entre sí.
Relacionando la tabla padre con la tabla hija La tarea más sencilla es la de relacionar la tabla detalle con la tabla maestra. Es una tarea sencilla, porque Visual Studio nos proporciona las herramientas necesarias para simplificar al máximo esta tarea.
Para llevar a cabo esta tarea, haga clic sobre el control DataGridView que corresponde a
232
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
los datos de la tabla maestra, y acceda a la ventana de Propiedades.
Dentro de la ventana de Propiedades, acceda a la propiedad DataSource como se indica en la figura.
Propiedad DataSource del control DataGridView de la información maestra Despliegue esta propiedad, y de la lista desplegable que aparece, seleccione la opción FK_Alquileres_Socios como se indica en la figura
Asignación de la clave de relación entre las tablas Cuando se asigna el campo de relación de las tablas, dentro de la aplicación se añade esta relación para que cuando naveguemos entre los datos de la tabla Socios aparezca toda la información de la tabla Alquileres relacionada con la tabla Socios.
Esto de lo que hablamos, está supeditado por el componente FK_Alquileres_SociosBindingSource que es lo que se indica en la figura
233
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Controles y componentes incluido el de relación entre tablas, añadidos al formulario Windows Para finalizar, ejecutaremos nuestra aplicación y comprobaremos que el funcionamiento de esta, incluida la relación entre tablas, funciona como esperábamos. En la figura, podemos observar el comportamiento de nuestra aplicación en ejecución.
Aplicación en ejecución, mostrando la correcta relación entre las tablas
8.21.- Manipulando los datos maestro detalle Obviamente, los datos maestro detalle no nos sirve únicamente para insertar las tablas de datos en un formulario, mostrarlos y navegar por ellos. Además de esto, podemos también manipular los datos maestro detalle, modificarlos, actualizarlos, borrarlos, sin hacer ninguna acción adicional. El control BindingNavigator ya proporciona todas las características necesarias para realizar estas acciones.
Podemos personalizar el control para permitir o denegar estas acciones. Además, dentro de la
234
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
ventana de Orígenes de datos, podemos seleccionar diferentes campos de las tablas y cambiar el tipo de control en el que queremos representar sus datos. A continuación veremos un breve ejemplo de como manipular datos para que nos sirva de aprendizaje de cómo hacer esto posible.
Modificando datos Ejecute la aplicación de ejemplo que hemos diseñado hasta ahora y sitúese en alguno de sus campos. Centrándonos en la información de la tabla Socios, cambiaremos un campo determinado, como el que se muestra en la figura
Modificaremos el valor de un campo para que nos sirva de ejemplo
Acto seguido, cuando hayamos realizado la modificación, haremos clic sobre la opción de Guardar datos, tal y como se muestra en la figura.
Opción del control BindingNavigator para guardar los datos modificados Como vemos, la manipulación de datos es realmente sencilla y en la relación de datos mostrada, no tiene porqué presentarnos ninguna dificultad.
Insertando y eliminando datos Si queremos agregar datos, deberemos hacer clic sobre la opción Agregar nuevo del control BindingNavigator como se muestra en la figura
235
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Añadir un registro nuevo es realmente sencillo
De la misma manera funciona el mecanismo para eliminar un registro, tal y como se muestra en la figura
Eliminar un registro de forma Rápida
236
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
237
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Vistas y ordenación de datos con la clase DataView
La clase DataView nos permite la aplicación de vistas personalizadas a partir de una
tabla contenida en un DataSet, así como la ordenación y búsqueda de filas.
Partiendo de un objeto DataTable situado en un DataSet, vamos a definir varias vistas simultáneamente, ordenar y buscar registros, con la ventaja de que el consumo de recursos es menor, puesto que los objetos DataView se alimentan del mismo DataTable. Para realizar algunas pruebas, se acompaña el proyecto Vistas
El DataSet del formulario de pruebas va a estar compuesto por dos tablas. El
Código fuente muestra el evento de carga del formulario.
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Handles MyBase.Load
' crear conexión
Dim oConexion As New SqlConnection()
oConexion.ConnectionString = "Server=(local);" & _
"Database=Northwind;uid=sa;pwd=;"
'crear dataset
oDataSet = New DataSet()
Dim oDataAdapter As SqlDataAdapter
' crear un adaptador de datos para la tabla Customers
oDataAdapter = New SqlDataAdapter("SELECT * FROM Customers", oConexion)
' añadir tabla al dataset con el adaptador
oDataAdapter.Fill(oDataSet, "Customers")
oDataAdapter = Nothing
' crear un adaptador de datos para la tabla Products
oDataAdapter = New SqlDataAdapter("SELECT * FROM Products", oConexion)
' añadir tabla al dataset con el adaptador
oDataAdapter.Fill(oDataSet, "Products")
oDataAdapter = Nothing
End Sub
238
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Vistas por código y DefaultView
Podemos crear una vista instanciando un objeto de la clase DataView, o también obteniendo la denominada vista por defecto de una tabla de un DataSet, a través de la propiedad DefaultView del objeto DataTable. La opción de menú Vistas + Normal del formulario, crea dos vistas de esta manera. Ver Código fuente .
Private Sub mnuNormal_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles mnuNormal.Click
' crear una vista por código y asignarla a un datagrid
Dim dvNormal As DataView
dvNormal = New DataView(oDataSet.Tables("Customers"))
Me.grdDatos.CaptionText = "Customers"
Me.grdDatos.DataSource = dvNormal
' tomar la vista por defecto de una tabla
' del dataset y asignarla a un datagrid
Me.grdDatosBIS.CaptionText = "Products"
Me.grdDatosBIS.DataSource = oDataSet.Tables("Products").DefaultView
End Sub
La Figura muestra estas vistas en sendos DataGrid del formulario.
239
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Objetos DataView creados por código y obtenido de DataTable.DefaultView.
Filtros con objetos DataView
La propiedad RowFilter de la clase DataView nos permite asignar a este objeto,
una cadena con la expresión de filtro, que en una consulta en lenguaje SQL sería la
parte correspondiente a la partícula Where.
El Código fuente muestra el código de la opción de menú Vistas + País, del formulario de ejemplo, en la que se crea un filtro que se muestra posteriormente en un DataGrid.
Private Sub mnuPais_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles mnuPais.Click
' crear dataview
Dim oDataView As New DataView()
oDataView.Table = oDataSet.Tables("Customers")
' establecer un filtro
oDataView.RowFilter = "Country='Spain'"
Me.grdDatos.CaptionText = "Filtrar Customers por país Spain"
Me.grdDatos.DataSource = oDataView
End Sub
La Figura muestra las filas de la tabla con el filtro aplicado.
DataView con filtro.
Como hemos comentado anteriormente, a partir de un DataTable podemos
obtener varios filtros mediante distintos objetos DataView, sin que ello
240
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
suponga una penalización en el consumo de recursos. Para demostrar este
punto, la opción Vistas + Combinada, crea una vista basada en un filtro combinado,
y una vista normal, ambas empleando la misma tabla base. Veamos el Código fuente
Private Sub mnuCombinada_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles mnuCombinada.Click
' tomar la tabla Customers del dataset y aplicar...
' ...filtro combinado por dos campos y depositar en un datagrid
Dim oDataView As New DataView()
oDataView.Table = oDataSet.Tables("Customers")
oDataView.RowFilter = "ContactTitle LIKE '%Manager%' AND Country IN
('Spain','USA')"
Me.grdDatos.CaptionText = "Filtro combinado por campos ContactTitle y Country"
Me.grdDatos.DataSource = oDataView
' ...filtro por un campo y depositar en otro datagrid
Dim oDV As New DataView()
oDV.Table = oDataSet.Tables("Customers")
oDV.RowFilter = "ContactName LIKE '%an%'"
Me.grdDatosBIS.CaptionText = "Filtro por campo ContactName"
Me.grdDatosBIS.DataSource = oDV
End Sub
La Figura muestra el formulario con los diversos filtros establecidos
241
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Filtros combinados con objetos DataView.
Búsquedas con DataView
Estableciendo el adecuado filtro a un objeto DataView, podemos realizar búsquedas de registros en tablas, como muestra el Código fuente, correspondiente a la opción de menú Vistas + Buscar fila, del formulario de ejemplo. Deberemos previamente, haber escrito en el TextBox del formulario, el identificador de la tabla Customers a buscar.
Private Sub mnuBuscarFila_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles mnuBuscarFila.Click
' crear un dataview y buscar una fila en la vista
' estableciendo un filtro
Dim oDataView As New DataView()
oDataView.Table = oDataSet.Tables("Customers")
oDataView.RowFilter = "CustomerID = '" & Me.txtCustomerID.Text & "'"
Me.grdDatosBIS.CaptionText = "Buscar ID cliente: " & Me.txtCustomerID.Text
Me.grdDatosBIS.DataSource = oDataView
End Sub
En la Figura vemos el resultado de una búsqueda, mostrado en uno de los DataGrid del formulario.
242
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Búsqueda de una fila en una tabla de un DataSet, empleando un DataView.
Ordenación de filas mediante DataView
Para ordenar las filas en un DataView emplearemos su propiedad Sort, asignándole una cadena con el nombre de columna/s a ordenar, tal y como muestra el Código fuente , de la opción de menú Ordenación + Normal, en el formulario del ejemplo.
Private Sub mnuOrdNormal_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles mnuOrdNormal.Click
' crear dataview y ordenar las filas con la propiedad Sort
Dim oDataView As New DataView()
oDataView.Table = oDataSet.Tables("Customers")
oDataView.Sort = "Country"
Me.grdDatos.CaptionText = "Ordenar por campo Country"
Me.grdDatos.DataSource = oDataView
End Sub
Veamos el resultado al ejecutar en la Figura
Si necesitamos ordenar por múltiples columnas de la tabla, sólo tenemos que asignar a Sort una cadena con la lista de columnas requeridas. Ver Código fuente .
243
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
DataView ordenando las filas por la columna Country.
oDataView.Sort = "Country, PostalCode"
También es factible asignar a un DataView una combinación de filtro y ordenación,
utilizando en la misma operación las propiedades RowFilter y Sort. El menú del
formulario Ordenación + Con filtro realiza este trabajo, que vemos en el Código
fuente .
Private Sub mnuOrdenFiltro_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuOrdenFiltro.Click
Dim oDataView As New DataView()
oDataView.Table = oDataSet.Tables("Customers")
' establecer un filtro al dataview
oDataView.RowFilter = "Country='USA'"
' ordenar las filas del filtro
oDataView.Sort = "City"
Me.grdDatos.CaptionText = "Filtrar por USA. Ordenar por campo City"
Me.grdDatos.DataSource = oDataView
End Sub
Los datos con el filtro y orden podemos verlos en el DataGrid del formulario, que muestra la Figura .
244
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Resultado de DataView con filtro y orden.
Obtener el esquema de un DataSet
El esquema de un DataSet consiste en toda la información contenida por este objeto, acerca de los nombres de tablas, columnas, relaciones, etc.; es decir, se trata de metainformación sobre los datos que contiene el DataSet.
Podemos obtener estos metadatos del DataSet recorriendo la colección que nos interese en cada caso: Tables, Columns, etc.
El Código fuente muestra como tras crear un DataSet, recorremos sus tablas, y dentro de estas, sus columnas, mostrando la información obtenida en un ListBox.
Private Sub btnEsquema_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnEsquema.Click
' crear conexión
Dim oConexion As New SqlConnection()
oConexion.ConnectionString = "Server=(local);" & _
"Database=Northwind;uid=sa;pwd=;"
' crear dataset
Dim oDataSet As New DataSet()
' crear adaptadores de datos para las tablas
' y añadir cada tabla al dataset con el adaptador
Dim oDataAdapter As SqlDataAdapter
oDataAdapter = New SqlDataAdapter("SELECT * FROM Customers", oConexion)
oDataAdapter.Fill(oDataSet, "Customers")
oDataAdapter = Nothing
245
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
oDataAdapter = New SqlDataAdapter("SELECT * FROM Orders", oConexion)
oDataAdapter.Fill(oDataSet, "Orders")
oDataAdapter = Nothing
oDataAdapter = New SqlDataAdapter("SELECT * FROM Products", oConexion)
oDataAdapter.Fill(oDataSet, "Products")
oDataAdapter = Nothing
oDataAdapter = New SqlDataAdapter("SELECT * FROM Territories", oConexion)
oDataAdapter.Fill(oDataSet, "Territories")
oDataAdapter = Nothing
' crear un objeto tabla y columna para mostrar
' la información del esquema que el dataset contiene
Dim oDataTable As DataTable
Dim oDataColumn As DataColumn
Me.lstEsquema.Items.Add("Estructura del DataSet")
' recorrer la colección de tablas del DataSet
For Each oDataTable In oDataSet.Tables
Me.lstEsquema.Items.Add("Tabla: " & oDataTable.TableName)
Next
' recorrer la colección de columnas de la tabla
For Each oDataColumn In oDataTable.Columns
Me.lstEsquema.Items.Add("Campo: " & _
oDataColumn.ColumnName & " --- " & _
"Tipo: " & oDataColumn.DataType.Name)
Next
End Sub
La Figura muestra el ListBox relleno con el esquema del DataSet tras haber pulsado el botón del formulario.
246
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Obtención del esquema de un DataSet.
247
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Ejemplos de programa de uso de clase en Visual Basic NET
Ejemplo Calcular el salario de un empleado, información a sacar por pantalla Nombre del
empleado y Salario semanal, datos conocidos: nombre, número de horas trabajadas y pago
por hora del empleado
El salario se calcula de la manera siguiente:
Si el número de horas trabajadas es mayor que 40, el excedente de 40 se paga al doble de
la cuota por hora, en caso de no ser mayor que 40 se paga a la cuota por hora normal.
Realicemos la solución de acuerdo al modelo-vista-controlador
Algoritmo Calcular Salario de un empleado
Algoritmo Calcular Salario de un empleado
Clase Empleado
1.- Declaraciones :Datos
NombreEmpleado: Cadena
HorasTrabajadas: Entero
PagoHora: Real
Salario: Real
2.- Metodo EstablecerNombre( nom: cadena)
NombreEmpleado = nom
Fin Metodo EstablecerNombre
3.- Metodo Establecerhoras(horas: Entero)
HorasTrabajadas = horas
Fin Metodo EstablecerHoras
4.- Metodo EstablecerPago( pago: Real)
PagoHora = pago
Fin Metodo EstablecerPago
5.-Metodo CalcularSalario( )
If HorasTrabajadas<= 40 Then
Salario = HorasTrabajadas * PagoHora
Else
Salario= (40*PagoHora)+
(( HorasTrabajadas -40) *( PagoHora * 2))
Endif
Fin Metodo EstablecerNombre
6.- Metodo ObtenerNombre() : Cadena
Return NombreEmpleado
Fin Metodo ObtenerNombre
7.- Metodo ObtenerSalario( ) : Real
Return Salario
Fin Metodo ObtenerSalario
Fin de clase empleado
Public Class Empleado
'Declaraciones de Datos
Private NombreEmpleado As String
Private HorasTrabajadas As Integer
Private PagoHora As Double
Private Salario As Double
Public ReadOnly Property obtenerNombre() As
String
' bloque Get obtener para devolver el valor
de la propiedad
Get
Return NombreEmpleado
End Get
End Property
Public WriteOnly Property establecerNombre()
As String
' bloque Set (Establecer) para asignar valor a
la propiedad
Set(ByVal Value As String)
NombreEmpleado = Value
End Set End Property
Public ReadOnly Property obtenerHoras() As Integer ' bloque Get para devolver el valor de la propiedad Get Return HorasTrabajadas End Get End Property
248
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Diseño en Visual Basic
Public WriteOnly Property EstablecerHoras()
As Integer
' bloque Set para establecer valor a la
propiedad
Set(ByVal hora As Integer)
HorasTrabajadas = hora
End Set
End Property
Public WriteOnly Property EstablecerPago()
As Double
' bloque Get para devolver el valor de la
propiedad
Set(ByVal value As Double)
PagoHora = value
End Set
End Property
Public ReadOnly Property ObtenerPagoHora()
As Double
' bloque Set para estsblecer el valor a la
propiedad
Get
Return PagoHora
End Get
End Property
Public Sub CalcularSalario()
' en este método calculamos el salario del
empleado
If HorasTrabajadas <= 40 Then
Salario = HorasTrabajadas * PagoHora
Else
Salario = (40 * PagoHora) +
((HorasTrabajadas - 40) * (PagoHora * 2))
End If
End Sub
Public ReadOnly Property ObtenerSalario() As
Double
Get
Return Salario
End Get
End Property
End Class
249
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Clase EjecutaEmpleado
Metodo Principal
Declaraciones
Variables
NEmple : Cadena
HT: Entero
PagoH: Real
Declarar, crear e iniciar objeto
Empleado objEmpleado = new
Empleado()
Solicitar nombre, número de horas,
pago por hora
Leer NEmple, HT, PagoH
Establecer
objempleado.EstablecerNombre(NEmple)
objEmpleado.EstablecerHoras(HT)
objEmpleado.EstablecerPago(PagoH)
Calcular ObjEmpleado.CalcularSalario()
Imprimir objEmpleado.ObtenerNombre()
objEmpleado.ObtenerSalario()
Fin Metodo principal
Fin clase EjecutaEmpleado
Rem Clase Ejecuta Empleado (Esta se
encuentra en el Form)
Public Class Form1
Public NEmple As String
Dim HT As Double
Dim PagoH As Double
Private Sub Button1_Click(ByVal
sender As System.Object, ByVal e As
System.EventArgs) Handles
Button1.Click
'Declarar e iniciar objeto
Dim objEmpleado As Empleado
objEmpleado = New Empleado()
'Trasladar datos a las variables
NEmple = TextBox1.Text
HT = Val(TextBox2.Text)
PagoH = Val(TextBox3.Text)
'Metodos establecer
objEmpleado.establecerNombre =
NEmple
objEmpleado.EstablecerPago = PagoH
objEmpleado.EstablecerHoras = HT
'Metodo Calcular
objEmpleado.CalcularSalario()
'Metodos obtener datos
Label4.Text = "Empleado " &
UCase(objEmpleado.obtenerNombre)
Label5.Text = "Pago por hora " &
objEmpleado.ObtenerPagoHora
Label6.Text = "Salario " &
objEmpleado.ObtenerSalario
End Sub
Private Sub Button2_Click(ByVal
sender As System.Object, ByVal e As
System.EventArgs) Handles
Button2.Click
End
End Sub
End Class
250
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Algoritmo y programa OO usando selección múltiple en Visual Basic NET
Ejercicio: Elaborar un algoritmo que dado un numero del 1 al 7, el programa
imprima por pantalla “Domingo ”,si es 1, “Lunes”, si es 2… “Sábado”, si es 7.
Solución:
Algoritmo PresentaDia de la semana
Clase PresentaDia
Declaraciones
Datos
NumDia : Entero
NombreDia : Cadena
Metodo EstablecerNDia( num: Entero)
NumDia = Num
Fin de método EstablecerDia
Metodo CalcularNombredia()
Swith NumDia
1: Nombredia = “Domingo”
2: Nombredia = “Lunes”
3: Nombredia = “Martes”
4: Nombredia = “Miércoles”
5: Nombredia = “Jueves”
6: Nombredia = “Viernes”
7: Nombredia = “Sábado”
DEFAULT
NombreDia = “No está en el rango de 1 a 7 “
ENDSWITCH
Fin Metodo CalcularNombreDia
Metodo ObtenerNombreDia() : Cadena
Return NombreDia
Fin Metodo ObtenerDia
Fin clase PresentaDia
Public Class PresentaDia
REM Declaraciones de Datos
Private INumDia As Integer
Public SNombreDia As String
' Metodo obtener nombreDia de solo
escritura
ReadOnly Property Nombre() As String
Get
Nombre = SNombreDia
End Get
End Property
'Metodo establecer Numero del Dia solo
lectura
WriteOnly Property Dia() As Integer
Set(ByVal value As Integer)
INumDia = value
End Set
End Property
' Metodo CalcularNombredia()
Public Sub CalcularDia()
Select Case (INumDia)
Case 1
SNombreDia = "Domingo"
Case 2
SNombreDia = "Lunes"
Case 3
SNombreDia = "Martes"
Case 4
SNombreDia = "Miercoles"
Case 5
SNombreDia = "Jueves"
Case 6
SNombreDia = "Viernes"
Case 7
SNombreDia = "Sabado"
Case Else
SNombreDia = "No existe ese dia"
End Select
End Sub
End Class
251
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Clase EjecutaPresentaDia
Metodo Principal
Declaraciones
Variables
Ndia : Entero
Declarar, crear e iniciar objeto
PresentaDia Objdia = new PresentaDia
Solicitar numero de dia
Leer Ndia
Establecer Objdia.EstablecerNDia(Ndia)
Calcular ObjDia.CalcularNombreDia()
Obtener ObjDia.ObtenerNombreDia()
Fin Metodo Principal
Fin Clase EjecutaPresentaDia
Public Class Form1
REM programa con clases utilizando
seleccion multiple
REM Elaborar un algoritmo que dado
un numero del 1 al 7, el programa
imprima por pantalla “Domingo ”,si
es 1, “Lunes”, si es 2… “Sábado”, si
es 7.
Dim INdia As Integer
' Declara la instancia de la clase
Dim objDia As PresentaDia
Private Sub Button2_Click(ByVal
sender As System.Object, ByVal e As
System.EventArgs) Handles
Button2.Click
End
End Sub
Private Sub Button1_Click(ByVal
sender As System.Object, ByVal e As
System.EventArgs) Handles
Button1.Click
objDia = New PresentaDia
objDia.Dia = Val(TextBox1.Text)
objDia.CalcularDia()
' presentar el nombre del dia
Label2.Text = "El dia de la semana
es " & objDia.Nombre
End Sub
End Class
252
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Algoritmo y programa OO usando Estructura de repetición DO…WHILE en
Visual Basic NET
Ejemplo: Elaborar un algoritmo para calcular e imprimir el sueldo de varios
empleado de una empresa.
Datos disponibles: Nombre, Horas Trabajadas, Cuota por Hora
Proceso: Sueldo = Horas Trabajadas * cuota por Hora
Imprimir: Nombre, Sueldo.
Solución:
Clase Empleado
Declaraciones
Datos
NombreE : Cadena
HorasT : Entero
PagoH : Real
Sueldo : Real
Metodo EstablecerNombreE(nom :
Cadena)
NombreE = nom
Fin método EstablecerNombreE
Metodo EstablecerHorasT (Horas : Enterol)
HorasT = Horas
Fin de método EstablecerHorasT.
Metodo EstablecerPagoH( Pago : Real)
PagoH = Pago
Fin Metodo EstablecerPagoH
Metodo CacularSueldo()
Sueldo = HorasT * PagoH
Fin método CalcularSueldo
Metodo ObtenerNombreE(): Cadena
Return NombreE
Fin Metoddo ObtenerNombreE
Metodo ObtenerSueldo() : Real
Return Sueldo
Fin método ObtenerSueldo
Fin Clase Empleado
Public Class Empleado
Private NombreE As String
Public Property Nombre() As String
Get
Nombre = NombreE
End Get
Set(ByVal valor As String)
NombreE = valor
End Set
End Property
Private HorasT As Double
Public Property Horas() As String
Get
Horas = HorasT
End Get
Set(ByVal valor As String)
HorasT = valor
End Set
End Property
Private PagoH As Double
Public Property Pago() As String
Get
Pago = PagoH
End Get
Set(ByVal valor As String)
PagoH = valor
End Set
End Property
Private Sueldo As Double
ReadOnly Property Salario() As Double
Get Salario = Sueldo End Get End Property Public Sub CalcularSueldo() Sueldo = HorasT * PagoH
End Sub End Class
253
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Clase EjecutaEmpleado
Metodo Principal
Declaraciones
Variables
NomEmple : Cadena
HTraba : Entero
PagoHora : Real
Desea : Carácter
Do
Declarar, crear e iniciar objeto
Empleado objEmpleado = new Empleado()
Solicitar Nombre, horas trabajadas, cuota por hora
Leer nomEmple, HTraba,PagoHora
Establecer
ObjEmpleado.EstablecerNombreE(NomEmple)
ObjEmpleado.EstablecerHorasT(HTraba)
ObjEmpleado.EstablecerPagoH(PagoHora)
Calcular ObjEmpleado.CalcularSueldo()
Imprimir ObjEmpleado.ObtenerNombreE()
ObjEmpleado.Obtenersueldo()
Preguntar “¿Desea procesar otro empleado (S/N)
?”
Leer Desea
WHILE Desea = “S”
Fin Metodo principal
Fin clase EjecutaEmpleado
Public Class Form1
Dim ObjEmpleado As Empleado
Private Sub Button2_Click(ByVal sender As
System.Object, ByVal e As System.EventArgs)
Handles Button2.Click
ObjEmpleado = New Empleado
' Recibir datos
ObjEmpleado.Nombre = TextBox1.Text
ObjEmpleado.Horas = Val(TextBox2.Text)
ObjEmpleado.Pago = Val(TextBox3.Text)
' Procesar salario
ObjEmpleado.CalcularSueldo()
Label4.Text = "El empleado " &
ObjEmpleado.Nombre & " tiene un salario de "
& ObjEmpleado.Salario
Dim otros As String
otros = InputBox("Otro proceso S/N")
If UCase(otros) = "S" Then
TextBox1.Text = ""
TextBox2.Text = ""
TextBox3.Text = ""
Label4.Text = ""
TextBox1.Focus()
End If
End Sub
Private Sub Button1_Click(ByVal sender As
System.Object, ByVal e As System.EventArgs)
Handles Button1.Click
End
End Sub
End Class
254
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Algoritmo y programa OO usando arreglos unidimensionales en Visual
Basic NET, Ejemplo:
Se conoce el número de unidades producidas por un obrero en cada uno de los 30
días del mes. Elaborar un algoritmo y programa que permita leer la producción de
cada uno de los 30 días y luego los visualice.
Clase Obrero
1.- Declaraciones
Datos
Producción: Arreglo[30] : Entero
2.- Método establecerProduccion(pro[]:
Entero)
Producción = pro
Fin método establecerProduccion
3.- Metodo obtenerProduccion(): Arreglo[]
Entero
Return producción
Fin método obtenerProduccion
Fin Clase Obrero
Clase Ejecutaobrero
1.- Metodo principal Declaraciones Variables Prod, prod2:arreglo[30] Entero I : Entero Declarar, crear e iniciar objeto Obrero objObrero = new Obrero() For i = 0; i<=29; i++ Solicitar producción del dia i +1 Leer prod[i ] EndFor
Establecer objObrero.establecerProduccion(prod)
Obtener Prod2 = objObrero.obtenerProduccion()
For i = 0 ; i <= 29: i++ Imprimir prod[i] EndFor
Fin Metodo principal Fin Clase EjecutaObrero
255
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Algoritmo y programa OO usando herencia en Visual Basic NET
Ejemplo:
En cierta empresa se tienen empleados; los empleados se dividen en dos tipos,
empleados por hora, a los que se les paga de acuerdo con el número de horas
trabajadas y a una cuota por hora. El otro tipo son los empleados asalariados, a
quienes se les paga de acuerdo a un sueldo fijo mensual. Se desea procesar a los
empleados para realizar los pagos por medio de un programa de computo.
Clase empleado
Declaraciones: Datos
# nombreEmpleado : cadena
# deptoEmple : cadena
# puestoTrabajo: cadena
Método establecerNombre(nom : cadena)
nombreEmpleado = nom
Fin método establecerNombre
Método establecerDepto(dep: cadena)
depatoEmple = dep
Fin de método establecerDepto
Método establecerPuesto(pues : cadena)
puestoTrabajo = pue
fin método establecerPuesto
Metodo obtenerNombre() : cadena
Return nombreEmpleado
Fin método obtenerNombre
Método obtenerPuesto() : cadena
Return puestoTrabajo
Fin método obtenerPuesto
Método obtenerDpto() : cadena
Return deptoEmple
Fin método obtenerDpto
Fin clase empleado
256
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Clase EmpleadoPor Hora
Declaraciones
Datos
horasTrabajadas : Entero
cuotaHora : Real
SueldoQnal : Real
Metodo establecerHoras(horasT : Entero)
horasTrabajadas = horasT
Fin método establecerHoras
Metodo establecerCuota(cuotaH : Real)
cuotaHora = cuotaH
Fin método establecerCuota
Metodo calcularSueldoQnal()
SueldoQnal = horasTrabajadas *
cuotaHora
Fin método CalcularSueldoQnal
Metodo obtenerSueldoQnal() : Real
Return sueldoQnal
Fin método obtenerSueldoQnal
Fin Clase EmpleadoPorHoras
Clase EmpleadoAsalariado
Declaraciones
Datos
SueldoQnalAsal : Real
SueldoMensual : Real
Método calcularrSueldoQnalAsal()
SueldoQnalAsal = SueldoMensual/2
Fin método calcularSueldoQnalAsal
Método establecerSueldoMensual(sdo : Real)
SueldoMensual = sdo
Fin método establecersueldoMensual
Metodo obtenerSueldoQnalAsal() : Real
Return SueldoQnalAsal
Fin método obtenerSueldoQnalAsal
Fin clase EmpleadoAsalariado
257
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Clase EjecutaEmpleado
Metodo principal
Declaraciones
Variables
nomEmple, depto, puesto : cadena
hrsTra,TipoEmp : Entero
cuoH, SdoMen : Real
desea : carácter
Do
Imprimir menú y solicitar tipo de empleado
Tipos de empleados
1.- Empleado por Horas
2.- Empleado asalariado
Teclee tipo
Leer tipoEmp
Solicitar Nombre, departamento y puesto
Leer nomEmple, depto, puesto
If tipoEmple = 1 then
Crear objeto EmpleadoPorHora
objEmpleado = new EmpleadoPorHora()
Solicitar número de horas trabajadas y cuota
por hora
Leer hrsTra, cuoH
Establecer
objEmpleado.
establecerNombre(nomEmple)
objEmpleado.establecerDepto(depto)
objEmpleado.establecerPuesto(puesto)
objEmpleado. establecerHoras(hrsTra)
objEmpleado.establecerCuota(cuoH )
objEmpleado. establecerHoras(hrsTra)
objEmpleado.establecerCuota(cuoH)
Calcular
objEmpleado. calcularSueldoQnal()
Visualizar
objEmpleado. obtenerNombre()
objempleado.obtenerPuesto()
objEmpleado.obtenerDpto()
objEmpleado. obtenerSueldoQnal()
Else
Crear objeto EmpleadoAsalariado
objEmpleado = new empleadoAsalariado()
Solicitar sueldo mensual
Leer SdoMen
258
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Establecer
objEmpleado. establecerNombre(nomEmple)
objEmpleado.establecerDepto(depto)
objEmpleado.establecerPuesto(puesto)
objEmpleado.
establecerSueldoMensual(SdoMen)
Calcular
objEmpleado. calcularSueldoQnalAsal()
Visualizar
objEmpleado. obtenerNombre()
objempleado.obtenerPuesto()
objEmpleado.obtenerDpto()
objEmpleado. obtenerSueldoQnalAsal()
Endif
Preguntar “¿Desea procesar otro empleado
S/N)? ”
Leer Desea
WHILE Desea = “S”
Fin metodo principal
Fin clase EjecutaEmpleado
259
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Algoritmo y programa OO usando polimorfismo en Visual Basic NET.
Ejemplo: El mismo ejercicio anterior, pero utilizando el concepto de
polimorfismo
Clase abstracta Empleado2 Declaraciones Datos # nombreEmpleado: Cadena # deptoEmple : Cadena # puestoTrabajo : Cadena # SueldoQna: Real Metodo establecerNombre(nom: Cadena) nombreEmpleado = nom Fin método establecerNombre Método establecerDepto(dep: cadena) deptoEmple = dep Fin de método establecerDepto Método establecerPuesto(pues : cadena) puestoTrabajo = pue fin método establecerPuesto Metodo abstracto calcularSueldoQna()
Metodo obtenerNombre() : cadena Return nombreEmpleado Fin método obtenerNombre Método obtenerPuesto() : cadena Return puestoTrabajo Fin método obtenerPuesto Método obtenerDpto() : cadena Return deptoEmple Fin método obtenerDpto
Método obtenerSueldoQna() : Real
Return SueldoQna
Fin método obtenerDpto
Fin clase Empleado2
260
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Clase EmpleadoPor Hora2 hereda de Empleado2 Declaraciones Datos horasTra : Entero cuotaHora : Real Metodo establecerHoras(horasT : Entero) horasTrab = horasT Fin método establecerHoras Metodo establecerCuota(cuotaH : Real) cuotaHora = cuotaH Fin método establecerCuota Metodo calcularSueldoQna() SueldoQnal = horasTrabajadas * cuotaHora Fin método CalcularSueldoQna Fin Clase EmpleadoPorHora2
Clase EmpleadoAsalariado2
Declaraciones
Datos
SueldoMensual : Real
Método calcularrSueldoQnalAsal()
SueldoQnalAsal = SueldoMensual/2
Fin método calcularSueldoQnalAsal
Metodo obtenerSueldoQnalAsal() : Real
Return SueldoQnalAsal
Fin método obtenerSueldoQnalAsal
Fin clase EmpleadoAsalariado2
261
MSc. Ing. Jorge J. Prado D. Docente: Univ. Nac. De Ingenieria, Managua
Clase EjecutaEmpleado2
Metodo principal
Declaraciones
Variables
nomEmple, depto, puesto : cadena
hrsTra,TipoEmp : Entero
cuoH, SdoMen : Real
desea : carácter
Do
Imprimir menú y solicitar tipo de empleado
Tipos de empleados
1.- Empleado por Horas
2.- Empleado asalariado
Teclee tipo
Leer tipoEmp
Solicitar Nombre, departamento y puesto
Leer nomEmple, depto, puesto
If tipoEmple = 1 then
Crear objeto EmpleadoPorHora2
objEmpleado = new empleadoPorHora2()
Solicitar número de horas trabajadas y cuota por
hora
Leer hrsTra, cuoH
Establecer
objEmpleado. establecerNombre(nomEmple)
objEmpleado.establecerDepto(depto)
objEmpleado.establecerPuesto(puesto)
objEmpleado.establecerSueldoMensual(SdoMen)
Calcular
objEmpleado.calcularSueldoQnalAsal()
Visualizar
objEmpleado.obtenerNombre()
objempleado.obtenerPuesto()
objEmpleado.obtenerDpto()
objEmpleado.obtenerSueldoQnalAsal
Endif
Preguntar “¿Desea procesar otro empleado
(S/N)? ”
Leer Desea
WHILE Desea = “S”
Fin método principal
Fin clase EjecutaEmpleado2