EXCEL VBA  ブック関連   自分用メモ  crossfish21

開いているブックを全て閉じる (Excelのアプリケーション自体は残る)

``` 01
    ' 開いているブックを全て閉じる(Excelのアプリケーション自体は残る)
    Workbooks.Close
```
---

ブックを閉じる

``` 02
   ' 1番目に開いたブックを閉じる
    Workbooks(1).Close
    
    ' ブック名を指定して閉じる
    Workbooks("aaa.xlsx").Close
    
    ' 保存してからブックを閉じる
    Workbooks("aaa.xlsx").Close SaveChanges:=True
    
    
    ' 開いていないブックを閉じようとするとエラーになるので注意
    
    On Error Resume Next
    Workbooks("開いていない.xlsx").Close
    On Error GoTo 0
```
[リンク1](http://officetanaka.net/excel/vba/file/file03.htm)

---

新規ブックを作成する

```
    ' 新規ブックを作成する
    Workbooks.Add
```
---
ブックを開く

```
    ' ブックを開く(フルパス指定)
    Workbooks.Open "C:まとめ総合ExcelVBAaaa.xlsx"
    Workbooks.Open Filename:="C:まとめ総合ExcelVBAaaa.xlsx"
    
    
    Workbooks.Open Filename:="C:まとめ総合ExcelVBAaaa.xlsx", ReadOnly:=True
    ' 読み取り専用で開く
    
    Workbooks.Open Filename:="C:まとめ総合ExcelVBAaaa.xlsx", Password:="readPASS", WriteResPassword:="writePASS"
    ' 読み取りパスワードを"readPASS"、書込みパスワードを"writePASS"で開く
    
    Workbooks.Open Filename:="C:まとめ総合ExcelVBAaaa.xlsx", UpdateLinks:=0, IgnoreReadOnlyRecommended:=True
    ' ブックのリンクを更新しない、「読み取り専用で開くことを推奨」を無視する(書込みできるように開く)
    
    
    ' ※データの書き換えをすると問題があるブックは、以下のように読み取り専用で開くのが手堅い
    Workbooks.Open Filename:="C:まとめ総合ExcelVBAaaa.xlsx", UpdateLinks:=0, ReadOnly:=True

    ' ※データの書き換えをする場合は、以下のようにするのが適当かな
    Workbooks.Open Filename:="C:まとめ総合ExcelVBAaaa.xlsx", UpdateLinks:=0, IgnoreReadOnlyRecommended:=True
    
    
    ' ファイルが存在しなかった場合はエラーになるので、その簡易対策
    On Error Resume Next
    Workbooks.Open "C:まとめ総合ExcelVBA存在しないブック.xlsx"
    On Error GoTo 0
    
    ' ファイルの存在を確認してから開く
        If Dir("C:まとめ総合ExcelVBAaaa.xlsx") <> "" Then
        Workbooks.Open "C:まとめ総合ExcelVBAaaa.xlsx"
    Else
        MsgBox "ファイルが存在しません。", vbExclamation
    End If
    
    ' ファイルを選択するダイアログを開く方法
    ' この方法ですでに開いているブックを二重に開いてもエラーにならないのでいいかも
    Dim OpenFileName As String
    OpenFileName = Application.GetOpenFilename("Microsoft Excelブック,*.xls?")
    If OpenFileName <> "False" Then
        Workbooks.Open OpenFileName
    Else
        MsgBox "キャンセルされました"
    End If
    
    ' すでに開いているブックを開こうとするとエラーになるので、事前に調べる
    Dim wb As Workbook
    For Each wb In Workbooks
        If wb.Name = "aaa.xlsx" Then
            MsgBox "aaa.xlsxは、すでに開いています"
            Exit Sub
        End If
    Next wb
    Workbooks.Open "C:まとめ総合ExcelVBAaaa.xlsx"
    
    
    ' 一番手堅いと思われるブックの開き方
    Dim buf As String
    Dim wb As Workbook
    Const Target As String = "C:まとめ総合ExcelVBAaaa.xlsx"
    
    ''ファイルの存在チェック
    buf = Dir(Target)
    If buf = "" Then
        MsgBox Target & vbCrLf & "は存在しません", vbExclamation
        Exit Sub
    End If
    ''同名ブックのチェック
    For Each wb In Workbooks
        If wb.Name = buf Then
            MsgBox buf & vbCrLf & "はすでに開いています", vbExclamation
            Exit Sub
        End If
    Next wb
    ''ここでブックを開く
    Workbooks.Open Target
```
[リンク1](http://officetanaka.net/excel/vba/file/file01.htm)

---
ブックを保存する

```
	' 上書き保存
    ActiveWorkbook.Save

    ' 名前を付けて保存
    ActiveWorkbook.SaveAs Filename:="C:まとめ総合ExcelVBAbb.xlsx"
```
[リンク1](http://officetanaka.net/excel/vba/file/file09.htm)

---
ブック関連のイベント

```
Private Sub Workbook_NewSheet(ByVal Sh As Object)
' 新しいシートを作成した時。引数の"Sh"は、新しく作成したシートになる

    Sh.Move After:=Worksheets(Sheets.Count)
    ' 新規作成したシートを、最後尾に移動する

End Sub


Private Sub Workbook_BeforeClose(Cancel As Boolean)
' ブックを閉じる前のイベント。引数の"Cancel"をTrueにすると、ブックを閉じる処理がキャンセルされる

    Dim answer As Long
    
    answer = MsgBox("ブックを閉じます。よろしいですか？", vbYesNo)
    If answer = vbNo Then
        Cancel = True   ' 閉じる処理をキャンセル
        MsgBox "ブックを閉じる処理は中止します"
    End If
    
End Sub


Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
' ブックを保存する前のイベント。引数の"Cancel"をTrueにすると、ブックを閉じる処理がキャンセルされる

    If IsNumeric(Cells(1, 1).Value) = False Then  ' セルA1の値が数値に評価できない場合
        Cancel = True
        MsgBox "セルA1の値を数値にしてから、ブックを保存してください"
    End If
    
End Sub


Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
' ブック内のいずれかのシートの、セルの値が変更された時に発生する
' 引数の"Sh"は値の変更されたセルのあるシート、引数の"Target"は値の変更されたセル
' アクティブシートが変わった時のイベントではない

    MsgBox Sh.Name
    MsgBox Target.Address

End Sub


Private Sub Workbook_Activate()  ' ブックがアクティブになった時
End Sub

Private Sub Workbook_AfterSave(ByVal Success As Boolean)   ' ブックを保存した後
End Sub

Private Sub Workbook_Open()   ' ブックを開いた時
End Sub


※※　他にも種類あり
```

[リンク1](http://excel-ubara.com/excelvba1/EXCELVBA424.html)
[リンク2](http://www.vba-ie.net/object/wb-event.html)

---

他のブックのコードを実行する

```
Sub aaa()

    Application.Run "bbb.xlsm!OtherBookSub"
    ' bbb.xlsm の OtherBookSub() を実行する。PrivateプロシージャでもOK
    ' ※ただし、bbb.xlsmを開いていない場合、開いてから実行されるのがどうも

End Sub



' bbb.xlsm の標準モジュール内にあるコード
Private Sub OtherBookSub()

    MsgBox "bbb.xlsm の OtherBookSub() が呼ばれました"

End Sub

```

[リンク1](http://officetanaka.net/excel/vba/tips/tips09.htm)

---

ブックを開かずに、セルの値を取得する

```
 MsgBox ExecuteExcel4Macro("'C:まとめ総合ExcelVBA[bbb.xlsx]シート1'!R1C1")
    ' C:まとめ総合ExcelVBAbb.xlsx 「シート1」シート セルA1の値を、ブックを開かずに取得
    ' セル番地はR1C1形式でしか指定できないので、使いにくい
    ' セルが空白だった場合、「0」が返るみたい。なお使いにくいな･･･
    
    Dim cellR1C1 As String
    Dim i As Long
    Dim j As Long
    
    ' bbb.xlsx 「シート1」 の Range(Cells(1,1),Cells(5,5)) の値を取得
    For i = 1 To 5
        For j = 1 To 5
            cellR1C1 = "R" & i & "C" & j
            Debug.Print ExecuteExcel4Macro("'C:まとめ総合ExcelVBA[bbb.xlsx]シート1'!" & cellR1C1)
        Next j
    Next i
    
    
    ' ※面倒なわりに制約も多いから、あまり使えないかな
```

[リンク1](http://officetanaka.net/excel/vba/tips/tips28.htm)

---

VBEのショートカットメニューに、項目を追加する

[リンク1](http://officetanaka.net/excel/vba/tips/tips04.htm)