miauのブログ

はてなダイアリー「miauの避難所」をはてなブログに移行しました。 https://zenn.dev/miau に移行しようと考え中

Excel 罫線の挙動を調べてみた

普段は「ドキュメントは最低限のものを Trac に書こう」運動を実施中の私ですが、今参画しているプロジェクトは典型的なウォーターフォール開発で、設計書は Excel で書くことになっています。

設計書のテンプレートは準備されているんですが、この罫線の設定があまり良くなくて。例えば一見何の問題もない

こんな表ですが、行を増やそうとして行をコピー or 挿入すると、

こんな感じで罫線が消えたり、逆に余計な罫線がわいて出たり。

他にも、印刷してみると

端の罫線が消えている問題があったりもして・・・ちょっと耐えられなくなったので、罫線まわりについて挙動を調べてみました。

罫線の挙動

「動作を検証した限りこうなっている」という情報です。誤り等あればご指摘ください。

罫線の概念

セルとセルの間に

このように罫線があった場合、内部的には

  • A セルの下罫線の情報
  • B セルの上罫線の情報

が個別に保持されていて、この組み合わせで描画される罫線が決まっています。

例えば、

一本に見えるこの罫線ですが、セルごとの情報に分解すると、

このように保持されている情報はそれぞれ異なっています。

表示の際は、罫線の両側のセルで設定されている罫線のうち、より「強い」ものが優先されるようになっています。「なし」は最弱なので、どちらか一方に罫線が設定されてれば罫線として表示されます。それ以外の線の強さはだいたい「セルの書式設定」→「罫線」で線のスタイルとして表示されている

この順と同じなんですが、No.3 の点線だけはやや強い位置にあるようです。(数字が大きいものほど強い)


罫線設定時の動作

あらかじめ隣接セルに

このような罫線(詳細は右。以下同様)を設定した上で、中央の 2 x 2 のセルを選択して、セルの書式設定で
こんな罫線を設定してみます。

見た目は左のようになりますが、詳細な情報を見ると右のようになっています。

ちょっとややこしいのですが、この動作から以下のことがわかります。(ツールバーで操作した場合も同じ動作になります。)

  1. 内側の線については、線の両側のセルに罫線が設定される
  2. 外枠の線については、選択したセルにだけ罫線が設定され、隣接したセルの罫線には設定は反映されない。
    • 元々の見た目が設定した罫線と同じ場合(左辺、下辺)は、隣接セルの罫線は変更されない
    • 元々の見た目が設定した罫線と異なる場合は、隣接セルの罫線は「なし」になる(上辺)
      • 一部が異なる場合も同様(右辺)
隣接セルの罫線変更時の動作

このように、セル A の下に罫線が設定されているとします。

この状態で B で「セルの書式設定」を開くと、

のように、B 側で罫線が設定されていないにも関わらず、上の罫線が設定されているように見えてしまいます。このように、通常の方法では Excel 上から各セルに設定された個別の情報を見ることはできないようになっています。(後述しますが、小細工すれば見ることができます。)

また、B の「セルの書式設定」で罫線をどこか一つでも変更すると、この「見た目上の書式」が実際に B のセルの内部情報に反映されます。例えば

のように下に二重線を引いた場合、上の線を操作していないにも関わらず、

このように B の上側に罫線が設定されてしまいます。

この動作が元で、表の罫線が一部だけコピーされている、というような自体がよく発生している気がします。

セルをコピーした場合の動作

隣接セルには影響を与えず、素直にセルの内部情報をコピーされます。

たとえば、

ここで A のセルを A' の位置にコピーすると・・・。

見た目は書式がコピーされていませんが、内部的にはちゃんと情報を持ったままコピーされています。(太線のほうが線として強いので表示されていないだけです。)

セルを削除した場合の動作

こちらも隣接セルには影響を与えず、単純にそのセルが削除されます。

セルを挿入した場合の動作

セル挿入方向の前方/後方のセルを元にして、罫線の種類が決まります。
上下左右の罫線それぞれについて、

  • 前方/後方のセルで罫線の種類が一致していれば、その罫線が使われる
  • そうでなければ罫線「なし」に設定される

というルールです。(挿入オプションもあるみたいなんですが、挙動がよくわかりませんでした・・・。)

実例を挙げると、

この例で「挿入」(「下方向にシフト」または「行全体」)して 3 行目を増やした場合は、このような罫線が設定されています。

追加された 3 行目は、

  • 左側の枠: 2 行目は「なし」、4 行目は太線と一致していないので、3 行目の左側も「なし」
  • 右側の枠: 2 行目、4 行目ともに太線なので、3 行目も太線

といった具合です。

挿入行の前方/後方の書式が完全に一致してないと枠線が消える方向に動作してしまいますので、枠線が正しく設定されている確信がない場合はあまり使わないほうがよさそうです。

これらの挙動を踏まえた上での方針

「セルの書式設定」で罫線を設定するのは無秩序な罫線の原因になりますので、テンプレートを作る人は、他の人が書式設定を個別に行わなくていい(行単位のコピー&ペーストだけで運用できる)形になるように気をつけるのがよさそうです。

例えば表を作るのであれば

  • 最後の 2 行は常に空けておく
  • 行が足りない場合は最後から二行目をコピーして行を増やす

というような運用にする等ですかね。

詳細情報を見ることはできないの?

Excel の罫線の挙動は上記のように複雑で、もう少しすっきりできなかったものかとも思いますが・・・一番の問題は Excel の標準では各セルで実際に保持されている罫線の情報を見る方法がない、ということだと思います。これができるツールもちょっと探したんですが、どうも見当たらず。

詳細情報を見るための作ってみた

ということで、Ruby + Win32OLE で HTML に変換するスクリプトを書いてみました。


こんな感じの Excel シートが、

こんな感じでセルが分離した形の HTML になります。各セルが保持している情報も見ることができますし、端の罫線が欠けているところも調べることができます。

OLE で罫線の情報を取得しても「セルの書式設定」画面と同じで隣接セルの情報も拾ってしまっていたので、セルをいったん右下のほうにコピーして、そこから情報を取得するようにしているのがポイント。

もっといい方法があることに気付くorz

・・・と、できあがって喜んでたんですが、

  • 外部スクリプトから Excel のブックを指定するのが面倒
  • 一つ一つのセルの情報を見に行っている&コピーまでしているので、動作が重い

という問題があり、あまり他人に勧められるものではなくて。

よく考えたら VBA でも楽に実装できそうなので、Excel アドインを作っちゃいました。(長くなるのでこれは別アイテムで)。

Ruby スクリプトの情報(いちおう)

とりあえずこの Ruby スクリプトはお蔵入りコースですが、何かの参考になるかもしれないので一応 gist に上げておきました。

Excel アドイン版ができてしまったので、やる気ない感じですみません。(ファイル指定もベタ書きのまんまです・・・。)

2 ファイルありますが、

  • xls2html_input.rb
    • Excel データ取得→YAML として吐き出す部分
  • xls2html_output.rb
    • YAML からデータを取り出して HTML を出力する部分

といった感じになっています。HTML 出力の調整のたびにデータ取得処理が走るのが嫌だったので、入力部と出力部に分けて、中間データを YAML で保持しています。

      • -

ということで、Excel アドインの話に続きます。