今回は、式言語を使用したクイズです。
問題: フィールド 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 件のコメント:
コメントを投稿