[VBS]Access2016 +64 bit Access97のテーブルとAccess2000/2003形式MDBのテーブルでデータを交換する

#訂正
この記事ではaccdbがうごかせませんでしたが、実は方法がありました
[[VBS32]Access2013 Later 64/32 Access97形式mdbにテーブルをコピーする](http://qiita.com/Q11Q/items/0ada315f6b5eb9b14f8b) をご覧ください。
#VBScript
C\hoge\DB97conDB.VBS
F:\TESTType97.mdbを
F:\TESTType10_2000.mdb
のTestTypeというテーブルに値を追加します。
必ず32Bitで起動します。CMD.exeでコマンドプロンプトをたちあげて
%SystemRoot%\SysWow64\cscript.exe //Nologo "C:\hoge\DB97ConDB.vbs"
を入力します。
###Set RS のみでいくタイプ
```vbnet:C:\hoge\DBConDB.vbs
Const DN= "F:\"
Const FN = "TESTType97.mdb"
Const FO = "test10_2000.mdb"
Const ForReading = 1
Const adOpenDynamic= 2 '動的カーソルレコードセットの全ての方向に移動することができます。他のユーザーが追加、更新、削除したレコードも参照することができます。
Const adLockOptimistic = 2 'レコード単位で共有的ロックを行います。Updateメソッドを呼び出した場合にのみ、共有的ロックします。

Dim dbe
Dim db120
Dim db
Dim db1
Dim rs
Dim fld
Dim i
Dim conn : Set conn = CreateObject("Adodb.connection")
Dim aRS : Set aRS =  CreateObject("Adodb.RecordSet")
Set dbe = CreateObject("DAO.DBEngine.36"): Set db = dbe.OpenDatabase(DN & FN):Set rs = db.OpenRecordset("SELECT * From TestType")
 conn.Open "Provider = Microsoft.JET.OLEDB.4.0; " & "Data Source = " & DN & FO & ";"
 aRS.Open "Select * From TestType" , conn,  adOpenDynamic, adLockOptimistic
rs.MoveFirst
aRS.MoveLast
do while rs.eof =false
aRS.addnew
For i = 0 To rs.Fields.count-1
Wscript.Echo rs.Fields(i).Name & ":::" & rs.fields(i).value
aRS.fields(i).value=rs.fields(i).value
Next
Wscript.Echo "-----"
rs.MoveNext
aRS.update
Loop
aRs.Close
db.close
```
###Adodbを使うタイプ
```vbnet:C:\hoge\DB97ConDB.vbs
'%SystemRoot%\SysWow64\cscript.exe //Nologo "C:\hoge\DB97ConDB.vbs"
Const DN= "F:\"
Const FN = "TESTType97.mdb"
Const FO = "test10_2000.mdb"

Dim dbe
Dim db1
Dim db
Dim dbf
Dim rs
Dim fld
Dim i
Dim Rst
Dim conn : Set conn = CreateObject("Adodb.connection")
Dim aRS : Set aRS =  CreateObject("Adodb.RecordSet")
Set dbf = CreateObject("DAO.DBEngine.36"): Set db1 = dbf.OpenDatabase(DN & FO):Set Rst = db1.OpenRecordset("SELECT * From TestType")
Set dbe = CreateObject("DAO.DBEngine.36"): Set db = dbe.OpenDatabase(DN & FN):Set rs = db.OpenRecordset("SELECT * From TestType")
 conn.Open "Provider = Microsoft.JET.OLEDB.4.0; " & "Data Source = " & DN & FO & ";"
rs.MoveFirst
do while rs.eof =false
Rst.addnew
For i = 0 To rs.Fields.count-1
Wscript.Echo rs.Fields(i).Name & ":::" & rs.fields(i).value
rst.fields(i).value=rs.fields(i).value
Next
Wscript.Echo "-----"
rs.MoveNext
RST.update
Loop
rst.Close
db.close
```
###Access2003形式MDBからAccess97形式mdb
```vbnet:C:\hoge\DB97ConDB.vbs
Const DN= "F:\"
Const FN = "TESTType97.mdb"
Const FO = "test10_2003.mdb"

Dim dbe
Dim db1
Dim db
Dim dbf
Dim rs
Dim fld
Dim i
Dim Rst
Dim conn : Set conn = CreateObject("Adodb.connection")
Dim aRS : Set aRS =  CreateObject("Adodb.RecordSet")
'Set dbf = CreateObject("DAO.DBEngine.36"): Set db1 = dbf.OpenDatabase(DN & FO):Set Rst = db1.OpenRecordset("SELECT * From TestType")
Set dbe = CreateObject("DAO.DBEngine.36"): Set db = dbe.OpenDatabase(DN & FO):Set rs = db.OpenRecordset("SELECT * From TestType")
'Db.Execute("Delete * From TestType")
DIm  objConnection :Set objConnection = CreateObject("ADODB.Connection") 
Dim  objRecordSet : Set objRecordSet = CreateObject("ADODB.Recordset") 

objConnection.Open "Provider = Microsoft.Jet.OLEDB.4.0; " & _ 
        "Data Source = F:\TESTType97.mdb"
objRecordSet.Open "SELECT * FROM TestType", objConnection,2,2 
rs.movefirst
do while rs.eof =false
objRecordSet.addnew
For i = 0 To rs.Fields.count-1
Wscript.Echo objRecordSet.Fields(i).Name & ":::" & rs.fields(i).value
objRecordSet.fields(i).value=rs.fields(i).value
Next
Wscript.Echo "-----"
rs.MoveNext
objRecordSet.update
Loop
objRecordSet.Close
rs.close
```
###Access97形式からAccess2003
```vbnet:C:\hoge\DB97ConDB.vbs
'%SystemRoot%\SysWow64\cscript.exe //Nologo "C:\hoge\DB97ConDB.vbs"
Const DN= "F:\"
Const FN = "TESTType97.mdb"
Const FO = "test10_2003.mdb"

Dim dbe
Dim db
Dim rs
Dim i
Dim Rst
Dim conn : Set conn = CreateObject("Adodb.connection")
Dim aRS : Set aRS =  CreateObject("Adodb.RecordSet")
Set dbe = CreateObject("DAO.DBEngine.36"): Set db = dbe.OpenDatabase(DN & FO):Set rs = db.OpenRecordset("SELECT * From TestType")
'Db.Execute("Delete * From TestType")
DIm  objConnection :Set objConnection = CreateObject("ADODB.Connection") 
Dim  objRecordSet : Set objRecordSet = CreateObject("ADODB.Recordset") 

objConnection.Open "Provider = Microsoft.Jet.OLEDB.4.0; " & _ 
        "Data Source = " & DN & FO & ";"
objRecordSet.Open "SELECT * FROM TestType", objConnection,2,2 
objRecordSet.movefirst
do while objRecordSet.eof =false
'objRecordSet.addnew
rs.addnew
For i = 0 To rs.Fields.count-1
rs.fields(i).value = objRecordSet.fields(i).value
Next
rs.update
objRecordSet.MoveNext
Loop
objRecordSet.Close
rs.close
```

#Accss2016 Accdbファイルに移行するにはどうするか。
1.まずAccess97のMDBファイルとAccess2016のaccdbファイルにともにテーブルを作ります。
2.これはデータ型を合わせます。
3.これはSQLで作った方が自由度は低いものの確実に同じものが作れるのでそれで作るとよいと思います。
4.***Access2016 の accdbファイルを2003mdbまたは2000mdb形式に変換して保存します。***
5. 上記のVBSのいずれかをファイル名、テーブルを合わせて実行します。
6. できたファイルをAccess2016によってAccdbに戻します

#処理の理由
 - vbscriptを32bitで動かすと、Dao3.6は使えますがDao120は使えません（エラーになる）
 - 2016形式Accdbは64Bitで処理されているらしく32BitVBSでは接続しません。
 - よって直接変換することはあきらめてAccess2000/2003形式MDBに一度変換し、Access97のデータを吸い出した後に、Access2016形式accdbにすることが良いようです。
 - この方法だとMicrosoft.OLEDB.12.0を使用する必要がありません。なのでAccess2010の再頒布版のインストールなしで変換できます。


#このスクリプトの必要性
1.  以前のシリーズと合わせると、***Microsoft Access データベース エンジン 2010 再頒布可能コンポーネントは不要***である。ということができます。Access2000形式まではVBS32Bit Dao36　Jet　Access2003形式ならAdodb Jet で処理できるからです。またAccess97以前のファイルもAccess2000までは再頒布可能コンポーネントなしで変換できます。
2.  また何らかの事情でAccess97形式MDBとAccess2016形式Accdbのデータベースを共通化させたい場合はAccess2000/2003形式のMDBを介してデータのやり取りは可能であるということがわかりました。
3.  したがって中間ファイルであるAccess2003/Access2000形式MDBに変換できるかどうかが共有するカギとなります。この形式のファイルは64ビットAccessにおいて32/64が関係なくDao-JetまたはAdodb-Jetの組み合わせで扱うことができるためです。
4.  データの交換はデータ形式が共通（添付ファイルなし、ルックアップフィールドなし）、文字コードが問題なしでSQLとテーブルのみに限った話です。マクロ等は実行すらできないので不明です。

###DAO.OpenRecordSet定数
[Database.OpenRecordset メソッド (DAO)](https://msdn.microsoft.com/ja-jp/library/office/ff820966.aspx)
 databaseの変数.OpenRecordset(Name, Type, Options, LockEdit)
 Name Microsoft Office Access データベース エンジンのデータベースに含まれるテーブル タイプの Recordset オブジェクトの場合は、テーブル名でのみ指定できます。
 Type 開く Recordset の型を示す RecordsetTypeEnum 定数。 指定しないときはテーブルタイプ。リンクされたテーブルまたはクエリを指定した場合、Dynaset を作成します

 |定数|値|説明|
 |:-------------:|:---:|:-----------------------------------------|
 | dbOpenDynamic| 16  |ダイナセット タイプの Recordset を開きます。|
 | dbOpenDynaset |2  |ダイナセット タイプの Recordset を開きます。|
 |dbOpenForwardOnly|8|前方スクロール タイプの Recordset を開きます。|
 |dbOpenSnapshot |4  |スナップショット タイプの Recordset を開きます。|
 |dbOpenTable|1|テーブル タイプの Recordset を開きます。 |

Options
dbConsistent 定数と dbInconsistent 定数は互いに排他的なので、この 2 つを同時に使用するとエラーになります。Options で dbReadOnly 定数を使用する場合に LockEdit 引数を指定してもエラーになります。

|名前|値|説明|
|:-------------:|:---:|:-----------------------------------------|
|dbAppendOnly|8|***ユーザーが新しいレコードをダイナセットに追加するのを許可しますが、既存のレコードを読み取ることは許可しません。***|
|dbConsistent|32|ダイナセット内の他のレコードに影響を与えないフィールドにのみ更新を適用します (ダイナセット タイプとスナップショット タイプのみ)。dbInconsistentと同時使用不可。|
|dbDenyRead|2|他のユーザーが Recordset のレコードを読み取れないようにします (テーブル タイプのみ)。|
|dbDenyWrite|1|他のユーザーが Recordset のレコードを変更できないようにします。|
|dbExecDirect2048|SQLPrepare ODBC 関数を最初に呼び出さずに、クエリを実行します。|
|dbFailOnError|128|エラーが発生した場合、更新をロールバックします。|dbForwardOnly|256|前方スクロールのみのスナップショット タイプ Recordset を作成します (スナップショット タイプのみ)。|
|dbInconsistent|16|他のレコードに影響が及ぶ場合でも、すべてのダイナセット フィールドに更新を適用します (ダイナセット タイプとスナップショット タイプのみ)。dbConsistentと同時使用不可。|
|dbReadOnly|4|Recordset を読み取り専用として開きます。LockEdit指定不可。|
|dbRunAsync|1024|クエリを非同期で実行します。|
|dbSeeChanges|512|編集中のデータを別のユーザーが変更している場合、実行時エラーを生成します (ダイナセット タイプのみ)。|
|dbSQLPassThrough|64|ODBC データベースに SQL ステートメントを送信します (スナップショット タイプのみ)。|

[LockTypeEnum](https://msdn.microsoft.com/ja-jp/library/office/ff834802.aspx)
レコードセットを開くときに使用されるレコード ロックの種類を指定します。

|名前|値|説明|
|:-------------:|:---:|:-----------------------------------------|
|dbOptimistic|3|レコード ID に基づく共有的同時ロック。カーソルは古いレコードと新しいレコードのレコード ID を比較し、そのレコードへのアクセスが最後に行われてから変更が加えられたかどうか判断します。|
|dbOptimisticBatch|5|共有的バッチ更新を可能にします (ODBCDirect ワークスペースのみ)。|
|dbOptimisticValue|1|レコード値に基づく共有的同時ロック。カーソルは古いレコードと新しいレコードのデータ値を比較し、そのレコードへのアクセスが最後に行われてから変更が加えられたかどうか判断します (ODBCDirect ワークスペースのみ)。Microsoft Access 2013 では、ODBCDirect ワークスペースはサポートされていません。Microsoft Access データベース エンジンを使用しないで外部データ ソースにアクセスする場合は、ADO を使用してください。|
|dbPessimistic|2|排他的同時ロック。カーソルは、レコードが更新可能であることを保証するために必要な最低限のロックを使用します。 |