【发布时间】:2017-02-20 09:22:16
【问题描述】:
我有一个从工作表中获取数据并创建图表的代码。在源表中,每一列都是一个系列,系列的数量可能会发生变化。
我的代码的作用:它读取使用的范围,以便绘制值。
Obs1:我创建的时间序列中的2个,数据是年化的,所以我倒数计算,如果之前的数据小于一年,代码显示为“没有足够的数据”。
问题:如果我使用 2 个时间序列(2 列)运行代码,我会在图表中得到两条线。但是,如果我随后删除其中一个系列并再次运行它,我会在图表中得到一条带值的线和第二条空线。
问题:如何解决这个问题?
我已经尝试过的: 我正在尝试更改引用范围的方式,以便它重新运行代码,它只返回到图表中具有值的行。问题是我找不到这样正确引用范围的方法。
相关部分代码:
Function Grapher(ChartSheetName As String, SourceWorksheet As String, ChartTitle As String, secAxisTitle As String)
Dim lColumn As Long, lRow As Long
Dim LastColumn As Long, LastRow As Long
Dim RetChart As Chart
Dim w As Workbook
Dim RetRange As Range
Dim chrt As Chart
Dim p As Integer
Dim x As Long, y As Long
Dim numMonth As Long
Dim d1 As Date, d2 As Date
Dim i As Long
Set w = ThisWorkbook
'find limit
LastColumn = w.Sheets(SourceWorksheet).Cells(1, w.Sheets(SourceWorksheet).Columns.Count).End(xlToLeft).column
LastRow = w.Sheets(SourceWorksheet).Cells(w.Sheets(SourceWorksheet).Rows.Count, "A").End(xlUp).Row
'check for sources that do not have full data
'sets the range
i = 3
If SourceWorksheet = "Annualized Ret" Or SourceWorksheet = "Annualized Vol" Then
Do While w.Worksheets(SourceWorksheet).Cells(i, 2).Text = "N/A"
i = i + 1
Loop
'##### this is the part I believe is giving the problem:
'##### the way to reference the last cell keeps getting the number of columns (for the range) from the original column count.
Set RetRange = w.Worksheets(SourceWorksheet).Range(w.Worksheets(SourceWorksheet).Cells(i, 1), w.Worksheets(SourceWorksheet).Cells.SpecialCells(xlLastCell)) '****************
Else
Set RetRange = w.Sheets(SourceWorksheet).UsedRange
'Set RetRange = w.Sheets(SourceWorksheet).Range("A1:" & Col_Letter(LastColumn) & LastRow)
End If
'''''''''''''''''''''''
For Each chrt In w.Charts
If chrt.Name = ChartSheetName Then
Set RetChart = chrt
RetChart.Activate
p = 1
End If
Next chrt
If p <> 1 Then
Set RetChart = Charts.Add
End If
'count the number of months in the time series, do the ratio
d1 = w.Sheets(SourceWorksheet).Range("A2").Value
d2 = w.Sheets(SourceWorksheet).Range("A" & LastRow).Value
numMonth = TestDates(d1, d2)
x = Round((numMonth / 15), 1)
'ratio to account for period size
If x < 3 Then
y = 1
ElseIf x >= 3 And x < 7 Then
y = 4
ElseIf x > 7 Then
y = 6
End If
'create chart
With RetChart
.Select
.ChartType = xlLine
.HasTitle = True
.ChartTitle.Text = ChartTitle
.SetSourceData Source:=RetRange
.Axes(xlValue).MaximumScaleIsAuto = True
.Axes(xlCategory, xlPrimary).HasTitle = True
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Date"
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = secAxisTitle
.Name = ChartSheetName
.SetElement (msoElementLegendBottom)
.Axes(xlCategory).TickLabelPosition = xlLow
.Axes(xlCategory).MajorUnit = y
.Axes(xlCategory).MajorUnitScale = xlMonths
'sets header names for modified sources
If SourceWorksheet = "Drawdown" Then
For lColumn = 2 To LastColumn
.FullSeriesCollection(lColumn - 1).Name = "=DD!$" & Col_Letter(lColumn) & "$1"
.FullSeriesCollection(lColumn - 1).Values = "=DD!$" & Col_Letter(lColumn) & "$3:$" & Col_Letter(lColumn) & "$" & LastRow
Next lColumn
ElseIf SourceWorksheet = "Annualized Ret" Then
For lColumn = 2 To LastColumn
.FullSeriesCollection(lColumn - 1).Name = "='Annualized Ret'!$" & Col_Letter(lColumn) & "$1"
Next lColumn
ElseIf SourceWorksheet = "Annualized Vol" Then
For lColumn = 2 To LastColumn
.FullSeriesCollection(lColumn - 1).Name = "='Annualized Vol'!$" & Col_Letter(lColumn) & "$1"
Next lColumn
End If
End With
End Function
Obs2:我的代码目前功能正常(有些功能我没有添加,以免浪费更多空间)。
【问题讨论】:
-
您是否尝试过将数据转换为表格,然后图表会随着数据的变化而自动调整?
-
@SJR 不,我没有。愿意举例说明如何做到这一点?
-
@DGMS89 : support.office.com/en-us/article/… 这应该解释很多,简而言之,Excel 表是智能对象(VBA 中的
ListObjects),如果您在之后的下一个可用行中添加数据,它将扩展表,所以应该有助于解决您的问题! ;) -
@R3uK 我读过它,现在正尝试使用该表。一个问题:表格可以直接在图表中使用(作为一个范围)?
-
@DGMS89 :是的,当您选择数据时,您会看到它将使用表格而不是基本的 Excel 引用。记录一个宏,看看它在代码中的样子,并尝试用这种格式更新你的! ;)