Enviar DataGridView por Email VB.net 2010

Iniciado por el_cantante, 18 Septiembre 2015, 15:37 PM

0 Miembros y 1 Visitante están viendo este tema.

el_cantante

Hola,
Estoy intentando enviar un DataGridView por Email.
Mi problema es que el email que  recibo repite por cada renglón del datagridview todo el mensaje. Y obviamente lo que yo busco hacer es que envie la tabla completa.
Me explico mejor con un ejemplo, lo que recibo es lo siguiente:

Buenos dias

nombre      apellido   
Juan          Perez

Saludos

Buenos dias

nombre      apellido   
Roberto      Diaz

Saludos


Y lo que yo quiero recibir es esto:


Buenos dias

nombre      apellido
Juan          Perez   
Roberto      Diaz

Saludos


Este es el codigo que exporta el datagridview y envia el email, por favor alguien me podria decir donde me equivoco?


Private Sub Button7_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button7.Click
        Dim html As String = String.Empty
        Dim Mail As New MailMessage

        Mail.Subject = My.Settings.oggetto
        Mail.To.Add(My.Settings.destinatario)
        Mail.From = New MailAddress(My.Settings.mittente)
        Mail.IsBodyHtml = True
        Dim tipo, nome, tipo_appuntamento, scadenza, note As String
        Dim strMailBody As String
        Dim i As Integer

        For i = 0 To DataGridView1.Rows.Count - 1

            tipo = DataGridView1.Item(0, i).Value.ToString
            nome = DataGridView1.Item(1, i).Value.ToString
            tipo_appuntamento = DataGridView1.Item(2, i).Value.ToString
            scadenza = DataGridView1.Item(3, i).Value.ToString
            note = DataGridView1.Item(4, i).Value.ToString

            html = html & "<HTML>"
            html = html & "<HEAD>"
            html = html & "<TITLE>Avvisi Sicurezza</TITLE>"
            html = html & "</HEAD>"
            html = html & "<BODY  bgcolor=""lightyellow"">"
            html = html & " " & Now() & " <BR> <BR> "
            html = html & "<B>Buongiorno, " & DataGridView1.Rows.Count & " <BR> "
            html = html & "Queste sono le scadenze per i prossimi " & My.Settings.allert & " giorno/i " & " <BR><BR> </B>"
            html = html & "<TABLE cellpadding=""1""  COLS=""1"" SIZE=""1"" border=""1"" BORDERCOLOR= ""black"">"
            html = html & "<TR><TH>"
            html = html & tipo & " </TH>"
            html = html & "<TH>"
            html = html & nome & "</TH>"
            html = html & "<TH>"
            html = html & tipo_appuntamento & " </TH>"
            html = html & "<TH>"
            html = html & scadenza & "</TH>"
            html = html & "<TH>"
            html = html & note & "</TH>"
            html = html & "</TR>"
            html = html & "</FONT></TABLE><BR>"
            html = html & "</BODY>"
            html = html & "</HTML>"

           
        Next

        Mail.Body = html

        Dim SMTP As New SmtpClient(My.Settings.server_email)
        SMTP.EnableSsl = True
        SMTP.Credentials = New    System.Net.NetworkCredential(My.Settings.utente_email, My.Settings.password_email)
        SMTP.Port = My.Settings.porta_email
        SMTP.Send(Mail)
        MsgBox("Email inviata!")
    End Sub


Gracias!

Saludos!  :)
El sistema del zapping mental en su apogeo, donde las horas pasan con la velocidad de la vida. No es el mismo domingo del principio, es un domingo anterior, otra temporada en el infierno, siete di­as atras.

ivancea96

Saca del bucle el <html>, el <head> y <body>. Saca TODO lo que no sea un <tr> y sus <td>/<th>.
En el bucle solo debe haber los datos que se repitan en cada registro.

eLank0

Áñadiendo a lo que dice el compañero ivancea96, estás repitiendo páginas HTML enteras dentro de tu código.

Salu2

el_cantante

#3
Gracias a sus consejos pude resolver el problema.
El código quedo así:

