ACCESS2013 Access 2016 でAccess2003の新しいMDBファイルを作る

```ps1:CreateAccessDataBase.ps1
# https://gallery.technet.microsoft.com/office/28a08699-7d60-492c-bc97-d6456a6c3739
# Set-ExecutionPolicy RemoteSigned -Scope Process -Force
# Success Windows 10 Access 2013(32bit)
# Microsoft Access データベース エンジン 2010 再頒布可能コンポーネントインストール済み
# QiiQ From Qiita
# CreateAccessDataBase.ps1
Function Check-Path($Db)
{
If(!(Test-Path -path (Split-Path -path $Db -parent)))
{
Throw "$(Split-Path -path $Db -parent) Does not Exist"
}
ELSE
{
If(Test-Path -Path $Db)
{
Throw "$db already exists"
}
}
} # Check-Path関数の終わり

Function Create-DataBase($Db)
{

$application =New-Object -ComObject Access.application
$application.NewCurrentDataBase($Db,10)
$application.CloseCurrentDataBase()
$application.Quit()
} # Create-DataBase関数の終わり

Function Invoke-ADOCommand($Db, $Command)
{
$connection = New-Object -ComObject ADODB.Connection
#$connection.Open("Provider= Microsoft.Jet.OLEDB.4.0;Data Source=$Db")
$connection.Open("Provider= Microsoft.Ace.OLEDB.12.0;Data Source=$Db")
$connection.Execute($command)
$connection.Close()
} # Invoke-ADOCommand 関数の終わり

# *** スクリプトのエントリポイント***

$Db =  [Environment]::GetFolderPath('Desktop') + "\TEST2003.mdb"
$table = "MyTest"
$Fields = "F1 Counter, F2 Date, F3 Integer, F4 Text"
$command = "Create Table $table `($Fields`)"

Check-Path -db $Db
Create-DataBase -db $Db
Invoke-ADOCommand -db $Db -command $command
```

####Access 2003 のMDBファイルは作成できる
以前、
[Access 2016(64 bit +win10Home)でmdbファイルは開ける MS Access 2013 Later can Open mdb file](http://qiita.com/Q11Q/items/a554aa07f1c25fbeb3f8)
という記事がかなりアクセス数が多く、実は一番参照されているようだ。
今回は97は無理だが、2003はできた

####今回のOSとAccessのバージョン
Access2013(32bit) + Windows 10
Access2016(64bit) + Windows 10
の2種類。というのも上記のパワーシェル版は2016は失敗するからだ。

####Access2013は公式サイトの書き換えで成功する
上記のパワーシェルスクリプトは
[Hey, Scripting Guy!　Windows PowerShell を使用して Office Access データベースを作成する方法はありますか](https://gallery.technet.microsoft.com/office/28a08699-7d60-492c-bc97-d6456a6c3739)
のものだが、1行書き換えないと動かなかった。
それは
\$connection.Open("Provider= Microsoft.Jet.OLEDB.4.0;Data Source=\$Db")
を
\$connection.Open("Provider= Microsoft.Ace.OLEDB.12.0;Data Source=\$Db")
に書き換えるという点である。

####Access 2016 64 bitはVBAなら可能
しかし、このPowershell ScriptはAccess 2016 64bitではエラーになった。
しかもDao3.6に参照設定をすることができなくなっている。(下記：[フィロの村note参照](http://note.phyllo.net/?eid=1106279))
しかし、実際はその必要がないようだ。
#####VBAの場合は以下のライブラリに参照設定していること
Microsoft Office 2016 Access database engine object Library
C:\Program Files\Common Files\Microsoft Shared\Office16...
この先は読めない。どうも隠しフォルダのようだ。エクスプローラーで開いても見えない。
この参照設定で作成できる
そして以下のコードでE:\にtest36.mdbができる
このMDBファイルはAccess 2002-2003形式である

```vbnet:CreateDao36Db
Sub test()
Dim db As DAO.Database
Dim ws As DAO.Workspace
Dim DE As DAO.DBEngine
Set ws = DBEngine.Workspaces(0)
Const DbName = "E:\test36.mdb"
ws.CreateDatabase DbName, dbLangJapanese, dbVersion40
End Sub
```
####Access2016 AdoxでできるMDBファイル
#####次のAdoxへの参照設定がカギである
Microsoft ADO Ext. 6.0 for DDL and Security
C:\Program Files\Common Files\System\ado\msadox.dll
#####そのうえで以下のコードを実行する
上記のDaoより時間がかかる
しかしAccess2007-2016形式のmdbファイルが作成される

```vbnet:adoxtest2016
Sub adoxtest()
Dim Cat As ADOX.Catalog
Set Cat = New ADOX.Catalog
  Cat.Create "Provider= Microsoft.Ace.OLEDB.16.0;Data Source=F:\db216.mdb;Jet OLEDB:Encrypt Database=False;"
  Set Cat = Nothing
End Sub
```

Access2013

```vbnet:adoxtest2013
Sub adoxtest()
Dim Cat As ADOX.Catalog
Set Cat = New ADOX.Catalog
  Cat.Create "Provider= Microsoft.Ace.OLEDB.15.0;Data Source=F:\db213.mdb;Jet OLEDB:Encrypt Database=False;"
  Set Cat = Nothing
End Sub
```

####Access2016 64Bitのエラーの原因をみていく
#####DAO
dbVersion40はdbVersion36のようにそれ以前のバージョンを指定するとエラーになる。
にすると「インストール可能なISAMドライバーが見つかりませんでした」
というエラーが出る。
しかし
[Access 2000 でファイルをインポート、エクスポート、またはリンクすると、エラー メッセージ "インストール可能な ISAM ドライバが見つかりませんでした" が表示されるか、一部のファイルの種類が表示されない](https://support.microsoft.com/ja-jp/help/209805/you-receive-a-could-not-find-installable-isam-error-message-or-some-file-types-are-missing-when-you-import-files,-export-files,-or-link-files-in-access-2000)
にあるようなレジストリ
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel
はJet以下がそもそもないためこのヘルプはWindows10では無効なようだ。
そこで、さらに手動で調べると、Windows10で以下が上記に対応するらしい
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Access Connectivity Engine\Engines\Jet 3.x
\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Access Connectivity Engine\ISAM Formats
このJet 3.ｘのレジストリの値からすると、C:\Program Files\Common Files\microsoft shared\OFFICE14\ACER3X.DLL
がJet臭いとしているが、参照設定はできない。
[Access 2013 で廃止、変更された機能](https://support.office.com/ja-jp/article/Access-2013-%E3%81%A7%E5%BB%83%E6%AD%A2%E3%80%81%E5%A4%89%E6%9B%B4%E3%81%95%E3%82%8C%E3%81%9F%E6%A9%9F%E8%83%BD-bc006fc3-5b48-499e-8c7d-9a2dfef68e2f)

>Jet 3.x IISAM ドライバーのサポートが削除されたのは、このドライバーが提供されなくなったためです。

また
[Microsoft Access データベース エンジン 2010 再頒布可能コンポーネントのインストール](https://support.microsoft.com/ja-jp/help/318161/-could-not-find-installable-isam-0x80004005-error-message-when-you-try-to-set-session-level-jet-properties)によって、Access2010の接続文字列Microsoft.Ace.OLEDB.12.0が使えるようになる。


#####ADOX
以下のような昔のADOXのVBAのコードの接続文字列ではJet.OLE.4.0というクラスがないというメッセージがでてエラーになる
[ADOX で Access97 の暗号化されたデータベースを作成するには？](http://www.gizcollabo.jp/vbtomo/log/archive/vbqanda2_158_4.html)
[ADOXを用いてAccess2000形式のデータベースを作成する](http://www.accessclub.jp/ado/adox/03.html)
"Provider=Microsoft.Jet.OLE.4.0;"DataSource=F:\Sample.mdb"
なのでMicrosoft.Jet.OLE.3.5.1などは当然だめで、書き換える必要がある。（下記[フィロの村](http://note.phyllo.net/?eid=1106279)参照）

####JET自体の対応はあるのだが再頒布可能コンポーネントが必要
Jet4.0の書き換えについては、
[64bit版Windowsでの「Microsoft.Jet.OLEDB.4.0」について](http://qiita.com/yaju/items/86314412741deb806366)
にあるように
Access2013以降の64bit版は
Microsoft Access データベース エンジン 2010 再頒布可能コンポーネントのインストールをインストールしたうえで書き換える。この場合64bitと32bit両方のドライバが必要となる。32bitと64bitを共存させること。


##まとめ
Microsoft Access データベース エンジン 2010 再頒布可能コンポーネントがインストールすると
Access2016 Access2013ともDaoを用いることでAccess 2002-2003のMDBファイルがつくれる
Access 2013 32BitではMSの公式のPowershellScriptを書き換えるとできる。しかしAccess2016 64bitではできない。
Access97形式のMDBファイルを作成する方法は見つからなかった。やはりISAMが削除された影響と考えられる。
ただしAccess97のMDBファイルを変換することはPowershellによって可能である。


###参考
#### Powershell Socript 元記事
[Hey, Scripting Guy! Windows PowerShell を使用して Office Access データベースを作成する方法はありますか](https://gallery.technet.microsoft.com/office/28a08699-7d60-492c-bc97-d6456a6c3739)
[Create Blank Access Database Using Powershell](https://stackoverflow.com/questions/25277690/create-blank-access-database-using-powershell)
この記事を作成したあとで実は同様のことがStackoverflowにあった。これからすると
Access 2010でも成功するようだ

#### 使用メソッド
[DBEngine.CreateDatabase メソッド (DAO)](https://msdn.microsoft.com/ja-jp/library/office/ff835033.aspx)
[Workspace.CreateDatabase メソッド (DAO)](https://msdn.microsoft.com/ja-jp/library/office/ff822832.aspx)
dbVwesion40 dbLangJapanese 等の変数はこのメソッドに解説がある

#####再配布可能コンポーネント関連
[Microsoft Access データベース エンジン 2010 再頒布可能コンポーネント ](https://www.microsoft.com/ja-jp/download/details.aspx?id=13255)
[64ビット版Windows環境に、32ビット版/64ビット版双方のMicrosoft Access ODBCドライバを共存させる方法 ](http://bitdatasci.blogspot.jp/2014/08/64windows3264microsoftccess-odbc.html)
#####DAO参照設定関連
[【VB6・VBAメモ】DAOの参照先(32bit/64bit)(mdb形式/accdb形式) - フィロの村note](http://note.phyllo.net/?eid=1106279)
>　Access2007以降、上記を残したまま、以下のライブラリが追加されました。
　「Microsoft Office XX.X Access Database Engine Object Library」
　※XX.XはExcelのバージョンで異なります。(2007→12.0, 2010→14.0, 2013→15.0)
> 「Microsoft DAO 3.6 Object Library」は、mdb形式への接続はAccessが32bitであれば動作するようですが、Accessが64bitだと動作しない(動作しないどころか参照の選択時にエラーとなる)ようです。
>　また、accdb形式への接続の場合も動作しないようです。
これらのような場合は「Microsoft Office XX.X Access Database Engine Object Library」へ参照を変更する必要がありそうです。
(こちらであれば全て動くようなので、むしろ早めに移行したほうが無難な気がします) 

##### Microsoft.Ace.OLEDB.12.0 は2007からのもの
[実行時にMicrosoft.ACE.OLEDB.12.0プロバイダーはローカルコンピュータに登録されていませんが出てしまう](https://social.msdn.microsoft.com/Forums/ja-JP/a65f43c4-a39b-4819-a0fe-1150badf6d7a/microsoftaceoledb120?forum=vbgeneralja)
[2007 Office system ドライバ: データ接続コンポーネント ](https://www.microsoft.com/ja-jp/download/details.aspx?id=23734)
Office 2007 用はこちらからダウンロードする それ以降は上記のものをダウンロードする
[sp_addlinkedserver (Transact-SQL)](https://docs.microsoft.com/ja-jp/sql/relational-databases/system-stored-procedures/sp-addlinkedserver-transact-sql)