如何在SSIS中通过Visual Basic 2019脚本任务发送包含文件夹所有文件列表的单封邮件
我明白你现在的困扰——把Script Task放在Foreach Loop里会逐个发邮件,移出又拿不到文件列表对吧?其实核心思路是先收集所有文件名到SSIS变量,再一次性发送,下面给你一步步讲怎么用VB2019实现:
解决步骤:收集文件列表 → 统一发送邮件
1. 准备SSIS变量
首先创建两个包级别的变量(确保Foreach Loop和外部Script Task都能访问):
User::CurrentFileName:字符串类型,用来存储Foreach Loop遍历到的单个文件名/路径(配置Foreach Loop时,在“映射”面板把变量设为这个)User::FileList:字符串类型,初始值为空,用来累加所有待处理文件的列表
2. 配置Foreach Loop里的Script Task
这个Script Task的作用是把每个遍历到的文件名追加到FileList变量中:
- 编辑Script Task,在“脚本”选项卡的
ReadOnlyVariables里选User::CurrentFileName,ReadWriteVariables里选User::FileList - 点击“编辑脚本”,替换成以下VB代码:
Public Sub Main() ' 获取当前遍历到的文件名 Dim currentFile As String = Dts.Variables("User::CurrentFileName").Value.ToString() ' 获取已收集的文件列表 Dim fileList As String = Dts.Variables("User::FileList").Value.ToString() ' 追加文件名(用换行+列表符号美化格式) If Not String.IsNullOrEmpty(fileList) Then fileList &= vbCrLf ' 已有内容则换行 End If fileList &= "- " & currentFile ' 用"- "作为列表项前缀 ' 更新FileList变量 Dts.Variables("User::FileList").Value = fileList Dts.TaskResult = ScriptResults.Success End Sub
3. 在Foreach Loop外部添加Script Task发送邮件
这个Script Task负责读取收集好的FileList,生成邮件内容并发送:
- 编辑Script Task,在
ReadOnlyVariables里选User::FileList(如果有单独的邮件配置变量,比如收件人、SMTP地址,也可以加在这里) - 点击“编辑脚本”,替换成以下代码(记得根据你的邮箱服务调整SMTP参数):
Imports System.Net.Mail Public Sub Main() ' 获取收集好的文件列表 Dim fileList As String = Dts.Variables("User::FileList").Value.ToString() ' 构建邮件内容 Dim mailBody As String = "您好,以下是本次收到的待处理文件列表:" & vbCrLf & vbCrLf & fileList ' ----- 配置邮件参数(根据你的实际情况修改)----- Dim smtpServer As String = "smtp.office365.com" ' 比如Outlook用这个,Gmail是smtp.gmail.com Dim smtpPort As Integer = 587 ' 常见端口:587(TLS)、465(SSL) Dim senderEmail As String = "your-sender-email@domain.com" Dim senderPassword As String = "your-app-password-or-password" ' 注意:Gmail/Outlook可能需要用应用密码 Dim recipientEmail As String = "recipient-email@domain.com" Dim mailSubject As String = "待处理文件接收通知" ' --------------------------------------------- ' 创建邮件对象(Using自动释放资源) Using mail As New MailMessage(senderEmail, recipientEmail) mail.Subject = mailSubject mail.Body = mailBody mail.IsBodyHtml = False ' 如果要HTML格式(比如带样式的列表),可以改成True ' 创建SMTP客户端 Using smtpClient As New SmtpClient(smtpServer, smtpPort) smtpClient.Credentials = New System.Net.NetworkCredential(senderEmail, senderPassword) smtpClient.EnableSsl = True ' 大多数邮箱服务需要开启SSL/TLS Try smtpClient.Send(mail) ' 打印成功日志 Dts.Events.FireInformation(0, "邮件发送成功", "包含所有文件的通知邮件已发送给收件人", "", 0, True) Dts.TaskResult = ScriptResults.Success Catch ex As Exception ' 捕获并记录错误 Dts.Events.FireError(0, "邮件发送失败", $"错误信息:{ex.Message}", "", 0) Dts.TaskResult = ScriptResults.Failure End Try End Using End Using End Sub
为什么之前移出Loop无效?
因为直接把Script Task放在Loop外面的话,它没有办法自动获取到所有文件名——Foreach Loop只会遍历文件,但不会主动把所有文件名保存下来。必须先通过Loop里的脚本把每个文件名累加进变量,外部的脚本才能拿到完整的列表。
额外优化建议
- 如果需要更美观的邮件格式,可以把
IsBodyHtml设为True,然后用HTML标签构建列表,比如把fileList的内容改成:' 构建HTML格式的列表 Dim htmlItems As String = String.Join("</li><li>", fileList.Split(vbCrLf).Select(Function(s) s.TrimStart("- "))) Dim mailBody As String = "<p>您好,以下是本次收到的待处理文件列表:</p><ul><li>" & htmlItems & "</li></ul>" - 建议把邮件配置(SMTP地址、收件人等)也做成SSIS变量,这样不需要修改脚本就能调整参数。
内容的提问来源于stack exchange,提问作者mb1002
相关产品推荐
相关产品推荐

