なでしこ開発日誌~フリーソフト作者を応援しよう!

私も多くのフリーソフトを公開していますが、ネット上には、いろいろなフリーソフトが公開されています。市販されているソフトだけでは、かゆいところになかなか手が届かないことが多いので、どんな人でもいくつかはフリーソフトをインストールしていることでしょう。

そして、そのフリーソフトの多くは、ソフトの作者の人の善意によってサポートが行われています。善意によって運営されているにもかかわらず、市販されているソフトよりサポートがしっかりしているものも少なくありません。要望に感謝を一言添えて送ったら、ソフトがバージョンして要望が叶ったなんてこともよくあります。素晴らしい限りです。

私も、自分の作ったソフトについて感想や要望が寄せられたら、できるだけ応えてあげたいと思います。つまり、フリーソフト作者は「貴方のソフトが役に立ちました!」という感謝の気持ちを報酬として受け取っているとも言えるでしょう。

世の中には、「どうしても、○○を完成させたい!」と、熱い想いを胸に日々作り続けている人がいます。そんな人の気持ちを後押しするには、どうしたら良いでしょうか? そのひとつの方法が、「面白そう! 使っていたい!」と応援することです。

毎年、年末になると、私にメールをくれる方がいます。文面は短く、「今年も貴方の作ったソフトが役に立ちました。ありがとう。」と数行だけですが、とても心に染みるメールです。来年もがんばって開発を続けようと思います。

読者の皆さんも、普段利用しているフリーソフトがあれば、感謝のメールを送ってみるのはどうでしょうか? それは、きっと作者の方の心に届き、次のバージョンアップの仕上がりをより素晴らしいものにすることでしょう。

今回作るもの~表を整形するプログラム

さて、今回作るのは、表を整形するプログラムです。皆さんは、Excelで作った表を同僚や取引先の人に見せたいときに、どうしているでしょうか?

もちろん、メールにExcelのファイルを添付すれば良いのですが、メールを受け取る相手にそれほど時間がない時、添付ファイルを開いてまで内容を見てくれそうにない時は、どうしたら良いでしょうか。また、メーリングリストやメールマガジンなどでは、ファイルを添付するのは嫌がられます。

そんな場合に、よく見かけるのが、以下のようにとても読みにくいメールです。

こんな表をコピーしてメールに貼り付けると……

タブ区切りテキストになるので凸凹に!!

Excelの表を範囲選択してコピーしてメモ帳に貼り付けると、タブ区切りのテキストとして貼り付けられます。一般的にタブは幅が十分でないため、凸凹でとても見づらいです。確かに、わざわざ人間の手で整形するのは面倒です。

そこで今回は、Excelの表を範囲選択コピーして得たタブ区切りのテキストをそれらしく整形するプログラムを作ってみたいと思います。

表を整形する方法を考える

では、表を整形する方法から考えてみたいと思います。

テキストで表を見やすくする一番簡単な方法は、適当な空白を入れて、列を揃えてあげることです。例えば、以下のようなデータでも、空白文字(スペース文字)を入れて列をきちんと整えれば、それなりに見やすくなります。

整形前

aaa,b,357
aa,b,8
a,bbbb,8745

整形後

aaa,b   ,357
aa ,b   ,8
a  ,bbbb,8745

ですので、今回表を整形するプログラムでも、各セルに適当な空白を挿入することにします。

TSV形式の扱い方

Excelの表を部分選択してコピーすると、クリップボードには、タブ区切りのTSV形式の文字列が入ります。カンマ区切りのデータのことを、CSV(Comma Separated Values)という様に、タブ区切りのテキストは、TSV(Tab Separated Values)とも言います。

なでしこには、TSV形式のデータを「TSV取得」命令を使って二次元配列変数に変換する機能があります。二次元配列変数にしてしまえば「変数[行,列]」の形式でデータの好きなセルの値を取り出すことができます。

適当な長さの空白を足す方法

それでは、TSV形式のデータへ、適当に空白文字を足して列をそろえるプログラムを作ってみようと思います。

タブ区切りのTSV形式だと区切りが分かりづらいので、まずは、カンマ区切りのCSV形式を使って適当に列を揃えてみます。

データは「AAA,B,357
AA,B,8
A,BBBBB,8745」
F列を0から(データの表列数-1)まで繰り返す
  F行を0から(データの表行数-1)まで繰り返す
    セルは、データ[F行,F列]&「.......」 # (※1)
    データ[F行,F列] = セルから7バイト左部分 # (※2)
データを表示。

適当な長さに切り揃えて表示したところ

このプログラムでは、「繰り返す」構文を使って、表の各セルを順々に処理していきます。列方向と行方向の繰り返しが入れ子になっていることで、全てのセルを処理することができます。

そして、適当に列を揃えている部分が(※1)と(※2)の部分です。(※1)では、まず、セルを取り出し、取り出したセルの直後に「.......」と適当な空白文字を付け加えています。ただ、全てのセルの直後につけたのでは、凸凹であることに変わりないので、(※2)で切り揃える処理を行います。それは、セルの左から7バイト分を取り出すという処理です。

この「(文字列S)から(N)バイト左部分」という命令では、文字列Sにある左からNバイト分の文字列を取り出す処理を行います。

