セル範囲の外枠に罫線を引く[Excel]

セル範囲の外枠罫線

VBAでセルの罫線の設定なんてしたことがなかったので知らなかったが、セル範囲の外枠だけに罫線を設定するのは非常にメンドクサイのだった。

セルの罫線はRangeオブジェクト配下のBordersコレクションで管理されている。

で、罫線の位置を指定する場合は、

Range.Borders(インデックス値)

の形でインデックスを指定してやればよい。

インデックス値は定数が設定されていて、

f:id:akashi_keirin:20180418114823j:plain

このように、「XlBordersIndex」という列挙体にまとめられている。

で、このインデックス値を省略すると、格子状に指定したのと同じになる。

私も、単純に罫線を引くだけのことならよくやっていて、

[Rangeオブジェクト式].Borders.LineStyle = xlContinuous

みたいなコードはしょっちゅう書いていたので、それこそ何も見ないでも書けるが、【セル範囲の外枠にだけ罫線を設定する】という場面に出くわして、「あれ、どうやるんだっけ?」となったのであるw

セルの外枠にだけ罫線を引く

徹底的に調べたわけではないので、実は簡単なやり方があるのかもしれないが、どうも、

[Rangeオブジェクト式].Borders(xlEdgeTop).LineStyle = xlContinuous
[Rangeオブジェクト式].Borders(xlEdgeRight).LineStyle = xlContinuous
[Rangeオブジェクト式].Borders(xlEdgeLeft).LineStyle = xlContinuous
[Rangeオブジェクト式].Borders(xlEdgeBottom).LineStyle = xlContinuous

というやり方になるみたい。線の太さや色の設定を省略してもこのコード。めんどくさすぎる。

手作業ならツールバーのアイコンクリック一発なのにw

というわけで、メソッド化してみた。

drawEdgeLinesメソッドの自作

まずはコードの紹介。

リスト1 標準モジュール
Option Explicit

Private Type BorderStyle    '……(1)'
  LineStyle_ As XlLineStyle
  Weight_ As XlBorderWeight
  ColorIndex_ As XlColorIndex
End Type

Public Sub drawEdgeLines(
             ByVal targetRange As Range, _
             Optional ByVal kindOfLineStyle As XlLineStyle = xlContinuous, _
             Optional ByVal kindOfWeight As XlBorderWeight = xlThin, _
             Optional ByVal kindOfColorIndex As XlColorIndex = xlAutomatic)    '……(2)'
  Dim borderStyle_ As BorderStyle    '……(3)'
  With borderStyle_
    .LineStyle_ = kindOfLineStyle
    .Weight_ = kindOfWeight
    .ColorIndex_ = kindOfColorIndex
  End With
  With targetRange    '……(4)'
    Call setBorderStyle(.Borders(xlEdgeBottom), borderStyle_)
    Call setBorderStyle(.Borders(xlEdgeLeft), borderStyle_)
    Call setBorderStyle(.Borders(xlEdgeRight), borderStyle_)
    Call setBorderStyle(.Borders(xlEdgeTop), borderStyle_)
  End With
End Sub

Private Sub setBorderStyle(ByVal targetBorder As Border, _
                           ByRef borderStyle_ As BorderStyle)    '……(*)'
  With targetBorder
    .LineStyle = borderStyle_.LineStyle_
    .Weight = borderStyle_.Weight_
    .ColorIndex = borderStyle_.ColorIndex_
  End With
End Sub

まずは(1)の

Private Type BorderStyle
  LineStyle_ As XlLineStyle
  Weight_ As XlBorderWeight
  ColorIndex_ As XlColorIndex
End Type

1つの罫線につき、3種類の設定(線の種類・太さ・色)があるので、ひとまとめの構造体にした。他から呼び出して使うようなものでもないので、Private指定。

(2)の

Public Sub drawEdgeLines(
             ByVal targetRange As Range, _
             Optional ByVal kindOfLineStyle As XlLineStyle = xlContinuous, _
             Optional ByVal kindOfWeight As XlBorderWeight = xlThin, _
             Optional ByVal kindOfColorIndex As XlColorIndex = xlAutomatic)

でメソッド本体の引数設定。

長ったらしく見えるので軽く引くかもw

第1引数targetRangeは枠線を設定したいセル範囲。

第2引数kindOfLineStyleは線の種類。「XlLineStyle」型にしているので、入力時にintellisenseが効く。「オブジェクト・ブラウザー」の使い方が分かってくると、こういう便利な引数指定ができるようになる。

第3引数kindOfWeightは線の太さ。

第4引数kindOfColorIndexは線の色。

(3)からの6行

Dim borderStyle_ As BorderStyle
With borderStyle_
  .LineStyle_ = kindOfLineStyle
  .Weight_ = kindOfWeight
  .ColorIndex_ = kindOfColorIndex
End With

で、自作構造体BorderStyleに引数で受け取った罫線の設定をぶち込む。

VBAでは小文字と大文字を区別しないので、BorderStyle型の変数名として「borderStyle」というのが使えない。とはいえ、BorderStyle型というのは自作型で、なおかつ1つしか使わないことが明白なので、変数名を「borderStyle」にしておきたい。そんなわけで、苦し紛れの策としてアンダースコアを付けて「borderStyle_」とした。

やっぱり、JavaとかC#みたいに

Person person = new Person();

って書きたいなあ。VBA大好きだけれど、こういうところが不便。

(4)からの6行

With targetRange
  Call setBorderStyle(.Borders(xlEdgeBottom), borderStyle_)
  Call setBorderStyle(.Borders(xlEdgeLeft), borderStyle_)
  Call setBorderStyle(.Borders(xlEdgeRight), borderStyle_)
  Call setBorderStyle(.Borders(xlEdgeTop), borderStyle_)
End With

いちいち似たようなコードを4回も書かないといけないので、こんなふうに1箇所にまとめた。

「setBorderStyle」というメソッドを引数を変えて4回読んでいるが、これも自作メソッドで、(*)の

Private Sub setBorderStyle(ByVal targetBorder As Border, _
                           ByRef borderStyle_ As BorderStyle)
  With targetBorder
    .LineStyle = borderStyle_.LineStyle_
    .Weight = borderStyle_.Weight_
    .ColorIndex = borderStyle_.ColorIndex_
  End With
End Sub

がそれ。BorderStyle型の引数(罫線の3種類の設定が全部入っている)を受け取って、線を引くだけのメソッド。

これで、細い実線をセル範囲の四方に引くだけなら、

Call drawEdgeLines([Rangeオブジェクト式])

だけでおk、ということになる。

使ってみた

f:id:akashi_keirin:20180418114839j:plain

画面上でこんなふうに範囲選択をして、次のコードを実行。

スト2 標準モジュール
Public Sub testDrawEdgeLines()
  Call drawEdgeLines(targetRange:=Selection, _
                     kindOfLineStyle:=xlContinuous, _
                     kindOfWeight:=xlMedium)
End Sub

一応引数は4つ中3つ渡した。

中太実線を選択範囲に引け、という命令。

f:id:akashi_keirin:20180418114850j:plain

この通り、無事に外枠罫線が設定された。

おわりに

外枠罫線だけを一発で引く方法ってあるのかしら?

それと、Bordersの引数を省略したときに「格子」になるようにしたのはさすが。

Bordersの引数を省略して「Bordersコレクションだョ全員集合!」みたいな設定だったら、VBAerはみんな発狂すると思うw

@akashi_keirin on Twitter

追記

なお、今回の記事は、単なる「車輪の再発明」に過ぎないこと、申し添えますw

akashi-keirin.hatenablog.com