即効テクニック |
任意のブックを開くには、WorkbooksコレクションのOpenメソッドを使います。 次のコードは、C:\Book1を開いて、Sheet1のセルA1に現在の日時を入力して保存します。Sub Sample1() Workbooks.Open Filename:="C:\Book1.xls" Sheets("Sheet1").Activate Range("A1") = Now ActiveWorkbook.Save End Subこれだけなら、特に難しくないマクロですが、このBook1を誰か別のユーザーが開いていたとしたらどうでしょう。 Book1が共有ブックとして保存されているのでしたら、複数のユーザーが編集できますが、共有ブックでない場合は「読み取り専用」として開かれてしまいますので、最後のSaveで上書き保存するところでエラーが発生します。 ブックを、他のユーザーが開いているかどうか判定するにはどうしたらいいでしょう。 ブックを開く前に判定する方法は、現実的には難しいです。 最も簡単な方法のひとつは、とりあえず開いてみて、そのブックが「読み取り専用」になっているかどうかを調べるやり方です。Sub Sample2() Workbooks.Open Filename:="C:\Book1.xls" If ActiveWorkbook.ReadOnly Then MsgBox "読み取り専用です" ActiveWorkbook.Close Else Sheets("Sheet1").Activate Range("A1") = Now ActiveWorkbook.Save End If End Subブックが読み取り専用かどうかは、WorkbookオブジェクトのReadOnlyプロパティで判定できます。 読み取り専用のときは、ReadOnlyプロパティがTrueになります。 とりあえず開いてから、ReadOnlyプロパティの値によって処理を分岐しています。 これで「読み取り専用」でもエラーが発生しなくなりましたが、ひとつ問題が残ります。 手作業でブックを開くとき、そのブックを誰か他のユーザーが開いていた場合、[使用中のファイル]ダイアログボックスが開き、現在そのブックを誰が編集しているかが表示されます。 ブックを開くには[読み取り専用]ボタンか[通知]ボタンをクリックするのですが、[通知]ボタンで開いた場合は、先に開いていたユーザーがそのブックを閉じたとき、こちらのExcelで「ブックを編集できるようになりました」というメッセージが表示されます。 先のSub Sample2のように、マクロでブックを開くときは、この[通知]ボタンがクリックされたことになりますので、ActiveWorkbook.Closeでブックをすぐに閉じても、その後、先に開いていたユーザーがブックを閉じると、こちらのExcelでは忘れた頃に「編集可能になりました」というメッセージが表示されてしまいます。 この「編集可能になりました」メッセージを表示しないようにするには、[通知]ボタンではなく[読み取り専用]ボタンでブックを開かなければなりません。 それには、Openメソッドの引数NotifyにFalseを指定します。 引数NotifyにFalseを指定すると、開いたブックが通知リストに登録されません。Sub Sample3() Workbooks.Open Filename:="C:\Book1.xls", Notify:=False If ActiveWorkbook.ReadOnly Then MsgBox "読み取り専用です" ActiveWorkbook.Close Else Sheets("Sheet1").Activate Range("A1") = Now ActiveWorkbook.Save End If End Subただし、引数NotifyにFalseを指定すると、[通知]ボタンがクリックされたことになりませんので、今度は「読み取り専用で開きますか」というメッセージがブックを開く前に表示されます。 このメッセージは、DisplayAlertsプロパティにFalseを指定することで抑止可能です。Sub Sample4() Application.DisplayAlerts = False Workbooks.Open Filename:="C:\Book1.xls", Notify:=False If ActiveWorkbook.ReadOnly Then MsgBox "読み取り専用です" ActiveWorkbook.Close Else Sheets("Sheet1").Activate Range("A1") = Now ActiveWorkbook.Save End If Application.DisplayAlerts = True End Sub