プログラミング: 2015年1月アーカイブ

今日、VB-Report を使った帳票出力プログラムを書いていた時の話。

色々帳票内の編集をした後で、例えば

For y As Integer = aaa To bbb
For x As Integer = ccc To ddd
Report.Cell("**Hoge", x, y - 1).Attr.LineBottom(VBReport8.BorderStyle.None, xlColor.Auto)
Report.Cell("**Hoge", x, y).Attr.LineTop(VBReport8.BorderStyle.None, xlColor.Auto)
Next
Next

みたいにして、余分な罫線を消している。

ちょっと説明すると、帳票デザイン時には「全行出力された」状態で、つまり全ての罫線が表示された形でテンプレートの Excel シートを作成している。
そのため、プログラムでデータのセットを行った後、最後に不要な(データが出力されていない)部分の罫線を消しているのである。
具体的には「消す」というより、「透明な線で罫線を上書きする」という感じだが。

で、実際にその罫線がデザイン時に「そのセルの上枠の線」として引かれたか「下枠の線」として引かれたかプログラム内ではわからないので、「1つ上のセルの下枠の線(LineBottom)」と「そのセルの上枠の線(LineTop)」の両方を消しているわけだ。

なのに、消えないのである。

まあ、よくあるミスとして、プログラム内で動的にセルを指定するので、全然間違ったセルに処理をしているとか、そういうことがあるんだけど、今回はそうではない。
位置はばっちり合っているのに消えないのである。

悩みましたよ・・・
VB-Report の情報をググったり。
横向きの罫線の位置は LineBottom か LineTop しか指定できないので、これで駄目ならどうしようもない。
試しに、BorderStyle.Hair で赤色の線を引いてみたけど、消せない罫線の上だけ赤色にならないのである。