Código (vbnet) [Seleccionar]

Dim html As String = String.Empty
       Dim html2 As String = String.Empty
       Dim html3 As String = String.Empty
       Dim Mail As New MailMessage

       Mail.Subject = My.Settings.oggetto
       Mail.To.Add(My.Settings.destinatario)
       Mail.From = New MailAddress(My.Settings.mittente)
       Mail.IsBodyHtml = True
       Dim tipo, nome, tipo_appuntamento, scadenza, note As String
       Dim strMailBody As String
       Dim i As Integer

       html = html & "<B>Buongiorno, " & " <BR> "
       html = html & "Queste sono le scadenze per i prossimi " & My.Settings.allert & " giorno/i " & " <BR><BR> </B>"
       html = html & "<TABLE cellpadding=""1""  COLS=""1"" SIZE=""1"" border=""1"" BORDERCOLOR= ""black"">"
       html3 = html3 & "</FONT></TABLE><BR><BR>"
       html3 = html3 & "Cordiali saluti"


       For i = 0 To DataGridView1.Rows.Count - 1

           tipo = DataGridView1.Item(0, i).Value.ToString
           nome = DataGridView1.Item(1, i).Value.ToString
           tipo_appuntamento = DataGridView1.Item(2, i).Value.ToString
           scadenza = DataGridView1.Item(3, i).Value.ToString
           note = DataGridView1.Item(4, i).Value.ToString


           html2 = html2 & "<TR><TH>"
           html2 = html2 & tipo & " </TH>"
           html2 = html2 & "<TH>"
           html2 = html2 & nome & "</TH>"
           html2 = html2 & "<TH>"
           html2 = html2 & tipo_appuntamento & " </TH>"
           html2 = html2 & "<TH>"
           html2 = html2 & scadenza & "</TH>"
           html2 = html2 & "<TH>"
           html2 = html2 & note & "</TH>"
           html2 = html2 & "</TR>"


       Next
       strMailBody += html & html2 & html3 & vbCrLf
       Mail.Body = strMailBody

       Dim SMTP As New SmtpClient(My.Settings.server_email)
       SMTP.EnableSsl = True
       SMTP.Credentials = New System.Net.NetworkCredential(My.Settings.utente_email, My.Settings.password_email)
       SMTP.Port = My.Settings.porta_email
       SMTP.Send(Mail)
       MsgBox("Email inviata!")


Muchas gracias!!  ;-)

Saludos!  :)
El sistema del zapping mental en su apogeo, donde las horas pasan con la velocidad de la vida. No es el mismo domingo del principio, es un domingo anterior, otra temporada en el infierno, siete di­as atras.

Eleкtro

#4
Cita de: el_cantante en 21 Septiembre 2015, 10:49 AMGracias a sus consejos pude resolver el problema.
El código quedo así:

Aunque es satisfactorio resolver un problema, lo cierto es que el código del algoritmo te ha quedado muy feo debido a que estás siguiendo muy, muy malos hábitos de programación, en general le estás dando mil vueltas a un algoritmo sencillo para llevar a cabo una tarea que debería representarse de manera simple.

Lo más destacable negativamente hablando respecto al rendimiento del código que has mostrado, son las múltiples re-asignaciones de variables, puedes utilizar el operador de concatenación (&=) pero seguiría sin ser óptimo para estas circunstancias.

Te sugiero que definas una nueva class/type que usarás cómo una especie de "container" del texto html, en esa class es donde desarrollarás el algoritmo y encapsularias los datos que hagan falta, no me mezcles toda la lógica con la class del Form cómo has hecho, separa los datos.

Te muestro un ejemplo funcional, con los cambios más importantes resaltados:

Código (vbnet,3,4,5,6,7,8,9,10,11,12,42,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75) [Seleccionar]
Public NotInheritable Class GridToHtmlTableExporter

   Private ReadOnly htmlFormat As String =
