1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

VBAにてMicrosoft Excelブックが開かれているか確認する

Posted at

 VBAからMicrosoftExcelのブックが更新可能かを判断する場合、ブックをファイルとしてAppendモードで開いて、エラーコードを確認するというのが定番のテクニックだそうだ。単なるファイルとして開くのでパフォーマンスが良いらしい。 
 しかしながら、そのブックがネットワーク上にある場合、ほかの人が使用中でもAppendモードで開けてしまうようである。
 これでは使えない。そもそも更新可能かを確かめるときは、いずれにせよMicrosoftExcelから開くことになる。そうであれば、「だれかが開いている事がむしろ多いです」という事が前提でなければ、ワークブックとしてきっちりと開いて確認したほうがむしろ速いかもしれない。なのでそうするよう作り直した。

 開いてみて[読み取り専用]モードであったなら書込み不能と判断し、戻り値としてFalseをセットして、開いたブックは閉じる。そうでなければ、Trueを返し、ブックは開いたままとする。

 関数名は"OpenBookWritable”とし、開こうとするブックのフルパスで引数として渡すこととする。

Function OpenBookWritable(フルパス名) As Boolean

    Application.DisplayAlerts = False
    '↑ ブックをほかの人が開いていたとき、「編集可能となった際に
        '通知しますか」のメッセージが出ないように抑止
    Workbooks.Open Filename:=フルパス名, Notify:=False
    '↑ 「読み取り専用で開きますか」の メッセージが出ないように抑止
    
    If ActiveWorkbook.ReadOnly Then
    '↑ 開いたブックが [読み取り専用]になっていたら
        ActiveWorkbook.Close
        '↑ ブックを閉じます。 開いた直後なので必ずActiveになる。
        OpenBookWritable = False '<= ブックは開かれてますよ、と返す。
    Else
        OpenBookWritable = True '<= ブックは開かれてませんよ、と返す。
    End If

    Application.DisplayAlerts = True
    '↑「編集可能となった際に通知しますか」のメッセージ抑止解除

End Function

より丁寧には、目的のブックが存在するかどうかを確認してからブックを開くことが望ましく、その場合は関数冒頭に次のような処理を追加するのもいいかな。

If Not CreateObject("Scripting.FileSystemObject").FileExists(フルパス名) Then
    OpenBookWritable = False
    Exit Function
End If

 おそらく問題とならないことが多いが、上のチェックを追加で入れた場合、「ブックがなくてFalseなのか、ブックがあるが誰かがつかんでいるのでFalseなのか」区別がつかないので、全体を関数として紹介するのは保留とする。ファイルが開かれていればスルー、というパターンは多いが、ファイルがなくてもスルー、というのは抵抗があるかも。

 なのでこの関数のテスト用に書いたドライバ。呼び出しはダイアログボックスから読み込みブックを指定するようにして「ブックがない場合はどうしよう」は考えずに済むようにした。

Sub OpenBookWritableドライバ()

Dim フルパス名 As String
Dim ブック名 As String

    '<ダイアログボックスを出して、 開くブックを選択する。 >
    フルパス名 = Application.GetOpenFilename("Microsoft Excel ブック,*.xls*")

    If フルパス名 = "False" Then
        MsgBox "キャンセルされました"
       Exit Sub
    End If

    If Not OpenBookWritable(フルパス名) Then
        MsgBox "ファイルが使用できません"
    Else
        DoEvents '何か処理
        
        '<FileSystemObject を利用して、ブック名を取り出す>
        ブック名 = CreateObject("Scripting.FileSystemObject").GetFileName(フルパス名)
        
        Application.DisplayAlerts = False
        Workbooks(ブック名).Save
        Workbooks(ブック名).Close
        Application.DisplayAlerts = True
    End If
End Sub
1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?