miércoles, 5 de junio de 2013

Agrupar datos en Crystal Report

A continuación tenemos un ejemplo de que permite agrupar los datos en un Crystal report. 

Para nuestro ejemplo estamos utilizando la base de datos Northwind en donde hemos creado un procedimiento almacenado llamado sp_Agrupar_Productos_por_categoria

1. Procedimiento SQL Server

Create proc sp_Agrupar_Productos_por_categoria
as
      begin
      select c.CategoryID ,
                  c.CategoryName ,
                  p.ProductID ,
                  p.ProductName ,
                  p.QuantityPerUnit,
                  p.UnitPrice,
                  p.UnitsInStock
                 
            from Products p inner join Categories c
            on c.CategoryID = p.CategoryID
            order by c.CategoryName asc
End

2. Elaboración de reporte

Luego de haber creado nuestro procedimiento almacenado procedemos a crear nuestro reporte. 
  1. Agregamos Nuevo Elemento - CrystalReport1.rpt
  2. Seleccionamos como informe en blanco
En nuestro caso estamos utilizando la conexión ODBC y para poder configurar nos dirigimos a la siguiente ruta:
Panel de control\Herramientas administrativas\Orígenes de datos ODBC
Luego de haber configurado el ODBC.

Paso 1: Procedemos a seleccionar "Campos de base de datos".


Paso 2: Nos mostrar un asistente de base de datos en donde seleccionamos muestro procedimiento almacenado.


Paso 3: Para poder crear grupos de datos en CrytalReport podemos realizar lo de la siguientes maneras.

  1. Crystal Report > Insertar > Grupo 
  2. Clic derecho > Insertar > Grupo

Paso 4: Nos mostrar el siguiente formulario en donde nos solicitara seleccionar el tipo de dato a agrupar, en nuestro caso seleccionaremos el CategoryID.


Paso 5: Luego de haber seleccionado el tipo de datos a agrupar procedemos a personalizar nuestro reporte con los datos necesario para mostrar.


Paso 6: Luego de haber finalizado con el diseño presionamos clic "Vista previa del informe principal"



Como podremos observar tenemos un reporte agrupado por el id Categoría.

domingo, 2 de junio de 2013

Exportar desde Datagridview a un PDF

 A continuación tenemos un ejemplo que nos permite exportar datos desde un datagridview a un PDF.

Para poder realizar dicha proceso se utiliza como referencia itextsharp.


Código fuente

Paso 1: Agregar las referencias

Imports iTextSharp.text
Imports iTextSharp.text.pdf
Imports System.IO

Paso 2: Cargamos los productos en el datagridview

