自分用のメモなので、形は整ってないです。
ブックを閉じる
Dim wb As Workbook
'Application.DisplayAlerts = False ブックを保存するかの確認メッセージを出さないようにするならこれで
Workbooks.Open Filename:="C:\work\b111.xlsx", ReadOnly:=True '読み取り専用で開く
Workbooks.Open Filename:="C:\work\b222.xlsx"
Workbooks.Open Filename:="C:\work\b333.xlsx"
Workbooks.Open Filename:="C:\work\b444.xlsx"
Workbooks.Open Filename:="C:\work\b555.xlsx", ReadOnly:=True
Set wb = ActiveWorkbook '最後に開いたブックになる
Debug.Print wb.Name ' b555.xlsx
'Workbooks(1).Close
' 1番目に開いたブックを閉じる(最初に開いたのが自分自身のブックの場合は、自分を閉じてしまう)
Workbooks("b222.xlsx").Close ' ブック名を指定して閉じる(保存はしない)
Workbooks("b333.xlsx").Close SaveChanges:=True ' 保存してからブックを閉じる
On Error Resume Next
Workbooks("開いていない.xlsx").Close
If Err.Number <> 0 Then Debug.Print "エラー発生"
On Error GoTo 0
Workbooks.Close
' 開いているブックを全て閉じる(Excelのアプリケーション自体は残る)。自分自身のブックも閉じてしまう
新規ブックを作成する
Dim wb As Workbook
Dim bookPath As String
Workbooks.Add ' 新規ブックを作成する
Set wb = Workbooks.Add ' 新規ブックを作成して、WorkbookオブジェクトにSET
wb.Worksheets(1).Name = "シート111"
wb.Worksheets(1).Copy '1番目のシートをコピーして、新規ブックとして切り離す
bookPath = "C:\work\XXX.xlsx"
If Dir(bookPath) = "" Then
wb.SaveAs bookPath 'ブックの保存
Else
MsgBox "既に存在するパスなので保存せず"
End If
ブックを開く 色々と面倒な事が多い。丁寧に進めるべき
Sub eeee()
Dim openFilePath As String '開くブックのフルパス
openFilePath = "C:\work\aaa.xlsx"
' ブックを開く(フルパス指定)
Workbooks.Open openFilePath
Workbooks.Open Filename:=openFilePath
Workbooks.Open Filename:=openFilePath, ReadOnly:=True
' 読み取り専用で開く
Workbooks.Open Filename:=openFilePath, Password:="readPASS", WriteResPassword:="writePASS"
' 読み取りパスワードを"readPASS"、書込みパスワードを"writePASS"で開く
Workbooks.Open Filename:=openFilePath, UpdateLinks:=False, IgnoreReadOnlyRecommended:=True
' ブックのリンクを更新しない、「読み取り専用で開くことを推奨」を無視する(書込みできるように開く)
' ※データの書き換えをすると問題があるブックは、以下のように読み取り専用で開くのが手堅い
Workbooks.Open Filename:=openFilePath, UpdateLinks:=False, ReadOnly:=True
' ※データの書き換えをする場合は、以下のようにするのが適当かな
Workbooks.Open Filename:=openFilePath, UpdateLinks:=False, IgnoreReadOnlyRecommended:=True
' ファイルが存在しなかった場合はエラーになるので、その簡易対策
On Error Resume Next
Workbooks.Open "C:\work\存在しないブック.xlsx"
If Err.Number <> 0 Then Debug.Print "エラー発生"
On Error GoTo 0
' ファイルの存在を確認してから開く
If Dir(openFilePath) <> "" Then
Workbooks.Open openFilePath
Else
MsgBox "ファイルが存在しません。", vbExclamation
End If
' ファイルを選択するダイアログを開く方法
' この方法ですでに開いているブックを二重に開いてもエラーにならないのでいいかも
Dim openFileName As String
openFileName = Application.GetOpenFilename _
("Excel ファイル (*.xls; *.xlsx; *.xlsm; *.xlsb),*.xls; *.xlsx; *.xlsm; *.xlsb")
If openFileName <> "False" Then
Workbooks.Open openFileName
Else
MsgBox "キャンセルされました"
End If
'開こうとしているブックと同名のブックがすでに開かれている、開くとエラーになる、はず。
'※明確ではないが、同名のファイルが開いていてもエラーにならないこともある?
'ただし、新しく開こうとしたブックが開かれないので、事前に同名ファイルが開かれていないかを確認するのは必須
'以下、同名ブックが開かれていないかの確認、その他の対処
Dim wb As Workbook
Dim wbTarget As Workbook '開いて作業するブック
Dim resultStr As String
openFilePath = "C:\work\bbb.xlsx"
resultStr = SamePath_SameName(openFilePath)
'同名のブック、同パスのブックが開かれているかを判定する処理を呼び出し
If resultStr = "SamePath" Then
'開こうとしているブックがすでに開いている場合は、そのブックの作業を続行
Set wbTarget = Workbooks(Dir(openFilePath))
If wbTarget.ReadOnly Then
'読み取り専用で開かれていた場合は、作業をしないという選択もある
MsgBox "指定のファイルが読み取り専用で開かれています"
Exit Sub
End If
ElseIf resultStr = "SameName" Then
'同名のブックが開かれている場合は、処理を中断
MsgBox "同名のファイルが開かれています"
Exit Sub
Else
'同名、同パスが無ければ、ブックを開く
Workbooks.Open openFilePath
End If
openFilePath = "C:\work\readOnlyP.xlsx"
If IsReadOnlyProperty(openFilePath) Then
'ファイルのプロパティで、読み取り専用になっているかを判定
'読み取り専用のブックでも、開いて更新のコードはエラーにならない(なるという話も)が、保存しても変更は反映されない
MsgBox "読み取り専用のブックです"
Exit Sub
End If
End Sub
Function SamePath_SameName(openFilePath As String) As String
'pathのExcelファイルが、現在開かれているブックの中に同名のものがあるかと、同じフルパスのものがあるかを判定する
'同名のものが無い場合は "Nothing" を返す
'同名のものがあるが、同パスのものは無い場合は "SameName" を返す
'同パスのものがある場合は "SamePath" を返す
Dim wb As Workbook
SamePath_SameName = "Nothing"
For Each wb In Workbooks
If wb.Path & "\" & wb.Name = openFilePath Then ' 同パスのものがある場合
SamePath_SameName = "SamePath"
Exit For
End If
If wb.Name = Dir(openFilePath) Then ' 同名のものがある場合
SamePath_SameName = "SameName"
Exit For
End If
Next wb
End Function
Function IsReadOnlyProperty(openFilePath) As Boolean
'pathで指定されたファイルが、読み取り専用属性を持つかを判定する
'読み取り専用で開かれているかを判定するのではないので、注意
Dim fa As VbFileAttribute 'ファイル属性
fa = GetAttr(openFilePath) 'ファイルの属性を取得
If (fa And vbReadOnly) = vbReadOnly Then
IsReadOnlyProperty = True
Else
IsReadOnlyProperty = False
End If
End Function
FileName 開くブックのファイル名。
UpdateLinks ファイル内の外部参照 (リンク) の更新方法を指定します。
ReadOnly ブックを読み取り専用モードで開くには、True を指定します。
Format テキスト ファイルを開く場合は、この引数で区切り文字を指定します。
Password パスワード保護されたブックを開くのに必要なパスワードを指定します。
WriteResPassword 書き込み保護されたブックに書き込みをするために必要なパスワードを指定します。
IgnoreReadOnlyRecommended [読み取り専用を推奨する] チェック ボックスをオンにして保存されたブックを開くときでも、読み取り専用を推奨するメッセージを非表示にするには、True を指定します。
Origin 開こうとしているファイルがテキスト ファイルの場合、それがどのような形式のテキスト ファイルかを指定します。
Delimiter 開こうとしているファイルがテキスト ファイルで、引数 Format が 6 の場合は、この引数で区切り文字を使用します。
Editable 開こうとしているファイルが Excel 4.0 のアドインの場合、この引数に True を指定すると、アドインがウィンドウとして表示されます。
Notify ファイルが読み取り/書き込みモードで開けない場合に、ファイルを通知リストに追加するには、True を指定します。
Converter ファイルを開くときに最初に使用するファイル コンバーターのインデックス番号を指定します。
AddToMru 最近使用したファイルの一覧にブックを追加するには、True を指定します。既定値は False です。
Local Excel の言語設定 に合わせてファイルを保存するには、True を指定します。
CorruptLoad 開くモードを、XlCorruptLoad列挙で指定します。
抽出(xlExtractData)、正常(xlnormalload)、修復(xlRepairFile)から指定します。
既定の動作はxlNormalLoadになり、回復は行われません。
ブックを保存する
' 上書き保存
ActiveWorkbook.Save
' 名前を付けて保存
ActiveWorkbook.SaveAs Filename:="C:\work\bbb.xlsx"
ブック関連のイベント
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
Activate ブック、ワークシート、グラフ シート、または埋め込みグラフがアクティブになったときに発生します。
AddinInstall ブックがアドインとして組み込まれたときに発生します。
AddinUninstall ブックのアドインとして組み込みを解除したときに発生します。
AfterSave ブックが保存された後に発生します。
AfterXmlExport Microsoft Office Excel がデータを保存するか、指定されたワークブックから XML データをエクスポートした後で発生します。
AfterXmlImport 既存の XML データ接続が更新されたか、または開いている Microsoft Excel ブックに新しい XML データがインポートされた後に発生します。
BeforeClose ブックを閉じる前に発生します。ブックが変更された場合、ユーザーに変更内容の保存を要求する前に、このイベントが発生します。
BeforePrint ブックまたはその中に含まれる内容を印刷する前に発生します。
BeforeSave ブックを保存する前に発生します。
BeforeXmlExport Microsoft Office Excel がデータを保存するか、指定されたワークブックから XML データをエクスポートする前に発生します。
BeforeXmlImport 既存の XML データ接続が更新されるか、または開いている Microsoft Excel ブックに新しい XML データがインポートされる前に発生します。
Deactivate グラフ、ワークシート、またはブックが非アクティブになったときに発生します。
NewChart 新しいグラフをブックに作成したときに発生します。
NewSheet 新しいシートをブックに作成したときに発生します。
Open ブックを開いたときに発生します。
PivotTableCloseConnection ピボットテーブル レポート接続が閉じた後に発生します。
PivotTableOpenConnection ピボットテーブル レポート接続が開いた後に発生します。
RowsetComplete ユーザーが OLAP ピボットテーブルで行セット アクションを起動するか、レコードセットを詳細表示するとイベントが発生します。
SheetActivate シートがアクティブになったときに発生します。
※すべてのシートが対象となります。
SheetBeforeDoubleClick 既定のダブルクリックの操作の前に、ワークシートをダブルクリックしたときに発生します。
※すべてのシートが対象となります。
SheetBeforeRightClick 既定の右クリックの操作の前に、ワークシートを右クリックしたときに発生します。
※すべてのシートが対象となります。
SheetCalculate ワークシートを再計算したり、グラフでデータをプロットして変更した後に発生します。
※すべてのシートが対象となります。
SheetChange ユーザーまたは外部リンクにより、ワークシートのセルが変更されるときに発生します。
※すべてのシートが対象となります。
SheetDeactivate シートが非アクティブになったときに発生します。
※すべてのシートが対象となります。
SheetFollowHyperlink Excel のハイパーリンクをクリックすると発生します。ワークシート レベルでのイベントについては、FollowHyperlink イベントのヘルプ トピックを参照してください。
※すべてのシートが対象となります。
SheetPivotTableAfterValueChange ピボットテーブル内のセルまたはセル範囲が編集または再計算された後に発生します (数式を含むセルの場合)。
※すべてのシートが対象となります。
SheetPivotTableBeforeAllocateChanges ピボットテーブルに変更が適用される前に発生します。
※すべてのシートが対象となります。
SheetPivotTableBeforeCommitChanges ピボットテーブルの OLAP データ ソースに対する変更が適用される前に発生します。
※すべてのシートが対象となります。
SheetPivotTableBeforeDiscardChanges ピボットテーブルに対する変更が破棄される前に発生します。
※すべてのシートが対象となります。
SheetPivotTableChangeSync ピボットテーブルが変更された後に発生します。
※すべてのシートが対象となります。
SheetPivotTableUpdate ピボットテーブル レポートのシートが更新された後に発生します。
※すべてのシートが対象となります。
SheetSelectionChange いずれかのワークシートで選択範囲を変更したときに発生します。選択範囲がグラフ シート上にある場合は発生しません。
※すべてのシートが対象となります。
Sync ドキュメント ワークスペースに含まれているブックのローカル コピーがサーバー上のコピーと同期されたときに発生します。
WindowActivate ブックのウィンドウがアクティブになったときに発生します。
WindowDeactivate ブックのウィンドウが非アクティブになったときに発生します。
WindowResize ブックのウィンドウ サイズを変更したときに発生します。
AfterRemoteChange リモートユーザーのブックへの編集が結合された後に発生します。
※Excel2016以降
BeforeRemoteChange リモートユーザーのブックへの編集が結合される前に発生します。
※Excel2016以降
ModelChange Excelデータモデルが変更された後に発生します。
※Excel2013以降
SheetBeforeDelete シートが削除されたときに発生します。
※Excel2013以降
SheetLensGalleryRenderComplete ワークシートの引き出し線ギャラリーのアイコン(動的および静的)のレンダリングが完了すると発生します。
※Excel2013以降
SheetTableUpdate シートテーブルが更新された後に発生します。
※Excel2013以降
他のブックのコードを実行する
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
ブックを開かずに、セルの値を取得する。あまり使えない
MsgBox ExecuteExcel4Macro("'C:\work\[bbb.xlsx]シート1'!R1C1")
' C:\まとめ総合\ExcelVBA\bbb.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
' ※面倒なわりに制約も多いから、あまり使えないかな
ブックのフルパスを取得する
Dim wbX As Workbook
For Each wbX In Workbooks
Debug.Print wbX.FullName 'FullNameでブックのフルパスを取得できる
Next wbX
ブックが既に開かれているかを確認する ネットワーク上のブックを誰かが開いているかも判定できる
Sub aaa()
Dim wbX As Workbook
Dim bookPath As String
bookPath = "C:\work\aaa.xlsx"
'ブックが開かれているかを確認するには、一般には以下のような方法が紹介されることが多い
For Each wbX In Workbooks
If wbX.FullName = bookPath Then
MsgBox "既に開かれています"
End If
Next wbX
'全てのブックを確認する必要があるので、やや非効率
'ネットワーク上のブックを誰かが開いていても判定できない
'以下のFunctionを使った方法が便利
Debug.Print IsBookOpened(bookPath)
End Sub
Public Function IsBookOpened(ByVal bookPath As String) As Boolean
On Error Resume Next
Open bookPath For Append As #1 '追加モードでブックを開く。実際にブックが開かれるわけではない
Close #1
If Err.Number <> 0 Then
IsBookOpened = True
'エラーが発生していれば、ブックのOpenに失敗している。他のユーザが既に開いていることになる
Else
IsBookOpened = False
End If
End Function
ブックが、ファイルのプロパティで読み取り専用になっているかを判定する
読み取り専用で開いているか、とは違うので、混同しないように
Sub aaa()
Dim wb As Workbook
Dim path As String
path = "C:\work\読み取り専用(プロパティで設定).xlsx"
path = "C:\work\aaa.xlsx"
MsgBox IsReadOnlyProperty(path)
End Sub
Function IsReadOnlyProperty(path) As Boolean
'pathで指定されたファイルが、読み取り専用属性を持つかを判定する
'読み取り専用で開かれているかを判定するのではないので、注意
Dim fa As VbFileAttribute 'ファイル属性
fa = GetAttr(path) 'ファイルの属性を取得
If (fa And vbReadOnly) = vbReadOnly Then
IsReadOnlyProperty = True
Else
IsReadOnlyProperty = False
End If
End Function
ブックが読み取り専用で開かれているかの判定と、読み取り専用に設定する・解除する方法
Dim wb As Workbook
Dim openFilePath As String
openFilePath = "C:\work\aaa.xlsx"
Workbooks.Open Filename:=openFilePath, ReadOnly:=True '読み取り専用で開く
Set wb = ActiveWorkbook
If wb.ReadOnly Then ' 読み取り専用で開いているかを判定
Call wb.ChangeFileAccess(xlReadWrite)
'標準APIらしい。xlReadWriteで読み取り専用を解除
MsgBox "読み取り専用だったので、解除しました"
Else
Call wb.ChangeFileAccess(xlReadOnly)
MsgBox "読み取り専用ではなかったので、読み取り専用にしました"
End If
'読み取り専用の設定を変更する前に、保存済みであるかを確認するのもいい
If wb.Saved Then '保存されている場合
Call wb.ChangeFileAccess(xlReadWrite)
Else
MsgBox "未保存なので、読み取り専用にはしません"
End If
新規ブックとして作成したブックが保存されているかを判定する
Worksheets(Worksheets.Count).Copy '末尾のシートを新規ブックとしてコピー
If (InStr(1, ActiveWorkbook.FullName, "\") > 0) Then
'FullName で新規ブックのパスを取得。.Pathでは取得できないので注意
'新規ブックのパスには、「\」が入っていないので、この段階では未保存と判定される
Debug.Print "保存済み"
Else
Debug.Print "未保存"
End If
Worksheets(Worksheets.Count).Copy
ActiveWorkbook.SaveAs Filename:="C:\work\abc.xlsx"
If (InStr(1, ActiveWorkbook.FullName, "\") > 0) Then
'この段階では保存済みと判定される
Debug.Print "保存済み"
Else
Debug.Print "未保存"
End If
VBAでブックを開く時の注意点 パスは違う同名のブックを開いてあるとトラブルの元なので、それだけでも確認を
Sub aaa()
'"C:\work\AAA\aaa.xlsx" と "C:\work\BBB\aaa.xlsx" が存在するとする
'"C:\work\BBB\aaa.xlsx"を開いた状態で、以下のコードを実行
Dim wb As Workbook
Dim bookPath As String
bookPath = "C:\work\AAA\aaa.xlsx"
Workbooks.Open Filename:=bookPath, ReadOnly:=True '読み取り専用で開く
Set wb = ActiveWorkbook
Debug.Print wb.Worksheets(1).Name
'これは"C:\work\AAA\aaa.xlsx"の第一シート名を取得するはずだが、"C:\work\BBB\aaa.xlsx"のシート名が取得される
wb.Close 'これは"C:\work\BBB\aaa.xlsx"が閉じられる
Set wb = Nothing
'ブックを開こうとしている時に、パスの違う同名のファイルが開かれている場合は、そちらが対象になってしまうようだ
'"C:\work\BBB\aaa.xlsx"が開かれていない場合は、"C:\work\AAA\aaa.xlsx"のシート名が取得される
'ブックを開く時は、同名のブックが開かれていないかを必ず確認すること
End Sub
読み取り専用推奨のブックを、VBAで読み取り専用を無視して開くと、VBAコードのあるブックを開いている間は、読み取り専用推奨のブックを開く時に読み取り専用推奨のメッセージが出ない?
VBAコードのあるブックを閉じた後に読み取り専用推奨のブックを開くと、メッセージは出るが。
本当か?
ファイルのプロパティで読み取り専用のブックをVBAで開き、内容を変更して保存すると、特にエラーにはならないが変更は反映されないようだ
あるブックをVBAでOpenした時、すでに同名のブック(パスは異なる)が開かれていると、エラーにはならずOpenしようとしたブックは開かれないらしい。事前に同名のブックが開かれていないかを確認する必要があるかも
同じパスのブックがすでに開いてある場合に、そのブックをさらにOpenしても、エラーにはならないようだが。
手動で同名のブックを開こうとするとエラーになるが、VBAでは開いてしまう? VBAでも同名ブックを開くとエラーになるはずだが?