4
2

More than 3 years have passed since last update.

node.jsからADO(ActvieX Data Object)を利用する方法

Last updated at Posted at 2021-05-19

前書き

  • 10年ぶりにWSHを利用したところ、ふとTypeScript(node.js)からActiveXを呼び出すことはできないのだろうか?と気になったため調査しました。

    • node.jsからActiveXを呼び出す機能を持つライブラリはあるのか?
    • ライブラリがあるなら、TypeScriptでも使えるのではないか?
    • TypeScriptから利用できるのであれば、ADOの型定義も誰か作っているのではないか?

調査結果

node.jsからActiveXオブジェクトを生成して呼び出すことは可能(winax)でした。

  • node.jsでActiveXを呼び出すことが可能なライブラリ「winax」を使う
  • TypeScript用の型定義もnpmに用意されている

    • @types/activex-adodb
    • @types/activex-adox
  • winaxは、WScriptランタイムのエミュレーションも可能

1:javascript(node)でADOを利用

  • winaxをインストール
npm i winax

javascriptでADOを利用するサンプル( mdb.js)

/**
 * node.jsでADOを利用してAccessのmdbファイルを利用するサンプル
 */
const fs = require('fs');
const path = require('path'); 
require('winax');  // npm i winax

// MDBファイルを作成する
// 要 Microsoft Access Database Engine 2016 Redistributable
// https://www.microsoft.com/en-us/download/details.aspx?id=54920
const filename = 'persons.mdb';
const data_path = path.join(__dirname, '/data/', filename);

// ファイルがあれば削除
if (fs.existsSync(data_path)) {
  fs.unlinkSync(data_path);
}

const constr = `Provider=Microsoft.ACE.OLEDB.12.0;Data Source=${data_path}`;
const cat = new ActiveXObject('ADOX.Catalog');
cat.Create(constr);
const con = cat.ActiveConnection;
try {
  // データ登録
  con.Execute('create Table persons (Name char(30), City char(30), Phone char(20), Zip decimal(5))');
  con.Execute("insert into persons values('John', 'London','123-45-67','14589')");
  con.Execute("insert into persons values('Andrew', 'Paris','333-44-55','38215')");
  con.Execute("insert into persons values('Romeo', 'Rom','222-33-44','54323')");

  // selectした結果を表示
  const rs = con.Execute('Select * from persons'); 
  const fields = rs.Fields;
  console.log(`Result field count: ${fields.Count}`);

  while (!rs.EOF) {
      // Access as property by string key
      const name = fields['Name'].Value;  
      // Access as method with string argument
      const town = fields('City').value;
      // Access as indexed array
      const phone = fields[2].value;
      // Access recordset
      const zip = rs[3].value;    

      console.log(`> Person: ${name} from ${town} phone: ${phone} zip: ${zip} `);
      rs.MoveNext();
  }
} finally {
  con.Close();
}

実行と確認(javascript)

ADOでデータ登録、取得が出来ていることを確認

> node mdb.js

Result field count: 4
> Person: John                           from London                         phone: 123-45-67            zip: 14589
> Person: Andrew                         from Paris                          phone: 333-44-55            zip: 38215
> Person: Romeo                          from Rom                            phone: 222-33-44            zip: 54323

2:TypeScript(node)でADOを利用する

typescriptと型定義をインストールしてから初期化(ts-config生成)

npm i typescript -D
npm i ts-node
npm i @types/node @types/activex-adodb @types/activex-adox -D

npx tsc -init

コンパイルが面倒なので、ts-nodeをインストールする(typescriptをコンパイルせずに実行できる)

typescriptに書き直したソース(mdb.ts)

  • ADODB.Recordsetなどで型指定行われるため、コーディングが楽になります
/**
 * node(typescript)でADOを利用してAccessのmdbファイルを利用するサンプル
 */
import fs from 'fs';
import path from 'path';

require('winax');  // npm i winax

// MDBファイルを作成する
// 要 Microsoft Access Database Engine 2016 Redistributable
// https://www.microsoft.com/en-us/download/details.aspx?id=54920
const filename = 'persons.mdb';
const data_path = path.join(__dirname, '/data/', filename);

// ファイルがあれば削除
if (fs.existsSync(data_path)) {
  fs.unlinkSync(data_path);
}

// mdbファイルを作成するため「ADODB.Connection」ではなく「ADOX.Catalog」を利用する
const constr = `Provider=Microsoft.ACE.OLEDB.12.0;Data Source=${data_path}`;
const cat: ADOX.Catalog = new ActiveXObject('ADOX.Catalog');
cat.Create(constr);
const con = cat.ActiveConnection as ADODB.Connection;

try {
  // データ登録
  con.Execute('create Table persons (Name char(30), City char(30), Phone char(20), Zip decimal(5))');
  con.Execute("insert into persons values('John', 'London','123-45-67','14589')");
  con.Execute("insert into persons values('Andrew', 'Paris','333-44-55','38215')");
  con.Execute("insert into persons values('Romeo', 'Rom','222-33-44','54323')");

  // selectした結果を表示
  const rs: ADODB.Recordset = con.Execute('Select * from persons'); 
  console.log(`Result field count: ${rs.Fields.Count}`);

  while (!rs.EOF) {
    // 型指定の都合でrs.Fields['Name'] はコンパイルエラー
    const name = rs.Fields('Name').Value;  
    const town = rs.Fields('City').Value;
    const phone = rs.Fields(2).Value;
    const zip = rs.Fields(3).Value;    

    console.log(`> Person: ${name} from ${town} phone: ${phone} zip: ${zip} `);
    rs.MoveNext();
  }
} finally {
  con.Close();
}

実行と確認(typescript)

ADOでデータを登録、取得が出来ていることを確認

> ts-node mdb.ts

Result field count: 4
> Person: John                           from London                         phone: 123-45-67            zip: 14589
> Person: Andrew                         from Paris                          phone: 333-44-55            zip: 38215
> Person: Romeo                          from Rom                            phone: 222-33-44            zip: 54323
4
2
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
4
2