最大文字数を調べる

先ほど作ったプログラムでは、セルの最大バイト数を7バイトと仮定して、全てのセルを7バイトに切りそろえていました。しかし、この方法だと、7バイト以上のセルがあったとしたら、セルの内容が途中で切れてしまいますし、「x」と「o」のどちらかしか記入されてない列でも7バイト分の長さを取られてしまいます。

そこで、各列の最大文字数を初めに調べておいて、各列ごとに最大のバイト数を変えるような処理を入れてみたいと思います。これにより、セルに長い文字列があれば、これを最大長として、列を揃えることができます。

以下は、CSV形式のデータの各列の最大文字数を調べるプログラムです。

データは「AAA,B,357
AA,B,8
A,BBBBB,8745」
F最大は空。
F列を0から(データの表列数-1)まで繰り返す
  F行を0から(データの表行数-1)まで繰り返す
    Nは、データ[F行,F列]のバイト数。
    もし(F最大[F列] < N)ならば
      F最大[F列] = N
F最大を表示。

CSVの各列の最大文字数を調べます

このプログラムでは、配列変数「F最大」に各列の最大バイト数を代入することにしています。そして、各セルごとに、バイト数を調べています。それ以前に調べた列の最大バイト数と、今回調べたバイト数を比較して、今回の方が大きければ、最大バイト数の値を更新します。

ちょっと複雑なので、このプログラムをもう少し単純にしてみます。ただ単に、数値がいくつかあって、その中から一番大きな値を調べるプログラムは以下のようになります。

データは「3
2
4
9
12
15」
最大値は0
F行を0から(データの行数-1)まで繰り返す
  N=INT(データ[F行])
  もし、N>最大値ならば
    最大値はN。
最大値を表示。
プログラムの動きがよく分からない方は、プログラムの先頭に「デバッグ。」と一文付け加えてみてください。すると、プログラムを一行ずつ実行して、各変数の値を調べることができます。

一行ずつ変数の値を目で確認しながら実行できます

10行プログラム~表を整形する

それでは、今回の10行プログラムを作ってみます。念のためプログラムの動きを箇条書きににしてまとめてみます。

  1. ユーザーからタブ区切りのデータを入力してもらう
  2. 各列ごとにセルの最大バイト数を調べる
  3. 各セルへ適当な空白文字を加えて列の最大値バイトで切り揃える
  4. 最終的に見やすく置換して結果を表示する

処理ごとに1行の日本語にしてみると、非常に当然のことのように思えるのですが、これを実際のプログラムに直すのは、ちょっと慣れが必要かもしれません。

特に、ここまでの解説でも見ましたが、列ごとにセルの文字列の最大文字数(バイト数)を調べる部分などは、繰り返し処理の中で値の比較を行うなど、理論的に考えプログラムに直す力が必要になります。(ただし、こうした一連の処理はプログラミングをしていると頻繁に出てくるので、ある程度慣れてしまうと、何も考えずに書けるようになるかもしれません。)

以下がなでしこで作ったプログラムです。Excelで作った表を範囲選択して得られたTSV形式のデータを入力すると、列を綺麗に揃えて出力します。

「Excelの表を範囲コピーして!」とメモ記入してTSV取得してデータに代入。#1
F列を0から(データの表列数-1)まで繰り返す #2
  F行を0から(データの表行数-1)まで繰り返す #3
    もし、F最大[F列]<バイト数(データ[F行,F列])ならば #4
      F最大[F列] = バイト数(データ[F行,F列]) #5
F列を0から(データの表列数-1)まで繰り返す #6
  F行を0から(データの表行数-1)まで繰り返す #7
    セルは、データ[F行,F列]&「............................」#8
    データ[F行,F列] = セルから(F最大[F列])バイト左部分。#9
データの「,」を「|」に置換して、「.」を「 」に置換して、メモ記入。#10

Excelの表を貼り付けると……

列を綺麗に揃えて表示してくれます

1行目では、ユーザーからTSV形式のデータを入力してもらい、これをなでしこの二次元配列変数へ変換し、変数「データ」に代入しています。

2行目から5行目では、列ごとに最大バイト数を調べています。そして、6行目から9行目で各セルの値を切り揃えます。

最後の10行目では、より表が読みやすくなるよう、文字を置換して、結果を画面に表示しています。

改造のヒント

今回のプログラムは、「列を揃える」ことを中心にした整形処理を行いました。このプログラムをさらに完成させるとしたら、より綺麗に表を出力することを考えて以下の機能を実現させてみてはどうでしょうか。

表の外枠を作る

今回は、セルの区切りに「|」記号だけを利用していましたが、罫線記号を利用するともっと綺麗な枠が作れます。

数値は右寄せに

今回は、プログラムの簡易化のため、全てのセルを左寄せにしましたが、数値を右寄せ、しかも、3桁で区切った通貨形式にするとぐっと表が見やすくなります。

表をExcelを使わずに作れるように

また、今回はExcelと連携したツールにした訳ですが、ちょっとした表を作るときに、Excelを起動するのは面倒なので、表の編集から自作ソフト内で簡潔できると、より便利になるかもしれません。