HOKKAPOKKA
@HOKKAPOKKA (HOKKA POKKA)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

添付ファイル付きメールを一度に大量に送る仕組みについて

解決したいこと

以下の項目が各列に並んでいるスプレッドシートがあります。
(要件によってはcsvでもテキストファイルでも、形体は変えられます)

A列:宛先のメールアドレス(.Toと.ccを含む)
B列:メールタイトル
C列:メール本文 だいたいは定型文
D列:添付するファイルのファイルパス(C:\MAIL\ATTACH_A.pdf など) 通常は1ファイル

このリストの行が最終的には10000行ほどになります。
メールサーバーを使って、その10000通のメールを自動的に出すためには、どうすればよいのでしょうか。

SMTPサーバーの知識や、自動化ツールの経験があればできると思いますが、社内にその経験のある者が
いません。RPAは導入しているのですが、提案があるのは人が対話型でやる
「新規メール編集画面を出す->A~Dを貼り付ける->送信ボタンを押す」
という操作を10000回繰り返すロボットを作る、という至って普通の方法で、いくら人の操作をRPAが
自動でやってくれるにしても、これでは10000通は時間がかかってしかたがありません。
また、現在はセキュリティーの観点から、SMTPサーバーをRPAが直接アクセスすることは社内で禁止されています。

使っているグループウェアのベンダーに相談するのが良いとは思っていますが、そもそもRPAをいったん忘れて、どんなSMTPサーバーでも普通は実装していそうな何らかの機能を使って上記を実現するには、SMTPの何を社内情報システム部門から開示してもらって、その使用許可を得たら実現でき、その時の利用するツールは何が候補なのかを知りたく思います。(場合によってはRPAとのハイブリットも検討します)

要するに、こういうときは一般的にはどんな仕組みを使うと実現できるかを知っておかないと会話にならないので、お知恵を拝借したく思います。普通はどうしますか?

