sábado, 18 de junio de 2011

Programación III

Los artículos para la clase de Programación III están publicados en el blog:
ucytprog3.blogspot.com

Saludos.

martes, 19 de abril de 2011

Ejercicio de DataGridView y Reporte

Tomando como punto de partida el ejercicio de solución del exámen del post anterior vamos a modificarlo para hacerlo un poco más especializado. Primero revisemos el formulario original


Si nos detenemos en la pantalla un momento podemos ver que hay varios puntos que podemos corregir para evitar que los usuarios cuando ingresen información registren información inconsistente.

Por ejemplo en el caso de la asignatura, en la pantalla de ingreso hay que digitarla, esto podría generar inconsistencia por ejemplo si alguien digita Programación I y posteriormente se ingresa Pogramación I, son dos cosas diferentes y si queremos generar posteriormente un listado de esta asignatura no nos aparecerían las dos correctamente. Para reforzar este punto vamos a crear una nueva tabla en la base de datos con la siguiente estructura.

  Del mismo modo los estudiantes deberían tener una tabla donde estén registrados y tengan un valor único como lo es su código de carnet.  La estructura de la tabla de estudiantes sería así:

Al final modificamos la estructura original de la tabla Notas quedando de la siguiente manera:


  El código de carnet debe enlazarse con el carnet de la tabla Estudiantes y el código de asignatura debe enlanzarse con el código de asignatura de la tabla Asignaturas.  De esta manera no se podrán ingresar a la tabla de notas estudiantes que no estén registrados en la tabla Estudiantes y lo mismo pasaría con las asignaturas.

Para el caso de las asignaturas, cambiaremos la pantalla eliminando el cuadro de texto txtAsignatura y lo sustituiremos por un control ComboBox llamado ComboBox1.

Utilizando los objetos DataAdapter, Dataset y Datatable, asignaremos al formulario los datos de las asignaturas para que puedan ser seleccionadas de las existentes en la tabla de Asignaturas.

Para ello daremos doble click en el formulario para que nos lleve al evento Form1_Load y escribiremos en el procedimiento lo siguiente:

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim da As New SqlDataAdapter("SELECT * FROM Asignaturas", cn)
Dim ds As New DataSet
da.Fill(ds)
ComboBox1.DataSource = ds.Tables(0)
ComboBox1.DisplayMember = "Descripcion"
ComboBox1.ValueMember = "Asignatura"
End Sub



ACLARACION:


Muchos controles tienen la propiedad o atributo DataSource la cual especifica una tabla de donde se sacarán los datos para mostrarlos. En el caso del ComboBox en la propiedad DataSource se asigna la tabla 0. También pudo ampliarse la declaración de la siguiente manera:







Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim da As New SqlDataAdapter("SELECT * FROM Asignaturas", cn)
Dim ds As New DataSet
da.Fill(ds)
Dim dt as new Datatable
dt = ds.Tables(0)
ComboBox1.DataSource = dt
ComboBox1.DisplayMember = "Descripcion"
ComboBox1.ValueMember = "Asignatura"
End Sub






Queremos también construir un formulario que muestre todas las notas ingresadas. Para esto utilizaremos algunos de los conocimientos adquiridos en Bases de Datos II y me refiero a las vistas de SQL Server.





CREACION DE LA VISTA EN SQL SERVER

El proceso de creación de la vista es sencillo. Queremos obtener el carnet del estudiante, su nombre, el nombre de la asignatura y su nota final. Para ello tendríamos que construir una sentencia select que mezcle la información de las tres tablas.

Podemos construirla manualmente. La tabla principal es Notas que es la que contiene tanto el carnet como el código de asignatura y la nota final, así que comenzamos con ella.

SELECT Notas.Carnet, Estudiante.Nombre, Asignatura.Descripcion, Notas.NotaFinal
FROM Notas INNER JOIN Estudiante ON Notas.Carnet = Estudiante.Carnet
INNER JOIN Asignatura ON Notas.Asignatura = Asignaturas.Asignatura

