AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / computer / 问题 / 1662727
Accepted
Lluser
Lluser
Asked: 2021-07-16 02:55:35 +0800 CST2021-07-16 02:55:35 +0800 CST 2021-07-16 02:55:35 +0800 CST

Excel - (柱形)图表 - 数据系列的 Z-index 根据实际值

  • 772

我有一个包含多个数据系列的柱形图。例如:

示例数据

默认柱形图

我不想让列彼此相邻,所以我设置了 reduceSeries overlap和Gap widthinFormat Data Series...

我得到了什么

现在这个系列是一个在另一个之上。但是它们的 Z 索引(Z 位置)是由图表中的系列顺序定义的,因此当最后一个系列具有最高值时,它的列会超出其他不可见的列。

是否可以根据实际值对列进行排序?我想把最小值放在最前面。就像在这张图片中一样(这里使用了古老的 mspaint-fu :))。

我想得到什么
(//已编辑 - 第一个版本被错误地绘制了)

PS:我需要它来处理非常大的数据系列(它看起来像直方图),所以我绝对不想把这些列放在一起。但它可能会被“过滤”到低系列视图,其中使用其他图表类型可能会导致显示这些离散值的失真。

感谢您的建议!

microsoft-excel microsoft-excel-2013
  • 2 2 个回答
  • 132 Views

2 个回答

  • Voted
  1. Best Answer
    Andi Mohr
    2021-07-16T05:07:18+08:002021-07-16T05:07:18+08:00

    一种方法是创建一个处理表来计算系列的升序。

    在此处输入图像描述

    列 E:G 使用公式计算出第一个最小的、第二个最小的等等SMALL(),其中第一个参数是您的值行,第二个参数是排名 - 所以单元格 E3 是=SMALL($A3:$C3,1)、 F3=SMALL($A3:$C3,2)和 G3 =SMALL($A3:$C3,3)。复制尽可能多的行,如果超过 3 个系列,则根据需要添加尽可能多的列。

    然后我们需要一个处理表,显示在 J:R 列中。

    每个系列都有一个列,每个可能的位置都按升序排列。在“第 1”列组中,在 J 列中,我们可以使用公式检查 A 系列是否是第一个最小系列

    `=IF(E3=A3,A3,0)`
    

    如果存在匹配,则显示该系列的值。如果不是,则显示零。

    现在,如果您使用范围 J2:R6 创建簇状柱形图并应用 100% 系列重叠,您会发现需要重新排序列。使用“选择数据”对话框重新排列列,使 3C 位于顶部,1A 位于底部。

    在此处输入图像描述

    最后,更改每个系列的颜色。所有 A 系列必须为蓝色,所有 B 系列必须为橙色,C 均为灰色(或任何您的实际颜色)。

    • 1
  2. Lluser
    2021-07-29T05:46:19+08:002021-07-29T05:46:19+08:00

    我为Andi Mohr 的解决方案自动化创建了宏。也许有人觉得它有用。

    特点/限制:

    • 适用于垂直柱形图
    • 为所需的所有部分系列创建带有列的“帮助”表。
    • 期望列中的数据系列
    • 禁用项目系列(在“选择数据源”中)可能会破坏宏!
    • “帮助”表可以移动到另一张表
    • 保持与原始表的交互性
    • 列颜色(填充)从源图表复制

    用法

    1. 将代码复制到 VBA 模块中
    2. 选择源表
    3. 运行宏

    动图

    宏使用示例

    代码

    Option Explicit
    
    Public Sub Chart_ZIndexAdjusted()
        Dim SourceChart As Chart
        Set SourceChart = ActiveChart
        
        If SourceChart Is Nothing Then
            Call MsgBox("No chart selected." & vbNewLine & "(Do not select chart Axis!)", vbOKOnly + vbExclamation, "Error")
            Exit Sub
        End If
        
        'Check Chart type
        Select Case SourceChart.ChartType
        Case xlColumnClustered 'comma separated values
            Debug.Print "ChartType OK"
        Case Else
            Call MsgBox("ChartType: " & CStr(SourceChart.ChartType) & " is not supported." & vbNewLine & vbNewLine & "More about ChartTypes: https://docs.microsoft.com/en-us/office/vba/api/excel.xlcharttype", vbOKOnly + vbExclamation, "Error")
            Exit Sub
        End Select
        
        Dim SeriesCol As SeriesCollection
        Set SeriesCol = SourceChart.SeriesCollection 'All series from the chart
        
        Dim ValRng() As Range
        ReDim ValRng(1 To SeriesCol.Count) 'Range arrays for each series
        
        Dim NameRng() As Range
        ReDim NameRng(1 To SeriesCol.Count) 'Range with name for each series
        
        Dim CategoriesVal As String 'Value specifying categories
        
        Dim SeriesCount As Long
        SeriesCount = SeriesCol.Count
        
        'Ranges addresses could be retrieved for each series from its Formula property
        Dim i As Long
        For i = 1 To SeriesCount
            Dim FormulaParts() As String
            FormulaParts = Split(SeriesCol(i).Formula, ",")
    
            Set NameRng(i) = Range(Mid(FormulaParts(0), Len("=SERIES(") + 1, Len(FormulaParts(0)) - Len("=SERIES(")))
            Set ValRng(i) = Range(FormulaParts(2))
            If i = 1 Then
                    CategoriesVal = FormulaParts(1)
            End If
        Next i
        
        'Check if all data are in one "table" and sheet
        Dim ValuesStartRow As Long
        Dim ValuesLength As Long
        Dim Sheet As Worksheet
        ValuesStartRow = ValRng(1).Cells.Item(1).Row
        ValuesLength = ValRng(1).Cells.Rows.Count
        Set Sheet = ValRng(1).Parent
        For i = 2 To SeriesCol.Count
            If Not ((ValuesStartRow = ValRng(i).Cells.Item(1).Row) _
                    And (ValuesLength = ValRng(i).Cells.Rows.Count) _
                    And (Sheet Is ValRng(i).Parent)) _
            Then
                Call MsgBox("Chart values are not on same sheet or lines or series does not have same length", vbOKOnly + vbExclamation, "Error")
                Exit Sub
            End If
        Next i
        
        Dim NTName As String 'Name for a new table for chart
        NTName = SourceChart.Name & "_InputData"
        
        'Look for old table and remove it
        With Sheet.ListObjects
            For i = 1 To .Count
                If .Item(i).Name = NTName Then
                    .Item(i).Delete
                End If
            Next i
        End With
        
        'check if there is space for table headers
        If ValuesStartRow < 2 Then
            Call MsgBox("No space for a new table headers" & vbNewLine & "(Add a row on top of the sheet and try it again.)", vbOKOnly + vbExclamation, "Error")
        End If
        
        Dim NTRange As Range 'New Table Range
        Set NTRange = Sheet.Cells(ValuesStartRow - 1, Sheet.UsedRange.Columns.Count + 3) 'Placed two cells right from most right cell in the sheet
        
        Dim NTCols As Long
        NTCols = SeriesCount * SeriesCount 'Count of columns needed is series count ^2
        
        Set NTRange = NTRange.Resize(ValuesLength, NTCols)
        'NTRange.Select
     
        Dim NT As ListObject 'A new table for a new chart
        Set NT = Sheet.ListObjects.Add(xlSrcRange, NTRange)
        NT.Name = SourceChart.Name & "_InputData"
        NT.Range.Select 'Select a new table (it scrolls to its position)
        
        'Populate a new table headers
        Dim j As Long
        With NT.HeaderRowRange.Cells
            For i = 1 To SeriesCount
                For j = 1 To SeriesCount
                    .Item((i - 1) * SeriesCount + j).Value2 = NameRng(j).Value2 & CStr(i)
                Next j
            Next i
        End With
        
        'Populate New Table with
        With NT.ListColumns
            For i = 1 To SeriesCount 'i is Z-index of column of the New Table
                Dim AllValsArray As String 'Array of addresses of all first series values
                AllValsArray = ValRng(1).Item(1).Address(False, False) 'The initial (1st) value (without delimiter)
                For j = 2 To SeriesCount
                    AllValsArray = AllValsArray & "," & ValRng(j).Item(1).Address(False, False) 'delimiter + added value
                Next j
                
                Dim FormulaText As String
                For j = 1 To SeriesCount
                    Dim ValueCellAddr As String 'Address of first cell with series values
                    ValueCellAddr = ValRng(j).Item(1).Address(False, False)
                    'Set text of formula
                    FormulaText = "=IF(RANK.EQ(" & ValueCellAddr & ",(" & AllValsArray & "),0)=" & i & "," & ValueCellAddr & ",0)"
                    'Insert formula to the first cell of the column
                    .Item((i - 1) * SeriesCount + j).DataBodyRange.Formula = FormulaText
                Next j
            Next i
        End With
        
        Dim ChObj As ChartObject 'Chartobject for selected chart
        For Each ChObj In Sheet.ChartObjects
            If ChObj.Chart Is SourceChart Then
                Exit For
            End If
        Next ChObj
        
        Dim NTChName As String 'Name for a new chart
        NTChName = ChObj.Name & "_ZindexAdjusted"
        
        'Find and delete existing Z-index Adjusted chart
        With Sheet.ChartObjects
            For i = 1 To .Count
                If .Item(i).Name = NTChName Then
                    Call .Item(i).Delete
                End If
            Next i
        End With
    
        Dim NTChObj As Object 'Must be Object Type! See: https://docs.microsoft.com/en-us/office/vba/api/excel.worksheet.chartobjects#return-value
        Set NTChObj = ChObj.Duplicate 'Create copy of the chart
        NTChObj.Name = NTChName 'Rename a new chart
        
        Dim FillColor() As Long
        ReDim FillColor(1 To SeriesCount)
        Dim LineColor() As Long
        ReDim LineColor(1 To SeriesCount)
        
        With SourceChart.SeriesCollection
            For i = 1 To SeriesCount
                'Saves color from the original chart
                FillColor(i) = SourceChart.SeriesCollection.Item(i).Format.Fill.ForeColor.RGB
                'LineColor(i) = SourceChart.SeriesCollection.Item(i).Format.Line.Forecolor.RGB
            Next i
        End With
    
        'Remove all series in copied chart
        With NTChObj.Chart.SeriesCollection
            For i = 1 To .Count
                .Item(1).Delete 'Item(1) because collection is re-numbered during loop
            Next i
            
            'Create a new series from the new table
            For i = 1 To NTCols
                Call .Add(NT.ListColumns.Item(i).Range, xlColumns, True, False) 'Add a new series
                With .Item(.Count).Format 'the last added series
                    'Set series colors (only the fill acc. to orginal chart)
                    .Fill.ForeColor.RGB = FillColor(i - (Fix((i - 1) / SeriesCount) * SeriesCount)) 'fix = trunc
                    '.Line.Forecolor.RGB = FillColor(i - (Fix((i - 1) / SeriesCount) * SeriesCount))
                End With
            Next i
        End With
        
        'Set copy catergories labels
        If Len(CategoriesVal) > 0 Then
            NTChObj.Chart.FullSeriesCollection(1).XValues = "=" & CategoriesVal
        End If
        
    'Lines bellow could be uncommented if you want features described in comments
    '============================================================================
    
    '    'Delete the original chart (not recommended)
    '    Call ChObj.Delete
    
    '    'Place the new chart over the original (original will be hidden under)
    '    NTChObj.Left = ChObj.Left
    '    NTChObj.Top = ChObj.Top
    
    End Sub
    
    • 0

相关问题

  • 带有“和”运算符的 Excel 数据透视表

  • 如何对整列使用 Excel 的 LENGTH 函数?

  • Excel 数组(2 个变量)

  • 如何从 WSL 打开 office 文件

  • VBA根据文件名重命名工作表

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何减少“vmmem”进程的消耗?

    • 11 个回答
  • Marko Smith

    从 Microsoft Stream 下载视频

    • 4 个回答
  • Marko Smith

    Google Chrome DevTools 无法解析 SourceMap:chrome-extension

    • 6 个回答
  • Marko Smith

    Windows 照片查看器因为内存不足而无法运行?

    • 5 个回答
  • Marko Smith

    支持结束后如何激活 WindowsXP?

    • 6 个回答
  • Marko Smith

    远程桌面间歇性冻结

    • 7 个回答
  • Marko Smith

    子网掩码 /32 是什么意思?

    • 6 个回答
  • Marko Smith

    鼠标指针在 Windows 中按下的箭头键上移动?

    • 1 个回答
  • Marko Smith

    VirtualBox 无法以 VERR_NEM_VM_CREATE_FAILED 启动

    • 8 个回答
  • Marko Smith

    应用程序不会出现在 MacBook 的摄像头和麦克风隐私设置中

    • 5 个回答
  • Martin Hope
    Saaru Lindestøkke 为什么使用 Python 的 tar 库时 tar.xz 文件比 macOS tar 小 15 倍? 2021-03-14 09:37:48 +0800 CST
  • Martin Hope
    CiaranWelsh 如何减少“vmmem”进程的消耗? 2020-06-10 02:06:58 +0800 CST
  • Martin Hope
    Jim Windows 10 搜索未加载,显示空白窗口 2020-02-06 03:28:26 +0800 CST
  • Martin Hope
    v15 为什么通过电缆(同轴电缆)的千兆位/秒 Internet 连接不能像光纤一样提供对称速度? 2020-01-25 08:53:31 +0800 CST
  • Martin Hope
    andre_ss6 远程桌面间歇性冻结 2019-09-11 12:56:40 +0800 CST
  • Martin Hope
    Riley Carney 为什么在 URL 后面加一个点会删除登录信息? 2019-08-06 10:59:24 +0800 CST
  • Martin Hope
    zdimension 鼠标指针在 Windows 中按下的箭头键上移动? 2019-08-04 06:39:57 +0800 CST
  • Martin Hope
    jonsca 我所有的 Firefox 附加组件突然被禁用了,我该如何重新启用它们? 2019-05-04 17:58:52 +0800 CST
  • Martin Hope
    MCK 是否可以使用文本创建二维码? 2019-04-02 06:32:14 +0800 CST
  • Martin Hope
    SoniEx2 更改 git init 默认分支名称 2019-04-01 06:16:56 +0800 CST

热门标签

windows-10 linux windows microsoft-excel networking ubuntu worksheet-function bash command-line hard-drive

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve