2023/04/19

Excel の列文字列を式で算出

今回は、式言語を使用したクイズです。

問題:

フィールド ColNum に入力された自然数(正の整数)を Excel の列番号 (A ~ Z、AA ~ ZZ)に変換する式を作成しましょう。

なお、入力値は 1~702 とし、結果は A ~ ZZ までの最大2桁とします。


問題解決のアプローチ

解決手法は様々あるかと思います。まさに、十人十色ですよね。

単純に考えると、@If を連ねて書いて実現できます。でも、700行も記述するのはかなり面倒ですよね。 A ~ Z の 26 文字に着目して、26 で割ってから処理をすると、@If を削減できるかもしれません。また、数列的なアプローチや 26 進数として数学的に処理する方法はないでしょうか?

もしかしたら、便利な関数があって、それを利用すると一発で解決!って可能性もありえます。

エレガントな表現や回りくどい記述、どんな方法でもプログラムとしては、結果が出れば正解です。ですが、ビジネスで開発をする限り、効率は重要です。例えば、以下のような点だと考えます。

  • 理解しやすいか?
  • メンテナンス性は高いか?
  • レスポンスは早いか?
  • 短いコードであるか?
  • 再利用はしやすいか?

はるか昔、パソコンが巷ではやり始めたころ、『1画面プログラミング』なんてものがありました。1画面で入る範囲で、どれだけ素晴らしいアプリを作れるか?的な競技(?)でした。これは、コード量圧縮に重きを置き、理解しやすさなどは完全に度外視したものではありましたが、問題解決の手段を突き詰めるという意味では、ビジネスでも応用できる部分はあると思います。


サンプルコード

さて、問題の解答例です。

Excel の列番号って A から始まって、Z までアルファベットの順で進みます。その次は、AA となり、AZ まで順に進み、次は BA となります。A ~ Z までの 26 文字を使った、26 進数のような感じなのですが、0 が存在しないので微妙に単純化できません。

私は以下のような式で実現してみました。

xChrs := "A":"B":"C":"D":"E":"F":"G":"H":"I":"J":"K":"L":"M":"N":
              "O":"P":"Q":"R":"S":"T":"U":"V":"W":"X":"Y":"Z";
xXls := xChrs : (xChrs *+ xChrs);
@Subset(@Subset(xXls; ColNum;)); -1)

列番号を構成する A ~ Z までの26文字をリストに準備します。これを使って、以下の行で A ~ ZZ までの文字列をリストに作成しています。

xXls := xChrs : (xChrs *+ xChrs);

ポイントは、演算子として使用している ”*+” です。これは、順列演算子と呼ばれるもので、リスト値同士をすべての組み合わせで加算し、それぞれのリスト値を返します。今回は、文字列ですので加算ではなく、文字列の連結として動作します。この部分だけで、AA ~ ZZ までのリストを一気に生成しています。

それに、一桁の部分をリスト連結させ、必要な文字列リストを完成させています。

最後に、ColNum に対応する値を抜き出します。いったん、その番号までのリスト全体を @Subset で取得して、もう一度 @Subset を -1 で使い、最後の要素だけを抽出し、結果を取得しています。


まとめ

今回のサンプルは、式としては非常に単純化できているかと思います。

ですが、A ~ ZZ までのすべて文字列をいったん一時変数に保管しています。よって、メモリ効率的には良くないといえます。要件が ZZZ までの3桁だったらこの方法はだめかもしれません。

要件に応じて、アプローチも変わることになります。プログラミングって面白いですね。
そう思うのは私だけでしょうか??

0 件のコメント:

コメントを投稿