La vista puede crearse directamente en SQL Server para ello seleccionamos el objeto Views o Vistas y presionando click con el botón derecho del mouse seleccionamos Nueva Vista (New View)


Se abrirá un diseñador de vistas y un cuadro de diálogo con las tablas existentes.  Seleccionar las tres tablas con Shift + Flechas y presionar el botón Add.  Se añadiran las tablas y quedará una pantalla parecida a la siguiente.

  Ahora seleccione los campos necesarios marcando cada uno en la tabla correspondiente.  De la tabla Notas el carnet, de la tabla Estudiantes el nombre, de la tabla asignaturas la descripción y de la tabla Notas la nota final.  Si se fija en el diseñador se va creando la sentencia SQL cada vez que selecciona algo.

Guardemos la vista con el nombre VistaNotas.

Ahora agregaremos un botón al formulario y le pondremos como nombre btnTodasNotas.  También agregaremos al proyecto un nuevo formulario llamado ConsultaNotas y agregaremos al formulario un control DataGridView, podemos dejarlo con el mismo nombre que Visual Basic asigna : DataGridView1 y dos botones, el primero dirá Salir y lo llamaremos btnSalir y su código ya lo conocemos (Me.Dispose()) y un segundo botón que se llamará btnReporte que explicaremos luego.   El formulario lucirá más o menos como el siguiente:


Ahora en el botón btnListado colocaremos  el siguiente código

Private Sub btnTodasNotas_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTodasNotas.Click
ConsultaNotas.ShowDialog()
End Sub

Con este código llamaremos al formulario ConsultaNotas desde el formulario Form1

El código del formulario ConsultaNotas es el siguiente:
Imports System.Data
Imports System.Data.SqlClient

Public Class ConsultaNotas
'Declararemos la conexión aquí para que esté visible a todos los procedimientos
Dim cn As New SqlConnection("Data source=3PHPB01\SQLEXPRESS;Initial Catalog=Examen2;Integrated Security=true")
Private Sub ConsultaNotas_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim da As New SqlDataAdapter("SELECT * FROM VistaNotas", cn)
Dim ds As New DataSet
da.Fill(ds)
DataGridView1.DataSource = ds.Tables(0)
End Sub
End Class

Nos falta crear el reporte de Notas registradas en el sistema. Visual Basic 2008 en su versión Profesional permite crear reportes con dos componentes Microsoft ReportViewer y Crystal Reports. Vamos a crear un reporte usando el Microsoft ReportViewer. Para ello podemos usar el asistente de reportes que es la manera más fácil, pero no la mas adecuada cuando programamos una aplicación real. Seleccionamos el proyecto y presionamos el botón derecho del mouse y seleccionamos la opción Add (Agregar) / New Item (Nuevo Elemento)


Seleccionar el elemento Report Wizard y colocar en el nombre del Reporte Notas.rdlc
(la extensión rdlc significa Report Definition Language Client side). Este asistente nos llevará de la mano para crear el reporte a través de varias pantallas.

En la primer pantalla nos dará una bienvenida al asistente de reportes, necesitamos dar click al botón Next. La pantalla solo nos informa de los pasos que se seguirán hasta concluir con el reporte que queremos.




En la segunda pantalla debemos escoger Database y presionar Next. 

report3

En esta tercer pantalla debemos crear una nueva conexión si no la hemos creado aún.  Cuando le damos click al botón correspondiente nos aparecerá un cuadro de diálogo donde debemos escribir el nombre de nuestro servidor y seleccionar la base de datos requerida (Examen2).

La pantalla es parecida a la siguiente:

report4

report5

Aqui podemos cambiar el nombre de la conexión o dejarlo como lo recomienda el sistema.  Presionamos Next y continuamos con la siguiente pantalla donde nos aparecerá los objetos de la base de datos. 