Private Sub Form1_Load(ByVal sender As System.ObjectByVal e As System.EventArgsHandles MyBase.Load
        Listar_Productos()
End Sub

Paso 3: Procedimiento para mostrar los productos

Sub Listar_Productos()
Try
   Dim Codigo() As Integer = {1, 2, 3, 4, 5}
   Dim Producto() As String = {"Camara""Impresora""Monitor""Ordenador""Scanner"}
   Dim Precio() As Double = {12.5, 20.5, 78.5, 20.25, 12.8}
   Dim Stock() As Double = {100, 150, 250, 300, 80}
   Dim RutaImagen() As String = {"D:\Exportar Desde Datagridview a PDF\Imagenes\camara.jpg",
                          "D:\Exportar Desde Datagridview a PDF\Imagenes\Impresora.jpg",
                          "D:\Exportar Desde Datagridview a PDF\Imagenes\monitor.jpg",
                          "D:\Exportar Desde Datagridview a PDF\Imagenes\ordenador.jpg",
                          "D:\Exportar Desde Datagridview a PDF\Imagenes\scanner.jpg"}
 dtgProductos.Rows.Clear()
 For i As Integer = 0 To Codigo.Length() - 1
    dtgProductos.Rows.Add()

    dtgProductos("txt_dtgProductos_Codigo", i).Value = Codigo(i)
    dtgProductos("txt_dtgProductos_Producto", i).Value = Producto(i)
    dtgProductos("txt_dtgProductos_Precio", i).Value = Precio(i)
    dtgProductos("txt_dtgProductos_Stock", i).Value = Stock(i)
    dtgProductos("txt_dtgProductos_RutaImagen", i).Value = RutaImagen(i)

    dtgProductos("img_dtgProductos_ImagenProducto", i).Value = System.Drawing.Image.FromFile(RutaImagen(i))
  Next

Catch ex As Exception
      MessageBox.Show(ex.Message, "vb.net"MessageBoxButtons.OK, MessageBoxIcon.Error)
 End Try
End Sub

Paso 4: Método para crear el reporte del PDF

'Metodo para crear el reporte en PDF.
Public Function GetColumnasSize(ByVal dg As DataGridViewAs Single()
  Dim values As Single() = New Single(dg.ColumnCount - 1) {}
   For i As Integer = 0 To dg.ColumnCount - 1
       values(i) = CSng(dg.Columns(i).Width)
   Next
   Return values
End Function

Paso 5: Creamos un proceso para crear el reporte

Public Sub ExportarDatosPDF(ByVal document As Document)
 'Se crea un objeto PDFTable con el numero de columnas del DataGridView. 
  Dim datatable As New PdfPTable(dtgProductos.ColumnCount)
 'Se asignan algunas propiedades para el diseño del PDF.
  datatable.DefaultCell.Padding = 3
  Dim headerwidths As Single() = GetColumnasSize(dtgProductos)
  datatable.SetWidths(headerwidths)
  datatable.WidthPercentage = 100
  datatable.DefaultCell.BorderWidth = 2
  datatable.DefaultCell.HorizontalAlignment = Element.ALIGN_CENTER
  'Se crea el encabezado en el PDF. 
   Dim encabezado As New Paragraph("PRODUCTOS INFORMATICOS"New Font(Font.Name = "Tahoma", 20, Font.Bold))

   'Se crea el texto abajo del encabezado.
    Dim texto As New Phrase("Reporte productos:" + Now.Date(), New Font(Font.Name = "Tahoma", 14, Font.Bold))
   'Se capturan los nombres de las columnas del DataGridView.
    For i As Integer = 0 To dtgProductos.ColumnCount - 1
         datatable.AddCell(dtgProductos.Columns(i).HeaderText)
    Next
    datatable.HeaderRows = 1
    datatable.DefaultCell.BorderWidth = 1
    'Se generan las columnas del DataGridView. 
    For i As Integer = 0 To dtgProductos.RowCount - 1
        For j As Integer = 0 To dtgProductos.ColumnCount - 1
           'compruebo que columna contien la imagen y en que columna deseo que se muestre
           If (j = 4) Then
              'capturo la ruta de la imagen
              Dim RutaImage As String
              RutaImage = dtgProductos("txt_dtgProductos_RutaImagen", i).Value
              'Procedo a convertir a imagen de tipo itextsharp.text.image
              Dim Img As Image = Image.GetInstance(RutaImage)
              'agrego la imagen a la celda
              datatable.AddCell(Img)
            Else
              datatable.AddCell(dtgProductos(j, i).Value.ToString())
            End If

        Next
            datatable.CompleteRow()
   Next
      'Se agrega el PDFTable al documento.
      document.Add(encabezado)
      document.Add(texto)
      document.Add(datatable)
End Sub

Paso 6: Programamos el botón btnExportarPDF

Private Sub btnExportarPDF_Click(ByVal sender As System.ObjectByVal e As System.EventArgsHandles btnExportarPDF.Click
   Try
      'Intentar generar el documento.
      Dim doc As New Document(PageSize.A4.Rotate(), 10, 10, 10, 10)
      'Path que guarda el reporte en el escritorio de windows (Desktop).
       Dim filename As String = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\Reporteproductos.pdf"
      Dim file As New FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)
      PdfWriter.GetInstance(doc, file)
      doc.Open()
      ExportarDatosPDF(doc)
      doc.Close()
      Process.Start(filename)
Catch ex As Exception
     'Si el intento es fallido, mostrar MsgBox.
      MessageBox.Show("No se puede generar el documento PDF.""Error"MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub

Resultado

Fuentes.

El código fuente a sido auditado por mi persona desde.

http://ripertec.wordpress.com/tag/exportar-datagridview-a-pdf-visual-basic-2008/

sábado, 13 de abril de 2013

Personalizar las filas de un Datagridview

La mayoría de los proyecto realizado, siempre utilizamos los mismos controles de siempre en esta oportunidad tenemos un ejemplo de como personalizas la filas de un datagridview.

El siguiente ejemplo nos muestra la siguiente imagen donde observamos que las columnas ("código"," producto", "precio * unidad") tienen las primeras fila un BackColor = Write , pero la ultima se asigno un BackColor  = PaleGreen, de misma manera la columnas de ("Cant")., tiene las primeras filas un BackColor  = LemonChiffon  pero la ultima fila tiene el color asignado BackColor =MistyRose.

Así mismo estamos utilizando el evento CellEndEdit del datagridview, que nos permitirá realizar los cálculos del importe a pagar luego de haber finalizado la edición de la celda ("Cant").


Código fuente

Paso 1: Programar función Listar_productos

Sub Listar_productos()
Try
    Dim Codigo() As Integer = {1, 2, 3, 4, 5}
    Dim Productos() As String = {"Gaseosa""Yogurt""Galletas""Chocolates""Caramelos"}
    Dim PreciosXunidad() As Double = {1.5, 1.2, 0.5, 0.5, 0.1}

    DataGridView1.Rows.Clear()
    For index As Integer = 0 To Codigo.Length - 1
        DataGridView1.Rows.Add()
        DataGridView1("txtCodigo", index).Value = Codigo(index)
        DataGridView1("txtProducto", index).Value = Productos(index)
        DataGridView1("txtPrecioXunidad", index).Value = PreciosXunidad(index)
    Next

'Agregamos una fila para que contendrá lo siguiente
 DataGridView1.Rows.Add()
 DataGridView1("txtProducto", DataGridView1.Rows.Count - 1).Value = "Importe Total Pagar S/."
 DataGridView1("txtPrecioXunidad", DataGridView1.Rows.Count - 1).Value = "===>"

Catch ex As Exception
            MessageBox.Show(ex.Message, "vb.net", _
                   MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub

Paso 2: Cargar los productos

Private Sub frmVentas_Load(ByVal sender As System.ObjectByVal e As System.EventArgsHandles MyBase.Load
    'Cargamos los productos
    Listar_productos()
End Sub

Paso 3: Asignamos formatos a las celda del datagridview

Private Sub DataGridView1_CellFormatting(ByVal sender As System.ObjectByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgsHandles DataGridView1.CellFormatting
Try
            
   Dim Tipo As String
   'comprobamos que sea la columna txtCant
   If (DataGridView1.Columns(e.ColumnIndex).Name.Equals("txtCant")) Then
      'Capturamos el valor de la celda
      Tipo = DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value
      If (DataGridView1.Rows.Count - 1 > e.RowIndex) Then
          If (Tipo = ""Then
              e.CellStyle.BackColor = Color.LemonChiffon
          Else
              e.CellStyle.BackColor = Color.White
          End If
      Else
          e.CellStyle.BackColor = Color.MistyRose
      End If

   ElseIf (DataGridView1.Columns(e.ColumnIndex).Name.Equals("txtProducto")) Then
      Tipo = DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value
      'verificamos que el valor de la celda contemga el siguiente Texto
      If (Tipo = "Importe Total Pagar S/."Then
      'asignamos un color que diferencie a las demas celdas de la columna txtProducto
         DataGridView1("txtCodigo", e.RowIndex).Style.BackColor = Color.PaleGreen
         DataGridView1("txtProducto", e.RowIndex).Style.BackColor = Color.PaleGreen
         DataGridView1("txtPrecioXunidad", e.RowIndex).Style.BackColor = Color.PaleGreen
      Else
         e.CellStyle.BackColor = Color.White
      End If

   ElseIf (DataGridView1.Columns(e.ColumnIndex).Name.Equals("txtImportePagar")) Then
      Tipo = DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value
      If (DataGridView1.Rows.Count - 1 > e.RowIndex) Then
         If (Tipo = ""Then
            e.CellStyle.BackColor = Color.White
         Else
           e.CellStyle.BackColor = Color.Silver
          End If
      Else
           e.CellStyle.BackColor = Color.MistyRose
      End If
   End If

Catch ex As Exception
            MessageBox.Show(ex.Message, "vb.net", _
                   MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub

Paso 4: Programar CellEndEdit

Private Sub DataGridView1_CellEndEdit(ByVal sender As System.ObjectByVal e As System.Windows.Forms.DataGridViewCellEventArgsHandles DataGridView1.CellEndEdit
Try
   'verifico que la columna seleccionad sea la de txtcant
   If (e.ColumnIndex = 3) Then
     'capturamos el precio y la cantidad ingresada de la fila actual
      Dim PrecioUnitario As Double = DataGridView1("txtPrecioXunidad", e.RowIndex).Value
      Dim Cantidad As Integer = DataGridView1("txtCant", e.RowIndex).Value
     'Calculamos el importe a pagar
      Dim ImportePagar As Double = PrecioUnitario * Cantidad
      'Asignamos el importe a pagar a la fila actual
      DataGridView1("txtImportePagar", e.RowIndex).Value = ImportePagar

      'ahora tendremos que calcular el total a apagar y las cantidades a vender
      'le descuento  filas porque una de ellas es la fila que dice // Importe Total Pagar S/.
      Dim CantVentas As Integer = 0
      Dim ImporteTotal As Double = 0
      For rows As Integer = 0 To DataGridView1.Rows.Count - 2
          CantVentas += DataGridView1("txtCant", rows).Value
          ImporteTotal += DataGridView1("txtImportePagar", rows).Value
      Next
      'ahora asignare los valores a la fila  // Importe Total Pagar S/.
      DataGridView1("txtCant", DataGridView1.Rows.Count - 1).Value = CantVentas
      DataGridView1("txtImportePagar", DataGridView1.Rows.Count - 1).Value = ImporteTotal

End If
Catch ex As Exception
            MessageBox.Show(ex.Message, "vb.net", _
                   MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub

Resultado

Como podemos apreciar se ha calculado el importe a pagar y a la vez estamos asignando la fila "Importe Total Pagar S/." , la cantidad total vendida y el importe total a pagar.

miércoles, 20 de marzo de 2013

Utilizar transacciones en SQL Server

Tenemos dos tipos de transacciones en SQL Server las implícitas y las explicitas.

Implícitas: Son aquellas que no debemos indicarle al SQL que hacemos una transacción pero el lo genera, por ejemplo como el siguiente caso.

DELETE FROM TABLA1
WHERE NU_CODIGO= 1

Explicitas: Las transacciones explicitas son aquellas que nosotros indicamos con la sentencia Begin    Transaction / Commit o Rollback Transaction

Paso 1: Crear tabla

CREATE TABLE TABLA1
(
NU_CODIGO INT  PRIMARY KEY,
CH_NOMBRE VARCHAR(50),
CH_APELLIDOS VARCHAR(100)
)

Paso 2: Crear procedimiento 

CREATE PROC GUARDAR_TABLA1(
      @NU_CODIGO        integer     ,
      @CH_NOMBRE        varchar(50) ,
      @CH_APELLIDOS     varchar(50) ,
-- variable de salida , para conocer el mensaje de la transaccion
      @MESSAGE          varchar(500) output
      )
AS
-- Asignamos un nombre a la transaccion
      BEGIN TRAN TRAN_GUARDAR_TABLA1
            BEGIN TRY
                  BEGIN
                        INSERT INTO TABLA1(NU_CODIGO ,
                                           CH_NOMBRE ,
                                           CH_APELLIDOS
                                           )
                                  VALUES(@NU_CODIGO ,
                                           @CH_NOMBRE ,
                                           @CH_APELLIDOS
                                                     )
                        set @MESSAGE= 'Registro guardado'
                  END
            END TRY
            BEGIN CATCH
                  -- si se produciera algun error desacera los cambios
                  ROLLBACK TRAN TRAN_GUARDAR_TABLA1
                  -- asignara a la variable el mensaje de error
                  SET @MESSAGE      =     ERROR_MESSAGE()
            RETURN
            END CATCH
COMMIT TRAN TRAN_GUARDAR_TABLA1

Paso 3: Primera ejecución

DECLARE @MESSAGE  VARCHAR(500)
EXEC GUARDAR_TABLA1 1, 'XXX', 'YYYY', @MESSAGE OUTPUT
SELECT @MESSAGE

Mensaje devuelto: Registro guardado

Paso 4: Segunda ejecución

DECLARE @MESSAGE  VARCHAR(500)
EXEC GUARDAR_TABLA1 1, 'XXX', 'YYYY', @MESSAGE OUTPUT
SELECT @MESSAGE

Mensaje devuelto:  Infracción de la restricción PRIMARY KEY 'PK__TABLA1__8F57AAEA08EA5793'. No se puede insertar una clave duplicada en el objeto 'dbo.TABLA1'

Notas:

  • BEGIN TRANSACTION: Marca el punto de inicio de una transacción local explícita.

  • ROLLBACK :  Revierte una transacción explícita o implícita hasta el inicio de la transacción o hasta un punto de retorno dentro de la transacción.Puede usar ROLLBACK TRANSACTION para borrar todas las modificaciones de datos realizadas desde el inicio de la transacción o hasta un punto de retorno.

  • COMMIT: Marca el final de una transacción correcta, implícita o explícita.

  • TRY / CATCH: Implementa el control de errores para Transact-SQL que es similar al manejo de excepciones en Microsoft Visual Basic