サーバーに置いてあったデータmdbを開くと「'AOIndex'は、このテーブルのインデックスではありません」のエラーが出て、開けなくなった。幸い、プログラムmdbからデータを見ることが出来た*1ので、作り直すことが出来た。
これに対処するため、プログラムmdbの AutoExec マクロに、サーバーにあるデータmdbのバックアップを取るモジュールを組み込んだ。ポイントは、
-
- バックアップ直前にデータmdbを開く
- 「終了」のマクロを起動する。
- これにより、開けなくなった直後を捉えられる‥‥のではないか。
- バックアップ(ファイルコピー)は、バッチファイルで行う。
- コピー後ファイル名の接頭語として、“yyyymmddhhnn_” を付ける。
- このため、バッチファイルは毎回作り直す。
- イニファイルの作り方で、バックアップを取る/取らないの指定ができる。
- バックアップ直前にデータmdbを開く
§メイン
Public Function BackupMDB() As Boolean On Error GoTo Err_BackupMDB Dim mbTitle As String Dim dsn As Long, i As Long Dim strCommand As String Dim backupPath As String, backupFullPath As String, backupFileName As String Dim strDate As String, batFullPath As String Dim strDataMDBPath As String, strBackupPath As String, BackupFileSuu As Long Dim strMDBName As String, exeAccess As String, cmdShell As String mbTitle = MYObjName & "/BackupMDB" VARAns = SysCmd(acSysCmdSetStatus, "データMDBのバックアップ処理中です。") If getParameter(strDataMDBPath, strBackupPath, BackupFileSuu) = False Then Exit Function If BackupFileSuu = 0 Then Exit Function 'ファイル名の接頭語 strDate = Format(Now(), "yyyymmddhhnn") & "_" '相対パス→絶対パス。 strDataMDBPath = get_PathName(strDataMDBPath) strBackupPath = get_PathName(strBackupPath) 'バックアップフォルダが無ければ作る。 BOOLAns = make_ExDir(strBackupPath) '今日初めてか? If isFirst(strBackupPath) = False Then Exit Function '先に削除する。(後で削除すると、正常なバックアップを削除してしまう可能性がある) LNGAns = DeleteFiles(strBackupPath, BackupFileSuu) 'msaccess.exeのパス exeAccess = SysCmd(acSysCmdAccessDir) & "Msaccess.exe" 'batファイルのフルパス batFullPath = CurrentProject.Path & "\" & BATFileName 'batファイルを作り替える。 If Dir(batFullPath) <> "" Then Kill batFullPath dsn = FreeFile Open batFullPath For Output As #dsn strMDBName = Dir(strDataMDBPath & "*.mdb") Do While strMDBName <> "" backupFileName = strDate & strMDBName backupFullPath = strBackupPath & backupFileName cmdShell = """" & exeAccess & """ """ & strDataMDBPath & strMDBName & """ /xS_Quit" VARAns = Wait_Shell32(cmdShell, vbMinimizedNoFocus) strCommand = "COPY """ & strDataMDBPath & strMDBName & """ """ & backupFullPath & """" Print #dsn, strCommand strMDBName = Dir() Loop Print #dsn, "EXIT" Close #dsn DoEvents VARAns = Wait_Shell32(batFullPath, vbMinimizedNoFocus) BackupMDB = True Exit_BackupMDB: VARAns = SysCmd(acSysCmdClearStatus) Exit Function Err_BackupMDB: MsgBox Err.Number & "/" & Err.Description, vbCritical, mbTitle Resume Exit_BackupMDB End Function
§イニファイルからバックアップ条件を読み出す
Public Function getParameter(argDataMDBPath As String, argBackupPath As String, argNissuu As Long) As Boolean On Error GoTo Err_getParameter Dim mbTitle As String Dim i As Long Dim iniFullPath As String, strSectionName As String, strKeyName As String mbTitle = MYObjName & "/getParameter" getParameter = False strSectionName = CurrentProject.Name i = InStrRev(strSectionName, ".", -1, vbTextCompare) strSectionName = Left(strSectionName, i - 1) iniFullPath = CurrentProject.Path & "\" & strSectionName & ".ini" 'イニファイルが無い時は終る。 STRAns = Dir(iniFullPath) If STRAns = "" Then Exit Function 'データMDBのパス strKeyName = "DataMDBPath" argDataMDBPath = get_iniString(iniFullPath, strSectionName, strKeyName) 'データMDBのパス strKeyName = "BackupPath" argBackupPath = get_iniString(iniFullPath, strSectionName, strKeyName) 'バックアップ日数 strKeyName = "NumberOfBackup" STRAns = get_iniString(iniFullPath, strSectionName, strKeyName) If STRAns = "" Then If argDataMDBPath = "" Then argNissuu = 0 Else argNissuu = DEFHozonNissuu Else argNissuu = Val(STRAns) End If getParameter = True Exit_getParameter: Exit Function Err_getParameter: MsgBox "イニファイルの取得に失敗しました。システム管理者に連絡してください。" _ & Err.Number & "/" & Err.Description, vbCritical, mbTitle Resume Exit_getParameter End Function
§今日最初の起動か?(バックアップは1日1回)
Public Function isFirst(argFolder As String) As Boolean On Error GoTo Err_isFirst Dim mbTitle As String Dim i As Long Dim FileName As String Dim backupDate As Date mbTitle = MYObjName & "/isFirst" FileName = Dir(argFolder) Do Until FileName = "" VARAns = getDate(FileName) If Not IsNull(VARAns) Then backupDate = CDate(VARAns) If DateDiff("d", backupDate, Now) = 0 Then isFirst = False: Exit Function End If FileName = Dir() Loop isFirst = True Exit_isFirst: Exit Function Err_isFirst: MsgBox Err.Number & "/" & Err.Description, vbCritical, mbTitle Resume Exit_isFirst End Function
§ファイル名からバックアップ日付を読み取る(接頭語が yyyymmddhhnn_ になっている)
Public Function getDate(argFileName As String) As Variant On Error GoTo Err_getDate Dim mbTitle As String Dim i As Long mbTitle = MYObjName & "/getDate" getDate = Null STRAns = Left(argFileName, 8) If Len(STRAns) <> 8 Then Exit Function STRAns = Left(STRAns, 4) & "/" & Mid(STRAns, 5, 2) & "/" & Mid(STRAns, 7, 2) If IsDate(STRAns) Then getDate = CDate(STRAns) Exit_getDate: Exit Function Err_getDate: MsgBox Err.Number & "/" & Err.Description, vbCritical, mbTitle Resume Exit_getDate End Function
§期限切れのファイルを削除する
Public Function DeleteFiles(argFolder As String, argFileSuu As Long) As Long On Error GoTo Err_DeleteFiles Dim mbTitle As String Dim ctrDelete As Long, i As Long, SakujoKensuu As Long Dim FileName As String, arrayFileName As String Dim backupDate As Date Dim SplitTBL As Variant, SplitCTR As Long mbTitle = MYObjName & "/DeleteFiles" DeleteFiles = 0 arrayFileName = "" FileName = Dir(argFolder) Do Until FileName = "" If IsDate(getDate(FileName)) Then arrayFileName = arrayFileName & "," & FileName End If FileName = Dir() Loop If arrayFileName = "" Then Exit Function arrayFileName = Mid(arrayFileName, 2) '並び替える VARAns = get_SortStrings(arrayFileName) If IsNull(VARAns) Then Exit Function SplitTBL = Split(VARAns, ",", -1, vbTextCompare) SakujoKensuu = UBound(SplitTBL) - argFileSuu If SakujoKensuu < 0 Then Exit Function ctrDelete = 0 For i = 0 To SakujoKensuu FileName = SplitTBL(i) Kill argFolder & FileName ctrDelete = ctrDelete + 1 Next DeleteFiles = ctrDelete Exit_DeleteFiles: Exit Function Err_DeleteFiles: MsgBox Err.Number & "/" & Err.Description, vbCritical, mbTitle Resume Exit_DeleteFiles End Function
*1:これが発見を遅らせた。