Queremos generar el reporte a partir de los datos contenidos en la vista recien creada (VistaNotas). Así que seleccionamos las vistas y marcamos la vista correspondiente

report6En la siguiente pantalla nos creará un nuevo dataset en forma gráfica donde aparecerán los datos de los campos de la vista. Presionamos Next.

report7Ahora en las siguientes pantallas ya entramos al diseño del reporte.  La primera pantalla es para seleccionar el tipo de reporte.  Seleccionaremos tabular y presionamos Next.

report8   Posteriormente miraremos una pantalla donde podremos entre otras cosas agrupar el reporte, definir que campos van en el detalle, etc.  Para nuestro caso lo que haremos será seleccionar todos los campos y presionar el botón Details (Detalle)


report10
report9



De aqui en adelante si queremos podemos presionar Finish o seguir dando algunas características para el reporte.

report11

Seleccionamos en esta pantalla en tipo Stepped y presionamos Next

report12
Aquí definimos el modelo de colores que nos guste más.  Seleccionemos el primero y presionemos Next.  Ya casi llegamos al final de la elaboración del reporte de esta manera fácil.

report13Esta pantalla es la conclusión del reporte con datos de lo creado por el asistente.  Solo presionamos Finish y nos llevará hasta el reporte creado para que le hagamos cambios si es necesario.

Llegaremos a la pantalla siguiente.

report14 

Aqui está creado el reporte.

Ahora grabamos y regresemos a la aplicación.  Agreguemos un nuevo formulario y pongamosle como nombre Reporte.  Agreguemos a este formulario un control Microsoft ReportViewer que encontraremos en la categoría Reporting de la Caja de Herramientas.

form2_1

Ahora en el control añadido vamos a la esquina superior derecha y encontraremos una flecha; presionémosla y aparecerá un menú emergente donde podremos seleccionar el reporte creado y además usar la ocpión DOCK IN PARENT CONTAINER (Acoplar en el contenedor principal), lo cual hará que el control tenga las dimensiones del formulario y se agrande o reduzca si el formulario se cambia de tamaño.

Bueno con esto estamos listos, solo falta ir al formulario ConsultaNotas y dar click en el boton btnReporte y escribir el código

Private Sub btnReporte_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnReporte.Click
Reporte.ShowDialog()
End Sub

En los enlaces siguientes les dejo el código completo de la aplicación y el script para la generación de la base de datos Examen2.  Si la base ya la tenían deben eliminarla y posteriormente ejecutar el script.  Dentro del script se crean dos estudiantes y dos asignaturas.  Pueden revisar los datos para que anoten el código del carnet y consulten.  No hay notas registradas para los estudiantes.  Prueba registrar notas para un estudiante y pruebe el botón Todas las Notas y el reporte.

NOTA
Para que funcione en su máquina debe cambiar las cadenas de conexión del programa para que apunten a su servidor. Además para que funcione el reporte debe ir al menú principal del Visual Basic y en el menú PROYECTO seleccionar la última opción ExamenSP_1C2011 Properties, y en el cuadro que aparece seleccionar el tab Setting.  Aparecerá la configuración del dataset creado por el asistente del reporte y podrá ver una cadena de conexión; con mucho cuidado solo cambie el nombre del servidor y listo.

Los enlaces para bajar la aplicación y el script están a continuación:
Programa completo
Script de creación de la BD

sábado, 9 de abril de 2011

Solución Examen Parcial (II) Miércoles 06 Abril 2011 - Matutino

Enunciado:
1) Crear una base de datos en SQL Server 2005 llamada Examen2
2) Crear una tabla llamada notas en la base Examen2 que tenga la siguiente estructura:

Campo Tipo
Carnet char(7)
Nombre varchar(50)
Asignatura varchar(50)
NotaPP int
NotaSP int
NotaTA int
NotaEF int
NotaFinal real

3) Crear un programa en visual basic 2008 que permita ingresar datos a
la tabla Notas.

4) La nota final se calculará en base a los parámetros de UCYT para los
cursos regulares.

