意外と知られてない!?ExcelでTypeScriptライクなコードが書ける件

まえがき
みなさんこんにちは、こんばんは、最近は多忙で色々と手が回ってないつっちーです。今回は小ネタです。突然ですが、皆さんはExcelでTypeScriptライクなコードが書けることをご存知でしょうか。筆者は、というかDWSメンバーは普段Windows環境で業務を行うことが少ないためあまり知られていなかったのですが、そんな「Office スクリプト」のご紹介です。
Office スクリプト
皆さんご存知の、Microsoft 365のExcelで利用できる自動化ツールです。旧来であれば「VBA (Visual Basic for Applications)」などが該当すると思いますが、なんといっても「TypeScript」で記述できることが大きな特徴です。Windows/Mac版ともに対応していますが、ビジネスまたは教育機関向けのライセンスが必要となるため、個人端末などでは利用できない場合があるかもしれません。
いいところ
DWSはエンジニアリング組織であり、嗜みとしてTypeScriptぐらいは全員書くことができる(と信じたい)ため、学習コストはほぼゼロです。まだまだExcelでの作業文化は残っているため、Excel内のデータをデータベースに登録したい、テスト用のJSONデータに変換したい、などのニーズはちらほら散見されます。これまでは各プログラミング言語のライブラリを使用してExcelにアクセスしたりしていたのですが、Office スクリプトを使用することでExcel内で完結させることができます。これは地味に嬉しいです。
やってみる
ExcelのテーブルデータをJSONデータに変換してみます。ただし、列名が日本語のままだとプログラミング言語からは扱いにくいので英語名に置換します。
検証するテーブル

Officeスクリプトの作成
「自動化」タブから「新しいスクリプト」を選択します。

Excelを操作するための独自APIが提供されているため、その辺りのチュートリアルをさらっと読み、あとは普段通りに、あえてモダンな構文を盛り込んで違和感なく記述できるか検証してみました。
記述したコード
const sheetName = "ユーザ一覧"
const tableName = "ユーザリスト"
type User = {
id: string
name: string
email: string
created_at: string
}
const keyMap = new Map<string, string>()
keyMap.set("ユーザID", "id")
keyMap.set("ユーザ名", "name")
keyMap.set("メールアドレス", "email")
keyMap.set("登録日", "created_at")
function main(workbook: ExcelScript.Workbook): User[] {
const table = workbook.getWorksheet(sheetName).getTables()[0];
const texts = table.getRange().getTexts()
// 先頭行を取り出して置換
const titles = texts.shift();
const keys = titles.map(title => keyMap.get(title))
if (table.getRowCount() <= 0) {
console.log("no record")
return
}
// 賛否ありますがreduceでオブジェクトに変換
const users: User[] = texts.map(row => row.reduce((acc, col, i) => {
acc[keys[i]] = col
return acc
},{} as User))
console.log(JSON.stringify(users))
return users;
}
実行結果
ちゃんとできていますね。ただのTypeScriptなので当然ですね。
[
{
"id": "U0001",
"name": "john_doe",
"email": "john.doe@example.com",
"created_at": "2023/10/18"
},
{
"id": "U0002",
"name": "jane_smith",
"email": "jane.smith@example.com",
"created_at": "2023/10/18"
},
// ...
]
できなかったこと
Node.js
fs
モジュールなどでファイルに出力したいなと考えたのですがダメでした。Office スクリプトはブラウザベースで動作しているため当然と言えば当然です。
DOM
document.createElement("a")
などでダウンロードリンクを作ればファイル出力できるかもと考えましたが、こちらもダメでした。OfficeスクリプトはあくまでExcelワークブック上で動作しており、Webページそのものにはアクセスできないようです。(documentオブジェクト自体にアクセスできませんでした)
あとがき
普通にちゃんとTypeScriptを書くことができました。それが今回最大の収穫です。当たり前のことを言っていると思われるかもしれませんが、当たり前のことを当たり前にできるということは、とても大事なのです。これを機に、皆さんもExcel周りの地味タスクを効率化してみてはいかがでしょうか。