ACCESS2013以降（64/32bit）でAccess1.0のMDBを作り、Access2003以降のMDBに変換する

####前回Access97/95以前のファイルが作成できなかった
これは[Access 2000/2003 +VB6.0 /VB5.0 ODBCDirect 幻の技術](http://qiita.com/Q11Q/items/0856d333936c9e5ffcc3)で取り上げたようにAccess1.1などは日本で未発売だった。したがってAccess1.0は日本語に対応していないため、dbLangJapaneseなどという定数は使えない。
したがって dbLangGeneral をつかう。

### Access 32Bit
####VBA版(64bitでは動作しません）

```Vb:MakeDaoOldDB.vbs
Sub Main()
'http://kazu-riders.blog.so-net.ne.jp/2009-03-27
'Access 2013 Later 32Bit
' 定数/変数宣言部
Const DB_LANG_JAPANESE = ";LANGID=0x0411;CP=932;COUNTRY=0"
Const DB_OPEN_DYNASET = 2
Const DB_APPEND_ONLY = 8
Const DRIVE_NAME = "F:\"
Const FILE_NAME = "TEST.mdb"
Const cnsDbVersion30_AC95_AC97_Jet30_Jet35 = 32
Const cnsDbVersion20_AC20_Jet20 = 16

Dim dbe, db, strDbPath
Dim wsh: Set wsh = CreateObject("Wscript.Shell")
' MDB がすでに存在するか調べます。
With CreateObject("Scripting.FileSystemObject")
If .FileExists(DRIVE_NAME & FILE_NAME) = True Then
MsgBox DRIVE_NAME & FILE_NAME & "はすでに存在します。終了します", vbOKOnly + vbInformation, "ファイルが存在します"
Exit Sub
End If
End With
' MDB を作成します。
Set dbe = CreateObject("DAO.DBEngine.36")
Set db = dbe.CreateDatabase(DRIVE_NAME & FILE_NAME, _
DB_LANG_JAPANESE, cnsDbVersion20_AC20_Jet20)
' テーブルを作成します。
db.Execute "CREATE TABLE 売上テーブル " _
& "(販売コード AUTOINCREMENT " _
& "CONSTRAINT PrimaryKey PRIMARY KEY, " _
& "支店 TEXT(255), " _
& "販売日 DATETIME, " _
& "商品 TEXT(255), " _
& "個数 INTEGER, " _
& "売上 CURRENCY);"
db.Execute "CREATE INDEX 販売日 " _
& "ON 売上テーブル (販売日) WITH DISALLOW NULL;"
' レコードを追加します。
GenRecs db.OpenRecordset("売上テーブル", _
DB_OPEN_DYNASET, _
DB_APPEND_ONLY)
' オブジェクト変数の参照を解放します。
db.Close: Set db = Nothing
Set dbe = Nothing
' ユーザーに結果を通知します。
MsgBox DRIVE_NAME & "に" & FILE_NAME _
& "' を作成しました。", vbInformation
End Sub

Function GetUniqueDbName(filename)
' デスクトップに "test.mdb" というファイルが無いか調べ、
' すでに存在していれば空文字列を、まだ存在していなければ
' フルパスを返します。
Dim strResult 'As String
Dim strDrive 'As String
Dim Ar As Variant
Ar = Split(filename, "\")
Set WshShell = CreateObject("WScript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
strResult = fso.BuildPath( _
WshShell.SpecialFolders("Desktop"), _
filename)
If fso.FileExists(strResult) Then
MsgBox "デスクトップに '" & "または" & Ar(0) & "に" & filename _
& "' と同名のファイルが既に存在します。" _
& vbCrLf & vbCrLf & "処理を中止します。", _
vbCritical
Else
GetUniqueDbName = strResult
End If
End Function

Sub GenRecs(rs)
' 過去 30 日分のテスト用レコードを追加します。
' 変数を初期化します。
varSites = Array("新宿", "渋谷", "池袋", "上野", "品川")
varProducts = Array("烏龍茶", "オレンジジュース", _
"グレープジュース", "コーヒー", "紅茶")
varPrices = Array(150, 250, 250, 180, 180)
' レコードを追加します。
With rs
For i = Date - 30 To Date
For j = 0 To (Int(6 * Rnd) + 5)
.AddNew
.Fields("支店").Value = varSites(Int(5 * Rnd))
.Fields("販売日").Value = i + Rnd
intProdId = Int(5 * Rnd)
.Fields("商品").Value = varProducts(intProdId)
.Fields("個数").Value = Int(10 * Rnd) + 2
.Fields("売上").Value = .Fields("個数").Value _
* varPrices(intProdId)
.Update
Next
Next
End With
End Sub
```
Set db = dbe.CreateDatabase(DRIVE_NAME & FILE_NAME, _
DB_LANG_JAPANESE, cnsDbVersion20_AC20_Jet20)
のcnsDbVersion20_AC20_Jet20を書き換えると
Access2.0~Access2003のMDBファイルが作成できる。

###VBScript 32Bit版
C\hoge\にファイルがあるとする
次に起動するにはCMD.EXEでコマンドプロンプトを立ち上げ
%SystemRoot%\SysWow64\cscript.exe "C:\hoge\gendbdao.vbs"
と32Bit出ない限りエラーになる
以下のVBSはこの方法を使う必要がありましたが、これを回避するため、32Bit強制起動ルーチンを追加しました。これによりダブルクリックするだけで32Bitで起動します。

###Access 2.0

```vb:GenDbDao.VBS
'32bit 強制起動
'http://scripting.cocolog-nifty.com/blog/2011/02/wsh6432bit-b32d.html
If InStr(LCase(WScript.FullName),"system32") Then 
If CreateObject("Scripting.FileSystemObject").FileExists(Replace(LCase(WScript.FullName),"system32","syswow64")) Then
  CreateObject("WScript.Shell").Run """" & Replace(LCase(WScript.FullName),"system32","syswow64") & """ """ & WScript.ScriptFullName & """"
  WScript.Quit
End If
End If
Main
Sub Main()
'http://kazu-riders.blog.so-net.ne.jp/2009-03-27
'%SystemRoot%\SysWow64\cscript.exe "C:\hoge\gendbdao.vbs"
'Access 2013 Later
'64 / 32 Ok
'
' 定数/変数宣言部
Const DB_LANG_JAPANESE = ";LANGID=0x0411;CP=932;COUNTRY=0"
Const DB_OPEN_DYNASET = 2
Const DB_APPEND_ONLY = 8
Const DRIVE_NAME = "F:\"
Const FILE_NAME = "TEST.mdb"
Const cnsDbVersion30_AC95_AC97_Jet30_Jet35 = 32
Const cnsDbVersion20_AC20_Jet20 = 16

Dim dbe, db, strDbPath
Dim wsh: Set wsh = CreateObject("Wscript.Shell")
' MDB がすでに存在するか調べます。
With CreateObject("Scripting.FileSystemObject")
If .FileExists(DRIVE_NAME & FILE_NAME) = True Then
MsgBox DRIVE_NAME & FILE_NAME & "はすでに存在します。終了します", vbOKOnly + vbInformation, "ファイルが存在します"
Exit Sub
End If
End With
' MDB を作成します。
Set dbe = CreateObject("DAO.DBEngine.36")
Set db = dbe.CreateDatabase(DRIVE_NAME & FILE_NAME, _
DB_LANG_JAPANESE, cnsDbVersion20_AC20_Jet20)
' テーブルを作成します。
db.Execute "CREATE TABLE 売上テーブル " _
& "(販売コード AUTOINCREMENT " _
& "CONSTRAINT PrimaryKey PRIMARY KEY, " _
& "支店 TEXT(255), " _
& "販売日 DATETIME, " _
& "商品 TEXT(255), " _
& "個数 INTEGER, " _
& "売上 CURRENCY);"
db.Execute "CREATE INDEX 販売日 " _
& "ON 売上テーブル (販売日) WITH DISALLOW NULL;"
' レコードを追加します。
GenRecs db.OpenRecordset("売上テーブル", _
DB_OPEN_DYNASET, _
DB_APPEND_ONLY)
' オブジェクト変数の参照を解放します。
db.Close: Set db = Nothing
Set dbe = Nothing
' ユーザーに結果を通知します。
MsgBox DRIVE_NAME & "に" & FILE_NAME _
& "' を作成しました。", vbInformation
End Sub

Function GetUniqueDbName(filename)
' デスクトップに "test.mdb" というファイルが無いか調べ、
' すでに存在していれば空文字列を、まだ存在していなければ
' フルパスを返します。
Dim strResult 'As String
Dim strDrive 'As String
Dim Ar 'As Variant
Ar = Split(filename, "\")
Set WshShell = CreateObject("WScript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
strResult = fso.BuildPath( _
WshShell.SpecialFolders("Desktop"), _
filename)
If fso.FileExists(strResult) Then
MsgBox "デスクトップに '" & "または" & Ar(0) & "に" & filename _
& "' と同名のファイルが既に存在します。" _
& vbCrLf & vbCrLf & "処理を中止します。", _
vbCritical
Else
GetUniqueDbName = strResult
End If
End Function

Sub GenRecs(rs)
' 過去 30 日分のテスト用レコードを追加します。
' 変数を初期化します。
varSites = Array("新宿", "渋谷", "池袋", "上野", "品川")
varProducts = Array("烏龍茶", "オレンジジュース", _
"グレープジュース", "コーヒー", "紅茶")
varPrices = Array(150, 250, 250, 180, 180)
' レコードを追加します。
With rs
For i = Date - 30 To Date
For j = 0 To (Int(6 * Rnd) + 5)
.AddNew
.Fields("支店").Value = varSites(Int(5 * Rnd))
.Fields("販売日").Value = i + Rnd
intProdId = Int(5 * Rnd)
.Fields("商品").Value = varProducts(intProdId)
.Fields("個数").Value = Int(10 * Rnd) + 2
.Fields("売上").Value = .Fields("個数").Value _
* varPrices(intProdId)
.Update
Next
Next
End With
End Sub
```
Set db = dbe.CreateDatabase(DRIVE_NAME & FILE_NAME, _
DB_LANG_JAPANESE, cnsDbVersion20_AC20_Jet20)
このVBSのcnsDbVersion20_AC20_Jet20を書き換えるとAccess2.0~Access2003のMDBファイルが作成できる。

###Access1.0をつくるには
ロケールをdbLangeGeneralにしないとエラーになる。
Const DB_Lang_Global = ";LANGID=0x0409;CP=1252;COUNTRY=0"

```vb:GenDao10.vbs
'32bit 強制起動
'http://scripting.cocolog-nifty.com/blog/2011/02/wsh6432bit-b32d.html
If InStr(LCase(WScript.FullName),"system32") Then 
If CreateObject("Scripting.FileSystemObject").FileExists(Replace(LCase(WScript.FullName),"system32","syswow64")) Then
  CreateObject("WScript.Shell").Run """" & Replace(LCase(WScript.FullName),"system32","syswow64") & """ """ & WScript.ScriptFullName & """"
  WScript.Quit
End If
End If
Main
Sub Main()
'http://kazu-riders.blog.so-net.ne.jp/2009-03-27
'%SystemRoot%\SysWow64\cscript.exe "%UERPROFILE%\Documents\MyScript\genDao10.vbs"
'Access 2013 Later
'64 / 32 Ok
'
' 定数/変数宣言部
Const DB_LANG_JAPANESE = ";LANGID=0x0411;CP=932;COUNTRY=0"
Const DB_Lang_Global = ";LANGID=0x0409;CP=1252;COUNTRY=0"
Const DB_OPEN_DYNASET = 2
Const DB_APPEND_ONLY = 8
Const DRIVE_NAME = "F:\"
Const FILE_NAME = "TEST.mdb"
Const cnsDbVersion30_AC95_AC97_Jet30_Jet35 = 32
Const cnsDbVersion20_AC20_Jet20 = 16
Const cndDBVerion10 =1
Dim dbe, db, strDbPath
Dim wsh: Set wsh = CreateObject("Wscript.Shell")
' MDB がすでに存在するか調べます。
With CreateObject("Scripting.FileSystemObject")
If .FileExists(DRIVE_NAME & FILE_NAME) = True Then
MsgBox DRIVE_NAME & FILE_NAME & "はすでに存在します。終了します", vbOKOnly + vbInformation, "ファイルが存在します"
Exit Sub
End If
End With
' MDB を作成します。
Set dbe = CreateObject("DAO.DBEngine.36")
Set db = dbe.CreateDatabase(DRIVE_NAME & FILE_NAME, _
DB_LANG_Global, cnsDBVersion10)
' テーブルを作成します。
db.Execute "CREATE TABLE 売上テーブル " _
& "(販売コード AUTOINCREMENT " _
& "CONSTRAINT PrimaryKey PRIMARY KEY, " _
& "支店 TEXT(255), " _
& "販売日 DATETIME, " _
& "商品 TEXT(255), " _
& "個数 INTEGER, " _
& "売上 CURRENCY);"
db.Execute "CREATE INDEX 販売日 " _
& "ON 売上テーブル (販売日) WITH DISALLOW NULL;"
' レコードを追加します。
GenRecs db.OpenRecordset("売上テーブル", _
DB_OPEN_DYNASET, _
DB_APPEND_ONLY)
' オブジェクト変数の参照を解放します。
db.Close: Set db = Nothing
Set dbe = Nothing
' ユーザーに結果を通知します。
MsgBox DRIVE_NAME & "に" & FILE_NAME _
& "' を作成しました。", vbInformation
End Sub

Function GetUniqueDbName(filename)
' デスクトップに "test.mdb" というファイルが無いか調べ、
' すでに存在していれば空文字列を、まだ存在していなければ
' フルパスを返します。
Dim strResult 'As String
Dim strDrive 'As String
Dim Ar 'As Variant
Ar = Split(filename, "\")
Set WshShell = CreateObject("WScript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
strResult = fso.BuildPath( _
WshShell.SpecialFolders("Desktop"), _
filename)
If fso.FileExists(strResult) Then
MsgBox "デスクトップに '" & "または" & Ar(0) & "に" & filename _
& "' と同名のファイルが既に存在します。" _
& vbCrLf & vbCrLf & "処理を中止します。", _
vbCritical
Else
GetUniqueDbName = strResult
End If
End Function

Sub GenRecs(rs)
' 過去 30 日分のテスト用レコードを追加します。
' 変数を初期化します。
varSites = Array("新宿", "渋谷", "池袋", "上野", "品川")
varProducts = Array("烏龍茶", "オレンジジュース", _
"グレープジュース", "コーヒー", "紅茶")
varPrices = Array(150, 250, 250, 180, 180)
' レコードを追加します。
With rs
For i = Date - 30 To Date
For j = 0 To (Int(6 * Rnd) + 5)
.AddNew
.Fields("支店").Value = varSites(Int(5 * Rnd))
.Fields("販売日").Value = i + Rnd
intProdId = Int(5 * Rnd)
.Fields("商品").Value = varProducts(intProdId)
.Fields("個数").Value = Int(10 * Rnd) + 2
.Fields("売上").Value = .Fields("個数").Value _
* varPrices(intProdId)
.Update
Next
Next
End With
End Sub
```
###変換にはDao.CompactDatabaseではなくJet.ComactDatabaseをVBSで使う

```VB:JetCmp10.VBS
Option Explicit
'32bit 強制起動
'http://scripting.cocolog-nifty.com/blog/2011/02/wsh6432bit-b32d.html
If InStr(LCase(WScript.FullName),"system32") Then 
If CreateObject("Scripting.FileSystemObject").FileExists(Replace(LCase(WScript.FullName),"system32","syswow64")) Then
  CreateObject("WScript.Shell").Run """" & Replace(LCase(WScript.FullName),"system32","syswow64") & """ """ & WScript.ScriptFullName & """"
  WScript.Quit
End If
End If
Const oldFile = "F:\test.mdb"
Const NewFile = "F:\test20_2003.mdb"
Dim JIRO : Set JIRO = CreateObject("JRO.JetEngine")
Dim strOldConnect : strOldConnect = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & oldFile
'Dim strNewConnect : strNewConnect ="Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=" & NewFile & ";Jet OLEDB:Engine Type =4;"
Dim strNewConnect : strNewConnect ="Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=" & NewFile & ";"
With CreateObject("Scripting.FileSystemObject")
If .FileExists(oldFIle)=False then Wscript.Quit
If .FileExists(NewFile)=True then Wscript.Quit
End With
JIRO.CompactDatabase strOldConnect, strNewConnect
Set Jiro = Nothing
```
TEST.mdbにあるAccess1.0ファイルをAccess2003MDBファイルに変換する


####Access1.0から好みのAccessのMDBファイルを作る

上記スクリプトで作成したものに限られるが、基本的にJetは古いバージョンから新しいバージョンは作ることができる。
Access1.0形式なら全バージョンに変換できる
Dim strNewConnect : strNewConnect ="Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=" & NewFile & ";Jet OLEDB:Engine Type =***4***;"

この4がポイント。下記の表にあるようにこれがAccess97/95のMDBファイルを指定する。
ちなみにJet OLEDBEngineTypeを指定しないとAccess2003のMDBファイルになる。
また変換元はJetのタイプを指定しなくても変換先より以前のMDBファイルなら自動的に変換する。


```VBNet:JetVerChng.vbs
Option Explicit
'%SystemRoot%\SysWow64\CScript.EXE "%USERPROFILE%\Documents\Myscript\JetVerChngvbs"
'32bit 強制起動
'http://scripting.cocolog-nifty.com/blog/2011/02/wsh6432bit-b32d.html
If InStr(LCase(WScript.FullName),"system32") Then 
If CreateObject("Scripting.FileSystemObject").FileExists(Replace(LCase(WScript.FullName),"system32","syswow64")) Then
  CreateObject("WScript.Shell").Run """" & Replace(LCase(WScript.FullName),"system32","syswow64") & """ """ & WScript.ScriptFullName & """"
  WScript.Quit
End If
End If
Const oldFile = "E:\test.mdb"
Const NewFile = "E:\test9795.mdb"
Dim JIRO : Set JIRO = CreateObject("JRO.JetEngine")
Dim strOldConnect : strOldConnect = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & oldFile & ";Jet OLEDB:Engine Type =1;"
Dim strNewConnect : strNewConnect ="Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=" & NewFile & ";Jet OLEDB:Engine Type =4;"
With CreateObject("Scripting.FileSystemObject")
If .FileExists(oldFIle)=False then Wscript.Quit
If .FileExists(NewFile)=True then Wscript.Quit
End With
JIRO.CompactDatabase strOldConnect, strNewConnect
Set Jiro = Nothing
```
#####ただし、できるのは上記のスクリプトで作成したMDBファイルです
本来のAccess2.0などで作ったバージョンは変換できません。
しかし、上記のスクリプトで作ったものは変換できます。
これはDAO,Access,JROがMDB作成したAccessのVersionを判定しているからです。
さらに意図的にMSがはねている可能性が大きい。
DbEnginにProjVerというプロパティがあり、2000形式以降のMDBに変換して、次のコードを実行する。
```vb
Sub ShowProp()
'For Access and MDB File Only Effective
Dim prp As DAO.Property, Prps As DAO.Properties
Dim oErr As ErrObject
Dim prpe As Property
For Each prp In CurrentDb.Properties
On Error Resume Next
Debug.Print prp.Name, prp.Value, prp.Type
If Err.Number <> 0 Then Debug.Print Err.Number, Err.Description: Err.Clear
On Error GoTo 0
Next

End Sub
```

するとイミディエイトに次のようなProjVerなるプロパティと値を得る。値はだしても意味がないので、正規表現で表記した。3はInteger型
'ProjVer        \d{1,3}           3'
この数字の並びは`\d{1,3}`はっきりした定数ではないようだ。FileFormat,AccessVersionとは違う。もしかするとMDBファイルのバイナリを読んで、このProjVerを現在のAccessのバージョン番号に書き換えれば変換するのかもしれないが、さすがにそこまでやることはない。


###参考リンク
####dbLangeJapaneseなどの中身
[LanguageConstants 列挙 (DAO)]( https://msdn.microsoft.com/ja-jp/library/office/ff821047.aspx)
>データベースを作成するための照合順序を指定します。
>Access1.0 は dbLangGeneral ";LANGID=0x0409;CP=1252;COUNTRY=0" を使用する
>日本語のテーブルはおおむね日本語になるらしい。この定数は文字列を表しているというのも他の定数と変わっている。
[Microsoft Access 2010 を使用したデータ プログラミング](https://msdn.microsoft.com/ja-jp/library/office/ff965871(v=office.14).aspx)
> Access 2007 より前の Access では、Microsoft Joint Engine Technology (JET) エンジンを使用していました。JET は Access の一部として一般に認められていましたが、かつて JET エンジンは別の製品でした。Microsoft Windows 2000 のリリース以来、JET は Windows オペレーティング システムの一部となり、Microsoft Data Access Components (MDAC) によって配布または更新されるようになりました。しかし、Access 2007 のリリースによって、JET エンジンは非推奨となり、MDAC で配布されなくなりました。その代わりに、現在 Access では、統合および改良された ACE エンジンを使用しています。ACE エンジンは、元になった JET コード ベースのコード スナップショットをとることから開発が始まったものです。
> ACE エンジンは、***以前のバージョンの JET エンジンとの完全な下位互換性があるので、以前のバージョンの Access から (.mdb) ファイルを読み書きできます。***このエンジンは現在 Access チームが所有しているため、開発者は、自らの Access ソリューションが将来も動作し続けることだけでなく、より高速で堅牢になり、機能が充実していくことにも確信を持てます。たとえば、Access 2010 のリリースで特に注目される改良点として、ACE エンジンのアップグレードによって 64 ビット版がサポートされ、SharePoint 関連テクノロジおよび Web サービス全般との統合が強化されたことが挙げられます。Microsoft は、開発者プラットフォームとしての Access に注力しています。

※以前のバージョンのAccessファイルを読み書きできるというのがポイント



[DAO コードを ADO に変換する](https://msdn.microsoft.com/ja-jp/library/ff193201.aspx)
適用対象:Access 2013 | Access 2016
Access 2013 Later Access では、DAO 3.6 以前のオブジェクト ライブラリを提供およびサポートしていません。

|DAO |ADO(ADODB) |
|:--:|:---------:|
|DBEngine|なし|
|Workspace|なし|
|Database|Connection|
|Recordset|Recordset|
|Dynaset-Type|Keyset|
|Snapshot-Type|Static|
|Table-Type|adCmdTableDirect オプションを持つ Keyset。|
|Field|Field|

|タスク|Dao| ADO|
|:-----------------:|:-------------------------------------|:-----------------|
|Recordset を開く |Dim db as Database |Dim rs as New ADODB.Recordset |
| |Dim rs as DAO.Recordset |rs.Open "Employees", CurrentProject.Connection, _ |
| |Set db = CurrentDB() | adOpenKeySet, adLockOptimisti |
| |Set rs = db.OpenRecordset("Employees")| |
|Recordsetを編集 |rs.Edit |rs("TextFieldName") = "NewValue"|
| |rs("TextFieldName") = "NewValue" |rs.Update |
| |rs.Update | |

最初に CancelUpdate メソッドを使用せずに、MoveNext、MoveLast、MoveFirst、MovePrevious メソッドを使ってカレント レコードからフォーカスを移動すると、暗黙的に Update メソッドが実行されます。


#### Jet And Replication Object Libray
[Microsoft Jet and Replication Objects 2.1 Library -](https://msdn.microsoft.com/ja-jp/library/cc326861.aspx)
>Microsoft Jet and Replication objects 2.1 オブジェクト モデルは、MSJRO.DLL によって提供されています。MSJRO.DLL は、Microsoft Office 2000 をセットアップすると組み込まれます。
[How To Compact Microsoft Access Database Through ADO](msJro.Dll)( https://support.microsoft.com/ja-jp/help/230501/how-to-compact-microsoft-access-database-through-ado)
>※JET OLE DB Provider version 4.0 (Msjetoledb40.dll)
>※NOTE: In DAO 3.60, the RepairDatabase method is no longer available. The above code shows the use of the CompactDatabase method. This method replaces the DAO 3.5 RepairDatabase method.
[JROでDBを最適化する（CompactDatabaseメソッド） - moug]( https://www.moug.net/tech/acvba/0070029.html)
[DBEngine.CompactDatabase メソッド (DAO)]( https://msdn.microsoft.com/ja-jp/library/office/ff844821.aspx)
[How To Compact Microsoft Access Database Through ADO]( https://support.microsoft.com/ja-jp/help/230501/how-to-compact-microsoft-access-database-through-ado)
Dim jro As jro.JetEngine
Set jro = New jro.JetEngine
jro.CompactDatabase "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=d:\nwind2.mdb;Jet OLEDB:Database Password=test", _
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=d:\abbc2.mdb;Jet OLEDB:Engine Type=4;Jet OLEDB:Database Password=test"
※パスワードがある場合にはこのパターンを使う Type
Tyepは次のとおり

|Jet OLEDB:Engine Type|Jet x.x Format MDB Files |ACCESS|
|:-------------------:|:-----------------------:|:----:|
|1|JET10 |Access1.0|
|2| JET11 |Access1.1|
|3| JET2X |Access2.0|
|4| JET3X |Access97/95|
|5| JET4X |Access2000|

### ProjVar関連
https://renenyffenegger.ch/notes/Microsoft/Office/Access/Object-Model/Database/properties/index
Access 2003 の例

[Accessバージョン、File形式のCheck方法：SampleFile187](http://www.accessclub.jp/supbeg/127.html)
まず、Accessファイルの形式を判別するのには、FileFormat プロパティ を利用します。
acFileFormatを使う例
[AccessバージョンをVBAで取得する方法 ：一日一見](http://www.accessclub.jp/supbeg/127.html)
Versionプロパティを用いれば、利用しているAccessのバージョンを簡単に取得することができます。このプロパティは、値の取得のみ可能です。
[Accessのビルト番号をVBAで取得する方法 ：一日一見](http://www.accessclub.jp/supbeg/128.html)
build番号の取得
Application.Version 現在使っているAccessのバージョン 
[【Access】MDEﾌｧｲﾙが作成できない時はﾊﾞｰｼﾞｮﾝを確認。](http://plus-sys.jugem.jp/?eid=100)
>ACCESSの2000以降のバージョンでプログラムを作る際、
プログラムの形式を2000形式で作る場合が多いと思います。
（環境にもよりますが。）
この時、開発用のACCESSが2002以降だと、「MDEファイルの作成」ボタンが
グレーアウトします。ACCESSプログラムのファイル形式と、MDEを変換する
ACCESSのバージョンが一致していない場合、MDEへ変換できないためです。
なので、私の場合、ACCESS2002上でmdbで開発（プログラムは2000ファイル形式）し、
納品前にACCESS2000上でMDE化を行っています。