5) El programa también deberá poder consultar las notas de un estudiante
y mostrar su estado (Aprobado o REPROBADo) en la barra de título

6) Se debe validar que las notas no sean menor que 0 ni mayor que 100
Si ingresara un dato en ese rango debe aparecer un mensaje de error
correspondiente.

SOLUCION:

Hay que diseñar un formulario para obtener o mostrar los datos al usuario. El diseño era parte del examen. Todo programador deber diseñar su propio formulario de acuerdo a su creatividad e ingenio. Una solución sencilla podría ser la siguiente:


El proyecto a realizar consta de un formulario.  Lo primero que hay que hacer es colocar al inicio del formulario dos líneas que nos permitirán tener acceso a la librería de datos ADO .NET para SQL Server.

Imports System.Data
Imports System.Data.SqlClient

Estas líneas se deben colocar al inicio del formulario, antes de la declaración de clase del formulario (Public Class Form1)

Para que nuestro sistema conecte al servidor SQL Server donde creamos la base de datos Examen2 necesitamos crear una cadena de conexión.  Es importante en este paso saber que usaremos la cadena de conexión por lo menos en dos puntos del programa y dos procedimientos diferentes, entonces para evitar estar digitando la cadena varias veces, se puede definir después de la declaración de la clase del formulario y antes de cualquier procedimiento.

Public Class Form1
    'Declararemos la conexión aquí para que esté visible a todos los procedimientos
    Dim cn As New SqlConnection("Data source=3PHPB01\SQLEXPRESS;Initial Catalog=Examen2;Integrated Security=true")


El botón Grabar (llamado btnGrabar) es el que hará el proceso de insertar el nuevo registro en la base de datos

Private Sub btnGrabar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGrabar.Click
        'Hay que validar las notas
        If Val(txtNotaPP.Text) < 0 Or Val(txtNotaPP.Text) > 100 Then
            MessageBox.Show("La nota del primer parcial no esta en el rango establecido...por favor revise")
            Exit Sub
        End If

        If Val(txtNotaSP.Text) < 0 Or Val(txtNotaSP.Text) > 100 Then
            MessageBox.Show("La nota del segundo parcial no esta en el rango establecido...por favor revise")
            Exit Sub
        End If

        If Val(txtNotaTA.Text) < 0 Or Val(txtNotaTA.Text) > 100 Then
            MessageBox.Show("La nota del trabajo acumulado no esta en el rango establecido...por favor revise")
            Exit Sub
        End If

        If Val(txtNotaEF.Text) < 0 Or Val(txtNotaEF.Text) > 100 Then
            MessageBox.Show("La nota del exámen final no esta en el rango establecido...por favor revise")
            Exit Sub
        End If

        'Calcular la nota final usando la función de usuario CalcularNotaFinal() y colocar el resultado
        'en la caja de texto.
        txtNotaFinal.Text = CalcularNotaFinal()

        'Si todo esta bien se sigue con la grabación de los datos
        Dim sql As String
        sql = "INSERT INTO Notas "
        sql &= "(Carnet, Nombre, Asignatura, NotaPP, NotaSP, NotaTA, NotaEF, NotaFinal)"
        sql &= "VALUES(@Carnet, @Nombre, @Asignatura, @NotaPP, @NotaSP, @NotaTA, @NotaEF, @NotaFinal)"

        Dim cmd As New SqlCommand(sql, cn)
        cmd.Parameters.AddWithValue("@Carnet", txtCarnet.Text)
        cmd.Parameters.AddWithValue("@Nombre", txtNombre.Text)
        cmd.Parameters.AddWithValue("@Asignatura", txtAsignatura.Text)
        cmd.Parameters.AddWithValue("@NotaPP", Val(txtNotaPP.Text))
        cmd.Parameters.AddWithValue("@NotaSP", Val(txtNotaSP.Text))
        cmd.Parameters.AddWithValue("@NotaTA", Val(txtNotaTA.Text))
        cmd.Parameters.AddWithValue("@NotaEF", Val(txtNotaEF.Text))
        cmd.Parameters.AddWithValue("@NotaFinal", CalcularNotaFinal())
        cn.Open()
        Dim i As Integer = cmd.ExecuteNonQuery()
        If i > 0 Then
            MessageBox.Show("Registro grabado...")
        Else
            MessageBox.Show("No se pudo guardar el registro...")
        End If
        cn.Close()
    End Sub

