MS Accessがインストールされていない環境でaccdbファイルを作成する方法

コンピュータ

有料のMicrosoft Accessはインストールしませんが、無償のランタイムライブラリは必要です。

スクリプトを書いているとたまに保存したファイルの1行(1レコード)のみ更新したい場面に出合います。そう言った場合、私のつたない知識ではファイルを全て読み込み、該当行を編集し、全てのデータを上書き保存するしかありません。ファイルを追記する方法は知ってはいるのですが、更新する方法はいまだに知りません。SQLで言うところのUPDATEに当たる物があればと調べてはいますが、なかなか見つかりません。

もしかするとそんな方法は無いかもしれないので、いっそのことデータベースを導入するのも良いのではと試してみた次第です。

スクリプトから扱えて無償で使える小規模でスタンドアローンなデータベースと言えばSQLiteが思いつくのですが、私が使っているWindowsはMS社の製品、MS社のデータベースマネージメントシステムと言えばMicrosoft Accessですがこれは有料の商品です。
とはいえ私が必要なのはアプリケーションとしてのMS AccessではなくMS Accessのデータベース部分のみですので、こちらは無償のランタイムライブラリをインストールすることで利用することが出来ます。

x86(32bit)かx64(64bit)はインストールされるWindowsが32bitか64bitかで選べばよいかと思います。64bit版のWindowsにx86(32bit)をインストールも可能とは思いますが、その場合powershellのx86(32bit)を起動しその中で利用することになります。普通はそのような組む合わせを好んでする必要は無いのですが、既存環境がWindowsが64bit版でMS Officeが32bit版がインストールされている場合がありますので、その場合も同様にpowershell側をofficeに合わせてx86(32bit)から利用する必要があります。

サンプルスクリプト

<#
.SYNOPSIS
ADOのテスト

.DESCRIPTION
データベースの作成、テーブルの作成、追加、更新、削除、参照

#>

$ErrorActionPreference = "STOP"

# accdbの場合
$fileName = Join-Path ([Environment]::GetFolderPath('MyDocuments')) "\t.accdb" 
$connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$fileName" 

# mdbの場合
#$fileName = Join-Path ([Environment]::GetFolderPath('MyDocuments')) "\t.mdb" 
#$connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=$fileName" 



# 既存の場合データベースの削除
$fileName | ? { Test-Path -LiteralPath $_ } | % { rm $_ }

# データベースの作成
$catalog = New-Object -ComObject "ADOX.Catalog" 
$db = $catalog.Create($connectionString) 
$db.Close()


# データベースへ接続
$connection = New-Object -ComObject "ADODB.Connection" 
$connection.Open($connectionString) 

# テーブルの作成
$sql = @"
CREATE TABLE MASTER (
  ID  Text(50)
, Name Text
, Pay Currency
, Height Double
, Birth Date 
, Married YesNo
,PRIMARY KEY (
  ID
 )
);
"@
$connection.Execute($sql) | Out-Null

# レコードの追加
$sql = @"
INSERT INTO MASTER VALUES (
  '0001'
, '岳 義人'
, 123456789
, 173.5
, #2000/12/01# 
, -1
);
"@
$connection.Execute($sql) | Out-Null
$sql = @"
INSERT INTO MASTER VALUES (
  '0002'
, '阿久沢 一'
, 824
, 165.5
, #1999/06/01# 
, 0
);
"@
$connection.Execute($sql) | Out-Null

$sql = @"
INSERT INTO MASTER VALUES (
  '0003'
, '陣内 保奈美'
, 300000
, 170.5
, #2001/06/21# 
, -1
);
"@
$connection.Execute($sql) | Out-Null

# レコードの更新
$sql = @"
UPDATE Master SET
 Name = '御嵩 義人'
WHERE
 ID = '0001'
;
"@
$connection.Execute($sql) | Out-Null

# レコードの削除
$sql = @"
DELETE FROM Master WHERE ID = '0002'
"@
$connection.Execute($sql) | Out-Null

# レコードの参照
$sql = @"
SELECT ID, Name FROM Master
"@
$connection.Execute($sql) | % {
    while ($false -eq $_.EOF) {
        $_.Fields['ID'].Value
        $_.Fields['Name'].Value
        $_.MoveNext()
    }
}


# データベースを閉じる
$connection.Close()

とりあえずデータベースの作成というか空のt.accdbファイルをDocumetnsフォルダに作成します。
Masterと言う名前のテーブルを作り、3件レコードを追加して、内1件の名前(Name)を変更し、1件レコードを削除し、その後のMasterテーブルの中身を参照するサンプルです。とりあえず個人的にこれだけ出来れば大体の要件は足ります。

久々にADOを触りましたが、.MoveNextと.EOFあたりが歴史と伝統を感じさせます。今時のやり方があるのかもしれませんが、とりあえずこれでも動くので良しとします。

コメント