VBA初心者です。
Outlookの特定のメールフォルダ(受信フォルダの下層のフォルダ『○○○自動配信メール』)のメールの
・件名
・未読(TrueかFalseか)
・本文
をエクセルで表示させるマクロを作りました。
(前回のデータを消して6行目から入力する)
このマクロは未読メールに対してのみ行いたいため、
If文を使って未読メールなら以下の処理を実行し、
もし未読メールでないならば、Else以下の処理を実行する
というようにしたいのですが、エラーが出てきてうまくいきません。
マクロの内容は下記のとおりです。
会社での業務に関するマクロのため、固有名詞があるところは○○○にしています。
------------------------------------------------------------------------
Option Explicit
Sub ○○○自動配信メールを取得()
Dim tol As Outlook.Application
Dim tns As Object
Dim toldir As Object
Dim tSyncObj As Outlook.SyncObject
Dim tmail As Object
Dim i As Integer
Dim lrow As Long
'データの表示エリアをクリアする
Rows("6:9999").Delete Shift:=xlUp '6行目から削除する
Range("a1").Select
'Outlookのインスタンスを作成
Set tol = New Outlook.Application
'名前空間を取得
Set tns = tol.GetNamespace("MAPI")
'○○○自動配信メールのフォルダを取得
Set toldir = tns.GetDefaultFolder(olFolderInbox).Folders("○○○自動配信メール")
' 未読のメールのみに処理を行なう
If tmail.UnRead = True Then
'項目名の表示
lrow = 6
Cells(lrow, 2) = "件名"
Cells(lrow, 3) = "未読"
Cells(lrow, 4) = "本文"
'アイテム数をループする
For i = 1 To toldir.Items.Count
'アイテムオブジェクト
Set tmail = toldir.Items.Item(i)
lrow = lrow + 1
'件名
Cells(lrow, 2) = tmail.Subject
'未読
Cells(lrow, 3) = tmail.UnRead
'本文
Cells(lrow, 4) = tmail.Body
Else
MsgBox "作成すべき教育記録はありません。"
End If
Set toldir = Nothing
Set tns = Nothing
Set tol = Nothing
End Sub
-------------------------------------------------------------------------
上記でマクロを実行すると、
『コンパイルエラー:Elseに対するIfがありません。』と表示されます。
どこの箇所から問題が起きているか絞ろうとして、
IfからElseまでの行を削除したり元に戻したりしてマクロを実行させてみた結果、
添付した画像の箇所を削除するときにエラーのメッセージが
『実行時エラー 91
オブジェクト変数またはWithブロック変数が設定されていません。』
に変わったので、この箇所が問題なのかなと思いましたが、
どのように直したらIfをElseに対するIfと認識してくれるのかがわかりません。
どなたか詳しい方、ご教授いただけますと助かります。
どうかよろしくお願いいたします。
A 回答 (6件)
- 最新から表示
- 回答順に表示
No.6
- 回答日時:
ANo3です
補足でご提示のコードは妙な省略のされ方になっているため、追いかけても文脈を理解できずよくわからないです。
とりあえず、②の後の Next i までは動作しているものと仮定して・・・
>rowData = wsData.Cells(Rows.Count, 2).End(xlUp).Row
で使用している、wsDataって、最初に宣言されているだけなので、何を参照しているのか不明です。(省略された中にあるのかも知れませんが…)
それで、エラーとなっているのではないでしょうか?
また、
>・ループ終了後のlrowの値をカウントし~~①
とありますが、Irowを参照しているようには思えません。
(どの部分がIrowへの参照なのでしょうか?)
なんだか、もっと単純化して考えた方が良いように思います。
一方で、#5の解説にもありますが、未読件数はOutLookのUnReadItemCountプロパティで取得できるようですので、そちらを利用する方法もありますね。
(ダイレクトに必要な値が返るので、算出が不要になります。)
No.5
- 回答日時:
#4の回答者です。
どうやら、私のほうの書き込みは、まったく読まれた形跡がないようですので、これ以上はフィードバックはしませんが。
>If ○○○自動配信メールフォルダ内の未読メールが0 Then
>・ループ終了後のlrowの値をカウントし、6(=1行も増えていない)時メッセージを表示させる旨を追記(①)
の質問に対する答え
私の回答が間違っているのなら、仕方がありませんが、
①.
未読チェックの方法(ループする前に終わっています)
If toldir.UnReadItemCount > 0 Then 'フォルダの未読のチェック'**
「フォルダ内で読まれていないアイテムの数を示す」というプロパティ
②
はすでに、#4の中で答えていますので割愛します。
以下の方式ですと、シートの負担が多すぎるので、
>Rows("6:9999").Delete Shift:=xlUp '6行目から削除する
(昔と今では、こういう部分の仕様が変わったと聞きます)だから、こう考えました。
↓
Intersect(ActiveSheet.UsedRange, Rows("6:9999")).ClearContents '*
データがある場所と、6行~9999行で重なり合うところのデータを消去するというほうが楽だと考えました。以上です。
No.4
- 回答日時:
#2の回答者です。
補足の2件は、これでよいはずです。
'*付きが修正点
'//
'データの表示エリアをクリアする
'6行目から削除する
Intersect(ActiveSheet.UsedRange, Rows("6:9999")).ClearContents '*
Range("A1").Select
'Outlookのインスタンスを作成
Set tol = New Outlook.Application
'名前空間を取得
Set tns = tol.GetNamespace("MAPI")
'○○○自動配信メールのフォルダを取得
Set toldir = tns.GetDefaultFolder(olFolderInbox).Folders("goo") '("○○○自動配信メール")
If toldir.UnReadItemCount > 0 Then 'フォルダの未読のチェック'**
' 未読のメールのみに処理を行なう
lrow = 6
Cells(lrow, 2) = "件名"
Cells(lrow, 3) = "未読"
Cells(lrow, 4) = "本文"
'アイテム数をループする
For i = 1 To toldir.Items.Count
'アイテムオブジェクト
Set tmail = toldir.Items.Item(i)
If tmail.UnRead Then
lrow = lrow + 1
Cells(lrow, 2) = tmail.Subject '件名
Cells(lrow, 3) = tmail.UnRead '未読
Cells(lrow, 4) = tmail.Body '本文
tmail.UnRead = False '***
End If
Next
Else '未読がなければ以下が表示される '****
MsgBox "作成すべき教育記録はありません。", vbExclamation
End If
Set toldir = Nothing
No.3
- 回答日時:
ANo1です。
スマホからなので方法だけになってしまいますが・・
> 『作成すべき~』が回数分出てくるため~~
#1にも書きましたように、ループ内で1件処理する毎にメッセージを出すようになっているためそのようになってしまいます。
多分、なさりたいことは未読が1件もなかった時だけ表示したいのではないかと想像します。
そのような場合によく用いられる方法として、処理を行ったかどうかのフラグ(変数)を設定しておきます。
現在のループ内のメッセージ表示処理をはずした上で、ループ内では、未読の処理を行ったらこのフラグをセットするようにしておいて、ループを抜けてからフラグをチェックし、セットされていなかったら(=1度も処理していない)メッセージを出すようにすれば良いです。
でも、ご提示のコードの場合は、フラグに代わる指標がすでにあるので、フラグを設定する必要はありません。
ループ終了後に lrow の値を見れば、何件処理したか(しなかったか)がわかるので、『⚪件処理しました』とか『ありませんでした』といった表示をすることが可能ですね。
>抽出が終わった後は既読にしたい~~
メソッドの仕様は存じませんが、
tmail.UnRead = False
で、既読にできるのであるなら、未読メールの処理を行っているところに、既読化の処理を追加しておけば良いはずです。
No.2
- 回答日時:
#1さんと内容的には、同じですが、私なりに手を加えてみました。
>MsgBox "作成すべき教育記録はありません。"
この部分をどう活かしてよいのか、今のところわかりません。
'//
'データの表示エリアをクリアする
''Rows("6:9999").Delete Shift:=xlUp '6行目から削除する
Intersect(ActiveSheet.UsedRange, Rows("6:9999")).ClearContents '*
Range("A1").Select
'Outlookのインスタンスを作成
Set tol = New Outlook.Application
'名前空間を取得
Set tns = tol.GetNamespace("MAPI")
'○○○自動配信メールのフォルダを取得
Set toldir = tns.GetDefaultFolder(olFolderInbox).Folders("○○○自動配信メール")
' 未読のメールのみに処理を行なう
'If tmail.UnRead = True Then '*
'項目名の表示
lrow = 6
Cells(lrow, 2) = "件名"
Cells(lrow, 3) = "未読"
Cells(lrow, 4) = "本文"
'アイテム数をループする
For i = 1 To toldir.Items.Count
'アイテムオブジェクト
Set tmail = toldir.Items.Item(i)
If tmail.UnRead Then '*
lrow = lrow + 1
'件名
Cells(lrow, 2) = tmail.Subject
'未読
Cells(lrow, 3) = tmail.UnRead
'本文
Cells(lrow, 4) = tmail.Body
End If '**
Next
'End If
Set toldir = Nothing
Set tns = Nothing
Set tol = Nothing
No.1
- 回答日時:
こんにちは
Outlookの制御はわかりませんが、ご提示のコードで構文的におかしそうな点を。
1)Forループの終りが不明。Next iがない。
2)If tmail.UnRead = True Thenの位置が変。
・オブジェクトtmailに代入される前に参照している。
・ループとの関係が包含関係にないように見える。
ひとまず、
If tmail.UnRead = True Then を
Set tmail = toldir.Items.Item(i) の後に移動して、
End If の後ろに Next i を入れたらどうでしょうか?
ただし、1件処理する毎に既読の場合にはメッセージが出るので、質問者様が意図なさっている動作とは違うのかもしれませんが。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/12】 急に朝起こしてきた母親に言われた一言とは?
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・好きな「お肉」は?
- ・あなたは何にトキメキますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・チョコミントアイス
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・あなたの習慣について教えてください!!
- ・ハマっている「お菓子」を教えて!
- ・高校三年生の合唱祭で何を歌いましたか?
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・家の中でのこだわりスペースはどこですか?
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
UWSCの終了の仕方
-
VBAで3秒だけ時間を止めたい
-
画面を強制的に再描画させる方法
-
C#で別のフォームのprogress ba...
-
流れ図(フローチャート)が分か...
-
乱数の桁数指定、または範囲指定。
-
Pro Tools の 波形を伸ばす方...
-
VB2010でCSVファイルの読み込み
-
アクティブセルから、A列最終行...
-
null 参照の例外が実行時に発生...
-
vb.netからエクセル関数書き込み
-
ネットワークループとルーティ...
-
【VBA】全て空白のセルの列の非...
-
エディットボックスのテキスト...
-
アセンブラによるウェイト(WAIT...
-
Application->Run();の機能につ...
-
JAVA グリッド
-
動的メモリ 解放がうまくいかない
-
VBA for i=1 to lastrow
-
EXCEL VBA ユーザーフォームの...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
UWSCの終了の仕方
-
画面を強制的に再描画させる方法
-
Escキーを押すと、中断する時と...
-
DOSコマンドのループ内のTIMEコ...
-
VBAでの一時停止と再開の方法
-
VBAで3秒だけ時間を止めたい
-
範囲指定したセルを1つずつ飛...
-
CSVファイルの特定の行だけを読...
-
vb.netからエクセル関数書き込み
-
ループフリー
-
GIFアニメをループさせたくない
-
VBA for i=1 to lastrow
-
DoEventsが必要な理由について
-
乱数の桁数指定、または範囲指定。
-
多重ループの抜けだし方
-
アクティブセルから、A列最終行...
-
Do whileでExitせず、ループの...
-
ボタンが押された時にループか...
-
データベースをEOFまでループさ...
-
テキストボックスの名前に変数...
おすすめ情報
fujillinさん、 WindFallerさん
ご回答いただきありがとうございます。
会社でしか動かせないため、確認が遅くなって申し訳ございません。
fujillinさんの仰る通りに
Set tmail = toldir.Items.Item(i)の後にIf tmail.UnRead = True Then
End If の後にNext iを入れたらうまく動きました。
しかし、『作成すべき~』が○○○自動配信メールのフォルダに
入っている回数分出てくるため、消すのが大変でした。
そこで、
If ○○○自動配信メールフォルダ内の未読メールが0 Then
Msgbox "作成すべき~"
Exit(このマクロを終了)
Else ←(未読メールが1通以上ある)
Irow = Irow + 1~
と続けられればできるのかなと思ったのですが、可能でしょうか?
すみません、もう一件追加です。
未読メールはExcelでの抽出が終わった後は既読にしたいのですが、
間違った箇所に
For Each tmail In toldir.Items
tmail.UnRead = False
と入れてしまっているようで、
1通分ほどしかExcelに表示されなかったです。
(繰り返し操作の中に入れたため、最初の1通分しか適用されなかった
との認識でいます)
この場合、どの箇所に入れればすべての未読メールに適用される
のでしょうか?
質問ばかりで申し訳ございません。
fujillinさん、 WindFallerさん
ご回答ありがとうございます。返答が遅くなり大変失礼いたしました。
今回はfujillinさんのご回答を元に、
・ループ終了後のlrowの値をカウントし、6(=1行も増えていない)時メッセージを表示させる旨を追記(①)
・tmail.UnRead = Falseを未読メールの処理を行っている最後に追記(②)
この土日に少し手を加え、
以前1枚だったシートを「無題」と「○○○メール貼り付け用シート」の2枚にしました。
マクロのボタンは「無題」にあり、ボタンを押すと「○○○メール~シート」がアクティブになり、○○○自動配信メールの情報は後者に反映されます。
メール受信日も必要なので追加しました。
しかし①の部分がよくないらしく(ステップインで各工程を確認)、『オブジェクト変数またはWithブロック変数が設定されていません』と表示されます。
現在のマクロは下記です。
-----------------------------------------------
Option Explicit
Sub ○○○自動配信メールを取得()
Dim tol As Outlook.Application
~(文字数制限のため、前回と変わらないところは~で省略
Dim lrow As Long
Dim rowData As Long '2017.04.09追加
Dim wsData As Object '2017.04.10追加
Sheets("○○○メール貼り付け用シート").Select
Rows("6:9999").Delete Shift:=xlUp '6行目から削除する
Range("a1").Select
'Outlookのインスタンスを作成
~
Set toldir = tns.GetDefaultFolder(olFolderInbox).Folders("○○○自動配信メール")
'項目名の表示
~
Cells(lrow, 4) = "本文"
Cells(lrow, 5) = "受信日"
'アイテム数をループする
~
Set tmail = toldir.Items.Item(i)
' 未読のメールのみに処理を行なう
~
'本文
Cells(lrow, 4) = tmail.Body
'受信日
Cells(lrow, 5) = tmail.ReceivedTime
tmail.UnRead = False '2017.04.09追加 ・・・②
End If
Next i
rowData = wsData.Cells(Rows.Count, 2).End(xlUp).Row
'2017.04.09追加_最後の行数を取得 ・・・①
If rowData = 6 Then
MsgBox "作成すべき教育記録はありません。"
End If
Set toldir = Nothing
Set tns = Nothing
Set tol = Nothing
Sheets("無題").Select
End Sub
文字数制限のため分かれてしまい申し訳ございません。