ExcelやNumbersで使われているセルのアドレス表記方法「A1形式」と数値の相互変換を行うAppleScriptです。
一応、自分でも昔に書いたルーチンを使い回していますが、26進数と10進数との間の変換で桁が増えたときの処理に難があって、上限値を設けてその間であれば変換できる、という感じになっていました。
もともと、このルーチンはExcel 2008でVBAの処理系を搭載しないことになったのを好機ととらえ、AppleScriptをエンコードしてExcelの隠しワークシート上に格納しておいて外部から実行する「ExcelAS」プロジェクトのために作成したものです。
実際に調布のMicrosoftでデモを行なって、US Microsoftに掛け合ってもらったものの、次バージョンでVBAの処理系を復活させることになって、(Visual BASIC互換の)「REALbasic」のエンジンを書いていたエンジニアをMSがヘッドハント。常識的に考えればVBAの廃止自体がおかしな決定だったので、その隙を狙えるかも? と企画して作ったものの、残念な結果になってしまいました。ただ、現在に至るもMac上のVBAの処理系、とくにエディタは作りが残念(Retina解像度に合ってないとか、日本語入力できないとか、フォームが使えないとか)なので、もうちょっとなんとかならないものかと思ってしまいます。
話をアドレス変換ルーチンに戻しましょう。実際に、そんなに大きな値の相互変換はしていないので問題視していませんでしたが、変換ルーチンに上限値のしばりがあるのはうっとおしいとは思っていました。ただ、ExelASプロジェクトの頓挫により、アドレス変換処理を書き換えるほどのインセンティブがなかったので、ながらく放置状態に。
そこで、定期的に行なっているChatGPTによるAppleScript記述実用性チェックの「お題」としてこのセルアドレスの相互変換を行わせてみました。ちゃんと動いているように見えます。こういうデータ変換系のプログラムは、割とChatGPTで書かせるのは「アリ」だと思います。
ただ、アプリケーションの詳細なコントロールを行わせると、首をひねってしまうような書き方を返してきます。
AppleScript名:Excel__Numbersセルアドレスの相互変換.scpt |
— 数値 → A1形式 set result1 to numberToCell(2024, 5) — "BYV5" display dialog "Number to Cell: " & result1 — A1形式 → 数値 set result2 to cellToNumber("BYV5") — {2024, 5} display dialog "Cell to Number: Column: " & item 1 of result2 & ", Row: " & item 2 of result2 — 数値からセルアドレス(A1形式)への変換 on numberToCell(columnNumber, rowNumber) set columnAddress to "" set tempNumber to columnNumber — 列番号をA-Z形式に変換 repeat while tempNumber > 0 set remainder to (tempNumber – 1) mod 26 set columnAddress to (character (remainder + 1) of "ABCDEFGHIJKLMNOPQRSTUVWXYZ") & columnAddress set tempNumber to (tempNumber – 1) div 26 end repeat — A1形式のアドレスを返す return columnAddress & rowNumber end numberToCell — セルアドレス(A1形式)から数値への変換 on cellToNumber(cellAddress) set columnPart to "" set rowPart to "" — 列部分と行部分を分離 repeat with char in cellAddress if char is in "0123456789" then set rowPart to rowPart & char else set columnPart to columnPart & char end if end repeat — 列部分を数値に変換 set columnNumber to 0 repeat with i from 1 to length of columnPart set char to character i of columnPart set columnNumber to columnNumber * 26 + (offset of char in "ABCDEFGHIJKLMNOPQRSTUVWXYZ") end repeat — 数値を返す return {columnNumber, (rowPart as integer)} end cellToNumber |