7.[PG3]Accessで、データ入力フォーム作成とメール送信してみよう その4
こちら第7回「プログラマー養成講座」のパート4になります!
目次はこちらからご参照下さい!
前回までのあらすじ:テーブル、フォームの作成が終わり、いよいよVBAを書くことになりました!
頑張ってみます。
Excelのファイル名変更のプログラムソースをちょっと見てみるか・・・。
Public Sub Jikkou()
'宣言
Dim i As Integer
'初期値設定
i = 1
'ループしてA行が、空になるまで処理
Do Until Worksheets("ファイル一覧").Cells(i, 1).Value = ""
If Worksheets("ファイル一覧").Cells(i, 1).Value = "ファイル操作.xlsm" Then
Worksheets("ファイル一覧").Cells(i, 3).Value = "ファイル名は変更しない"
ElseIf Worksheets("ファイル一覧").Cells(i, 2).Value = "" Then
Worksheets("ファイル一覧").Cells(i, 3).Value = "記入なし"
ElseIf Dir(ThisWorkbook.Path & "\" & Worksheets("ファイル一覧").Cells(i, 1).Value) = "" Then
Worksheets("ファイル一覧").Cells(i, 3).Value = "A列のファイルが存在しません"
ElseIf Dir(ThisWorkbook.Path & "\" & Worksheets("ファイル一覧").Cells(i, 2).Value) <> "" Then
Worksheets("ファイル一覧").Cells(i, 3).Value = "B列のファイルが存在しています"
Else
Name ThisWorkbook.Path & "\" & Worksheets("ファイル一覧").Cells(i, 1).Value As ThisWorkbook.Path & "\" & Worksheets("ファイル一覧").Cells(i, 2).Value
Worksheets("ファイル一覧").Cells(i, 3).Value = "ファイル名を変更しました"
End If
i = i + 1
Loop
End Sub
前に見た時は、結構長いと思ってたけど、こんなに短かったっけ・・・。
セル位置を覚えるための変数を数字宣言して、
変数に1を入れて、
あとはA列が””になるまでループしていくって感じかな。
今回は、
①まずテーブルからデータをとってきて、
②メール送信して、
③成功だったら、SendDateTimeに日時を入れて、
④失敗だったら、エラーメッセージを出して、
⑤終わり
って流れかな?
では検索するとして。。。
「AccessVBA テーブル」で検索してみようかな。
お、一番上に出てきたのが「ACCESS VBA テーブルの値を取得する方法」ってWEBサイトだ。見に行ってみよう。
ふむふむ、「DLookup」とかを使えば、指定したレコードが取れるのか。
DLookup("MailTo", "テーブル1", "ID=4")
こういう感じか。
あれ、赤くなっちゃってる!?
一応、やってみようかな・・・。
構文エラー・・・。検索してみようかな。
うーん、し、師匠・・・。エラーがどうすれば直るかわかりません。
ほんとだ!なおった!
でもIDがわからないから・・・
どうやってループ処理すれば・・・
うーん、「Access フィールド 空」とかで検索してみるか・・・
あ、これならIDが取れるんだ。
そうか、ひらめいた!!
Dim id As Integer
id = DLookup("ID", "テーブル1", "SendDateTime is null")
MsgBox DLookup("MailTo", "テーブル1", "ID = id")
MsgBox DLookup("MailFrom", "テーブル1", "ID = id")
MsgBox DLookup("MailCC", "テーブル1", "ID = id")
MsgBox DLookup("MailTitle", "テーブル1", "ID = id")
MsgBox DLookup("MailBody", "テーブル1", "ID = id")
MsgBox DLookup("UserName", "テーブル1", "ID = id")
こんな感じで、テーブルデータ全部取得できるし、
「SendDateTimeが空の時に処理をする」をクリアしてると思う!
Private Sub コマンド2_Click()
'宣言
Dim id As Integer
Dim MailTo As String
Dim MailFrom As String
Dim MailCC As String
Dim MailTitle As String
Dim MailBody As String
Dim UserName As String
id = DLookup("ID", "テーブル1", "SendDateTime is null")
MailTo = DLookup("MailTo", "テーブル1", "ID = id")
MailFrom = DLookup("MailFrom", "テーブル1", "ID = id")
MailCC = DLookup("MailCC", "テーブル1", "ID = id")
MailTitle = DLookup("MailTitle", "テーブル1", "ID = id")
MailBody = DLookup("MailBody", "テーブル1", "ID = id")
UserName = DLookup("UserName", "テーブル1", "ID = id")
MsgBox Mailsend(MailFrom, MailTo, MailCC, MailTitle, MailBody, "")
End Sub
あ、すごい。できた気がする。
あれ、駄目みたい・・・。
「Mailsend」で引っかかってるってことかな?
なるほど、これで「True」がきてるってことはメール送信が成功しているってことですね。ふむふむ。じゃぁこれで完成するのでは!?
Private Sub コマンド2_Click()
'宣言
Dim id As Integer
Dim MailTo As String
Dim MailFrom As String
Dim MailCC As String
Dim MailTitle As String
Dim MailBody As String
Dim UserName As String
id = DLookup("ID", "テーブル1", "SendDateTime is null")
MailTo = DLookup("MailTo", "テーブル1", "ID = id")
MailFrom = DLookup("MailFrom", "テーブル1", "ID = id")
MailCC = DLookup("MailCC", "テーブル1", "ID = id")
MailTitle = DLookup("MailTitle", "テーブル1", "ID = id")
MailBody = DLookup("MailBody", "テーブル1", "ID = id")
UserName = DLookup("UserName", "テーブル1", "ID = id")
If Mailsend(MailFrom, MailTo, MailCC, MailTitle, MailBody, "") = True Then
MsgBox "メール送信しました"
Else
MsgBox "メール失敗しました"
End If
End Sub
あ、
>③成功だったら、SendDateTimeに日時を入れて、
これ忘れてますね。
えっと、
「access データ更新」で検索してみよう。
あ、いや、こっちか
「accessVBA データ更新」
なんか難しいこと言われている気がするけど、関数だと無理なのかな。
DoCMDだとできるのかな?
DoCmd.RunSQL "UPDATE テーブル1 SET テーブル1.SendDateTime = date();"
ちがうか
DoCmd.RunSQL "UPDATE テーブル1 SET テーブル1.SendDateTime = date() WHERE ID = id;"
あれ、2件の更新!?
1件じゃないの?
データ取得するときはこれであってるのに。
「AccessVBA 検索 2件の更新」
(・・・)
駄目だ・・・5分経ったので、師匠ヘルプ・・・
DoCmd.RunSQL "UPDATE テーブル1 SET テーブル1.SendDateTime = date() WHERE ID = " & id & ";"
え、でもDLookupはうまくいっている気がするんですけど・・・
本当だ。。。
ID=1,2,3,4,5ってあって、ID=1にSendDateTimeを入れたら、
idには2がはいったのに、
MailTo = DLookup("MailTo", "テーブル1", "ID = id")
でとってきたのはID=1のレコードのMailToだった・・・。
それでは、idのところをダブルコーテーションの外にして・・・
こんな感じかな。
Private Sub コマンド2_Click()
'宣言
Dim id As Integer
Dim MailTo As String
Dim MailFrom As String
Dim MailCC As String
Dim MailTitle As String
Dim MailBody As String
Dim UserName As String
id = DLookup("ID", "テーブル1", "SendDateTime is null")
MailTo = DLookup("MailTo", "テーブル1", "ID = " & id)
MailFrom = DLookup("MailFrom", "テーブル1", "ID = " & id)
MailCC = DLookup("MailCC", "テーブル1", "ID = " & id)
MailTitle = DLookup("MailTitle", "テーブル1", "ID = " & id)
MailBody = DLookup("MailBody", "テーブル1", "ID = " & id)
UserName = DLookup("UserName", "テーブル1", "ID = " & id)
If Mailsend(MailFrom, MailTo, MailCC, MailTitle, MailBody, "") = True Then
MsgBox "メール送信しました"
DoCmd.RunSQL "UPDATE テーブル1 SET テーブル1.SendDateTime = date() WHERE ID = " & id & ";"
Else
MsgBox "メール失敗しました"
End If
End Sub
良し、動いたかな。
これで①~⑤の機能は全部満たしたかな?
完成しました!
あれ、これだとメール1件ずつ?
あ、ほんとだ、「SendDateTime is null」で5件分データ取ってきてて、5件分の処理しているのかと思っちゃってました。
UserNameは、忘れていました・・・。
うーん、そういえば・・・
さっきDlookup調べているときに、DCountってのも見つけたんですよね。
これで5件とかだったら、5回ループするとか?
まずは現在の位置をカウントする変数が必要で、
あとは最大数を覚えとく変数が必要かな。
Excelのときのループと同じ感じでできるかな。
Private Sub コマンド2_Click()
'宣言
Dim count As Integer
Dim i As Integer
Dim id As Integer
Dim MailTo As String
Dim MailFrom As String
Dim MailCC As String
Dim MailTitle As String
Dim MailBody As String
Dim UserName As String
count = DCount("ID", "テーブル1", "SendDateTime is null")
Do Until i = count
id = DLookup("ID", "テーブル1", "SendDateTime is null")
MailTo = DLookup("MailTo", "テーブル1", "ID = " & id)
MailFrom = DLookup("MailFrom", "テーブル1", "ID = " & id)
MailCC = DLookup("MailCC", "テーブル1", "ID = " & id)
MailTitle = DLookup("MailTitle", "テーブル1", "ID = " & id)
MailBody = DLookup("MailBody", "テーブル1", "ID = " & id)
UserName = DLookup("UserName", "テーブル1", "ID = " & id)
If Mailsend(MailFrom, MailTo, MailCC, MailTitle, MailBody, "") = True Then
MsgBox "メール送信しました"
DoCmd.RunSQL "UPDATE テーブル1 SET テーブル1.SendDateTime = date() WHERE ID = " & id & ";"
Else
MsgBox "メール失敗しました"
End If
i = i + 1
Loop
End Sub
よし、0件の時もエラーになってないっぽいし、これでOKかな。
わかりました!
①は簡単。コメントアウトするだけでいいんだからね。
②はメッセージはすぐだし、IDも変数にとってあるから大丈夫。「Access ループ 抜ける」で検索して。。。なるほど。。。「Exit Do」で良いのかな。
③もやる箇所はわかるから、検索だな。「docmd.runsql メッセージ 非表示」で出てきたサイトをそのまま参照しちゃおう。
④送信件数は、iでいいのかな。これもメッセージだけ変えれば、他はいじる必要なさそうかな。
Private Sub コマンド2_Click()
'宣言
Dim count As Integer
Dim i As Integer
Dim id As Integer
Dim MailTo As String
Dim MailFrom As String
Dim MailCC As String
Dim MailTitle As String
Dim MailBody As String
Dim UserName As String
count = DCount("ID", "テーブル1", "SendDateTime is null")
Do Until i = count
id = DLookup("ID", "テーブル1", "SendDateTime is null")
MailTo = DLookup("MailTo", "テーブル1", "ID = " & id)
MailFrom = DLookup("MailFrom", "テーブル1", "ID = " & id)
MailCC = DLookup("MailCC", "テーブル1", "ID = " & id)
MailTitle = DLookup("MailTitle", "テーブル1", "ID = " & id)
MailBody = DLookup("MailBody", "テーブル1", "ID = " & id)
UserName = DLookup("UserName", "テーブル1", "ID = " & id)
If Mailsend(MailFrom, MailTo, MailCC, MailTitle, MailBody, "") = True Then
'MsgBox "メール送信しました"
DoCmd.SetWarnings False
DoCmd.RunSQL "UPDATE テーブル1 SET テーブル1.SendDateTime = date() WHERE ID = " & id & ";"
DoCmd.SetWarnings True
Else
MsgBox "ID" & id & "でエラーがあったので処理を中断しました。"
Exit Do
End If
i = i + 1
Loop
MsgBox i & "件のメール送信処理を完了しました"
End Sub
わかりました、ありがとうございました!
これにて、
ぜ ぜ ぜ 是非みたいです!
Private Sub コマンド2_Click()
'変数宣言
Dim daoDB As dao.Database
Dim daoRS As dao.Recordset
Dim strMailTitle As String
Dim strMailBody As String
Dim c As Integer
'TABLE読込
Set daoDB = CurrentDb()
Set daoRS = daoDB.OpenRecordset("Select * From テーブル1 Where SendDateTime Is Null", dbOpenDynaset, dbDenyWrite)
c = 0
If daoRS.RecordCount > 0 Then
Do Until daoRS.EOF
If daoRS!MailFrom <> "" And daoRS!MailTo <> "" Then
strMailTitle = Replace(daoRS!MailTitle, "{UserName}", daoRS!UserName)
strMailBody = Replace(daoRS!MailBody, "{UserName}", daoRS!UserName)
If Mailsend(daoRS!MailFrom, daoRS!MailTo, daoRS!MailCC, strMailTitle, strMailBody, "") = True Then
daoRS.Edit
daoRS!SendDateTime = Now
daoRS.Update
Else
MsgBox "ID:" & daoRS!id & " でエラーがあったので処理を中断しました。"
Exit Do
End If
End If
c = c + 1
daoRS.MoveNext
Loop
End If
MsgBox c & "件のメール送信処理を完了しました"
On Error Resume Next
Set daoRS = Nothing
Set daoDB = Nothing
End Sub
確かに違う・・・。これを想定していた・・・!?
勉強になりました。。。ありがとうございました!
次回からは、VBAはここでいったん終わりになりまして、
いよいよ、ひさきが、世界に羽ばたくとき!!
WEB言語のPHPの世界に足を踏み込みます!お楽しみに!
この記事が気に入ったらサポートをしてみませんか?