参考までに、会社で使っているグループウェアはサーバーメールシグマ(https://www.worksap.co.jp/services/groupware/)です。
ただし、上記の仕組みが作れるのであれば、小規模のグループウェアを別途(この業務専用に)用意することも考えます。

自分で試したこと

RPAによる対話型メール送信

0

メール10000通の送信は基本的には攻撃行為です。
添付ファイルのデータ容量にもよりますが
1件256kBでもSMTPサーバ上は数GB以上ぶつけることになるかと思います。
もし外部向けに御社のメールサーバが性能の限りメールを出すと
送信元ISP(プロバイダ)が御社のネットワークを切り離します。
乗っ取りなどのセキュリティインシデントを疑われ、完全に解決するまでインターネット村八分になることが予想されます。

普通はどうしますか?

負荷分散(時間やメールサーバを分散させる)などの工夫やメール配信サービスを利用します。
いずれにしても添付ファイルはやめてファイルへのリンクにするなど
なるべく負荷を下げる必要は出てくると思います。

0Like

1万件は別として、ExcelのVBAを使ってシートに並べた情報から自動的にメールを送信することができます。
プレビューで人が確認しながらでも、ノールックで自動的に送信でも、自在に実現できます。
ググればいくつもヒットしますが、例えば、下記URLに解説があります。

次に性能ですが、1万件を1件づつ、1万通のメールを送信する場合、例えば、1通のメール送信が2秒としても、20,000秒≒約5.5時間です。実測してみないと本当の時間は分かりませんが・・・

1万件は、メールタイトル、本文、添付ファイルも1万種類バラバラでしょうか?
同じタイトル、本文、添付ファイルであるなら、複数の宛先をBCCで1通のメールとすることで、メール件数自体を減らすことができるし、サーバの負荷も減るはずです。

あと、頻度がどの程度なのか? メール送信する期限があるのかなど・・・
例えば、1万件の送信が月に1度であるなら、数日に分けて1日あたり数千づつ送信してもよいのかなど、メール送信の要件に拠ります。

要件を整理して優先付けされるとよいかと思います。

0Like

アドバイスいただき恐縮です。
1万件は、毎月発生しますが、運用次第では月に3回(10日おき)に分けて3000+3000+4000 等の送付タイミングも検討できます。
また、メールタイトルと本文はある程度共通化できますが、添付ファイルだけは各メールですべて個別のものになります。(要するに添付ファイルも10000種類)
各メールに100KB前後の1添付ファイルが付きます。よって,宛先bccでまとめることは不可です。

世の中には、Hubspot、WEBCAS、配配メール等のサービスがあることをなんとなく調べましたが、VBAとかでなんとかなるのであれば、有償サービスにたよらず、自分で運用ができるのではとも思い始めました。(VBSの開発スキルのある人は探さなければならないですが)

0Like

VBSの開発スキルのある人は探さなければならないですが

SE技術者を新たに雇うならば、配信サービスの方が安いかもしれません。そうで無いかもしれません。
価格対効果をよく検討されることをお勧めします。

0Like

もしMicrosoft365を利用しているようでしたら、Power Automate (Power Automate Desktopではありません)をつかってExcelやCSVに用意した宛先にぐるぐると送信すれば簡単にできます。
https://mocabrown.com/blog/archives/6239

ただし、1日あたりのメール送信数制限が5000件となっています。1日5000までのメールアドレスに送信できますがそれ以上は送信されません。
https://support.microsoft.com/ja-jp/office/outlook-com-%E3%81%A7%E3%81%AE%E9%80%81%E4%BF%A1%E5%88%B6%E9%99%90-279ee200-594c-40f0-9ec8-bb6af7735c2e

添付ファイルをつけたり、本文の内容を変える(〇〇様の部分を差し替えるなど)も簡単にできますので、送信数さえカバーできるならおすすめの方法です。

どうしても超える場合は、処理を分けて別ユーザーで実行してもよいと思います。

0Like

このPower Automateとやらには非常に興味があります。1日5000通でも運用で逃げられそうです。
これは現在使っているSMTPサーバーではなく、Office365を有償で買って、outlookのメアドを取得し、そのアドレスからメールを発信する仕組みということでしょうか。

0Like

いま会社でMicrosoft365を使用していないなら、そういうことになります。
初期状態では、送信メールのアドレスは aaa@test.onmicrosoft.com のようになります。
「test」の部分はMicrosoft365の契約時に決められます。
会社でExcelなど利用しているなら、すでに会社で契約しているかもしれませんから、総務やIT部門に聞いてみることをお勧めします。
@マークより後ろを会社のドメインに差し替えることも可能です。もちろん、担当者レベルでできることではないので、SMTPサーバなど管理している部署に相談は必須です。

0Like

会社ではMicrosoft365は使用していません。
ただ、私のプライベートPCにはMicrosoft 365 Apps for Enterprise というのが入っていて、
普段使っていないですが、xxx@onmicrosoft2019.com 形式のメアドが振られていました。
この環境でテストはできますか?
Power Automateは別途購入する必要があるでしょうか。下記のどれになりますか。
https://powerautomate.microsoft.com/ja-jp/pricing/
そして一番気になるのは、教えていただいたサイトでは、”一斉”メールの配信とありますが、私が実行したいのは、個別のメールです。そのあたり、実現可能でしょうか。
また、この仕組みを独学で試すにはちょっと時間がかかりそうですが、何か使える有料指導とか、私のやりたいことに近い例の掲載されているサイトとかご存知ないでしょうか。

0Like

Microsoft365 Apps for Enterprize には含まれてなさそうですね。

テスト環境として、Power Apps 開発者向けプランを使うと良いと思います。しばらく無料で試せます。

取得方法はYoutubeが参考になります。

一斉メールと書いてありますが、動きとしては、Excelの表の上から順番にメールアドレスをToに設定して送信を繰り返すループですので、1人1通ずつ送信できます。

今回はホワイトリストは不要だと思うので、ブログの後半の送信のところだけ試してみると感覚が掴めると思います。

0Like

無用かと思いますが、Excel VBAでメールを送信するプログラムを提示しておきます。
Excelシートのフォーマットは、次の構成としています。

A列:宛先のメールアドレス
B列:メールタイトル
C列:メール本文
D列:添付するファイルのファイルパス
E列:正常時は処理時間(秒数)、エラー時はエラーメッセージ

また、1行目は列の見出し行として、実際のデータは2行目からの想定。

Option Explicit
Option Base 0

Global gCancel As Boolean

Dim olApp As Outlook.Application

const A = 1
const B = 2
const C = 3
const D = 4
const E = 5

Sub メール送信()
    gCancel = False
    Set olApp = New Outlook.Application
    Dim n As Long, rtn As VbMsgBoxResult
    
    '件数チェック
    Dim 件数 As Long: 件数 = 0
    While Not IsEmpty(Cells(件数 + 2, A))
        Cells(件数 + 2, E).ClearContents
        件数 = 件数 + 1
    Wend
    
    If vbYes <> MsgBox(prompt:="メール送信を開始しますか?" + vbCrLf + "(メール件数:" & 件数 & ")", Buttons:=vbQuestion + vbYesNo + vbSystemModal, Title:=ThisWorkbook.name) Then
        MsgBox prompt:="中止しました。", Buttons:=vbOKOnly + vbCritical, Title:=ThisWorkbook.name
        Exit Sub
    End If

    Dim startTime As Double
    Dim endTime As Double
    Dim lapTime As Double

    startTime = Timer()
    
'   Load UserForm1
'   UserForm1.Caption = ThisWorkbook.name
'   UserForm1.ProgressBar1.Min = 0
'   UserForm1.ProgressBar1.Max = 件数
'   UserForm1.ProgressBar1.Value = 0
'   UserForm1.Label1.Caption = "0"
'   UserForm1.Label3.Caption = "/ " & Format(件数, "#,###")
'   UserForm1.Show vbModeless
  
    
    Dim row As Long: row = 2
    While Not IsEmpty(Cells(row, A))
        If gCancel Then
            If vbYes = MsgBox(prompt:="メール送信を中止しますか?", Buttons:=vbYesNo + vbQuestion + vbSystemModal, Title:=ThisWorkbook.name) Then
'               UserForm1.Hide
                GoTo ErrExit
            End If
            gCancel = False
        End If
        
        lapTime = Timer()
'       UserForm1.ProgressBar1.Value = row - 1
'       UserForm1.Label1.Caption = Format(row - 1, "#,###")
        Application.StatusBar = Format(row - 1, "#,###") & " / " & Format(件数, "#,###") & " 件目を処理中"
        DoEvents
        
        Dim skip As Boolean: skip = False
        Dim 宛先 As String: 宛先 = Cells(row, A)
        Dim adr_to As String: adr_to = ""
        Dim adr_cc As String: adr_cc = ""
        Dim adr_bcc As String: adr_bcc = ""
        Dim adr As Long: adr = 1 'To:1, Cc:2, Bcc:3
        If Len(宛先) > 0 Then
            Dim ary As Variant: ary = Split(宛先, ";")
            For n = LBound(ary) To UBound(ary)
                Dim p As Long: p = InStr(ary(n), ":")
                If p > 0 Then
                    If "to:" = LCase(Left(ary(n), 3)) Then
                        adr = 1
                    ElseIf "cc:" = LCase(Left(ary(n), 3)) Then
                        adr = 2
                    ElseIf "bcc:" = LCase(Left(ary(n), 4)) Then
                        adr = 3
                    End If
                    ary(n) = Mid(ary(n), p + 1)
                End If
                If adr = 1 Then
                    adr_to = adr_to & ary(n) & ";"
                ElseIf adr = 2 Then
                    adr_cc = adr_cc & ary(n) & ";"
                ElseIf adr = 3 Then
                    adr_bcc = adr_bcc & ary(n) & ";"
                End If
            Next
        Else
            Cells(row, E) = "宛先無し"
            skip = True
        End If
        
        If Len(Cells(row, B)) = 0 Then
            Cells(row, E) = "メールタイトル無し"
            skip = True
        End If
        
        If Len(Cells(row, C)) = 0 Then
            Cells(row, E) = "本文無し"
            skip = True
        End If
        
        Dim 添付ファイル As String: 添付ファイル = Cells(row, D)
        If Len(添付ファイル) = 0 Then
            Cells(row, E) = "添付ファイル無し"
            skip = True
        ElseIf Not fileExists(filepathStrip(添付ファイル)) Then
            Cells(row, E) = "添付ファイルが見つからない"
            skip = True
        End If
        
        If skip Then GoTo Skip_mail
        
        Call makeMailSend(row, adr_to, adr_cc, adr_bcc) 'メール作成&送信
        
        lapTime = Timer() - lapTime
        Cells(row, E) = lapTime
        
Skip_mail:
        row = row + 1
    Wend
    
'   UserForm1.Hide
    Application.StatusBar = False
    endTime = Timer()
    MsgBox prompt:="メール送信を完了しました" & vbCrLf & "(" & Format(endTime - startTime, "0.000") & "秒)", Buttons:=vbInformation + vbOKOnly + vbSystemModal, Title:=ThisWorkbook.name
    Exit Sub
    
    
    
    
ErrExit:
    If gCancel Then
        MsgBox prompt:="メール送信を中止しました", Buttons:=vbOKOnly + vbCritical, Title:=ThisWorkbook.name
    Else
        MsgBox prompt:="エラーのため中止します", Buttons:=vbOKOnly + vbCritical, Title:=ThisWorkbook.name
    End If
End Sub

Sub makeMailSend(row As Long, adr_to As String, adr_cc As String, adr_bcc As String)
    Dim mailTemplate As MailItem
    Set mailTemplate = olApp.CreateItem(olMailItem)
    With mailTemplate
        .To = adr_to
        .CC = adr_cc
        .BCC = adr_bcc
        .subject = Cells(row, B)
        .body = Cells(row, C)
        .BodyFormat = olFormatPlain
                
        .Attachments.Add Source:=filepathStrip(Cells(row, D)), Type:=olByValue

        .Send   '送信する(保存しない)
'       .Save   '下書きに保存
'       .Display 'プレビュー

'       .Close olDiscard
    End With
End Sub

Function filepathStrip(path As String) As String
    filepathStrip = path
    If Len(path) < 2 Then Exit Function
    If Left(path, 1) = """" Then filepathStrip = Mid(path, 2, Len(path) - 2)
End Function

Function extractFileName(path As String) As String
    Dim PathName As String, FileName As String, pos As Long
    pos = InStrRev(path, "\")
    extractFileName = IIf(pos = 0, path, Mid(path, pos + 1))
End Function

Function fileExists(f As String) As Boolean
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    fileExists = fso.fileExists(f)
    Set fso = Nothing
End Function

補足:A列の書式

宛先のメールアドレス(.Toと.ccを含む)

これに関して書式が不明のため、以下の書式を想定しました。

  • メールアドレスを複数指定する場合は、;(セミコロン)で区切る
  • ccやbccにしたい場合は、メールアドレスの前に"cc:"や"bcc:"(”to:"も可)を付加する。これ以降のメールアドレスが対象となる
  • 例:a1@mail.com;a2@mail.com;cc:a3@mail.com;a4@mail.com;to:a5@mail.com → a1、a2とa5はTo、a3とa4はCcで送信される

補足:D列の添付ファイルは1ファイルのみを想定していますが、少しの変更で複数ファイルにも対応可能です。


1件あたり1秒かからず送信できました。もちろん、PC性能に依存します。

1Like

すごく感謝です。これならVBAの学習でいけるかもです。(はげみになります!)
これは、メールのプラットフォームはoutlookとか限定でしょうか?
くどいようですが、SMTPサーバー側では何をしておけばよいでしょうか。
システム前提条件と起動方法をもうすこしご教示いただけないでしょうか。

0Like

オブジェクトの説明のサイト紹介します。

添付ファイルではなく、url指定を推奨します。
参照設定にてオブジェクトを選択して下さい。

0Like

メールのプラットフォームはoutlookとか限定でしょうか?

Outlookが前提ということでは無いです(サーバ側はなんでもよい)。
Windowsに標準装備しているメールクライアントアプリ「メール」にて、メールの送信・受信が行えるPCであれば問題ないです。

もし、メールが未設定のPCでVBAを動かすと、その時点でメール設定画面が出てくると思われます。
そこに、メールアドレス(=送信者のメールアドレス)やSMTP、IMAP/POPのサーバアドレス等の設定が必要です。最初に1通だけ送信して確認してください。


SMTPサーバー側では何をしておけばよいでしょうか。

Windows PCにて人が操作してメールを送信することと変わりませんので、特に無いですが、
時間あたりの送信数が非常に多いため、サーバ側のメール転送能力やスプールの容量が関係します。
1件あたりのメール容量と単位時間あたりのメール送信数を、システム管理者に伝えて確認するのがよいと思います。


システム前提条件と起動方法をもうすこしご教示いただけないでしょうか。

PCでExcelとメールが使えること、ぐらいです。
提示したVBAの具体的な使い方や質問等は、本題と外れるため、新たなQ&Aにしていただければ詳しくお答えいたします。

0Like

dame.png

Windowsに標準装備しているメールクライアントアプリ「メール」にて、メールの送信・受信が行えるPCであれば問題ないです。
と、ありあますが、私の環境に入っているのは Microsoft Office Home and Business 2021
です。ここに入っている(と思われる)Outlook でも良いのでしょうか。

実は、まずは無料で作ったGmailアカウントのメールをこの環境に入っているOutlookで使えるようにしないと始まらないと思い、半日はまったのですが、いまだにつながらず、別の問題(?)で苦しんでいます。(添付画像の画面が出ます)

0Like

以下をすべて確認してください。

  • スマホ等から、無料で作ったGmailのアドレスにメールが送信できるか? メアド正しい?
  • Microsoft Office Home and Business 2021のOutlookでも同じはずですが、メールのアカウント設定は、Windows標準のメールソフトの方が簡単では無いかと思います。設定画面の見た目で判断するしか無いですが・・・
  • 以下のページを参考に、メールを最新化してやり直す。こときに、設定するGmailアドレスでGoogleにログインしておくとが必須。

  • Outlookにも無料メールがあるので、これを取得してPCに設定してみる。『outlook無料メール取得』でググれば手順は分かると思います。

なお、自分が確認した環境は、hotmail.comドメインで、Office365のOutlookではなく、Windows標準の「メール」に初めてメール設定した環境です。
Outlookのメールアドレスだとアドレスとパスワードだけでメール設定完了します。
その場合も、取得したOutlookアドレスでMicrosoftアカウントにログインしておく必要があったと思います。


追伸:できれば、Gmailを設定したときの設定画面のスクショを添付したください。個人情報は塗りつぶして。

0Like

@nak435さん
すみません、あらぬところで足をとられまして。
Windows標準のメールアプリはすでに最新になっていたようで、Microsoft Storeで更新ボタンが出ませんでした。そのままGmail設定しても、エラーにはならないけれどもメールの送信/受信がさっぱりできず、あきらめかけていたらなぜか画面上でoutlookに誘導され、言われるがままにやってみたらなぜかそのoutlookで送受信できるようになりました。このoutlookですが、アプリなのかブラウザなのか365なのか自分が何のソフト操作をしているのかさっぱりヘルプをみてもわからないのですが、画面の様子と、ヘルプいじっていたらMicrosoft Storeに遷移したのでその画面ショットを添付します。
本論に戻りますが、この環境でご提示いただいたVBAが稼働するかわかりますでしょうか。
また、起動は、メーリングリストをExcelで開いた状態で、開発->Visual Basicと開いて貼り付ける方法になりますでしょうか。outlook_screen.png
store.png

0Like

この環境でご提示いただいたVBAが稼働するかわかりますでしょうか。

おそらく大丈夫だと思います。

メーリングリストをExcelで開いた状態で、開発->Visual Basicと開いて貼り付ける方法になりますでしょうか。

Visual Basic画面の左側のプロジェクトツリーに該当のブックが表示されていると思いますが、それを右クリック→挿入→標準モジュールを選択します。新規で作成されたモジュール(Module1)にVBAのコードを全部貼り付けます。

一点、Visual Basic画面のメニュー→参照設定で「Microsoft Office 16.0 Object Library」にチェックを付けてください。

開発→Visual Basic→マクロで表示されるマクロ一覧から「メール送信」を選択して「実行」します。

1Like

@HOKKAPOKKA さん

前回お伝えした、「Visual Basic画面のメニュー→参照設定で「Microsoft Office 16.0 Object Library」にチェックを付けてください。」が間違いでした。
すみませんが、Visual Basic画面のメニュー→参照設定で「Microsoft Outlook 16.0 Object Library」にチェックをつけて再実行してください🙇

ここは「Q&A」ではなく「意見交換」となっているので、以降は、このVBAだけのQ&Aを新しく登録して欲しいです。(ここに意見していただいた他の方にも毎回メールが飛んでご迷惑でしょうから)

0Like

「Microsoft Outlook 16.0 Object Library」にチェックをつけて再実行してください
これをやったら、エラーメッセージが変わりました。
このVBAだけのQ&Aを新しく登録して欲しいです。
承知しました。このあと新規で入れますが、拾っていただけますでしょうか。

1Like

Your answer might help someone💌