Access 2013 Later Make Access 97 mdb Access 2013以降で Access97 のMDBファイルを作る

#Settings
Disk Drive Letter
ON Such 1TB HDD enough space have, In This article Drive E: ,we use Root Folder E:\
And All File make back up.
We make Access 97/95 File.
E:\TEST97.MDB
Database Language
Const DB_LANG_JAPANESE = ";LANGID=0x0411;CP=932;COUNTRY=0"
Because Test adding Records are Japanese
But If you always only use Engilsh
Const DB_Lang_Global = ";LANGID=0x0409;CP=1252;COUNTRY=0"
And Access 2.0 earlier DB_Lang_Japanese occur error
And Convert Access 2003-2002 MDB File
E:\test2000_2003.mdb
Make Access 97/95 mdb File
Source accdb whitch You want to copy Table
E:\2017AC2013.accdb (Access 2013 accdb file)
Source Table Name
H27Copy on E:\2017AC2013.accdb (You make this table and make some record on H27Copy. Data Type see H27CopyC)
H27Copy and H27CopyC Table Field Name and Data Type
Field Name Type
F01 Integer
F02 Integer
F03 TEXT(255)
F04 TEXT(255)
F10Name TEXT(255)
F11Duration TEXT(255)

#設定
まず余裕のあるハードディスクを用意しましょう。複数のファイルをつくりますし、最適化（Compact）でファイルサイズが増大することがあります。なおAccess97の最大ファイルサイズは1GBです。なのでもとのファイルは500MB以下にしましょう
E:\のルートを使用します
必ずバックアップファイルを作成してください。
作成するAccess97/95ファイル名は
***E:\TEST97.MDB***
データベースの作成言語はdbLangJapaneseにします。これは作成するテーブルに日本語が入っているためです。
***Const DB_LANG_JAPANESE = ";LANGID=0x0411;CP=932;COUNTRY=0"***
ただし、日本語が入ったテーブルを作成しない場合、Access1.1/1.0ファイルは日本語が使用できないので全般設定を使います。Access2.0以前ではエラーが発生してデータベースが作れません。
***Const DB_Lang_Global = ";LANGID=0x0409;CP=1252;COUNTRY=0"***
次にAccess97/95のMDBファイルはAccess2013では開けません。このためAccess2003-2002のMDBファイルに変換します。このファイル名を
***E:\test2000_2003.mdb***
とします。
さらにAccess97/95に移行したいテーブルがあるaccdbファイルを
***E:\2017AC2013.accdb ***
そして2017AC2013.accdbの移行したいテーブルの名前を
***H27Copy***
TEST97.MDBに作りたいテーブルの名前を
***H27CopyC***
とします
H27Copy と H27CopyC のテーブルのフィールド名とデータタイプを次のようにします。
Field Name Type
F01 Integer
F02 Integer
F03 TEXT(255)
F04 TEXT(255)
F10Name TEXT(255)
F11Duration TEXT(255)
# Script
Make DB VbScript
%USERPROFILE%\Documents\Myscript\gendaodb2.vbs
Convert Db VBSCRIPT
%USERPROFILE%\Documents\Myscript\JetCompact.vbs

#スクリプト名とファイルの場所
データベースを作るスクリプトはDocument\MyScript\gendaodb2.vbs
%USERPROFILE%\Documents\Myscript\gendaodb2.vbs
変換するスクリプトJetCompact.vbs
%USERPROFILE%\Documents\Myscript\JetCompact.vbs
#Script Step And Point
Step 1 Setting is OK? Customize You want. But Custmaize accuracy.
Step 2 2 VBSCRIPT run 32 bit Cscript
CMD.exe and Show Command Prompt
%SystemRoot%\SysWow64\CScript.EXE "%USERPROFILE%\Documents\Myscript\gendaodb2.vbs"
Step 3 gendaodb2.vbs Make Db File (DbLangJapanese and Jet 3.0/3.5 Access 97/95) >>> Make Table on db File >>> Recordset make >>>make table on db >>> addnew
From Creating Database to "Set db = nothing" , we can make new table on Access97/95 File. Even Access 1.0 is enable.
Step 4 Command Prompt %SystemRoot%\SysWow64\cscript.exe "%USERPROFILE%\Documents\MyScript\JetCompact.vbs"
Step 5 E:\test2000_2003.mdb click and open with Access 2010 Lager 64/32 bit and recognize H27CopyC table have records

