メール自動作成マクロ用のクラスを作る
Excelから、VBAでLotusNotesやThunderbirdのメールを作るマクロ。
メンテナンスしやすくて拡張性のあるものにしたいと思って試行錯誤中。「これでうまく行くんじゃね?」というところまで漕ぎ着けたので、うpしておく。
なるべく〈オブジェクト指向〉っぽくしたいんだけど、所詮素人なので、「オメー、そりゃダメだよw」というところがあったら、教えてください。
前回書いたように、
「Main」と名付けたワークシートに
こんな表を作って送信先アドレスとか本文とか添付ファイルのフルパスとかを入れておき、
「ユーザ情報」と名付けたワークシートに
こんな表を作って、送信者のデータを入れておくこととする。
んで、標準モジュールの宣言セクションでは、
'定数' Public Const EMBED_ATTACHMENT As Integer = 1454 Public Const MAIN_SHEET_NAME As String = "Main" Public Const MAIN_FONTSIZE As Integer = 12 '本文のフォントサイズ' Public Const SUB_FONTSIZE As Integer = 10 '添付ファイル名、署名のフォントサイズ'
定数の宣言をこんな風に(今回は関係ないのもあるけど)。
'構造体の宣言' Public Type mlData mailTo As String CC As String BCC As String mailSubject As String belongsTo As String jobTitle As String personName As String returnReceipt As String End Type '構造体変数の宣言' Public mldt As mlData
今回は、構造体変数を使用してみる。
'列挙体(列名を表すのに使用)' Public Enum colNum isSent = 1 numOf sendTo mailTo CC BCC mailSubj belongsTo jobTitle personName p01 p02 p03 p04 p05 p06 p07 p08 p09 p10 att01 att02 att03 att04 att05 att06 att07 att08 att09 att10 returnReceipt End Enum
前回同様、列挙体を宣言。
'クラス変数' Public md As MailData Public nsc As NotesStartedChecker 'モジュールレベル変数' Dim mlBody() As String Dim mlAttFiles() As String Dim mlSenderData() As String
あとは、クラスのインスタンス用のPublic変数と、モジュールレベル変数を準備する。
※「nsc」は今回は使いません。
クラスモジュールを挿入して、「オブジェクト名」を「MailData」にする。
クラスモジュールに下記のコードを書く。
Option Explicit 'フィールド' Private mailTo_ As String '送信先アドレス' Private CC_ As String 'CC' Private BCC_ As String 'BCC' Private mailSubject_ As String 'メール件名' Private belongsTo_ As String '送信相手の勤務先' Private jobTitle_ As String '送信相手の肩書' Private personName_ As String '送信相手の氏名' Private returnReceipt_ As String '受信確認の有無' Private mailBody_() As String 'メール本文の配列' Private attFiles_() As String '添付ファイルフルパスの配列' Private senderData_() As String '送信者データの配列' Private numOfBody_ As Integer 'メール本文配列の要素数' Private numOfAttFiles_ As Integer '添付ファイルフルパス配列の要素数' Private numOfSenderData_ As Integer '送信者データ配列の要素数' 'アクセサ' Public Property Get mailTo() As String mailTo = mailTo_ End Property Public Property Get CC() As String CC = CC_ End Property Public Property Get BCC() As String BCC = BCC_ End Property Public Property Get mailSubject() As String mailSubject = mailSubject_ End Property Public Property Get belongsTo() As String belongsTo = belongsTo_ End Property Public Property Get jobTitle() As String jobTitle = jobTitle_ End Property Public Property Get personName() As String personName = personName_ End Property Public Property Get returnReceipt() As String returnReceipt = returnReceipt_ End Property Public Property Get mailBody(ByVal i As Integer) As String mailBody = mailBody_(i) End Property Public Property Get attFiles(ByVal i As Integer) As String attFiles = attFiles_(i) End Property Public Property Get senderData(ByVal i As Integer) As String senderData = senderData_(i) End Property Public Property Get numOfBody() As Integer numOfBody = numOfBody_ End Property Public Property Get numOfAttFiles() As Integer numOfAttFiles = numOfAttFiles_ End Property Public Property Get numOfSenderData() As Integer numOfSenderData = numOfSenderData_ End Property 'コンストラクタ' Private Sub Class_Initialize() End Sub 'メソッド' Public Sub getMailBasicData(ByRef mldt As mlData) '……(1)' 'メールの基礎データを取得する' mailTo_ = mldt.mailTo CC_ = mldt.CC BCC_ = mldt.BCC mailSubject_ = mldt.mailSubject belongsTo_ = mldt.belongsTo jobTitle_ = mldt.jobTitle personName_ = mldt.personName returnReceipt_ = mldt.returnReceipt End Sub Public Sub getMailBodyArray(ByRef mlBody() As String) '……(2)' 'メール本文の配列を取得する' Dim i As Integer numOfBody_ = UBound(mlBody()) '……(3)' ReDim mailBody_(numOfBody_) '……(4)' For i = 1 To UBound(mlBody()) mailBody_(i) = mlBody(i) '……(5)' Next End Sub Public Sub getMailAttFilesArray(ByRef mlAttFiles() As String) '……(6)' '添付ファイルフルパスの配列を取得する' Dim i As Integer numOfAttFiles_ = UBound(mlAttFiles()) ReDim attFiles_(numOfAttFiles_) For i = 1 To UBound(mlAttFiles()) attFiles_(i) = mlAttFiles(i) Next End Sub Public Sub getSenderDataArray(ByRef mlSenderData() As String) '……(7)' '送信者データの配列を取得する' Dim i As Integer numOfSenderData_ = UBound(mlSenderData()) ReDim senderData_(numOfSenderData_) For i = 1 To UBound(mlSenderData()) senderData_(i) = mlSenderData(i) Next End Sub Public Sub createLotusNotesMail() '……(8)' 'LotusNotesのメールを作成する' End Sub Public Sub createThunderbirdMail() '……(9)' 'Thunderbirdのメールを作成する End Sub
なんだかものすごく長いコードになってしまったが、前回との最大の違いは、
クラスとワークシートとの関係を完全に断ち切った
こと。
こうすることで、メール作成用のデータを入力したExcelワークシートの作り方が変わった場合でも、このクラスに関しては使い回しをすることができる。おおっ、ちょっと〈オブジェクト指向〉っぽいぞw
例によって、コードの解説。
- まず、コンストラクタがなくなっちゃってます。Private変数にデフォルト値が入って不都合な点が思い浮かばないので。コンストラクタのうまい使い道があったら教えてほしいぐらい。
- (1)は、メールの基礎情報……というか、実際は値が一つしかないようなパラメータを一気にMailDataオブジェクトのプロパティにセットするメソッド。引数を構造体で渡しているところがミソ。
- (2)は、本文の配列をMailDataオブジェクトのプロパティにセットするメソッド。引数に配列をまるごと渡している。
- 引数で渡された配列をUboundで調べたら要素数が分かるので、(3)でnumOfBodyプロパティにセット。
- その要素数を早速使って、(4)で仮配列mailBody_()をReDimする。
- あとは、Forループを使って(5)で引数として渡された配列の要素を、MailDataオブジェクトのプロパティ配列にセットしている。
- (6)では、添付ファイルのフルパスについて(2)と同じことをしている。
- (7)では、送信者のデータについて(2)と同じことをしているだけ。
- (8)と(9)は、今後実装予定のメソッド。(7)までで、およそメールを作成するために必要なデータは全て取得済みなので、あとはそれぞれのメーラーに合わせてメールを作成する処理を書けば良い。
で、このクラスにメール作成用のデータを渡す処理は、メール用データのあるワークシートの作りに合わせて標準モジュールに書く。まあ、これは、前回コンストラクタに書いていたものを移植すれば良いだけなので、もはや大した手間ではあるまい。
とりあえず、今回はここまで。このクラスにメール作成用データを渡す処理は、もう書いているんだけど、今回すでにかなり長くなってしまっているので、次回投稿します。