Excelでの使用例


ListViewコントロールを使ってコメントを管理する例を紹介します。TreeViewコントロールと組み合わせて使うとさらに効果的ですが、ここではListViewコントロールを中心に作ってみましょう。TreeViewコントロールについては、「UserFormでツリービューを使う」をご覧ください。

こんなイメージです。

ListViewコントロールの初期化とコメントの取得

ListViewコントロールの初期化は、前に解説した通りです。列見出し(ColumnHeader)を追加するとき、同時に列幅も指定しています。

続いて、アクティブシートにあるすべてのコメントを取得します。なお、本項ではコメントに関する技術的な解説は割愛いたします。それは、また別のコンテンツで解説しましょう。

Private Sub UserForm_Initialize()
    Dim Memo
    With ListView1
        ''プロパティ
        .View = lvwReport           ''表示
        .LabelEdit = lvwManual      ''ラベルの編集
        .HideSelection = False      ''選択の自動解除
        .AllowColumnReorder = True  ''列幅の変更を許可
        .FullRowSelect = True       ''行全体を選択
        .Gridlines = True           ''グリッド線
        ''列見出し
        .ColumnHeaders.Add , "_Address", "アドレス", 46
        .ColumnHeaders.Add , "_View", "表示", 46
        .ColumnHeaders.Add , "_Text", "テキスト", 126
        ''コメントの取得
        Call GetComments
    End With
End Sub

アクティブシートのコメントを取得する処理は、ほかの機会にも利用しますので独立したプロシージャとしました。

Sub GetComments()   ''すべてのコメントを取得する
    Dim Memo
    With ListView1
        .ListItems.Clear
        For Each Memo In ActiveSheet.Comments
            With .ListItems.Add
                .Text = Memo.Parent.Address(0, 0)
                .SubItems(1) = Memo.Visible
                .SubItems(2) = Memo.Text
            End With
        Next Memo
        If .ListItems.Count > 0 Then .ListItems(1).Selected = True
    End With
End Sub

チェックボックスによる処理

チェックボックスを利用して、2つの処理を行います。

  1. シート上の全コメントについて、表示/非表示を切り替える
  2. コメント1行目に自動入力される作成者の、表示/非表示を切り替える

(1)シート上の全コメントについて、表示/非表示を切り替える