<a><![CDATA[
<B>Buongiorno, <BR> Queste sono le scadenze per i prossimi {0} giorno/i <BR><BR> </B>

<TABLE cellpadding="1" COLS="1" SIZE="1" border="1" BORDERCOLOR= "black">
{1}
</TABLE>

<BR><BR> Cordiali saluti.
]]></a>.Value

   Public ReadOnly Property Allert As String
       Get
           Return Me.allertB
       End Get
   End Property
   Private ReadOnly allertB As String

   Public ReadOnly Property DataGridView As DataGridView
       Get
           Return Me.dgvB
       End Get
   End Property
   Private ReadOnly dgvB As DataGridView

   Public ReadOnly Property Document As String
       Get
           Return Me.documentB
       End Get
   End Property
   Private ReadOnly documentB As String

   <DebuggerStepThrough>
   <DebuggerHidden>
   Public Sub New(ByVal allert As String,
                  ByVal dgv As DataGridView)

       Me.dgvB = dgv
       Me.allertB = allert
       Me.documentB = String.Format(Me.htmlFormat, allert, Me.ParseGridElements(dgv))

   End Sub

   Public Overrides Function ToString() As String
       Return Me.documentB
   End Function

   Private Function ParseGridElements(ByVal dgv As DataGridView) As String

       Dim sb As New StringBuilder

       For rowIndex As Integer = 0 To (dgv.RowCount - 1)

           If Not (rowIndex = dgv.NewRowIndex) Then

               sb.Append("<TR>")
               sb.AppendLine()

               For colIndex As Integer = 0 To (dgv.ColumnCount - 1)
                   sb.AppendFormat("<TH> {0} </TH>", dgv.Item(colIndex, rowIndex).Value.ToString)
                   sb.AppendLine()
               Next colIndex

               sb.Append("</TR>")
               sb.AppendLine()

           End If

       Next rowIndex

       Return sb.ToString

   End Function

End Class


Lo usarías de la siguiente manera:
Código (vbnet,15,17,18) [Seleccionar]
Public NotInheritable Class Form1 : Inherits Form

   Private Sub Form1_Load() Handles MyBase.Shown

       ' Construyo las filas de un Grid con 5 columnas.
       With Me.DataGridView1
           .Rows.Add({"Row1-Value1", "Row1-Value2", "Row1-Value3", "Row1-Value4", "Row1-Value5"})
           .Rows.Add({"Row2-Value1", "Row2-Value2", "Row2-Value3", "Row2-Value4", "Row2-Value5"})
       End With

   End Sub

   Private Sub Button1_Click() Handles Button1.Click

       Dim htmlExporter As New GridToHtmlTableExporter("allert", Me.DataGridView1)

       ' La propiedad Document contiene el texto final del documento html.
       Console.WriteLine(htmlExporter.Document)

   End Sub

End Class


Resultado de ejecución:
Citar<B>Buongiorno, <BR> Queste sono le scadenze per i prossimi allert giorno/i <BR><BR> </B>

<TABLE cellpadding="1" COLS="1" SIZE="1" border="1" BORDERCOLOR= "black">
<TR>
<TH> Row1-Value1 </TH>
<TH> Row1-Value2 </TH>
<TH> Row1-Value3 </TH>
<TH> Row1-Value4 </TH>
<TH> Row1-Value5 </TH>
</TR>
<TR>
<TH> Row2-Value1 </TH>
<TH> Row2-Value2 </TH>
<TH> Row2-Value3 </TH>
<TH> Row2-Value4 </TH>
<TH> Row2-Value5 </TH>
</TR>
</TABLE>

<BR><BR> Cordiali saluti.

Espero que te sirva de algo el ejemplo :)

Saludos!








ivancea96

Vaya Elektro, le estás diciendo cómo construir una casa, empezando por cómo encontrar los materiales en las minas jaja

el_cantante

Muchísimas gracias Eleкtro! No me esperaba una explicación tan detallada  :)
Voy a modificar el código siguiendo tu ejemplo.

Saludos! y nuevamente gracias!  :)
El sistema del zapping mental en su apogeo, donde las horas pasan con la velocidad de la vida. No es el mismo domingo del principio, es un domingo anterior, otra temporada en el infierno, siete di­as atras.