VAブリッジ:エクセルファイルを使った簡易的な共同編集を実現(エクセルVBA)

サンプル

事務所内での情報共有、どうされていますか?

共有サーバーにあるエクセルファイルをみんなで閲覧したり、編集したりしているんですが、『読み取り専用』になっていて編集できなかったり、誰かが開いたままで保存できなかったりします。タイミングによっては、番号のついた別のファイルができてしまう場合もあって、困っています。

「共同編集」という機能もありますが、OneDriveを使用していない環境では使えないのが欠点ですよね。

かといって、本格的なデータベースソフトを導入するのはハードルが高いですし……。もっと手軽に、みんなで一つのデータを管理できないでしょうか?

分かりました。エクセルファイルを「入力用」と「データ保管用」に分けることで、少人数での共同編集をスムーズに行えるアドインを作ってみましょう。

サンプルのダウンロード

Windows環境の場合は、こちらを用いたほうが簡単にインストールできます。

インストール方法

Excel版VBAアドインのインストール方法

操作マニュアル

VAサーチシリーズ(統合版) 操作マニュアル

仕様

1. プロジェクト概要

システム名: VA Bridge System (VAブリッジ)

目的: ネットワーク上の「マスタExcelファイル」と、ユーザーの手元にある「ローカルブック」間でデータを同期し、強力な排他制御を用いてマルチユーザー環境でのデータ整合性を維持する。

基本アーキテクチャ:

  • データストア: 共有フォルダ上のExcelファイル(マスタ)。
  • クライアント: ユーザー配布用のExcelファイル(ローカル)。
  • 同期方式:
    • 読み込み: マスタのデータをローカルへ全件洗い替え(既存削除→コピー)。
    • 書き込み: 排他ロック取得後、ローカルのデータをマスタへ全件洗い替え(マスタ削除→値貼り付け)。
  • SharePoint対策: ローカルファイルは「揮発性」とみなし、保存(Ctrl+S)を禁止し、閉じる際はデータを破棄する。

2. モジュール構成

以下のモジュールを作成し、各責務を分離する。

モジュール名種類役割
ThisWorkbookDocumentブックオープン時のイベントフック開始、バージョン管理。
basMainStandardアプリケーションのエントリーポイント。リボンUIからのコールバック処理、メンテナンスモード判定。
basSyncStandardコアロジック。マスタとの読み書き、排他制御、ヘッダー整合性チェック、デザイン変更。
basConfigStandardCustomDocumentProperties を用いた設定値の永続化管理。
basSettingsStandardシステム定数(ロック待機時間、プロパティキー名など)の管理。
basUtilityStandardWindows/Macクロスプラットフォーム対応(パス変換)、ファイル操作、ユーザー名取得。
clsAppEventsClassExcelアプリケーションイベントの監視(Workbook_BeforeSave, Workbook_BeforeClose 等)。
frmSettingsFormマスタファイルのパス設定、ローカルシートとマスタシートの紐付けを行うUI。
frmModeSelectFormデータ読み込み時に「閲覧モード」か「編集モード」かを選択させるダイアログ。

3. 詳細機能要件

3.1 堅牢な排他制御機能 (basSync, basUtility)

マルチユーザー編集における競合を防ぐため、以下の仕様を厳密に実装する。

  • ロックファイル仕様:
    • マスタファイルと同じフォルダに .lock ファイルを作成する。
    • ファイル名形式: [マスタファイル名].[ユーザー名].lock
    • 内容: テキストファイルとして作成し、「ユーザー名」「マシン名」「ロック取得日時」を書き込む。
    • 文字コード: Windows/Mac間の文字化けを防ぐため、必ず UTF-8 で入出力を行う。
  • ロック取得ロジック:
    • 編集モード選択時: 自身のロックファイルを作成する。作成直後に「他人の有効なロックファイル」が存在しないか再確認し、競合していれば自身のロックを削除して失敗とする。
    • 有効期限: ロックファイルのタイムスタンプが 20分 を経過している場合は「スタレ(古い)ロック」とみなし、無視(またはクリーンアップ)する。
  • 楽観的ロック(Optimistic Locking):
    • 読み込み完了時に、マスタファイルの更新日時を LastSyncTime としてローカルに保存する。
    • 書き込み開始時に、現在のマスタファイルの更新日時と LastSyncTime を比較する。
    • もしマスタの方が新しい場合は「競合発生」とみなし、書き込みを中止してユーザーに詳細なリカバリ手順(別ブックへの退避など)を案内する。

