複数の利用者にマクロを仕込んだワークブックを配布した場合に、後になってマクロを改変しなければならないことはよくあることです。定例的な業務になるものであれば「アドイン化」でプログラム部分をデータブックと分離することをお勧めしますが、そこまでの使用頻度でないという場合でも、何らかの対策を採っておくと、いざという時に無駄な作業を強いられずに済みます。
この「モジュール入れ替え機能」は、ブックの立ち上げ時にブックの所在フォルダに更新用モジュール(*.bas)があるか、また、そのバージョンが以前に更新したものより新しいかを自動的に判断して、そのモジュールを自動的に入れ替えるものです。
標準モジュールの入れ替えを目的とするなら、特に改造することなく「modPERLACE_MODULE.bas」を目的のブックにインポートさせて、立ち上げマクロの先頭に呼び出す記述を加えるだけで利用できます。
最近のPCでは、モジュールの更新作業に時間は掛かりませんが、
処理状態はステータスバーに表示されます。
更新が完了すると、自動的に上書き保存されて、
このようにメッセージが表示されます。ここで「OK」をクリックすると、一旦Excelが終了します。
これは、コンパイルチェックを受けているプロジェクトのモジュールを書き換えていることによって、Excelが不安定になるのを防ぐためです。
サンプル「Module入れ替え機能サンプル.xlsm」がダウンロードできるので、確認してみて下さい。
「Module入れ替え機能サンプル.xls」と同じフォルダに新しいバージョンの更新用モジュールがない場合は、そのまま起動時のプロシージャから標準モジュールの「TEST1」プロシージャが呼ばれます。
当初のバージョンは「100」で、
このようにメッセージ表示されます。
起動時のプロシージャは、
'***************************************************************************************************
' モジュール入れ替え機能サンプル ThisWorkbook(Class)
'
' 作成者:井上治 URL:https://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'***************************************************************************************************
'変更日付 Rev 変更履歴内容------------------------------------------------------------------------>
'04/11/07(1.00)新規作成
'19/10/28(1.10)*.xlsm化
'20/03/17(1.11)記述修正(標準化準拠)、他
'***************************************************************************************************
Option Explicit
'***************************************************************************************************
' ■■■ ワークブックイベント ■■■
'***************************************************************************************************
'* 処理名 :Workbook_Open
'* 機能 :ブック起動イベント
'---------------------------------------------------------------------------------------------------
'* 返り値 :(なし)
'* 引数 :(なし)
'---------------------------------------------------------------------------------------------------
'* 作成日 :2004年11月07日
'* 作成者 :井上 治
'* 更新日 :2020年03月17日
'* 更新者 :井上 治
'* 機能説明:
'* 注意事項:
'***************************************************************************************************
Private Sub Workbook_Open()
'-----------------------------------------------------------------------------------------------
' モジュール交換機能
Call modPERLACE_MODULE.REPLACE_MODULE(g_cnsModuleUpdFile, _
g_cnsModuleUpdSh, _
g_cnsModuleUpdRange, _
"", _
g_cnsModuleUpdModule1)
'-----------------------------------------------------------------------------------------------
' 本体処理(このプロシージャは入れ替え対象)
Call Module1.TEST1
ThisWorkbook.Saved = True
End Sub
'----------------------------------------<< End of Source >>----------------------------------------
'100 ←バージョン情報(整数3桁) ※このバージョンによりModule自動更新が判断される
'***************************************************************************************************
' モジュール入れ替え機能サンプル Module1(Module)
'
' 作成者:井上治 URL:https://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'***************************************************************************************************
'変更日付 Rev 変更履歴内容------------------------------------------------------------------------>
'04/11/07(1.00)新規作成
'19/10/28(1.10)*.xlsm化
'20/03/17(1.11)記述修正(標準化準拠)、他
'***************************************************************************************************
Option Explicit
Option Private Module
'===================================================================================================
Public Const g_cnsTitle As String = "モジュール入れ替え機能"
' 交換用モジュールのファイル名
Public Const g_cnsModuleUpdFile As String = "REPLACE_Module1.bas" ' 交換モジュールファイル
Public Const g_cnsModuleUpdSh As String = "設定" ' バージョン値格納シート
Public Const g_cnsModuleUpdRange As String = "$B$2" ' バージョン値格納セル
Public Const g_cnsModuleUpdModule1 As String = "Module1" ' モジュール名
'***************************************************************************************************
' ■■■ 外部公開プロシージャ ■■■
'***************************************************************************************************
'* 処理名 :TEST1
'* 機能 :主要(本体)処理
'---------------------------------------------------------------------------------------------------
'* 返り値 :(なし)
'* 引数 :(なし)
'---------------------------------------------------------------------------------------------------
'* 作成日 :2004年11月07日
'* 作成者 :井上 治
'* 更新日 :2020年03月17日
'* 更新者 :井上 治
'* 機能説明:
'* 注意事項:
'***************************************************************************************************
Public Sub TEST1()
'-----------------------------------------------------------------------------------------------
MsgBox "これは交換前のモジュールです。", , g_cnsTitle
End Sub
'----------------------------------------<< End of Source >>----------------------------------------
'101 ←バージョン情報(整数3桁) ※このバージョンによりModule自動更新が判断される
'***************************************************************************************************
' モジュール入れ替え機能サンプル Module1(Module)
'
' 作成者:井上治 URL:https://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'***************************************************************************************************
'変更日付 Rev 変更履歴内容------------------------------------------------------------------------>
'04/11/07(1.00)新規作成
'19/10/28(1.10)*.xlsm化
'20/03/17(1.11)記述修正(標準化準拠)、他
'***************************************************************************************************
Option Explicit
Option Private Module
'===================================================================================================
Public Const g_cnsTitle As String = "モジュール入れ替え機能"
' 交換用モジュールのファイル名
Public Const g_cnsModuleUpdFile As String = "REPLACE_Module1.bas" ' 交換モジュールファイル
Public Const g_cnsModuleUpdSh As String = "設定" ' バージョン値格納シート
Public Const g_cnsModuleUpdRange As String = "$B$2" ' バージョン値格納セル
Public Const g_cnsModuleUpdModule1 As String = "Module1" ' モジュール名
'***************************************************************************************************
' ■■■ 外部公開プロシージャ ■■■
'***************************************************************************************************
'* 処理名 :TEST1
'* 機能 :主要(本体)処理
'---------------------------------------------------------------------------------------------------
'* 返り値 :(なし)
'* 引数 :(なし)
'---------------------------------------------------------------------------------------------------
'* 作成日 :2004年11月07日
'* 作成者 :井上 治
'* 更新日 :2020年03月17日
'* 更新者 :井上 治
'* 機能説明:
'* 注意事項:
'***************************************************************************************************
Public Sub TEST1()
'-----------------------------------------------------------------------------------------------
MsgBox "これは交換後のモジュールです。", , g_cnsTitle
End Sub
'----------------------------------------<< End of Source >>----------------------------------------
'***************************************************************************************************
' モジュール入れ替え機能サンプル modPERLACE_MODULE(Module)
'
' 作成者:井上治 URL:https://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'***************************************************************************************************
' [参照設定]
' ・Microsoft Scripting Runtime
'***************************************************************************************************
'変更日付 Rev 変更履歴内容------------------------------------------------------------------------>
'04/11/07(1.00)新規作成
'19/10/28(1.10)*.xlsm化、64ビット版Office対応
'20/03/17(1.11)記述修正(標準化準拠)、他
'***************************************************************************************************
Option Explicit
Option Private Module
'===================================================================================================
Private Const g_cnsTitle As String = "モジュール自動更新"
Private Const g_cnsUpdGuide As String = "新しいバージョンの更新用モジュール(VBA)が存在します。"
#If VBA7 Then
' Sleep
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
' Sleep
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
'***************************************************************************************************
' ■■■ 外部公開プロシージャ ■■■
'***************************************************************************************************
'* 処理名 :REPLACE_MODULE
'* 機能 :Module入れ替え機能
'---------------------------------------------------------------------------------------------------
'* 返り値 :処理成否(Boolean)
'* 引数 :Arg1 = 入れ替えモジュールのファイル名(String,パスは自ブック所在に固定)
'* Arg2 = バージョン情報の収容シート名(String)
'* Arg3 = バージョン情報の収容セルアドレス(String)
'* Arg4 = バージョン情報の収容シートの保護パスワード(String)
'* Arg5 = 入れ替え対象モジュール名(String)
'---------------------------------------------------------------------------------------------------
'* 作成日 :2004年11月07日
'* 作成者 :井上 治
'* 更新日 :2020年03月17日
'* 更新者 :井上 治
'* 機能説明:
'* 注意事項:モジュール入替え時及び処理失敗時はExcelが終了します(VBA動作が不安定となるため)
'***************************************************************************************************
Public Function REPLACE_MODULE(ByVal strModuleFile As String, _
ByVal strSheetName As String, _
ByVal strRangeAddr As String, _
ByVal strPassWord As String, _
ByVal strModule As String) As Boolean
'-----------------------------------------------------------------------------------------------
Dim objFso As FileSystemObject ' FileSystemObject
Dim objTs As TextStream ' TextStream
Dim objWbk As Workbook ' 本ブック
Dim objMSGStyle As VbMsgBoxStyle ' メッセージアイコン
Dim objVerSh As Worksheet ' バージョン情報所在シート
Dim objVBProject As Object ' VBProject
Dim objVBComponent As Object ' VBComponent
Dim lngVerN As Long ' バージョン値(新)
Dim lngVerO As Long ' バージョン値(旧)
Dim lngLines As Long ' 行番号
Dim blnOpen As Boolean ' テキストOpen判定
Dim blnClose As Boolean ' Close指示
Dim blnInteractive As Boolean ' Interactive状態
Dim strRec As String ' テキストレコード
Dim strFilename As String ' 更新モジュールファイル名
Dim strMSG As String ' メッセージWORK
Dim strErrMSG As String ' エラ-メッセージ
Dim strStep As String ' 処理ステップ(表示用)
REPLACE_MODULE = False
Set objFso = New FileSystemObject
Set objWbk = ThisWorkbook
objMSGStyle = vbExclamation
blnInteractive = Application.Interactive
On Error GoTo REPLACE_MODULE_ERROR
'-----------------------------------------------------------------
strStep = "000"
strFilename = objFso.BuildPath(objWbk.Path, strModuleFile)
' 同一フォルダに更新モジュールがないか、ブックが読み取り専用の時は終了(正常扱い)
If Not objFso.FileExists(strFilename) Or objWbk.ReadOnly Then
REPLACE_MODULE = True
GoTo REPLACE_MODULE_EXIT
End If
strStep = "001"
' 更新モジュールファイルをテキストとしてOpen
Set objTs = objFso.OpenTextFile(strFilename, ForReading, False, TristateUseDefault)
blnOpen = True
' 1REC目は無視(Attribute VB_Name = "Module1")
objTs.ReadLine
' レコード取得(2レコード目)
strRec = objTs.ReadLine
objTs.Close
blnOpen = False
strStep = "002"
' 新Version取得(2桁目から3桁の数値(整数)として取得)
lngVerN = Val(Trim(Mid(strRec, 2)))
Set objVerSh = objWbk.Worksheets(strSheetName)
strStep = "003"
' 旧Version取得(指定セル:数値(整数)であること)
lngVerO = Val(objVerSh.Range(strRangeAddr).Value)
' バージョンの新旧確認(更新済み等は正常終了)
If lngVerO >= lngVerN Then
REPLACE_MODULE = True
GoTo REPLACE_MODULE_EXIT
End If
'=================================================================
' ※新しいバージョンのモジュールが見つかった時の確認処理
'-----------------------------------------------------------------
strStep = "010"
' 他ブックが開いている時は警告終了
If Application.Workbooks.Count > 1 Then
strErrMSG = g_cnsUpdGuide & vbCr
strErrMSG = strErrMSG & "モジュールの更新後、一旦Excelを終了するため" & vbCr
strErrMSG = strErrMSG & "他のブックを閉じてから再度起動して下さい。"
objMSGStyle = vbInformation
blnClose = True
GoTo REPLACE_MODULE_EXIT
End If
' モジュール入替えメッセージ
strMSG = g_cnsUpdGuide & vbCr
strMSG = strMSG & " ( Ver" & Format(lngVerO, "000")
strMSG = strMSG & " ⇒ Ver" & Format(lngVerN, "000") & " )" & vbCr
strMSG = strMSG & "モジュールの更新を行ないますか?" & vbCr & vbCr
strMSG = strMSG & "※更新後は上書き保存され一旦終了します。"
' モジュール入替えの確認(一旦Excelが終了するため)⇒キャンセルは不成功
If MsgBox(strMSG, vbInformation + vbYesNo, g_cnsTitle) <> vbYes Then GoTo REPLACE_MODULE_EXIT
'=================================================================
' ※モジュール入れ替え処理(本体)
'-----------------------------------------------------------------
strStep = "020"
' モジュール更新開始
Application.StatusBar = "モジュール更新中....( →Ver" & Format(lngVerN, "000") & ")"
' VBプロジェクトを取得し、Moduleを入れ替える
On Error Resume Next
Set objVBProject = objWbk.VBProject
' Excelのセキュリティ設定によるエラー処置
If ((Err.Number = 1004) And (Left(Err.Description, 7) = "プログラミング")) Then
strErrMSG = "マクロセキュリティ設定が必要です。" & vbCr & vbCr
strErrMSG = strErrMSG & "Excelリボンの「ファイル」タブから「オプション」を開き、" & vbCr
strErrMSG = strErrMSG & "「トラストセンター(セキュリティセンター)の設定」へ進み、" & vbCr
strErrMSG = strErrMSG & "「マクロの設定」にある" & vbCr
strErrMSG = strErrMSG & "「VBAプロジェクトオブジェクトモデルへのアクセスを信頼する」に" & vbCr
strErrMSG = strErrMSG & "チェックを付けてから本ブックを開いて下さい。"
blnClose = True
GoTo REPLACE_MODULE_EXIT
End If
On Error GoTo REPLACE_MODULE_ERROR
strStep = "030"
Set objVBComponent = objVBProject.VBComponents(strModule)
' 更新中のエラーを避けるためイベントを停止
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Interactive = False
blnInteractive = False
strStep = "031"
' Workbook側でModule1内プロシージャを参照しているため、
' Removeできないので、コードを書き換え一旦Excelを終了する
With objVBComponent.CodeModule
' コードを削除(全行)
lngLines = .CountOfLines
If lngLines <> 0 Then .DeleteLines 1, lngLines
' Module1をBASファイルからインポートする
.AddFromFile strFilename
End With
Set objVBComponent = Nothing
Set objVBProject = Nothing
strStep = "032"
' バージョンのセット
With objVerSh
If .ProtectContents = True Then
.Unprotect strPassWord
.Protect strPassWord, UserInterfaceOnly:=True
End If
.Range(strRangeAddr).Value = lngVerN
End With
'=================================================================
' ※終了処理(上書き保存させてExcelを終了)
'-----------------------------------------------------------------
strStep = "040"
' 上書き保存
Application.StatusBar = False
Application.EnableEvents = True
objWbk.Save
Sleep 200 ' 処理間隔を空ける
Application.Interactive = True
Application.ScreenUpdating = True
' コンパイル済みモジュールを入れ替えているため、
' このまま動作させず一旦Excelを終了する
strMSG = "モジュールの更新は正常に終了しました。" & vbCr
strMSG = strMSG & "一旦、終了します。起動し直して下さい。" & vbCr
strMSG = strMSG & "(このExcelブックだけもう一度起動して下さい)"
MsgBox strMSG, vbInformation, g_cnsTitle
' 終了
Application.Quit
objWbk.Close False
End
'===================================================================================================
' エラートラップ
REPLACE_MODULE_ERROR:
' 実行時エラー発生時に処理ステップ番号を含めて表示させます。
strErrMSG = Err.Description & " Step:" & strStep
objMSGStyle = vbCritical
'===================================================================================================
' 終了
REPLACE_MODULE_EXIT:
If blnOpen Then objTs.Close
Set objTs = Nothing
Set objFso = Nothing
' Interactive復旧
If Not blnInteractive Then
Application.Interactive = True
Application.EnableEvents = True
Application.ScreenUpdating = True
End If
' エラーメッセージがあれば表示
If strErrMSG <> "" Then
MsgBox strErrMSG, objMSGStyle, g_cnsTitle
End If
Application.StatusBar = False
On Error GoTo 0
' Close指示か
If blnClose Then
objWbk.Saved = True
objWbk.Close False
End If
End Function
'----------------------------------------<< End of Source >>----------------------------------------
![]() |
←modPERLACE_MODULE.zip (36KB) |