Remark If you not want to make sell table, You cut Lines
#スクリプトの流れとポイント
1.設定を確認してください。実際に変換したいファイルがあれば変えてもいいですが、正確に変更してください。
2.VBScriptは全て32Bitでしか動作しません。64ビットではエラーになります。
CMD.EXEよりコマンドプロンプトを起動し
%SystemRoot%\SysWow64\CScript.EXE "%USERPROFILE%\Documents\Myscript\gendaodb2.vbs"
と入力します
3.するとDBを作成しテーブルを作り、Accdbのテーブルに接続してレコードセットを作り、データを流し込みます。
つまり　Set Db　から　Db=Nothingまでの間はVersion97以前のファイルでもテーブル、クエリも作成できます。
4.しかし出来上がったファイルはそのままではAccess2013等では開けないので
コマンドプロンプトよりJetCompact.vbsで変換します
%SystemRoot%\SysWow64\cscript.exe "%USERPROFILE%\Documents\MyScript\JetCompact.vbs"
5.出来上がったE:\test2000_2003.mdbを開いて、中を確認してください。

#スクリプト/Script

###GenDaoDB2.vbs
にほんごのテーブルが不要な時はCut Line StartからEndの間の行を削除してください。

```vbnet:GenDaoDB2.vbs
Main
Sub Main()
'http://kazu-riders.blog.so-net.ne.jp/2009-03-27
'%SystemRoot%\SysWow64\cscript.exe "%USERPROFILE%\Documents\MyScript\gendaodb2.vbs"
'Access 2013 Later
'64 / 32 Ok
'
' Block OF Constitution And Variant
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 = "E:\"
Const FILE_NAME = "TEST97.mdb"
Const cnsDbVersion30_AC95_AC97_Jet30_Jet35 = 32
Const cnsDbVersion20_AC20_Jet20 = 16
Const cndDBVerion10 =1
Const dbn ="e:\2017AC2013.accdb"
Dim sdb ' As DAO.Database
Dim DE
Set DE = WScript.CreateObject("DAO.DBEngine.120")
set sdb= De.OpenDatabase("E:\2017AC2013.accdb")
Dim srs,rst 'As DAO.Recordset
Dim sSQL 'As String
Dim i
Dim dbe, db, strDbPath
Dim dbe2 : Set dbe2 = CreateObject("DAO.DBEngine.36")
Dim wsh: Set wsh = CreateObject("Wscript.Shell")
' MDB is Already?
With CreateObject("Scripting.FileSystemObject")
If .FileExists(DRIVE_NAME & FILE_NAME) = True Then
MsgBox DRIVE_NAME & FILE_NAME & " is already made. Vbscript end", vbOKOnly + vbInformation, "There is file."
Exit Sub
End If
End With
' MDB Start Making...
Set dbe = CreateObject("DAO.DBEngine.36")
Set db = dbe.CreateDatabase(DRIVE_NAME & FILE_NAME, _
DB_LANG_JAPANESE, cnsDbVersion30_AC95_AC97_Jet30_Jet35)
' Start making table on Table
'''''''''''''''''''''''''''''''''''''''Cut Line Start
db.Execute "CREATE TABLE Sell_Table " _
& "(SellCode AUTOINCREMENT " _
& "CONSTRAINT PrimaryKey PRIMARY KEY, " _
& "Branch TEXT(255), " _
& "SaleDate DATETIME, " _
& "Goods TEXT(255), " _
& "Quantity INTEGER, " _
& "SalesRevenu CURRENCY);"
db.Execute "CREATE INDEX SaleDate " _
& "ON Sell_Table (SaleDate) WITH DISALLOW NULL;"
' Add New Record
GenRecs db.OpenRecordset("Sell_Table", _
DB_OPEN_DYNASET, _
DB_APPEND_ONLY)
'''''''''''''''''''''''''''''''''''''''Cut Line End
'Second Table Make From accdb File
db.Execute "CREATE TABLE H27CopyC " _
& "(F01 INTEGER, " _
& "F02 INTEGER, " _
& "F03 TEXT(255), " _
& "F04 TEXT(255), " _
& "F10Name TEXT(255), " _
& "F11Duration TEXT(255));"

set srs = db.Openrecordset("H27CopyC",DB_OPEN_DYNASET, _
DB_APPEND_ONLY)
set rst = sdb.OpenRecordset("H27Copy")

Do while rst.eof=False
srs.Addnew
For i = 0 to srs.fields.count-1
srs.fields(i).Value = rst.fields(i).Value
Next
srs.update
rst.movenext
Loop


' Release Reference Object variant
db.Close: Set db = Nothing
sdb.close :set sdb=nothing
Set dbe = Nothing
Set DE =Nothing
' Nortify Result to User
MsgBox DRIVE_NAME & "to" & FILE_NAME _
& "' Making Finished", vbInformation
End Sub

Function GetUniqueDbName(filename)
' In Drive "test.mdb" is There?
' False Return FullPath
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 "Same name File on Detop" & "OR" & Ar(0) & "" & filename _
& "' Is ther" _
& vbCrLf & vbCrLf & "Script Quit Force", _
vbCritical
Else
GetUniqueDbName = strResult
End If
End Function

Sub GenRecs(rs)
' Last 30 days Test Record add
' initialize vaiant
varSites = Array("新宿", "渋谷", "池袋", "上野", "品川")
varProducts = Array("烏龍茶", "オレンジジュース", _
"グレープジュース", "コーヒー", "紅茶")
varPrices = Array(150, 250, 250, 180, 180)
' Add New Record
With rs
For i = Date - 30 To Date
For j = 0 To (Int(6 * Rnd) + 5)
.AddNew
.Fields("branch").Value = varSites(Int(5 * Rnd))
.Fields("SaleDate").Value = i + Rnd
intProdId = Int(5 * Rnd)
.Fields("Goods").Value = varProducts(intProdId)
.Fields("Quantity").Value = Int(10 * Rnd) + 2
.Fields("SalesRevenu").Value = .Fields("Quantity").Value _
* varPrices(intProdId)
.Update
Next
Next
End With
End Sub
```
###JetCompact.vbs