3.2 データ同期ロジック (basSync)

  • ヘッダー整合性チェック:
    • 同期(読み書き両方)前に、ローカルとマスタのテーブルヘッダー(列名・列数)が完全に一致するか確認する。不一致の場合は処理を中断する。
  • 読み込み (Load):
    • マスタを「読み取り専用」で開く。
    • ローカルの既存データをクリアし、マスタのデータをコピー&ペーストする。
  • 書き込み (Write):
    • マスタを「書き込み可」で開く。
    • マスタの既存データをクリアし、ローカルのデータを「値のみ」貼り付ける(書式はマスタ側を維持)。
    • 処理完了後、ローカルの Saved プロパティをTrueにし、編集モード(ロック)を解除する。

3.3 Windows / Mac クロスプラットフォーム対応 (basUtility)

  • パス解決:
    • Windowsのドライブレター(例: O:\Folder)と、Macのマウントパス(例: /Volumes/O/Folder)を動的に相互変換する GetLocalPath 関数を実装する。
    • 設定ファイルにどちらのOSで保存されたパスであっても、実行中のOSに合わせてパス区切り文字(\/)とプレフィックスを変換して使用する。
  • APIの使い分け:
    • Shiftキー判定やユーザー名取得において、#If Mac Then を使用してコードを分岐させる。

3.4 SharePoint / OneDrive 対策と安全性 (clsAppEvents)

  • 保存の完全ブロック:
    • ローカルファイル上での Ctrl+S や「名前を付けて保存」イベント(Workbook_BeforeSave)をキャッチし、Cancel = True で保存を禁止する。
    • データの永続化は、リボンの「データ書き込み」ボタン経由でのみ許可する。
  • 終了時のデータ破棄:
    • ブックを閉じる際(Workbook_BeforeClose)、変更を保存せずに閉じる処理を行う。
    • SharePoint等の同期クライアントが「変更の競合」を誤検知しないよう、閉じる直前にブックを強制的に「読み取り専用 (ChangeFileAccess xlReadOnly)」に切り替える手法を採用する。

3.5 メンテナンスモード (ThisWorkbook, basMain)

  • 発動条件: ブック起動時に Shiftキー が押されている場合。
  • 挙動: アドイン機能(保存禁止、自動読み込み、終了時破棄)を全て無効化し、通常のExcelブックとしてメンテナンス可能にする。

3.6 UI / UX

  • モードによる視覚変化:
    • 「編集モード(ロック中)」の場合、テーブルスタイルをオレンジ系(例: TableStyleMedium3)に変更し、シート保護を解除する。
    • 「閲覧モード」の場合、テーブルスタイルを元に戻し、シート保護(操作禁止)を適用する。
  • フォーム:
    • frmSettings: ファイル選択ダイアログを使用し、マスタパスを設定・保存する。
    • frmModeSelect: 読み込み時に表示。「閲覧(ロックなし)」か「編集(ロックあり)」かを選択させる。

3.7 設定の永続化 (basConfig)

  • 外部ファイル(iniやレジストリ)を使わず、ブック自体の CustomDocumentProperties を使用して設定値(マスタパス、シート紐付け情報、LastSyncTime)を保存する。

4. コード出力要件

  1. コーディング規約: 全モジュールで Option Explicit を必須とする。
  2. エラー処理: 適切な On Error GoTo ハンドリングを実装し、ファイル未存在やロック取得失敗時の挙動を定義する。
  3. Ribbon XML: customUI.xml の定義を含める。ボタンは「データ読み込み」「データ書き込み」「設定」の3つを配置する。

管理者向けの情報

VBAコード

このアドインは、VBAコードが閲覧・編集可能な状態で公開されています。basSettingsモジュールの定数を修正することで、ロックファイルの有効時間などを変更できます。

ユーザー定義処理

VABridge_AfterLoad(読み込み後)およびVABridge_BeforeSave(書き込み前)という名前のプロシージャをユーザーファイルの標準モジュールに作成することで、独自の処理を自動実行させることができます。

コメント

タイトルとURLをコピーしました