Excelの拡張機能(データ分析)にヒストグラムを作る機能はありますが、あらかじめデータ区分作る必要があり、パッとヒストグラムを見たいときには不便です。そこで、選択しているシートの範囲をそのままヒストグラムにするVBAを作りました。
機能、使い方は
1.選択する範囲は、矩形範囲でも、はなれていても良い。
2.選択後にマクロ「選択範囲ヒストグラム作成」を起動する。
3.データの区間はマクロで設定する。聞いてくるので修正できます。
4.ヒストグラムのデータは、シートに作成しない。
Sub 選択範囲ヒストグラム作成()
Dim xCount() As Long, xRank() As Double
Dim ix As Long, i As Long, imax As Long
Dim xmax As Double, xmin As Double, xstep As Double
Dim xsum As Double, xcnt As Long
Dim iy As Long ', iyS As Long, iyE As Long
Dim strtemp As String, xbuf As Variant, iflg As Integer
Dim objChart As Object, chartTtl As String, xStr As Variant
Dim rng As Range, cl As Variant
'データの取得と区分のカウント
Set rng = Selection
For Each cl In rng
iy = cl.Row
ix = cl.Column
If IsNumeric(cl) = True And cl.Text <> "" Then
If iflg = 0 Then
xmax = cl.Value
xmin = xmax
iflg = 1
End If
xsum = xsum + cl.Value
xcnt = xcnt + 1
If xmax < cl.Value Then xmax = cl.Value
If xmin > cl.Value Then xmin = cl.Value
End If
Next cl
If xmax = xmin Or xcnt = 0 Then
MsgBox "数値のセルを選択してから実行してください。" & " min=" & CStr(Round(xmin)) & " max=" & CStr(Round(xmax))
Exit Sub
End If
'***ヒストグラムデータの作成***
'xmaxの桁で区分幅xstepを設定、その桁で最大最少を設定。必要なら値は入力しなおす。
xstep = 10 ^ (Int(Log(xmax - xmin) / Log(10)) - 1)
strtemp = CStr(xstep * Round(xmin / xstep)) & "," & CStr(xstep * Round(xmax / xstep)) & "," & CStr(xstep)
strtemp = InputBox("区分を入力してください。開始値 終了値 ステップ値", "区分の設定", strtemp)
If strtemp = "" Then Exit Sub
strtemp = Replace(strtemp, " ", ",")
strtemp = Replace(strtemp, " ", ",")
xbuf = Split(strtemp, ",") 'xbuf(0,1,2)=xmin,xmax,xstep
'区分数
imax = (xbuf(1) - xbuf(0)) / xbuf(2) ' + 1
ReDim xRank(imax), xCount(imax), xStr(imax)
'ランク値を設定
For i = 1 To imax
xRank(i) = xbuf(0) + (i - 1) * xbuf(2)
xStr(i) = CStr(xRank(i)) & "~"
Next i
xStr(0) = "~" & CStr(xRank(1))
'データのランクへのカウント
For Each cl In rng
If IsNumeric(cl.Value) = True Then '数値の時だけ処理する
iflg = 0
For i = 1 To UBound(xRank)
If cl.Value < xRank(i) Then 'ランク値より小さい時に下のランクにカウント
xCount(i - 1) = xCount(i - 1) + 1
iflg = 1
Exit For
End If
Next i
If iflg = 0 Then 'カウントされないときは最高値にカウントする
i = UBound(xRank)
xCount(i) = xCount(i) + 1
End If
End If
Next cl
'***ヒストグラム図の作成***
chartTtl = "min=" & CStr(xmin) & " max=" & CStr(xmax) & _
" mean=" & CStr(xsum / xcnt) & " n=" & xcnt & " cond=" & strtemp
Set objChart = plotHistogram(xStr, xCount, , , chartTtl) ', rng(rng.Count).Offset(1, 0))
Call moveChartPosVisibleRange(objChart)
rng.Select
Set rng = Nothing
Set objChart = Nothing
End Sub
'チャートを見える範囲内に移動する。addOffsetは内側へ入れるセル数
Function moveChartPosVisibleRange(chartObj As Object, _
Optional addOffsetRow As Long = 1, Optional addOffsetCol As Long = 1)
Dim VR As Range
Dim cl As String, TL As Range, BR As Range
Dim mvRow As Long, mvCol As Long
Dim AC As Range
Set AC = ActiveCell
chartObj.Activate
With chartObj
'画面範囲と現在のチャートの左上、右下
Set VR = ActiveWindow.VisibleRange
Set TL = .TopLeftCell
Set BR = .BottomRightCell
'現在のチャートの左上、右下が画面範囲外にある時の移動量を決める。両方の場合右下を優先する(後で計算する)。
If TL.Row < VR(1).Row + addOffsetRow Then
mvRow = VR(1).Row - TL.Row + addOffsetRow
End If
If TL.Column < VR(1).Column + addOffsetCol Then
mvCol = VR(1).Column - TL.Column + addOffsetCol
End If
If BR.Row > VR(VR.Count).Row - addOffsetRow Then
mvRow = VR(VR.Count).Row - BR.Row - addOffsetRow
End If
If BR.Column > VR(VR.Count).Column - addOffsetCol Then
mvCol = VR(VR.Count).Column - BR.Column - addOffsetCol
End If
'ありえない位置への移動は修正
If TL.Row + mvRow < 1 Then mvRow = 1 - TL.Row
If BR.Row + mvRow > Rows.Count Then mvRow = Rows.Count - BR.Row
If TL.Column + mvCol < 1 Then mvCol = 1 - TL.Column
If BR.Column + mvCol > Columns.Count Then mvCol = Columns.Count - BR.Column
'チャートの左上の位置を変更
cl = TL.Address(False, False)
cl = Range(cl).Offset(mvRow, mvCol).Address(False, False)
.Top = Range(cl).Top
.Left = Range(cl).Left
End With
AC.Select
Set AC = Nothing
Set VR = Nothing
Set TL = Nothing
Set BR = Nothing
End Function
Function plotHistogram(xdata As Variant, ydata As Variant, _
Optional xttl As String, Optional yttl As String, Optional chartTtl As String = "title", _
Optional BarRGB As Long = 16761024)
'Optional posChart As Range, _
Dim oChart As ChartObject
Dim AC As Range
Set AC = ActiveCell
'チャートオブジェクトを適当な位置で作成する
ActiveCell.Resize(5, 1).Select
Set oChart = ActiveSheet.ChartObjects.Add(10, 10, 300, 200)
oChart.Activate
With oChart.Chart
.ChartType = xlColumnClustered 'グラフ形式を設定。縦棒グラフ
'これを繰り返すと複数のラインが描ける
With .SeriesCollection.NewSeries
'.Name = "ChartTitle"
.Values = ydata '1軸目の値
If IsEmpty(xdata) = False Then
.XValues = xdata
End If
.Format.Line.ForeColor.RGB = RGB(0, 0, 0) '棒グラフの外枠の色
.Format.Fill.ForeColor.RGB = BarRGB '棒グラフの色
End With
.ChartGroups(1).GapWidth = 0 '棒グラフの間隔
If xttl <> "" Then
.Axes(xlCategory, xlPrimary).HasTitle = True
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = xttl
End If
If yttl <> "" Then
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = yttl
End If
End With '.HasTitle = Trueにならないことがあるため入れてみた。
With oChart.Chart '.HasTitle = Trueにならないことがあるため入れてみた。
DoEvents '.HasTitle = Trueにならないことがあるため入れてみた。
If .HasTitle = False Then
.HasTitle = True 'グラフタイトル
End If
With .ChartTitle
.Text = chartTtl
.Format.TextFrame2.TextRange.Font.Size = 11
.Format.TextFrame2.TextRange.Font.Bold = msoFalse
End With
.HasLegend = False '凡例表示
End With
AC.Select
Set plotHistogram = oChart
Set oChart = Nothing
Set AC = Nothing
End Function