SharePoint上のフォルダーにExcelブックを保存する場面は、社内のファイル共有から共同編集まで、多くの業務で活躍します。しかしVBAで保存する際、予期せぬエラーやパス指定に悩まされることもしばしば。本記事では、実務に役立つ解決策を具体例とともに解説します。
VBAで保存する前に、アップロード方法を決める
| 方法 | 保存先と確認事項 |
|---|---|
| 同期フォルダーへ保存 | SharePointライブラリをOneDriveで同期し、エクスプローラーで見えるローカルパスへ保存。VBAの保存後に同期状態とWebのファイルを確認します。 |
| ExcelからHTTPSの保存先を使う | デスクトップExcelでサインインし、同じ保存先へ手動で保存できることを先に確認。共有リンクや一覧画面のURLをファイルパスとして流用しません。 |
| Microsoft Graphで直接アップロード | 同期を経由しないAPI処理。アクセストークン、対象ライブラリ、必要な権限を設計する別方式です。SaveAsだけでAPI認証を実装したことにはなりません。 |
この記事のコードはWindowsのデスクトップExcelで、マクロを含む対象の.xlsmブック自身に置く例です。PERSONAL.XLSBやアドインへ置くとThisWorkbookはレポートではなくマクロの格納先を指します。まず対象のコピーで試し、実際の同期先フォルダーを選んでください。保存方式はSharePoint Onlineの同期フォルダーを想定し、ボタンを押した利用者が結果を確認する対話実行の例です。同期の準備はSharePointとTeamsのファイルをPCと同期する公式手順で確認できます。
ThisWorkbookはマクロを格納するブック、ActiveWorkbookは最前面のブックを指します。PERSONAL.XLSBなどから別ブックを保存する設計では、対象のWorkbookオブジェクトを明示的に取得・確認してください。単純にActiveWorkbookへ置換すると、意図しないブックを保存するおそれがあります。
VBAでSharePointフォルダーに保存する意義とメリット
SharePointに保存すると、組織の権限設定に沿ってファイルを共有できます。VBAはブックの保存操作をまとめられますが、閲覧・編集権限やライブラリの設定を自動的に適切な状態へ変更するものではありません。保存先と共有範囲は管理者の運用に合わせます。
メリット1:共同編集とバージョン管理
共同編集の条件は、保存先、Excelの版、サインイン、ファイル形式で確認します。Microsoftの共同編集手順では.xlsx、.xlsm、.xlsbを対象とし、SharePoint Onlineへの保存を案内しています。.xlsmという拡張子だけで共同編集ができないとは判断せず、実際に使うExcelと編集作業の条件を確認します。バージョン履歴は誤った更新の復元にも役立ちます。
メリット2:手動作業の削減による効率化
ボタンから保存処理を呼び出せば、決めた保存先と形式で繰り返し保存できます。ただし、Excelをタスクスケジューラで起動するだけで、無人処理やクラウド反映まで保証されるわけではありません。Microsoftの無人Office自動化に関する説明では、認証や対話ダイアログ、非対話環境の制約が示されています。夜間実行が必要なら、実行環境とライセンス、失敗時の監視を別途設計します。
基本的な保存方法:VBAのSaveAs文を活用
Workbook.SaveAsは保存先と形式を指定するメソッドです。以下は保存ダイアログでSharePointの同期済みローカルフォルダーを選ぶ例です。GetSaveAsFilenameは名前を取得するだけで保存しないため、その後にSaveAsを実行します。キャンセル時と、確認時点で同名ファイル・フォルダーがある場合は終了します。SaveAsは開いているブックの保存先・名前も変更するため、元の保存先を維持したい場合は後述のSaveCopyAsを使います。
Sub SaveToSharePoint()
Dim target As Variant
Dim savePath As String
Dim fso As Object
On Error GoTo ErrorHandler
If ThisWorkbook.FileFormat <> xlOpenXMLWorkbookMacroEnabled Then
MsgBox "この例は対象の.xlsmブックに置いて実行してください。"
Exit Sub
End If
target = Application.GetSaveAsFilename( _
InitialFilename:="New_Report.xlsm", _
FileFilter:="Excel Macro-Enabled Workbook (*.xlsm), *.xlsm")
If VarType(target) = vbBoolean Then Exit Sub
savePath = CStr(target)
If LCase$(Right$(savePath, 5)) <> ".xlsm" Then
MsgBox ".xlsmの名前を指定してください。"
Exit Sub
End If
If Not (savePath Like "[A-Za-z]:\*") Then
MsgBox "同期済みローカルフォルダーの絶対パスを選んでください。"
Exit Sub
End If
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FolderExists(fso.GetParentFolderName(savePath)) Then
MsgBox "保存先フォルダーが存在しません。"
Exit Sub
End If
If fso.FileExists(savePath) Or fso.FolderExists(savePath) Then
MsgBox "同名の項目があります。別名を選んでください。"
Exit Sub
End If
If Not Application.DisplayAlerts Then
MsgBox "警告が抑止されています。この例では保存を中止します。"
Exit Sub
End If
ThisWorkbook.SaveAs Filename:=savePath, _
FileFormat:=xlOpenXMLWorkbookMacroEnabled
If Not fso.FileExists(savePath) Then
Err.Raise vbObjectError + 819, , "保存先のファイルを確認できません。"
End If
MsgBox "ローカルに保存しました。OneDriveとWeb側の内容を確認してください。"
Exit Sub
ErrorHandler:
MsgBox "エラー " & Err.Number & ": " & Err.Description, vbCritical
End Sub
この存在確認は保存先を予約する処理ではありません。確認後に他の処理が同名ファイルを作る可能性があるため、同じ出力先への同時実行は避け、上書き確認が出たらキャンセルしてください。DisplayAlerts=FalseではSaveAsの上書き確認が自動的に承認されるので、本例は警告が抑止されている場合に中止します。ドライブ文字が付いていてもネットワークドライブの場合があり、コードだけではOneDrive同期先か判定できません。
パス指定のポイント
ブラウザーのアドレスバーに表示されるURLは、フォルダー一覧、ビュー、共有リンクなどを指すことがあり、SaveAsの保存先ファイルパスとは限りません。同期方式ではエクスプローラーから実際の同期先フォルダーのパスを取得します。HTTPS方式を使う場合は、同じサインイン状態のExcelで手動保存できる対象かを確認してからコードへ指定します。SaveAsにはMicrosoft GraphのBearerトークンを渡す引数はありません。URL文字列の変更だけではサインインやアクセス権の問題は解決しません。
WebDAVのネットワークドライブ割り当てはOneDrive同期と別方式です。Microsoftの説明では、WebDAVはOneDrive同期より低速で信頼性も劣る旧方式とされています。保存エラーの回避策として、古いInternet Explorer向けの設定やセキュリティ設定変更をそのまま適用せず、組織の管理者に保存方式を確認してください。
注意点:スラッシュの使い方
URLの区切りはスラッシュ、Windowsのローカルパスの区切りはバックスラッシュです。両者を混ぜず、どちらの方式で保存するかを決めます。同期先の組織名・ライブラリ名・ユーザー名は環境ごとに異なるため、以下は置換が必要な形式例です。
| 指定方式 | 形式例 |
|---|---|
| 同期済みローカルパス | C:\Users\ユーザー名\組織名\ライブラリ名\New_Report.xlsm |
バックアップやコピーをとる場合のSaveCopyAs活用
Workbook.SaveCopyAsは、開いているブックを変更せずにコピーを保存します。SaveAsはブックの保存先や名前を変えるのに対し、SaveCopyAsはコピーの作成に使います。SaveCopyAsにはFileFormat引数がないため、拡張子だけを.xlsxへ変えて形式変換しません。下の例は.xlsmから.xlsmへのコピーです。既存のバックアップ親フォルダーの下に実行ごとの新しいフォルダーを作り、既存フォルダーは再利用しません。同じ秒に再実行してフォルダー名が衝突した場合も、上書きせずエラーで停止します。
Sub MakeBackupAndSave()
'既存のローカルフォルダーへ置換する
Const BACKUP_FOLDER As String = "D:\Backup"
Dim runFolder As String, backupPath As String
Dim fso As Object
On Error GoTo ErrorHandler
If ThisWorkbook.FileFormat <> xlOpenXMLWorkbookMacroEnabled Then
MsgBox "この例は.xlsmブック用です。": Exit Sub
End If
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FolderExists(BACKUP_FOLDER) Then
MsgBox "バックアップフォルダーを確認してください。": Exit Sub
End If
runFolder = BACKUP_FOLDER & "\Backup_" & Format(Now, "yyyymmdd_hhnnss")
'CreateFolderは同名フォルダーが存在するとエラーになる
fso.CreateFolder runFolder
backupPath = runFolder & "\MyWorkbook.xlsm"
ThisWorkbook.SaveCopyAs Filename:=backupPath
If Not fso.FileExists(backupPath) Then
Err.Raise vbObjectError + 819, , "コピーのファイルを確認できません。"
End If
MsgBox "コピーを保存しました。元ブックの保存先は変わりません。" & _
vbCrLf & backupPath
Exit Sub
ErrorHandler:
MsgBox "エラー " & Err.Number & ": " & Err.Description & vbCrLf & _
"空フォルダーや作成途中のコピーが残る場合があります。保存先を確認してください。", vbCritical
End Sub
CreateFolderは既存フォルダーに対してエラーになります。この例の出力フォルダーは処理専用とし、保存中に別の処理から書き込まないでください。SaveCopyAs自体には「上書き禁止」の引数がないため、既存の共有ファイルへそのまま繰り返し保存する用途にはしません。ローカルのコピーは、SharePointへのアップロードや元ブックの保存を意味しません。
運用のコツ
- バックアップフォルダーを日付ごとに作成して、定期的に
SaveCopyAsを実行することで履歴管理を強化できます。 - SharePointライブラリでバージョン管理が有効な場合でも、あえて手動バックアップを残しておくと、万が一のときに復元が簡単です。
- 本記事の例は
.xlsm専用です。.xlsbなど別形式を扱う場合は、その形式に合わせて判定とファイル名を変更し、拡張子だけを付け替えないでください。
よくあるエラーと対処法
SharePointフォルダーに保存しようとすると、以下のようなエラーに遭遇することがあります。原因と対処法を把握しておくと、運用トラブルを迅速に解消できます。
エラー1:パスが見つからない (エラー76など)
- 確認: エラー76だけでURLや同期遅延を原因と決めません。同期方式なら指定したローカルフォルダーが存在するか、フォルダー名とユーザーごとの同期先が一致するかを確認します。
- 対処: エクスプローラーで対象フォルダーを開き、実際のローカルパスをコードと比較します。Webの一覧URLを貼り直す対処とは分けます。フォルダーは事前に作成し、同じ場所へ手動で保存できるか確認します。
エラー2:ファイル形式が合わない、または読み取り専用 (エラー1004など)
- 確認: エラー1004は保存先へのアクセス、同名ファイル、ファイル形式など複数の条件で確認が必要です。番号だけでマクロや権限が原因とは断定せず、エラーの説明と実際の保存先を記録します。
- 対処法: このサンプルでは拡張子
.xlsmとFileFormat:=xlOpenXMLWorkbookMacroEnabledを揃えます。マクロを保持できる形式は.xlsmだけではありませんが、.xlsxへの変換ではマクロを保持できません。また、SharePoint上の編集権限、チェックアウトなどのライブラリ設定も確認してください。
エラー3:同期遅延・ローカルキャッシュの問題
- 確認: VBAのローカル保存は成功したがWebに見えない場合は、保存エラーと分けてOneDriveの同期状態を確認します。オフラインや同期の一時停止、アクセス権、ライブラリの設定など、表示された状態に沿って調べます。
- 対処: OneDriveのアイコンで処理中・一時停止・エラーを確認し、ブラウザーで対象ライブラリのファイル名と更新内容を照合します。読み取り専用権限、チェックアウト必須、必須メタデータなど同期に影響する設定は管理者に確認します。保存完了のメッセージだけをアップロード完了の証拠にしません。
実運用で押さえておくべきポイント
SharePointは便利な反面、従来のローカルフォルダーやファイルサーバーとは違った挙動を見せることがあります。以下のポイントを理解しておくと、スムーズな運用が可能です。
1. パスの取得方法を統一する
- ThisWorkbook.PathがローカルパスかHTTPSか、未保存で空かを確認します。文字列へ機械的にBackupを足しても、存在する保存先にはなりません。
- 同期方式では実際のローカル同期先を設定として管理します。PCやユーザーが変わったら再確認し、URLとローカルパスを同じ変数の意味で混在させません。
参考コード:実際の同期先パスを定義する
Sub SaveToDefinedPath()
'必ずエクスプローラーで確認した実際の同期先に置換する
Const SYNC_FOLDER As String = "C:\Users\ユーザー名\組織名\ライブラリ名\Data"
Dim savePath As String
Dim fso As Object
On Error GoTo ErrorHandler
If ThisWorkbook.FileFormat <> xlOpenXMLWorkbookMacroEnabled Then
MsgBox "この例は.xlsmブック用です。": Exit Sub
End If
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FolderExists(SYNC_FOLDER) Then
MsgBox "実際の同期先パスへ置換してください。": Exit Sub
End If
savePath = SYNC_FOLDER & "\MyMacroFile_" & Format(Now, "yyyymmdd_hhnnss") & ".xlsm"
If fso.FileExists(savePath) Or fso.FolderExists(savePath) Then
MsgBox "同名の項目があるため保存を中止します。": Exit Sub
End If
If Not Application.DisplayAlerts Then
MsgBox "警告が抑止されています。この例では保存を中止します。": Exit Sub
End If
ThisWorkbook.SaveAs Filename:=savePath, FileFormat:=xlOpenXMLWorkbookMacroEnabled
If Not fso.FileExists(savePath) Then
Err.Raise vbObjectError + 819, , "保存先のファイルを確認できません。"
End If
MsgBox "ローカルに保存しました。同期とWeb側の内容を確認してください。"
Exit Sub
ErrorHandler:
MsgBox "エラー " & Err.Number & ": " & Err.Description, vbCritical
End Sub
2. バージョン管理とメジャー/マイナー バージョンの運用
- SharePointライブラリのバージョン履歴と保持の設定は、管理者の運用に合わせて確認します。VBAで同名ファイルを更新するか、日時付きの別名コピーを増やすかも決めておきます。別名で作成したコピーは、元ファイルのバージョン履歴へ自動的に追加されるわけではありません。既存履歴を一律に削除する運用にはしません。
- 「マイナーバージョンをドラフトとして管理する」「承認があるまで公開バージョンに上げない」といった運用をしている場合は、VBAでの保存によって一時的にドラフトバージョンが増えることがあるため注意が必要です。
3. マクロ付きブックの共同編集条件を確認する
- 公式の共同編集対象には.xlsmも含まれます。読み取り専用になった場合は、拡張子だけで判断せず、権限、使用中のExcel、ファイルの状態を確認します。
- 集計を行う担当ブックと配布用の結果を分けたい場合は、共同編集の対象と保存タイミングを業務ルールとして決めます。Power Automateなどへの移行は、マクロ処理の代替が実装できるかを確認して検討します。
実際の業務フロー構築例
ここでは、定期的にレポートを生成してSharePointに自動で保存するフローの一例を示します。想定シナリオとして、毎月月初に売上集計ファイルを更新し、SharePoint上の「月次レポート」フォルダーに保存するケースを考えます。
フロー概要
- 対象の.xlsmブックをデスクトップExcelで開き、マクロボタンから処理する
- 業務ごとに実装したデータ取り込みと集計を完了する(下の保存コードには含みません)
- 集計済みの対象ブックを、ローカルの新しいバックアップフォルダーへSaveCopyAsでコピーする
- そのバックアップファイルを、SharePointの同期済みフォルダーへ上書き禁止でコピーし、同期後にWebの内容を確認する
サンプルコード
Sub MonthlyReportAutomation()
'2つの既存フォルダーを実際の環境へ置換する
Const SYNC_FOLDER As String = "C:\Users\ユーザー名\組織名\ライブラリ名\MonthlyReports"
Const BACKUP_FOLDER As String = "D:\Backup"
Dim runName As String, reportName As String
Dim runFolder As String, syncPath As String, backupPath As String
Dim fso As Object
Dim stage As String
On Error GoTo ErrHandler
stage = "保存先の確認"
If ThisWorkbook.FileFormat <> xlOpenXMLWorkbookMacroEnabled Then
MsgBox "集計済みの対象.xlsmブックで実行してください。": Exit Sub
End If
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FolderExists(SYNC_FOLDER) Or Not fso.FolderExists(BACKUP_FOLDER) Then
MsgBox "同期先とバックアップ先の既存フォルダーを確認してください。": Exit Sub
End If
runName = "MonthlyReport_" & Format(Now, "yyyymmdd_hhnnss")
reportName = runName & ".xlsm"
runFolder = BACKUP_FOLDER & "\" & runName
backupPath = runFolder & "\" & reportName
syncPath = SYNC_FOLDER & "\" & reportName
If fso.FileExists(syncPath) Or fso.FolderExists(syncPath) Then
MsgBox "同期先に同名の項目があるため保存を中止します。": Exit Sub
End If
stage = "新しいバックアップフォルダーの作成"
fso.CreateFolder runFolder
stage = "バックアップへのコピー保存"
ThisWorkbook.SaveCopyAs Filename:=backupPath
If Not fso.FileExists(backupPath) Then
Err.Raise vbObjectError + 819, , "バックアップファイルを確認できません。"
End If
stage = "同期フォルダーへのコピー"
'第3引数Falseでコピー時点の同名ファイルも上書きしない
fso.CopyFile backupPath, syncPath, False
MsgBox "バックアップと同期先へのローカルコピーが完了しました。" & vbCrLf & _
"OneDriveの同期後にWeb側のファイルと内容を確認してください。"
Exit Sub
ErrHandler:
MsgBox stage & "でエラー " & Err.Number & ": " & Err.Description & vbCrLf & _
"バックアップだけ、または作成途中のファイルが残る場合があります。" & vbCrLf & _
"保存先を確認し、同名ファイルを自動削除して再試行しないでください。", vbCritical
End Sub
このサンプルは、集計済みの.xlsmブックから一度作ったバックアップを、同期先にもコピーします。元ブックの保存先は変更せず、売上の取り込み・集計・グラフ更新・認証・同期完了の判定は実装していません。CopyFileの第3引数Falseは、コピー先の既存ファイルを上書きしない指定です。ただし、これはローカル側の制御であり、別のPCが作成した未同期のファイルやSharePoint上の競合までは防げません。出力先と実行担当を決め、Web側にも同名ファイルがないことを事前に確認します。
途中で失敗しても、それまでに作ったフォルダーやコピーは自動で取り消されません。実行段階と両方の保存先を確認し、再実行前に原因を解消します。ローカルバックアップは元ブックと同程度の機密情報を含むため、社内のアクセス制限・保管期間に従って管理してください。
高度な運用:Power Automateとの連携
PCからの同期を使わず直接アップロードする設計では、Microsoft GraphのdriveItemコンテンツアップロードAPIなどを検討できます。APIはBearerトークンと必要なアクセス許可を使うため、VBAのSaveAsとは認証・実装の範囲が異なります。アップロード後の通知や承認は、Power Automateなどのクラウド側フローと役割を分けて設計します。
API認証を追加する場合も、利用者へ配布するブックにパスワード、クライアントシークレット、アクセストークンを固定値で埋め込まないでください。Microsoftのクライアント分類では、デスクトップアプリはシークレットを安全に保持できる前提ではありません。必要な権限を絞り、認証方式・トークンの保管と更新・失敗時の処理を管理者と別途設計します。
VBAとPower Automateの使い分け
- VBA向き: Excelファイルの操作や集計処理など、クライアントアプリケーション内の操作がメインとなる作業。
- Power Automate向き: SharePoint上のファイル操作や通知、承認ワークフローなど、クラウド上のイベントをトリガーにした自動化。
まとめ:エラーを恐れずSharePoint×VBAを使いこなそう
SharePointへVBAで保存するときは、次の項目を確認します。
- 保存方式を決める:同期済みローカルパスと、Excelで確認済みのHTTPS保存先を区別する
- 保存形式を揃える:本記事の例は
.xlsm+FileFormat:=xlOpenXMLWorkbookMacroEnabled - 同期のタイミングに注意:同期クライアントの挙動をチェック
- 失敗時の確認:エラー番号と説明、対象ブック、ローカルとWebの状態を記録する
- バックアップ運用:
SaveCopyAsやSharePointのバージョン管理を上手く活用
実際の運用では、企業内ポリシーに合わせて権限管理やフォルダー階層の設計をしておくことも大切です。クラウドとローカルを使い分けながら、VBAでの自動保存処理を賢く組み立てることで、毎日の業務が格段に効率アップするでしょう。ぜひ本記事の内容を参考に、エラーを恐れずSharePoint×VBAの活用に挑戦してみてください。
保存形式はXlFileFormatの公式一覧で確認できます。.xlsxはxlOpenXMLWorkbook、.xlsmはxlOpenXMLWorkbookMacroEnabledです。上のコードはWorkbook.FileFormatを確認して.xlsmに限定しています。.xlsx用へ変更する場合は対象ブック・拡張子・FileFormatを揃え、マクロを残す必要があるブックを.xlsxへ変換しないでください。
固定パスのコードで使うFolderExistsは、フォルダーの存在確認です。フォルダーを作成したり、同期や編集権限を確認したりする処理ではありません。
導入前にテスト用のブックで確認すること
コードは環境に合わせて確認するための例です。本番のブックではなく、機密情報を含まないテスト用の.xlsmブックと専用フォルダーで、次を順に確認してください。
- 通常保存:ローカルにファイルができ、開き直した内容が期待どおりであることを確認する。SaveAsの後は開いているブックの名前・保存先が変わり、SaveCopyAsの後は変わらないことも確認する。
- 中止条件:ダイアログのキャンセル、.xlsxの選択、保存先フォルダーの不存在、既存の同名ファイル・フォルダーで処理が止まることを確認する。
- 途中失敗:同期先に書き込めない場合など、バックアップだけが残るケースを確認する。失敗後に残ったファイルを、成功したレポートとして配布しない。
- クラウド反映:OneDriveの同期が完了した後、ブラウザーで対象ライブラリのファイル名と内容を確認する。オフラインや同期一時停止のときは、ローカル保存成功とクラウド未反映を区別する。


コメント