1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

VBScriptでMS Accessのdecompile,compile,repair

Posted at

概要

某所では、ファイルサイズの肥大化を避けるため、accdbに手を入れる度にデコンパイル、コンパイル、および[データベースの最適化と修復]をすることになっている(慣わし・仕来りの類)
毎回手作業でやりたくないので作った。

accdb_optimize.vbs
Dim Excel
Set Excel = WScript.CreateObject("Excel.Application")

Const SHIFT_KEY = &H10
Const CMD = "C:\Windows\System32\cmd.exe"
Const MSACCESS = """C:\Program Files {(}x86{)}\Microsoft Office\Office16\MSACCESS.EXE"" "
Const AAA_DB_PATH     = "C:\aaa.accdb"
Const BBB_DB_PATH     = "C:\bbb.accdb"
Const CCC_DB_PATH     = "C:\ccc.accdb"
Const DDD_DB_PATH     = "C:\ddd.accdb"

Sub API_keybd_event(bVk, bScan, dwFlags, dwExtraInfo)
    Dim strFunction
    Const API_STRING = "CALL(""user32"",""keybd_event"",""JJJJJ"", $1, $2, $3, $4)"
    strFunction = Replace(Replace(Replace(Replace(API_STRING, "$1", bVk), "$2", bScan), "$3", dwFlags), "$4", dwExtraInfo)
    Call Excel.ExecuteExcel4Macro(strFunction)
End Sub

Sub optimize(dbPath)
    Dim WshShell,acApp,ctrl,acForm,i,objExecCmd
    Set WshShell = WScript.CreateObject("WScript.Shell")
    
    WshShell.Run(CMD)
    WScript.Sleep(1000)
    WshShell.SendKeys(MSACCESS & dbPath & " /decompile")

    'Shift on
    Call API_keybd_event(SHIFT_KEY, 0, 1, 0)
    
    'Decompile
    WshShell.SendKeys("{enter}")
    WScript.Sleep(2000)

    'Shift off
    Call API_keybd_event(SHIFT_KEY, 0, 3, 0)
    
    'Compile
    Set acApp = GetObject(dbPath)
    Set ctrl = acApp.VBE.CommandBars.FindControl(,578)
    ctrl.Execute()
    WScript.Sleep(1000)
    
    'Close shutter bar
    Call acApp.DoCmd.SelectObject(acForm, "", True)
    acApp.DoCmd.Minimize()
    WScript.Sleep(1000)
    
    'Close ACCDB
    WshShell.SendKeys("%{F4}")
    WScript.Sleep(3000)

    'Just in case(shift off)
    Call API_keybd_event(SHIFT_KEY, 0, 3, 0)

    'Compact and repair database
    WshShell.AppActivate(CMD)
    WshShell.SendKeys(MSACCESS & dbPath & " /compact")
    WshShell.SendKeys("{enter}")
    WScript.Sleep(2000)

    'Close CMD
    WshShell.AppActivate(CMD)
    WshShell.SendKeys("exit{enter}")
End Sub

Sub main
    Dim input_no
    input_no = CStr(InputBox("Decompile, compile, compress and repair ACCDB." & vbCrLf & _
                             "Please input the number for target App." & vbCrLf & _
                             vbCrLf & _
                             "1:AAA" & vbCrLf & _
                             "2:BBB" & vbCrLf & _
                             "3:CCC" & vbCrLf & _
                             "4:DDD", _
                             "ACCDB optimization tool"))

    If input_no = "" Then
        exit sub
    Elseif input_no = "1" Then
        optimize(AAA_DB_PATH)
    Elseif input_no = "2" Then
        optimize(BBB_DB_PATH)
    Elseif input_no = "3" Then
        optimize(CCC_DB_PATH)
    Elseif input_no = "4" Then
        optimize(DDD_DB_PATH)
    Else
        Call MsgBox("The menu does not have that number. " & input_no)
        Exit Sub
    End if
    Call MsgBox("Optimization complete.", vbInformation)
End Sub

'execute main procedure
main()

解説

  • 処理の完了検知ができないので、所々で適当な秒数sleepしてる。
  • Shift押しながらdecompileしないと、スタートアップフォームやマクロが起動してしまうので、Excel経由でWindows APIを使って、Shiftキーを押しっぱなしたことにしている。

所感

  • mission-criticalなところでMS Accessをアプリとして使うのはやめたほうがいい気がします...
  • Accessでimport/exportを6,000回くらい繰り返すと、謎のエラーで動かなくなる...
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?