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! :)
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.
Áñadiendo a lo que dice el compañero ivancea96, estás repitiendo páginas HTML enteras dentro de tu código.
Salu2
Gracias a sus consejos pude resolver el problema.
El código quedo así:
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! :)
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:
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:
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!
Vaya Elektro, le estás diciendo cómo construir una casa, empezando por cómo encontrar los materiales en las minas jaja
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! :)