Comentando un poco el código, hemos hecho inicialmente la validación de las cajas de texto que corresponden a las notas para garantizar que estas no sean ni menor que 0 ni mayor que 100. La validación se puede hacer de diferentes maneras, la que se presenta no es la mejor pero la más simple. Nótese que el código se puede copiar cuatro veces solo cambiando el control de texto correspondiente. La función VAL convierte una expresión en un número. Se recomienda usar la funciones Convert (Ej. Convert.ToInt32(txtNotaPP.Text))

Si revisan el código, hemos utilizado una función llamada CalcularNotaFinal que calcula la nota final del estudiante en base a lo que hemos digitado en las cajas de texto. El uso de funciones simplifican el código que se escribe y lo deja más legible. La función es la siguiente:

Private Function CalcularNotaFinal() As Integer
        Dim npp, nsp, nta, nef As Integer
        npp = Val(txtNotaPP.Text)
        nsp = Val(txtNotaSP.Text)
        nta = Val(txtNotaTA.Text)
        nef = Val(txtNotaEF.Text)
        Dim notafinal As Integer
        notafinal = npp * 0.2 + nsp * 0.2 + nta * 0.2 + nef * 0.4
        Return notafinal
    End Function

Finalmente en el botón con los tres puntos (btnBuscar) hacemos la búsqueda del carnet del estudiante y mostramos los datos. Se evalúa la nota final y se coloca en la barra de titulo el estado del estudiante (APROBADO o REPROBADO)

  Private Sub btnBuscar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBuscar.Click
        'Validemos que ya hemos colocado un código de carnet
        If txtCarnet.Text = "" Then
            MessageBox.Show("No se ha digitado el código de carnet")
            Exit Sub
        End If

        Dim cmd As New SqlCommand("SELECT * FROM Notas WHERE Carnet = @Carnet", cn)
        cmd.Parameters.AddWithValue("@Carnet", txtCarnet.Text)
        cn.Open()
        Dim dr As SqlDataReader = cmd.ExecuteReader()
        If dr.Read() Then
            txtNombre.Text = dr("Nombre")
            txtAsignatura.Text = dr("Asignatura")
            txtNotaPP.Text = dr("NotaPP")
            txtNotaSP.Text = dr("NotaSP")
            txtNotaTA.Text = dr("NotaTA")
            txtNotaEF.Text = dr("NotaEF")
            txtNotaFinal.Text = dr("NotaFinal")

            'Colocar el estado de la nota en la barra de titulo
            If Val(txtNotaFinal.Text) >= 70 Then
                Me.Text = "Alumno : " & txtNombre.Text & " esta APROBADO "
            Else
                Me.Text = "Alumno : " & txtNombre.Text & " esta REPROBADO "
            End If
        Else
            MessageBox.Show("El carnet " & txtCarnet.Text & " no tiene notas registradas")
        End If
        cn.Close()
    End Sub

Y eso es todo. El programa completo lo pueden bajar en el siguiente enlace para que lo tengan. Es probable que lo usemos en clase.
Proyecto Completo en VB 2008
Script para crear la base de datos

El script para crear la base de datos Ejercicio2 es un archivo con las instrucciones para crear la BD.  Solo se requiere abrir en el SQL Management Studio (consola de SQL Server) y ejecutarlo.  No se preocupe si la base no aparecer, solo vaya al objeto Databases y con el botón derecho seleccione Refresh.

Hasta pronto.