Excel VBA:创建一个基于值而不是系列排序的簇状柱形图?

Excel VBA: Create a clustered column chart that sorts based on value not series?

这是我的问题:我有 user-specified 数量的数据集,我想将其绘制在聚集柱形图上。我在 visual basic 中创建图表并将数据集添加为单独的系列,以便它们可以通过颜色区分并在图例上具有不同的标题:

ActiveWorkbook.Charts.Add 'all of this just adds a new chart
ActiveChart.ChartArea.Select
With ActiveChart
    .ChartType = xlColumnClustered
    .HasTitle = True
    .ChartTitle.Text = "Ordered Distribution Graph"
    .Axes(xlCategory, xlPrimary).HasTitle = True
    .Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Item"
    .Axes(xlCategory, xlPrimary).CategoryType = xlCategoryScale
    .Axes(xlValue, xlPrimary).HasTitle = True
    .Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "Total"
    .Legend.Position = xlLegendPositionBottom
End With

ActiveSheet.Move After:=Sheets(ActiveWorkbook.Sheets.count)
ActiveSheet.Name = "Distribution Chart"

For j = 0 To UBound(chartLabels) 'here is where I handle the data based on global variables
    If IsEmpty(chartLabels(j)) Then Exit For
    Erase xval
    Erase yval
    ReDim Preserve xval(0 To 0)
    ReDim Preserve yval(0 To 0)
    xval(0) = chartData(0, j, 0)
    yval(0) = chartData(2, j, 0)

    For i = 0 To UBound(chartData, 3) - 1
        If Not IsEmpty(chartData(2, j, i + 1)) Then
            ReDim Preserve xval(0 To i + 1)
            ReDim Preserve yval(0 To i + 1)
            xval(i + 1) = chartData(0, j, i + 1)
            yval(i + 1) = chartData(2, j, i + 1)
        End If
    Next

    Call bubblesortData(j, UBound(xval)) 'separate sort function

    ActiveChart.SeriesCollection.NewSeries 'plots each series
    ActiveChart.SeriesCollection(j + 1).XValues = xval
    ActiveChart.SeriesCollection(j + 1).Values = yval
    ActiveChart.SeriesCollection(j + 1).Name = main.chartLabels(j)
    ActiveChart.ChartGroups(1).GapWidth = 10
    ActiveChart.ChartGroups(1).Overlap = -10
Next

Sheets(ActiveWorkbook.Sheets.count).Activate

目前,每组数据使用bubblesortData(setNumber, numberOfDataPoints)子程序排序(xval和yval是全局数组):

Sub bubblesortLosses(b As Variant, tot As Variant)
Dim changed As Integer, temp As Variant

Do
changed = 0
    For i = 0 To tot - 1
    If Not IsEmpty(xval(i)) Then
        If yval(i) > yval(i + 1) Then
            temp = xval(i)
            xval(i) = xval(i + 1)
            xval(i + 1) = temp
            temp = yval(i)
            yval(i) = yval(i + 1)
            yval(i + 1) = temp
            changed = 1
        End If
    End If
    Next

Loop Until changed = 0
End Sub

这工作正常,但结果如下:

每组都是根据我的排序排序的,但我希望 所有 的数据根据​​ y-axis 值排序。我想不出一种方法来实现这一点,同时还保持数据按系列分开。有没有办法根据相应的 y-axis 值而不是基于系列位置来显示 x-axis 值??

经过大量搜索,我找到了适合我的解决方案组合,主要是从这个 link 中提取信息:http://peltiertech.com/chart-with-a-dual-category-axis/

...以及来自各种 Whosebug 的帖子,表明以编程方式执行此操作是不可能的,必须通过对我有用的工作表来完成。我像上面 link 那样填写了工作表单元格,除了使用 Visual Basic。然后,在绘制数据图表后,我隐藏了工作表。这对我有用,因为每次用户使用新数据集重新开始时都会清除工作表。这是我的代码:

Sub Distribution()
Dim runningTotal, seriesNumber, sheetName

seriesNumber = 1
runningTotal = 2

currDist = currDist + 1
sheetName = "DistData" + CStr(currDist)

ActiveWorkbook.Sheets.Add
ActiveSheet.Move After:=Sheets(ActiveWorkbook.Sheets.count)
ActiveSheet.Name = sheetName
ActiveSheet.Visible = True

For j = 0 To UBound(chartLabels)
    If IsEmpty(chartLabels(j)) Then Exit For
    Erase xval
    Erase yval
    ReDim Preserve xval(0 To 0)
    ReDim Preserve yval(0 To 0)
    xval(0) = chartData(0, j, 0)
    yval(0) = chartData(2, j, 0)

    For i = 0 To UBound(chartData, 3) - 1
        If Not IsEmpty(chartData(2, j, i + 1)) Then
            ReDim Preserve xval(0 To i + 1)
            ReDim Preserve yval(0 To i + 1)
            xval(i + 1) = chartData(0, j, i + 1)
            yval(i + 1) = chartData(2, j, i + 1)
        End If
    Next

    Call bubblesortLosses(j, UBound(xval))

    Sheets(sheetName).Select

    Cells(1, seriesNumber + 2) = chartLabels(j)
    Cells(runningTotal, 1) = chartLabels(j)

    For k = 0 To UBound(xval)
        Cells(runningTotal, 2) = xval(k)
        Cells(runningTotal, seriesNumber + 2) = yval(k)
        runningTotal = runningTotal + 1
    Next

    seriesNumber = seriesNumber + 1

Next

ActiveWorkbook.Charts.Add
ActiveChart.ChartArea.Select
With ActiveChart
    .ChartType = xlColumnStacked
    .HasTitle = True
    .ChartTitle.Text = "Ordered Distribution Graph"
    .Axes(xlCategory).TickLabels.MultiLevel = True
    .Axes(xlCategory).HasTitle = True
    .Axes(xlCategory).AxisTitle.Characters.Text = "Item"
    .Axes(xlCategory).CategoryType = xlCategoryScale
    .Axes(xlValue).HasTitle = True
    .Axes(xlValue).AxisTitle.Characters.Text = "Total"
    .Legend.Position = xlLegendPositionBottom
End With

ActiveSheet.Move After:=Sheets(ActiveWorkbook.Sheets.count)
ActiveSheet.Name = "Distribution " + CStr(currDist)

ActiveChart.ChartGroups(1).GapWidth = 10
ActiveChart.ChartGroups(1).Overlap = 100

Sheets(sheetName).Visible = False
Sheets(ActiveWorkbook.Sheets.count).Activate

End Sub

bubblesort 子例程与问题中使用的相同。我的其中一项测试的最终结果如下:

列出了商品编号,但出于保密原因,图片中的类别标签被删掉了。它们读起来类似于 "Series 1"、"Series 2" 和 "Series 3"