もう7年も前になるのか、
Microsoft Excelで作ったアンケートを集計するためのツールを作った。
なにしろ集計箇所の指定が楽なのでアンケートのみならず、開発ドキュメントの特定欄(はっきり言って日付)がきちんと辻褄が合っているかのチェックに使ったりして重宝した。
しかしながら「チェックボックス」には対応してなかったのだな。必要なときはチェックボックスの値を別シートからリンクして、その別シートを集計する、という形で対処していた。
このたび、直接チェックボックスを扱えるようにしたくなり、作ったサブルーチンがこちら。
アクティブシートのチェックボックスの一覧をVariant型の二次元配列で返します。
要素"0"はチェックボックスの名前。
要素"1"はチェックボックスと最も共有面積が広いセルの行数
要素"2"は同じく列数
要素"3"はチェックボックスのON/OFF
どのセルにあると判断するかにはちょっと悩んだ。チェックボックスの左上がかかっているもの、なんてので済めば問題なかったのだが、デフォルトではチェックボックスの高さがセルの高さより大きかったりするんだな。なのでチェックボックスという「図形」と最も広い面積を共有しているセルを選択することとした。
Function チェックボックス一覧取得() As Variant
Dim answer As Variant
Dim cb As CheckBox
Dim Buf As String
Dim 左上端(2) As Single
Dim 左下端(2) As Single
Dim 右上端(2) As Single
Dim 右下端(2) As Single
Dim 左上セル As Range
Dim 右下セル As Range
Dim 上端 As Single
Dim 下端 As Single
Dim 左端 As Single
Dim 右端 As Single
Dim 共有面積 As Single
Dim old_共有面積 As Single
Dim セル行 As Long
Dim セル列 As Long
Dim i As Long, j As Long
Dim ct As Long
ct = 0
ReDim answer(0 To 3, 0 To ct)
'チェックボックスをループ
For Each cb In ActiveSheet.CheckBoxes
左上端(1) = cb.Left
左上端(2) = cb.Top
左下端(1) = cb.Left
左下端(2) = cb.Top + cb.Height
右上端(1) = cb.Left + cb.Width
右上端(2) = cb.Top
右下端(1) = cb.Left + cb.Width
右下端(2) = cb.Top + cb.Height + cb.Width
DoEvents
Set 左上セル = cb.TopLeftCell
Set 右下セル = cb.BottomRightCell
old_共有面積 = 0
所属セル行 = 0
所属セル列 = 0
For i = 左上セル.Row To 右下セル.Row
For j = 左上セル.Column To 右下セル.Column
'セルの作る四角形とチェックボックスの作る四角形の重なり面積を求める
'まずは重なり部分の左端
If cb.Left < Cells(i, j).Left Then
左端 = cb.Left
Else
左端 = Cells(i, j).Left
End If
'重なり部分の右端
If cb.Left + cb.Width > Cells(i, j).Left + Cells(i, j).Width Then
右端 = cb.Left + cb.Width
Else
右端 = Cells(i, j).Left + Cells(i, j).Width
End If
'つまり重なった部分のY軸方向の長さは
重なりの幅 = cb.Width + Cells(i, j).Width - (右端 - 左端)
'今度は重なり部分の上端
If cb.Top < Cells(i, j).Top Then
上端 = cb.Top
Else
上端 = Cells(i, j).Top
End If
'続いて下端
If cb.Top + cb.Height > Cells(i, j).Top + Cells(i, j).Height Then
下端 = cb.Top + cb.Height
Else
下端 = Cells(i, j).Top + Cells(i, j).Height
End If
'ということで重なりの高さは
重なりの高さ = cb.Height + Cells(i, j).Height - (下端 - 上端)
共有面積 = 重なりの高さ * 重なりの幅
If 共有面積 > old_共有面積 Then
old_共有面積 = 共有面積
所属セル行 = i
所属セル列 = j
End If
DoEvents
Next j
Next i
ReDim Preserve answer(0 To 3, 0 To ct)
answer(0, ct) = cb.Name
answer(1, ct) = 所属セル行
answer(2, ct) = 所属セル列
If cb.Value = 1 Then
answer(3, ct) = "ON"
Else
answer(3, ct) = "OFF"
End If
ct = ct + 1
DoEvents
Next cb
チェックボックス一覧取得 = answer
DoEvents
End Function
このサブルーチンを作ったツール、動画で紹介しています。
https://youtu.be/D4iMNRmpJVo
Microsoft Excelのワークシートで作ったアンケートを集計するツールです。