またまたデータ取り込み&グラフ描画に手を加えた。
仕事中に取り込んだデータから任意に選択したデータのみグラフ化したいと思い、チェックボックスを導入してチェックが付いたデータのみグラフ化するようにした。
サンプル
今回使うサンプルは下記ボタンから入手可能である。
マクロ本体「exp12_comp.xlsm」を開くと、下のようなウィンドウが表示される。
基本的な使い方は下記記事とほぼ同じである。
しかし今回は「データファイル取得」からデータを取り込むと、A7セルの「グラフ表示」以降にチェックボックスが出現する。
このチェックボックスをONにして「グラフ作成」をクリックすると、チェックボックスがONになっているデータのみがグラフ描画される。
またチェックボックスの追加に伴い、マクロを動かすボタンが2つ追加されている。
「全データ選択」ボタンはチェックボックス全てをONに、「全データ選択解除」ボタンはチェックボックスを全てOFFにする。
コード詳説
「exp12_cpmp_xlsm」には7つのマクロが保存されている。
いつも通り、以前別記事で解説したマクロについては本記事での解説を省略し、新たに追加したマクロ、コードのみ解説していく。
データファイル取得
「データファイル取得」マクロの中身は下記のようになっている。
Sub データファイルの取得()
Dim FD As FileDialog
Dim i As Long
Dim j As Long
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Set FD = Application.FileDialog(msoFileDialogFilePicker)
FD.AllowMultiSelect = True
j = Worksheets.Count
If FD.Show = True Then
For i = 1 To FD.SelectedItems.Count
Workbooks.OpenText Filename:=FD.SelectedItems(i)
Cells.Select
Selection.Copy
ActiveWindow.Close
Sheets.Add After:=Worksheets(j)
With Worksheets(j + 1)
.Name = Dir(FD.SelectedItems(i))
.Paste
.Hyperlinks.Add Anchor:=Cells(1, 5), _
Address:="", _
SubAddress:="'" & Worksheets(1).Name & "'" & "!A1", _
TextToDisplay:=Worksheets(1).Name
.Cells(1, 1).Select
End With
With Worksheets(1)
.Activate
.Hyperlinks.Add Anchor:=Cells(j + 7, 2), _
Address:="", _
SubAddress:="'" & Worksheets(j + 1).Name & "'" & "!A1", _
TextToDisplay:=Worksheets(j + 1).Name
.OLEObjects.Add(ClassType:="Forms.CheckBox.1", _
Width:=10, _
Height:=Cells(j + 7, 1).Height * 2 / 3, _
Top:=Cells(j + 7, 1).Top + (Cells(j + 7, 1).Height - Cells(j + 7, 1).Height * 2 / 3) / 2, _
Left:=Cells(j + 7, 1).Left + (Cells(j + 7, 1).Width - 10) / 2).Select
End With
j = j + 1
Next
End If
Worksheets(1).Activate
Worksheets(1).Range("A1").Select
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
太字の部分が新たに追加したコードである。
その他のコードについては下記記事を参照されたい。
今回追加したコード
.OLEObjects.Add(ClassType:="Forms.CheckBox.1", _
Width:=10, _
Height:=Cells(j + 7, 1).Height * 2 / 3, _
Top:=Cells(j + 7, 1).Top + (Cells(j + 7, 1).Height - Cells(j + 7, 1).Height * 2 / 3) / 2, _
Left:=Cells(j + 7, 1).Left + (Cells(j + 7, 1).Width - 10) / 2).Select
は、シートへのリンクの隣にチェックボックスを追加するコードである。
Worksheets(i).OLEObjects.Add(ClassType:=”Forms.CheckBox.1″, Width=W, Height=H, Top=T, Left=L)
⇒ i番目のワークシート上に幅W、高さHのチェックボックスを、上端が縦方向の座標T、左端が横方向の座標Lの位置に来るように配置する。
データ抽出および表示
下記記事を参照。
全データ選択・全データ選択解除
「全データ選択」マクロの中身は下記のようになっている。
Sub 全データ選択()
Dim CB As Object
For Each CB In Worksheets(1).OLEObjects
CB.Object.Value = True
Next
End Sub
中身としてはシンプルで、For~Each構文で全てのチェックボックスを対象に挙げ、全てのチェックボックスの値が「True」、つまりチェックボックスがONになるようにしている。
「全データ選択解除」マクロも「全データ選択」とコード自体はほぼ同じである。
Sub 全データ選択解除()
Dim CB As Object
For Each CB In Worksheets(1).OLEObjects
CB.Object.Value = False
Next
End Sub
ただしチェックボックスの値を「False」にすることで、すべてのチェックボックスをOFFにするようにしている。
グラフ作成
「グラフ作成」マクロの中身は下記のようになっている。
Sub グラフ作成()
Dim GraphA As Shape
Dim GraphB As Shape
Dim i As Long
Dim j As Long
Dim Wmin As Variant
Dim Wmax As Variant
Dim Wmini As Variant
Dim Wmaxi As Variant
Set GraphA = Worksheets(1).Shapes.AddChart2(XlChartType:=xlXYScatterSmoothNoMarkers)
With GraphA
.Top = Worksheets(1).Range("H6:M6").Top
.Left = Worksheets(1).Range("H6:M6").Left
.Width = Worksheets(1).Range("H6:M6").Width
.Chart.ChartTitle.Text = Worksheets(1).Range("H3").Value
End With
Set GraphB = Worksheets(1).Shapes.AddChart2(XlChartType:=xlXYScatterSmoothNoMarkers)
With GraphB
.Top = Worksheets(1).Range("H18:M18").Top
.Left = Worksheets(1).Range("H18:M18").Left
.Width = Worksheets(1).Range("H18:M18").Width
.Chart.ChartTitle.Text = Worksheets(1).Range("I3").Value
End With
For i = 2 To Worksheets.Count
j = 1
Do Until IsNumeric(Worksheets(i).Cells(j, 1)) = True And Worksheets(i).Cells(j, 1).Value <> "" _
And IsNumeric(Worksheets(i).Cells(j + 1, 1)) = True And Worksheets(i).Cells(j + 1, 1).Value <> "" _
And IsNumeric(Worksheets(i).Cells(j + 2, 1)) = True And Worksheets(i).Cells(j + 2, 1).Value <> "" _
And IsNumeric(Worksheets(i).Cells(j + 3, 1)) = True And Worksheets(i).Cells(j + 3, 1).Value <> "" _
And IsNumeric(Worksheets(i).Cells(j + 4, 1)) = True And Worksheets(i).Cells(j + 4, 1).Value <> ""
j = j + 1
Loop
With GraphA.Chart
.SeriesCollection.NewSeries
.FullSeriesCollection(i - 1).Name = Worksheets(1).Cells(i + 6, 3).Value
.FullSeriesCollection(i - 1).XValues = Worksheets(i).Range(Worksheets(i).Cells(j, 1), Worksheets(i).Cells(j, 1).End(xlDown))
.FullSeriesCollection(i - 1).Values = Worksheets(i).Range(Worksheets(i).Cells(j, 2), Worksheets(i).Cells(j, 2).End(xlDown))
If Worksheets(1).OLEObjects("CheckBox" & i - 1).Object.Value = True Then
.FullSeriesCollection(i - 1).IsFiltered = False
Else
.FullSeriesCollection(i - 1).IsFiltered = True
End If
End With
With GraphB.Chart
.SeriesCollection.NewSeries
.FullSeriesCollection(i - 1).Name = Worksheets(1).Cells(i + 6, 3).Value
.FullSeriesCollection(i - 1).XValues = Worksheets(i).Range(Worksheets(i).Cells(j, 1), Worksheets(i).Cells(j, 1).End(xlDown))
.FullSeriesCollection(i - 1).Values = Worksheets(i).Range(Worksheets(i).Cells(j, 3), Worksheets(i).Cells(j, 3).End(xlDown))
If Worksheets(1).OLEObjects("CheckBox" & i - 1).Object.Value = True Then
.FullSeriesCollection(i - 1).IsFiltered = False
Else
.FullSeriesCollection(i - 1).IsFiltered = True
End If
End With
Wmaxi = WorksheetFunction.Max(Worksheets(i).Range(Worksheets(i).Cells(j, 1), Worksheets(i).Cells(j, 1).End(xlDown)))
If Wmaxi <> Int(Wmaxi) Then
Wmaxi = Int(Wmaxi) + 1
End If
If i = 2 Then
Wmax = Wmaxi
ElseIf Wmax < Wmaxi Then
Wmax = Wmaxi
End If
Wmini = Int(WorksheetFunction.Min(Worksheets(i).Range(Worksheets(i).Cells(j, 1), Worksheets(i).Cells(j, 1).End(xlDown))))
If i = 2 Then
Wmin = Wmini
ElseIf Wmin > Wmini Then
Wmin = Wmini
End If
Next
i = Worksheets.Count
Do While GraphA.Chart.FullSeriesCollection.Count <> Worksheets.Count - 1
GraphA.Chart.FullSeriesCollection(i).Delete
Loop
i = Worksheets.Count
Do While GraphB.Chart.FullSeriesCollection.Count <> Worksheets.Count - 1
GraphB.Chart.FullSeriesCollection(i).Delete
Loop
With GraphA.Chart
.Axes(xlCategory).MinimumScale = Wmin
.Axes(xlCategory).MaximumScale = Wmax
.Axes(xlCategory, xlPrimary).HasTitle = True
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = Worksheets(1).Range("L3").Value
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = Worksheets(1).Range("J3").Value
.SetElement (msoElementLegendRight)
End With
With GraphB.Chart
.Axes(xlCategory).MinimumScale = Wmin
.Axes(xlCategory).MaximumScale = Wmax
.Axes(xlCategory, xlPrimary).HasTitle = True
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = Worksheets(1).Range("L3").Value
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = Worksheets(1).Range("K3").Value
.SetElement (msoElementLegendRight)
End With
End Sub
大きく分けると、変更点が1つ、追加点が1つある。
変更点は、データ系列を参照する「SerisesCollection」のほとんどを「FullSeriesCollection」に変更したことである。
両者の違いは、フィルターで除外されたデータ系列を含むか否かにある。
SerisesCollection
⇒ フィルターで除外されていない(グラフ表示がONになっている)データ系列のみ操作。
FullSeriesCollection
⇒ フィルターで除外されている(グラフ表示がOFFになっている)データ系列を含む全てのデータ系列を操作。
下図において、チェックがついているデータ系列のみを扱うのが「SeriesCollection」、チェックが付いていないデータ系列を含めすべてのデータ系列を扱うのが「FullSeriesCollection」である。
追加点は、チェックボックスのON/OFFでグラフの表示/非表示を切り替えるコードを挿入したことである。
If Worksheets(1).OLEObjects("CheckBox" & i - 1).Object.Value = True Then
.FullSeriesCollection(i - 1).IsFiltered = False
Else
.FullSeriesCollection(i - 1).IsFiltered = True
End If
チェックボックスの値が「True」、すなわちチェックボックスがONならグラフを表示、チェックボックスの値が「False」、すなわちチェックボックスがOFFならグラフを非表示にする。
(変数).Chart.FullSeriesCollection(i).IsFiltered = True/False
⇒ 変数に格納したグラフのi番目のデータ系列のグラフを、「True」なら非表示、「False」なら表示する。
データファイル転記シートおよびグラフの削除
「データファイル転記シートおよびグラフの削除」マクロの中身は下記のようになっている。
Sub データファイル転記シートおよびグラフの削除()
Dim i As Long
Dim shp As Shape
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Do While Worksheets.Count <> 1
Worksheets(2).Delete
Loop
Worksheets(1).Range("B8", ActiveCell.SpecialCells(xlLastCell)).Select
Selection.Clear
For Each shp In Worksheets(1).Shapes
If shp.Type = msoChart Or shp.Type = msoOLEControlObject Then
shp.Delete
End If
Next
Worksheets(1).Range("A1").Select
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
以前作成したマクロとほとんど変わらないが、図表削除のコード
For Each shp In Worksheets(1).Shapes
If shp.Type = msoChart Or shp.Type = msoOLEControlObject Then
shp.Delete
End If
Next
のみ太字部分を追加して、チェックボックスをグラフと一緒に削除している。
その他のコードについては下記記事を参照。
グラフ削除
下記記事を参照。
終わりに
最近仕事の都合でマクロを扱う機会が少なくなり、ネタがなくなってきた。
マクロだけでなくPythonもやりたいし、他にもやりたいことが多い。
なんか久々に本屋でじっくり本を吟味してみたい衝動に駆られている…
引越先にも本屋はあるのだが、ジュンク堂レベルの大型書店で時間が許す限り本を見たい…
END
コメント