OUTLOOKで他人のスケジュールが見にくいのでEXCELに出力するマクロ
いまいちOUTLOOKの予定表って見ずらくて他人の予定を把握しずらい。
もうちょっとシンプルなサイボ〇〇ライクな表示と印刷しやすい形にならないか?と思って、ちゃちゃっとAI作成しました。AIまじすごw
予定を入れる機能はありません。スケジュールを表示するだけです。
画面の見た目は、時間が青太文字のあと予定、土日祝日着色され、祝日表示されます。
人の作ったマクロファイルなんて怖くて開けないと思うのでオープンソースでw
使い方
EXCELで新規ファイル作成し、以下マクロを貼って実行すると、
【対象メアド】と【予定表】シートが作られるので、
【対象メアド】シートのA列にスケジュールを検索したいメアドを入れ
【予定表】シートの開始日、検索日数の黄色欄にそれぞれ入力して
更新ボタンを押すと、【予定表】シートにスケジュールを表示する
検索には時間がかかるので、パソコン放置する時にでも動かしておきましょう
もちろんファイル保存はマクロありで保存しないとだめですよ?
初めて実行する場合は、以下の【Microsoft Outlook●ObjectLibrary】を有効にしないと動きません
' =============================
' Outlook予定表 一括取得ツール
' =============================
Public Sub GetGroupSchedules_Final()
Dim olApp As Object, olNamespace As Object
Dim wsMain As Worksheet
Dim wsList As Worksheet
Dim isNewConfig As Boolean: isNewConfig = False
' --- 【追加】自動シート作成・チェック処理 ---
On Error Resume Next
Set wsList = ThisWorkbook.Worksheets("対象メアド")
Set wsMain = ThisWorkbook.Worksheets("予定表")
On Error GoTo 0
' 「対象メアド」シートがなければ作成
If wsList Is Nothing Then
Set wsList = ThisWorkbook.Worksheets.Add(Before:=ThisWorkbook.Worksheets(1))
wsList.Name = "対象メアド"
wsList.Range("A1").Value = "アドレス"
wsList.Range("B1").Value = "名称用テキスト(任意)"
wsList.Columns("A:B").ColumnWidth = 25
isNewConfig = True
End If
' 「予定表」シート(メイン画面)がなければ作成
If wsMain Is Nothing Then
Set wsMain = ThisWorkbook.Worksheets.Add(After:=wsList)
wsMain.Name = "予定表"
isNewConfig = True
End If
' アクティブシートを「予定表」にする
wsMain.Select
' アドレスリストが空、または新規作成された直後の場合はメッセージを出して終了
If isNewConfig Or wsList.Cells(wsList.Rows.Count, "A").End(xlUp).Row < 2 Then
Beep
MsgBox "「対象メアド」シートのA列にメールアドレスを入力してください。" & vbLf & _
"入力後、もう一度マクロを実行するか「更新」ボタンを押してください。", vbInformation, "初期設定"
' ユーザーが入力しやすいように「対象メアド」シートを選択して終了
wsList.Select
' 初期状態でもボタンだけは「予定表」シートに配置しておく
Call SetupUpdateBtn(wsMain)
Exit Sub
End If
' --------------------------------------------
Beep
On Error Resume Next
Set olApp = CreateObject("Outlook.Application")
Set olNamespace = olApp.GetNamespace("MAPI")
On Error GoTo 0
If olApp Is Nothing Then MsgBox "Outlookを起動できませんでした。", vbCritical: Exit Sub
' --- 1. 期間とUIの設定 (1行目) ---
Dim startDate As Date: startDate = IIf(IsDate(wsMain.Range("B1").Value), wsMain.Range("B1").Value, Date)
Dim searchDays As Integer: searchDays = IIf(wsMain.Range("D1").Value > 0, wsMain.Range("D1").Value, 7)
Dim endDate As Date: endDate = startDate + searchDays - 1
wsMain.Range("B1").Value = startDate
wsMain.Range("D1").Value = searchDays
With wsMain
.Rows(1).RowHeight = 45
With .Range("A1:D1")
.Font.Name = "HG丸ゴシックM-PRO": .Font.Size = 16: .VerticalAlignment = xlCenter
End With
.Range("B1").ShrinkToFit = True
.Range("A1").Value = "開始日:": .Range("C1").Value = "検索日数:"
.Range("A1,C1").HorizontalAlignment = xlRight
.Range("D1").Interior.Color = vbYellow: .Range("D1").Font.Bold = True
.Rows("2:" & .Rows.Count).Clear
.Columns("A").ColumnWidth = 18: .Columns("C").ColumnWidth = 14
' ボタンの再作成
Call SetupUpdateBtn(wsMain)
End With
' --- 2. 日付ヘッダー作成 (2行目) ---
Application.ScreenUpdating = False
Dim col As Long, targetDate As Date, hName As String
wsMain.Cells(2, 1).Value = "氏名 / 日付"
wsMain.Rows(2).RowHeight = 39
For col = 0 To searchDays - 1
targetDate = startDate + col
hName = GetHolidayName(targetDate)
With wsMain.Cells(2, col + 2)
.Value = targetDate
.NumberFormatLocal = "m/d(aaa)"
If hName <> "" Then .Value = .Text & vbLf & hName
.Font.Name = "HG丸ゴシックM-PRO": .Font.Size = 14: .Font.Bold = True
.HorizontalAlignment = xlCenter: .VerticalAlignment = xlCenter: .WrapText = True
.ShrinkToFit = True
If hName <> "" Or Weekday(targetDate) = vbSunday Then
.Interior.Color = RGB(255, 230, 230): .Font.Color = vbRed
wsMain.Columns(col + 2).ColumnWidth = 18
ElseIf Weekday(targetDate) = vbSaturday Then
.Interior.Color = RGB(220, 230, 241): .Font.Color = vbBlue
wsMain.Columns(col + 2).ColumnWidth = 18
Else
.Interior.Color = RGB(250, 250, 250): .Font.Color = vbBlack
wsMain.Columns(col + 2).ColumnWidth = 22
End If
End With
Next
' --- 3. 予定取得処理 ---
Dim lastMailRow As Long: lastMailRow = wsList.Cells(wsList.Rows.Count, "A").End(xlUp).Row
Dim mailRow As Long, rowIdx As Long: rowIdx = 3
Dim mailAddr As String, recipient As Object, olFolder As Object
Dim colBValue As String, dispName As String
' 1行目の見出しスキップのため 2 からループ開始
For mailRow = 2 To lastMailRow
mailAddr = wsList.Cells(mailRow, "A").Value
colBValue = Trim(wsList.Cells(mailRow, "B").Value)
If mailAddr <> "" Then
Set recipient = olNamespace.CreateRecipient(mailAddr)
If recipient.Resolve Then
Set olFolder = Nothing
On Error Resume Next
Set olFolder = olNamespace.GetSharedDefaultFolder(recipient, 9)
On Error GoTo 0
dispName = recipient.Name
If colBValue <> "" Then
dispName = dispName & vbLf & colBValue
End If
If Not olFolder Is Nothing Then
wsMain.Cells(rowIdx, 1).Value = dispName
Call ProcessAppointments(olFolder, wsMain, rowIdx, startDate, endDate)
Else
wsMain.Cells(rowIdx, 1).Value = dispName & " (取得不可)"
wsMain.Cells(rowIdx, 1).Font.Color = RGB(150, 150, 150)
End If
End If
rowIdx = rowIdx + 1
End If
Next
' --- 4. 仕上げ ---
With wsMain.Range(wsMain.Cells(2, 1), wsMain.Cells(rowIdx - 1, searchDays + 1))
.Borders.LineStyle = 1: .VerticalAlignment = xlTop: .WrapText = True
End With
If rowIdx > 3 Then wsMain.Rows("3:" & rowIdx - 1).AutoFit
Application.ScreenUpdating = True
Beep
MsgBox "更新しました。"
End Sub
' --- 予定取得サブ ---
Private Sub ProcessAppointments(folder As Object, ws As Worksheet, rowIdx As Long, sDate As Date, eDate As Date)
Dim filter As String: filter = "[End] >= '" & Format(sDate, "yyyy/mm/dd 00:00") & "' AND [Start] <= '" & Format(eDate, "yyyy/mm/dd 23:59") & "'"
Dim items As Object: Set items = folder.items
items.IncludeRecurrences = True: items.Sort "[Start]"
Dim restrictedItems As Object: Set restrictedItems = items.Restrict(filter)
Dim appt As Object, checkDate As Date, targetCol As Long, timeStr As String
For Each appt In restrictedItems
For checkDate = Int(appt.Start) To Int(appt.End)
If checkDate = Int(appt.End) And Format(appt.End, "HH:mm") = "00:00" Then Exit For
If checkDate >= sDate And checkDate <= eDate Then
targetCol = (checkDate - sDate) + 2
If appt.AllDayEvent Then
timeStr = "【終日】"
Else
timeStr = Format(appt.Start, "HH:mm") & "-" & Format(appt.End, "HH:mm")
End If
With ws.Cells(rowIdx, targetCol)
.Value = .Value & IIf(.Value <> "", vbLf, "") & timeStr & " " & appt.Subject
End With
End If
If checkDate > eDate Then Exit For
Next
Next
' --- 装飾処理 ---
Dim c As Long, i As Long, pos As Long, lines Variant, decoLen As Integer
For c = 2 To (eDate - sDate) + 2
If ws.Cells(rowIdx, c).Value <> "" Then
lines = Split(ws.Cells(rowIdx, c).Value, vbLf): pos = 1
For i = 0 To UBound(lines)
decoLen = IIf(lines(i) Like "##:##-##:##*", 11, IIf(lines(i) Like "【終日】*", 4, 0))
If decoLen > 0 Then
With ws.Cells(rowIdx, c).Characters(pos, decoLen).Font
.Color = vbBlue: .Bold = True
End With
End If
pos = pos + Len(lines(i)) + 1
Next
End If
Next
End Sub
' --- 複数年対応・祝日自動判定ロジック ---
Private Function GetHolidayName(targetDate As Date) As String
Dim y As Integer, m As Integer, d As Integer, w As Integer
Dim hName As String
y = Year(targetDate)
m = Month(targetDate)
d = Day(targetDate)
w = Weekday(targetDate)
hName = ""
Select Case m
Case 1
If d = 1 Then hName = "元日"
If d = GetNthWeekday(y, 1, 2, 2) Then hName = "成人の日"
Case 2
If d = 11 Then hName = "建国記念の日"
If d = 23 Then hName = "天皇誕生日"
Case 3
If d = GetVernalEquinox(y) Then hName = "春分の日"
Case 4
If d = 29 Then hName = "昭和の日"
Case 5
If d = 3 Then hName = "憲法記念日"
If d = 4 Then hName = "みどりの日"
If d = 5 Then hName = "こどもの日"
Case 7
If d = GetNthWeekday(y, 7, 2, 3) Then hName = "海の日"
Case 8
If d = 11 Then hName = "山の日"
Case 9
Dim keiro As Integer, syunbun As Integer
keiro = GetNthWeekday(y, 9, 2, 3)
syunbun = GetAutumnalEquinox(y)
If d = keiro Then
hName = "敬老の日"
ElseIf d = syunbun Then
hName = "秋分の日"
ElseIf d = keiro + 1 And d = syunbun - 1 Then
hName = "国民の休日"
End If
Case 10
If d = GetNthWeekday(y, 10, 2, 2) Then hName = "スポーツの日"
Case 11
If d = 3 Then hName = "文化の日"
If d = 23 Then hName = "勤労感謝の日"
End Select
If hName <> "" Then
GetHolidayName = hName
Exit Function
End If
' --- 振替休日の判定 ---
If w = 2 Then
If GetHolidayName(targetDate - 1) <> "" And GetHolidayName(targetDate - 1) <> "振替休日" Then
GetHolidayName = "振替休日"
Exit Function
End If
ElseIf m = 5 And d = 6 And (w = 3 Or w = 4) Then
If Weekday(DateSerial(y, 5, 3)) = 1 Or Weekday(DateSerial(y, 5, 4)) = 1 Or Weekday(DateSerial(y, 5, 5)) = 1 Then
GetHolidayName = "振替休日"
Exit Function
End If
End If
GetHolidayName = ""
End Function
Private Function GetNthWeekday(y As Integer, m As Integer, targetW As Integer, n As Integer) As Integer
Dim firstDay As Date, firstW As Integer, dayOffset As Integer
firstDay = DateSerial(y, m, 1)
firstW = Weekday(firstDay)
dayOffset = targetW - firstW
If dayOffset < 0 Then dayOffset = dayOffset + 7
GetNthWeekday = 1 + dayOffset + (n - 1) * 7
End Function
Private Function GetVernalEquinox(y As Integer) As Integer
Select Case y Mod 4
Case 0, 1, 2: GetVernalEquinox = Int(20.8431 + 0.242194 * (y - 1980) - Int((y - 1980) / 4))
Case 3: GetVernalEquinox = Int(21.2421 + 0.242194 * (y - 1980) - Int((y - 1980) / 4))
End Select
End Function
Private Function GetAutumnalEquinox(y As Integer) As Integer
Select Case y Mod 4
Case 0, 1, 2: GetAutumnalEquinox = Int(23.2488 + 0.242194 * (y - 1980) - Int((y - 1980) / 4))
Case 3: GetAutumnalEquinox = Int(24.2488 + 0.242194 * (y - 1980) - Int((y - 1980) / 4))
End Select
End Function
' --- ボタン作成サブ ---
Private Sub SetupUpdateBtn(ws As Worksheet)
Dim btn As Object
For Each btn In ws.Shapes
If btn.Name = "Btn_UpdateSchedules" Then btn.Delete
Next btn
Set btn = ws.Shapes.AddShape(5, ws.Range("E1").Left + 5, 5, 120, 35)
With btn
.Name = "Btn_UpdateSchedules"
.OnAction = "'" & ThisWorkbook.Name & "'!GetGroupSchedules_Final"
.Fill.ForeColor.RGB = RGB(255, 255, 255)
.Fill.Solid
.Line.ForeColor.RGB = vbBlack
.Line.Weight = 2.25
With .TextFrame
.Characters.Text = "更 新"
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
With .Characters.Font
.Name = "HG丸ゴシックM-PRO"
.Size = 24
.Bold = True
.Color = vbRed
End With
End With
End With
End Sub

