LoginSignup
0
0

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-07-02

訂正

この記事ではaccdbがうごかせませんでしたが、実は方法がありました
[VBS32]Access2013 Later 64/32 Access97形式mdbにテーブルをコピーする をご覧ください。

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 のみでいくタイプ

C
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を使うタイプ

C
'%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

C
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

C
'%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)
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 エラーが発生した場合、更新をロールバックします。
dbInconsistent 16 他のレコードに影響が及ぶ場合でも、すべてのダイナセット フィールドに更新を適用します (ダイナセット タイプとスナップショット タイプのみ)。dbConsistentと同時使用不可。
dbReadOnly 4 Recordset を読み取り専用として開きます。LockEdit指定不可。
dbRunAsync 1024 クエリを非同期で実行します。
dbSeeChanges 512 編集中のデータを別のユーザーが変更している場合、実行時エラーを生成します (ダイナセット タイプのみ)。
dbSQLPassThrough 64 ODBC データベースに SQL ステートメントを送信します (スナップショット タイプのみ)。

LockTypeEnum
レコードセットを開くときに使用されるレコード ロックの種類を指定します。

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