こればっかりやってたわけじゃないんだけど、結局解決に 2時間かかりましたぜ(^^;

解決方法は、「テンプレートの Excel シートの罫線を引き直す」です。
つまり、原因はわかんなかった(^^;;;
でも、一旦 Excel 上で罫線を消して、もう一度同じ位置に「下枠の線」として罫線を引いてやると、ちゃんと消すことができるようになった・・・むーん・・・

まあ、原因はわからないけど、そういう時は「テンプレートを作り直せ」ということがわかったからいいかな(^^;(もう、このプログラム、制作が 4日遅れてるんですけど・・・(^^;)
設定情報なんかを "01100" みたいな文字列にして保管することってあるだろう。
例えば、YES/NO 式のアンケート結果を DB に保存する時に、
「5問の答えを、YES なら 1、NO なら 0 にして一つの文字列にして保存」
なんてね。(特に、Web 系なんかで、フレームワーク化するために DB の全項目の型を「文字列型(VARCHAR)」に統一してる時なんかさ)

上の例が A さんのデータだとすれば、A さんは、2問目、3問目のみ YES と答え、その他は NO と答えたということだな。

こういう文字列を処理する時、1バイトずつに分解して配列に突っ込むのもよくやる方法だろう。

Perl なら、split 関数使って、

@data = split //, $enquate;

で、

$data[0] = 0
$data[1] = 1
$data[2] = 1
$data[3] = 0
$data[4] = 0

のように保存される。
本来、// の間には区切り文字(separator)が入るが、何も入れなければ1文字ずつに分解する。

VB.NET にも Split メソッドが存在しているので、

Dim data() As String = enquate.Split()

みたいに書いてみたけど駄目だった。
Split メソッドの場合、区切り文字を省略した場合、半角スペースを指定したものとみなすようだ。
なんだその仕様(^^;
ああ、英語の場合は、単語間に半角スペースが入るのでこういう仕様は都合がいいのか。文章を単語毎に分割する時。ま、半角スペースくらい、面倒くさがって省略すんなやって思うけど。

まあ、代わりにキャラクタ単位で文字列を分割して配列化する ToCharAllay メソッドがあるので許すけど。

Dim data() As Char = enquate.ToCharArray

これで、data 配列に1文字ずつに分解されたデータが格納される。
VB.NET + VB-Report 環境での話。

VB-Report というのは Excel で帳票設計できるアドバンスソフトウェア製の帳票作成ツールで、例えば、Excel シートのあるセルに **Hoge とタグを書いておけば、VB.NET のプログラム内で、

Cell("**Hoge", 0, 0).Value = "ほげ"

と書けば、**Hoge と書かれたセルの位置に「ほげ」という文字が印刷される。

Cell("**Hoge", 0, 1).Value = "ほげほげ"

と書けば、その1行下に「ほげほげ」という文字が印刷される。

Excel の「セルの書式設定」で設定した属性もちゃんと効く。
例えば、「文字の制御」の「縮小して全体を表示する」にチェックを入れておけば、そのセルに長い文字が入れば、Excel でそうであるように、帳票も文字が縮小される。

・・・が、例えば文字を打つ位置が固定ではない場合がある。
合計表示をする部分だけ太字にしたいんだけど、明細行数は決まってないから、どのセルが合計表示セルになるかわからない・・・みたいなケース。
こういう時は、プログラム内で属性をセットしてやることもできる。

Cell("**Goukei", 0, i).Attr.FontStyle = VBReport8.FontStyle.Bold

これで、そのセルの文字は Bold(太字)になる。

あと、良く使うのは上にも書いた縮小表示か。

Cell("**Hoge", 0, 1).Attr.ShrinkToFit = True

こんな感じ。
セルの結合もできる。

Pos(4, 10, 8, 12).Attr.MergeCells = True

上の例は、 4列目の 10行目から 8列目の 12行目までを結合しろということ。**Hoge のように名前を付けたセルを基準にせず、直接 X,Y の座標でセルを指定した場合は、Cell オブジェクトではなく Pos オブジェクトを使う。セル名を使って、

Cell("D10", "H12").Attr.MergeCells = True

のようにもできるけど。
セルの連結をして、更に「縮小して全体を表示する」にしたい場合は、

Pos(4, 10, 8, 12).Attr.MergeCells = True
Pos(4, 10, 8, 12).Attr.ShrinkToFit = True

のように続けて書けばいい。

ちなみに、インターネット上で VB-Report についてググると、バージョン 3 の頃の情報がやたらヒットする。
その頃が VB-Report の全盛期だったのだろうか???(^^;
バージョン 3 と 8 ではプロパティ名等が全然違うので、ググった結果が全然役に立たないことも多い。
「書いてあるとおりのプロパティが設定できんやん!!?」という時は、大概バージョン違いの情報を見ているので注意ね。
日頃、VB.NET で正規表現をあまり使うことがないので、単純な文字列の抽出でも「どうすんだっけ?」とググっちゃうことがあるので、たまにはちゃんとメモっておこう。

文字列 "123-456-78" を 123、456、78 の文字列に分解し、それぞれ key1、key2、key3 へ代入するのであれば、

・Perl
my $t = "123-456-78";
my($key1, $key2, $key3) = ();
if ($t =~ /^(\d+)\-(\d+)\-(\d+)$/) {
($key1, $key2, $key3) = ($1, $2, $3);
}

・VB.NET
Dim t as String = "123-456-78"
Dim r As New Regex("^(\d+)\-(\d+)\-(\d+)$")
Dim m As Match = r.Match(t)
Dim key1 As Integer = m.Groups(1).Value
Dim key2 As Integer = m.Groups(2).Value
Dim key3 As Integer = m.Groups(3).Value

となる。

Perl と VB.NET のどちらも、マッチした文字列のインデックスは 1から始まる($1 = m.Groups(1))ので、そこはわかりやすいだろう。ちなみに、VB.NET の場合、m.Groups(0)にはマッチングした文字列全体が入っている。上の例で言えば "123-456-78" だ。
Perl にはこういう「マッチした文字列全体」という、実際何に使うのかよくわからないものが格納される変数は無い。
ちなみに、Perl で $0 は「自分自身のスクリプト名(プログラム名)」が入っている。

このアーカイブについて

このページには、2015年1月以降に書かれたブログ記事のうちプログラミングカテゴリに属しているものが含まれています。

前のアーカイブはプログラミング: 2014年12月です。

次のアーカイブはプログラミング: 2015年2月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。


月別 アーカイブ

電気ウナギ的○○ mobile ver.

携帯版「電気ウナギ的○○」はこちら