```vbnet:JetCompact.vbs
Option Explicit
'%SystemRoot%\SysWow64\CScript.EXE "%USERPROFILE%\Documents\Myscript\JetCompact.vbs"
'32 Bit Cscript.exe Force [WSHスクリプトを64/32bitが違っていたら起動し直す。](http://scripting.cocolog-nifty.com/blog/2011/02/wsh6432bit-b32d.html) 
If InStr(LCase(WScript.FullName),"syswow64") Then
  CreateObject("WScript.Shell").Run """" & Replace(LCase(WScript.FullName),"syswow64","sysnative") & """ """ & WScript.ScriptFullName & """"
  WScript.Quit
End If

Const oldFile = "E:\test97.mdb"
Const NewFile = "E:\test2000_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 =5;"
'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
```

#その他
###ADOとDAOのデータタイプの違い
[Access テーブルを作成および修正する](https://msdn.microsoft.com/ja-jp/library/cc376282.aspx)
DAO フィールドのデータ型名は、ADOX のデータ型名とは異なります。次は、Access ユーザー インターフェイスおよび DAO のデータ型と、ADOX データ型との対応表です。

|Access ユーザー インターフェイスのデータ型|DAO データ型|ADOX データ型|
|:----------------------------------------:|:----------:|:------------|
|Yes/No 型 |dbBoolean|adBoolean
|数値型 (FieldSize = バイト型) |dbByte|adUnsignedTinyInt|
|通貨型|dbCurrency|adCurrency |
|日付/時刻型 |dbDate|adDate|
|数値型 (FieldSize = 小数型) |dbDecimal|adDecimal|
|数値型 (FieldSize = Double) |dbDouble|adDouble|
|数値型またはオートナンバー型 (FieldSize = レプリケーション ID 型)|dbGUID|adGUID |
|数値型 (FieldSize = 整数型) |dbInteger |adSmallInt|
|数値型またはオートナンバー型 (FieldSize = 長整数型)|dbLong| adInteger |
|OLE オブジェクト型|dbLongBinary|adLongVarBinary |
|メモ型|dbMemo adLongVarWChar |
|数値型 (FieldSize = Single)|dbSingle|adSingle |
|テキスト型|dbText|adVarWChar |
|ハイパーリンク型|dbMemo、およびdbHyperlinkField に設定された DAO Attributes プロパティ|adLongVarWCharおよび Jet OLEDB:Hyperlink に設定された ADOX プロバイダ別 Column プロパティ |


###フィールドの属性およびプロパティを詳細設定する
フィールドのデータ型の指定に加え、フィールドを数値の自動追加型に設定する (Access ユーザー インターフェイスのオートナンバー型)、フィールドをアクティブになっているハイパーリンクの保存に使用する (Access ユーザー インターフェイスのハイパーリンク型) など、その他のフィールド属性も指定できます。DAO を使用して数値の自動追加型フィールド、またはハイパーリンク型のフィールドを作成するときは、適切な定数をフィールドの Attributes プロパティに追加してください。ADOX で同じフィールドを作成するには、フィールド作成に使用する Column オブジェクトの Properties コレクションで適切なプロパティを設定します。次のコードでは、フィールドの AutoIncrement プロパティを True に設定し、ADOX で数値の自動追加型フィールドを作成する方法を説明します。

```vbnet:CreateAutoNumberField
Sub CreateAutoNumberField(strDBPath As String)
Dim catDB As ADOX.Catalog
Dim tbl As ADOX.Table

Set catDB = New ADOX.Catalog
' カタログを開きます。
catDB.ActiveConnection = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & strDBPath

Set tbl = New ADOX.Table
With tbl
.Name = "Contacts"
Set .ParentCatalog = catDB
' フィールドを作成し、新規の Table
' オブジェクトの Columns コレクションに関連付けます。
With .Columns
.Append "ContactId", adInteger
' ContactId フィールドをオートナンバー型に設定します。
.Item("ContactId").Properties("AutoIncrement") = True
.Append "CustomerID", adVarWChar
.Append "FirstName", adVarWChar
.Append "LastName", adVarWChar
.Append "Phone", adVarWChar, 20
.Append "Notes", adLongVarWChar
End With
End With

' データベースの Tables コレクションに新規 Table を追加します。
catDB.Tables.Append tbl

Set catDB = Nothing
End Sub
```
次は、フィールドの DAO Attributes プロパティの定数と、数値の自動追加型フィールドの ADO プロバイダ別 Column プロパティ、およびその他の対応表です。

|Access ユーザー インターフェイスのデータ型|DAO Attributes プロパティ定数 | ADOX プロバイダ別 Column プロパティ |
|:-----------------------------------------|:------------------------------:|:-----------------------------------|
|オートナンバー型 |dbAutoIncrField |AutoIncrement True に設定|
|Numeric フィールドの既定値 (Text フィールドのユーザー インターフェイスからは使用不可)|dbFixedField|ColumnAttributes adColFixed に設定|
|ハイパーリンク型 |dbHyperlinkField |Jet OLEDB:Hyperlink True に設定(Memo フィールドのみ? adLongVarWChar データ型) |
| 該当なし |dbSystemField |該当なし |
|Text フィールドの既定値 |dbVariableField |ColumnAttributes / Not adColFixed に設定 |