#vb.net #smtp #sendmail
#vb.net #smtp #отправить почту
Вопрос:
Я пытаюсь отправить электронное письмо кандидатам, которые подали заявку на работу, иногда мне нужно отправить несколько сотен или даже тысяч писем, поэтому код будет полезным.
Это то, что я написал, но проблема в том, что почта отправляется несколько раз на один и тот же адрес (на некоторые адреса один или два раза, а иногда и больше).
Небольшое объяснение приведенного ниже кода. Код считывает активную базу данных заданий и выбирает кандидатов, которые не были включены (столбец FMZ в базе данных, «X»), затем считывает уникальный идентификатор кандидата в другой базе данных для адреса электронной почты, на который будет отправлено письмо. Даже базовый msgbox, приведенный ниже SmtpServer.Send(mail)
, активируется для каждого кандидата только один раз, но почта отправляется несколько раз. Вот код.
'Step 1 - All candidates in DBAP that applied for ClientID/Job ID
For i As Integer = 0 To dsPoslovi.Tables(0).Rows.Count - 1
If dsPoslovi.Tables(0).Rows(i)(1).ToString() = ATS_IDKlijent AndAlso dsPoslovi.Tables(0).Rows(i)(2).ToString() = ATS_IDPosao Then
'Step 2 - Send mails to those not contacted yet (X in FMZ column)
If dsPoslovi.Tables(0).Rows(i)(8).ToString() <> "X" Then
IDKandidataAP = dsPoslovi.Tables(0).Rows(i)(0).ToString()
IDKandidataAP2 = dsPoslovi.Tables(0).Rows(i)(3).ToString()
'Read mail addresses
For x As Integer = 0 To dsCL.Tables(0).Rows.Count - 1
If dsPoslovi.Tables(0).Rows(i)(3).ToString() = dsCL.Tables(0).Rows(x)(1).ToString() Then
MailKandidata = dsCL.Tables(0).Rows(x)(7).ToString()
If MailKandidata.Contains("@") = True Then
SmtpServer.Send(mail)
MsgBox(MailKandidata)
End If
End If
Next
'Update active job database
Dim cmd As New OleDbCommand(query, myCONN)
myCONN.Open()
cmd.Parameters.AddWithValue("FMZ", "X")
cmd.Parameters.AddWithValue("ID", IDKandidataAP)
cmd.ExecuteNonQuery()
myCONN.Close()
End If
End If
Next
Комментарии:
1. Отсутствует некоторый код: как
2. Спасибо. Я этого не знал (SmtpServer. Отправка (почта)) не должна быть в цикле, только mail.To.Add(
Ответ №1:
Поскольку я не люблю печатать, я разрешил значение DataSet.Tables
a DataTable
и перебрал Rows
коллекцию. Для меня это более читабельно.
Я думаю, что проблема в mail.To
коллекции. Каждая итерация добавляет получателя и отправляет электронное письмо каждому получателю. Я создаю коллекцию внутри циклов и отправляю почту только один раз вне цикла. Почта будет отправлена каждому получателю в коллекции.
Я не уверен, что происходит с. IDKandidataAP2
Похоже, что он не используется в этом методе и перезаписывается на каждой итерации.
Я исправил код базы данных. Соединение и команда должны быть объявлены в Using
блоке один раз вне циклов. Я создаю коллекцию параметров вне цикла и изменяю значение параметра @ID только внутри цикла. Я догадался, как может выглядеть строка обновления. Этот Add
метод предпочтительнее AddWithValue
. Я догадался о типах данных. Проверьте свою базу данных на наличие фактических типов.
Private ATS_IDKlijent As String = "" '?
Private ATS_IDPosao As String = "" '?
Private dsCL As New DataSet
Private dsPoslovi As New DataSet
Private mail As New MailMessage
Private SmtpServer As New SmtpClient()
Private IDKandidataAP As String
Private IDKandidataAP2 As String
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim dt As DataTable = dsPoslovi.Tables(0)
'Step 1 - All candidates in DBAP that applied for ClientID/Job ID
Dim query = "Update SomeTable Set FMZ = @FMZ Where ID = @ID;"
Using myCONN As New OleDbConnection("Your connection string"),
cmd As New OleDbCommand(query, myCONN)
cmd.Parameters.Add("@FMZ", OleDbType.VarChar).Value = "X"
cmd.Parameters.Add("@ID", OleDbType.VarChar)
myCONN.Open()
For Each row As DataRow In dt.Rows
If row(1).ToString() = ATS_IDKlijent AndAlso row(2).ToString() = ATS_IDPosao Then
'Step 2 - Send mails to those not contacted yet (X in FMZ column)
If row(8).ToString() <> "X" Then
IDKandidataAP = row(0).ToString()
IDKandidataAP2 = row(3).ToString()
'Read mail addresses
Dim dt2 As DataTable = dsCL.Tables(0)
For Each row2 As DataRow In dt2.Rows
If row(3).ToString() = row2(1).ToString() Then
Dim MailKandidata = row2(7).ToString()
If MailKandidata.Contains("@") = True Then
Dim ToAddress As New MailAddress(MailKandidata)
mail.To.Add(ToAddress)
MsgBox(MailKandidata)
End If
End If
Next
'Update active job database
cmd.Parameters("@ID").Value = IDKandidataAP
cmd.ExecuteNonQuery()
End If
End If
Next
End Using 'Closes and disposes the connection and disposes the command.
SmtpServer.Send(mail)
End Sub