シートの全コメントを表示するには、ApplicationオブジェクトのDisplayCommentIndicatorプロパティで設定します。すべてのコメントを表示しているときは、DisplayCommentIndicatorプロパティに1が設定されていますので、UserFormの初期化処理でチェックボックスの状態に反映させます。この、DisplayCommentIndicatorプロパティは少々クセ(というかバグ)のあるプロパティです。まぁ、そのへんの話は、別のコンテンツで詳しくやりましょう(^^;

Private Sub UserForm_Initialize()
    Dim Memo
    With ListView1
        ''プロパティ
        .View = lvwReport           ''表示
        .LabelEdit = lvwManual      ''ラベルの編集
        .HideSelection = False      ''選択の自動解除
        .AllowColumnReorder = True  ''列幅の変更を許可
        .FullRowSelect = True       ''行全体を選択
        .Gridlines = True           ''グリッド線
        ''列見出し
        .ColumnHeaders.Add , "_Address", "アドレス", 46
        .ColumnHeaders.Add , "_View", "表示", 46
        .ColumnHeaders.Add , "_Text", "テキスト", 126
        ''コメントの取得
        Call GetComments
        CheckBox1 = Application.DisplayCommentIndicator > 0
    End With
End Sub

チェックボックスがクリックされたら、DisplayCommentIndicatorプロパティの設定も変わるようにします。オフのときは「コメントマークのみ」表示するとします。このプロパティを変更すると、すべてのコメントのVisibleプロパティが変化しますので、ListViewコントロールのデータも更新してやります。

Private Sub CheckBox1_Click()   ''[コメントを表示する]
    Dim SelectedRow As Long
    Application.DisplayCommentIndicator = (CheckBox1 + 1) * (-2) + 1
    With ListView1
        If .ListItems.Count = 0 Then Exit Sub
        SelectedRow = ListView1.SelectedItem.Index
        Call GetComments
        ListView1.ListItems(SelectedRow).Selected = True
    End With
End Sub

(CheckBox1 + 1) * (-2) + 1は、ちょっと意地になりました(^^; すなおにIfステートメントやSelect Caseステートメントを使った方が簡単かもしれません。DisplayCommentIndicatorプロパティを変更すると、コメントのVisibleプロパティが変化しますので、GetCommentsをコールして、すべてのコメントを取得し直しています。ここでのポイントは、ListViewコントロールで選択されていた行を保持するということです。GetCommentsプロシージャではListItems.Clearを実行していますので、そのままだと毎回1行目が選択されてしまいます。ちょっと、UIとしてはお粗末です。そこで、現在選択されている行番号を変数(SelectedRow)に格納しておき、GetCommentsの後で選択し直してやります。注意すべきは、ListViewコントロールにデータが登録されていないケースです。1件もデータがないということは、選択されている行が存在しないということですから、上の考え方ではエラーになります。そこで、まずListViewコントロールに登録されているデータの個数を調べています。

(2)コメント1行目に自動入力される作成者の、表示/非表示を切り替える

コメント挿入すると、1行目に作成者名(ユーザー名)が自動的に入力されます。複数のユーザーで使う共有ブックなら役立つ機能ですが、ひとりで使っている場合は邪魔な気もします。今回のように、コメントのテキストをListViewコントロールで表示するときは、なおさらそう思います。そこで、チェックボックスで作成者名の表示/非表示を切り替えられるようにします。

作成者名を消すということは、要するに「コメントの2行目以降をテキストとする」ということです。しかし、もしかするとユーザーが、自ら作者名を削除しているかもしれません。そこで「1行目の行末が:かどうか」という判断も入れておきましょう。

Private Sub CheckBox2_Click()   ''[作成者を表示しない]
    Dim i As Long, buf As String
    With ListView1
        If .ListItems.Count = 0 Then Exit Sub
        If CheckBox2 Then
            For i = 1 To .ListItems.Count
                buf = Range(.ListItems(i)).Comment.Text
                If Right(Left(buf, InStr(buf, vbLf) - 1), 1) = ":" Then
                    .ListItems(i).SubItems(2) = Mid(buf, InStr(buf, vbLf) + 1)
                End If
            Next i
        Else
            For i = 1 To .ListItems.Count
                .ListItems(i).SubItems(2) = Range(.ListItems(i)).Comment.Text
            Next i
        End If
    End With
End Sub

2つのチェックボックスによる処理をプログラミングしましたが、実は両者は整合性がとれていません。[コメントを表示する]チェックボックスを切り替えると、相変わらず作者名ごとデータが登録されてしまいます。[コメントを表示する]チェックボックスのコードを変更すれば対応は簡単ですが、ここでは割愛します。ListViewコントロールの使い方という本筋から大きく離れるからです。あと、ちょっと解説が面倒くさいからです(^^; 興味のある方はチャレンジしてください。

コメントのセルを選択する

ListViewコントロールでデータをダブルクリックしたら、そのコメントが挿入されているセルにアクティブセルを移動してみましょう。まぁ、これは簡単ですね。でも、実装していると便利な機能です。

Private Sub ListView1_DblClick()
    Range(ListView1.SelectedItem).Select
End Sub

コメントを削除する

[Delete]キーを押したら、選択しているコメントを削除できるようにします。

Private Sub ListView1_KeyUp(KeyCode As Integer, ByVal Shift As Integer)
    With ListView1
        If .ListItems.Count = 0 Then Exit Sub
        If KeyCode = 46 Then
            Range(.SelectedItem).ClearComments
            Call GetComments
        End If
    End With
End Sub

コメントを削除するには、RangeオブジェクトのClearCommentsメソッドを実行します。この場合は、必ずコメントが挿入されているセルですから、削除の前にコメントの有無を判定する必要はありません。その代わり、ListViewコントロールにデータが登録されていないとエラーになりますので、そちらの判定を加えておきます。コメントを削除したら、シート上の全コメントを取得し直すのを忘れないでください。