web-dev-qa-db-ja.com

VBAを使用したグラフデータラベルの書式設定

たくさんのグラフを含むダッシュボードを開発しています。これらのグラフに表示されるデータが変わると、数値の形式も変わります。現在、グラフ内のすべてのシリーズをループしている最中に、データの基になっているスプレッドシートから目的のフォーマットコードを取得しようとして問題が発生しました。これまでのコードは次のとおりです。

Sub FixLabels(whichchart As String)
Dim cht As Chart
Dim i, z As Variant
Dim seriesname, seriesfmt As String
Dim seriesrng As Range

Set cht = Sheets("Dashboard").ChartObjects(whichchart).Chart

    For i = 1 To cht.SeriesCollection.Count
        If cht.SeriesCollection(i).name = "#N/D" Then
            cht.SeriesCollection(i).DataLabels.ShowValue = False
            Else
            cht.SeriesCollection(i).DataLabels.ShowValue = True
                seriesname = cht.SeriesCollection(i).name
                Debug.Print seriesname

これにより、エラーが発生しないシリーズの名前を取得し、エラーが発生するシリーズを非表示にすることができます。ここまでは順調ですね。次にフォーマットについて説明します。このワークブックで使用可能なすべてのシリーズ名が格納されている列があり、左側の1列には、整数の場合は「int」、整数の場合は「#、#」のフォーマットコードがあります。重要な小数点以下の桁数、およびパーセント率の「%」。これらはプレーンテキストとして保存されます。したがって、コードの最後のビットは次のようになります。

Select Case seriesfmt
   Case "int"
      Cht.SeriesCollection(i).DataLabels.NumberFormat = "#"
   Case "#,#"
      Cht.SeriesCollection(i).DataLabels.NumberFormat = "#,###"
   Case "%"
      Cht.SeriesCollection(i).DataLabels.NumberFormat = "#.0%"
End Select
End If
Next i

最後に、ここでの本当の問題は、その間にあるものです。シリーズフォーマットが取得できません!私の最善の推測は:

With Sheets("CxC").Range("K22:K180")
seriesfmt = .Find(seriesname).Offset(0, -1).Value
End With

Withブロックが定義されていないとのエラーが発生しました。 Withメソッドの有無にかかわらず、Setメソッドの有無にかかわらず、同じコマンドのいくつかの組み合わせを試しましたが、WorksheetFunctionMatchを試しましたが役に立ちませんでした。この問題を解決するための助けは大いに感謝されます!

5
Gabriel Menezes

Formulaプロパティを使用して、シリーズソース範囲に登ることができます。

それはフォーマットを持っているので:

=SERIES(,,sheetname!sheetRange,)

次に、区切り文字として「、」を使用して配列に分割すると、その「3番目の要素」に関心があります。

だからあなたはコーディングすることができます:

Sub FixLabels(whichchart As String)
    Dim cht As Chart
    Dim i As Long

    With Sheets("Dashboard").ChartObjects(whichchart).Chart '<--| reference your chart
        For i = 1 To .SeriesCollection.Count '<--| loop through all series
            With .SeriesCollection(i) '<--| reference current series
                If .Name = "#N/D" Then
                    .DataLabels.ShowValue = False
                Else
                    .HasDataLabels = True '<--| be sure labels are "activated"
                    .DataLabels.ShowValue = True '<--| show data labels
                    .DataLabels.NumberFormat = GetFormat(Split(.Formula, ",")(2)) '<-- set data label format
                End If
            End With
        Next i
    End With
End Sub


Function GetFormat(dataSource As Variant) As String
    With Range(dataSource).Cells(1, 1) '<-- reference the first cell of the data source
        Select Case True
            Case InStr(.Text, "%") > 0
                GetFormat = "#.0%"
            Case Int(CDbl(.Text)) = CDbl(.Text)
                GetFormat = "#"
            Case Else
                GetFormat = "#,###"
        End Select
    End With
End Function
3
user3598756