Vba 需要帮助制作动态图表吗
下午好!我是一名大学生,整个夏天都在为一家化工公司合作。我已经完成了Excel VBA编程中的一个非常基础的课程,所以我缺乏语言的工作基础。 最近,我的任务是在我的一位前任编写的代码的基础上进行构建,目的是生成动态图形 目标是:编写一个代码,在4个不同的图表(每个反应堆一个)上显示我公司2年内的17种不同产品。该工作簿大约有六张不同的数据表,其中一张有一个按钮,用户可以按下该按钮启动所有必要的数据计算、单元格填充和图形生成 由于这取决于客户需求,因此无法知道我们将在两年内生产17种产品中的每种产品多少批次。我的代码需要动态地说明这一点 我复习了两年前的课堂材料,并购买了John Walkenbach的2015 VBA Power编程书。我正在自学VBA代码,但仍然不完全理解其中一些代码是如何工作的。我希望这里的人能够解释为什么我的代码不起作用,以及我应该如何修复它 我开始的时候非常简单,目的是使用制作每个批次所需的总时间(周期时间)和批次完成的日期分别作为y和x值来绘制单个产品的两个批次。代码如下所示:Vba 需要帮助制作动态图表吗,vba,excel,dynamic,charts,Vba,Excel,Dynamic,Charts,下午好!我是一名大学生,整个夏天都在为一家化工公司合作。我已经完成了Excel VBA编程中的一个非常基础的课程,所以我缺乏语言的工作基础。 最近,我的任务是在我的一位前任编写的代码的基础上进行构建,目的是生成动态图形 目标是:编写一个代码,在4个不同的图表(每个反应堆一个)上显示我公司2年内的17种不同产品。该工作簿大约有六张不同的数据表,其中一张有一个按钮,用户可以按下该按钮启动所有必要的数据计算、单元格填充和图形生成 由于这取决于客户需求,因此无法知道我们将在两年内生产17种产品中的每种产
Sub Chart_Excerpt()
Sheets.Add After:=Sheets(Sheets.Count)
Sheets(Sheets.Count).Select
Sheets(Sheets.Count).Name = "G350 Charts"
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlXYScatter
ActiveChart.SeriesCollection(1).XValues = "='Biyearly Report'!$CY$802:$CY$803"
ActiveChart.SeriesCollection(1).Values = "='Biyearly Report'!$CZ$802:$CZ$803"
End Sub
该代码可以工作,但是它不是动态的。我尝试将End Sub之前的最后两行改为:
ActiveChart.SeriesCollection(1).Values = Range (Cells(802, 103), Cells(803, 103))
ActiveChart.SeriesCollection(1).Values = Range (Cells(802, 104), Cells(803, 104))
然后,我尝试用更好的方法(如abc和xyz)替换特定的非动态引用:
ActiveChart.SeriesCollection(1).Values = Range (Cells(abc, 103), Cells(xyz, 103))
ActiveChart.SeriesCollection(1).Values = Range (Cells(abc, 104), Cells(xyz, 104))
其中abc和xyz分别是数据选择的第一行和最后一行。它们是用一个简单的公式计算出来的,我验证了这个公式的正确性,它是基于一个前合作学生编写的一段代码。数据输入是垂直的,因此列数将保持不变,而行数将根据每个产品的批次数而变化
这不起作用,所以我取出了变量,重新输入了具体的参考802到803。令我惊讶的是,这也没用。从那以后,我了解到Excel VBA以数组的形式读取数据以进行系列收集,所以我知道我一定是因为试图强制它读取一个范围而设置了失败
但是,它对我的阵列也不起作用。以下是我的新代码:
Sub Chart_Excerpt()
Dim A() As Double, AA as Integer, s as Series, Result as Variant, N as Integer
'''Everything in above excerpt here [], but commented to be inactive
Call Data_Series
End Sub
“好的,好的”
“好的,好的”
不幸的是,无论我做什么,我都会继续收到“下标超出范围”、“用户定义错误”、“对象丢失”等错误消息。有没有办法为这样的图表动态编码?有没有人建议我下一步应该尝试什么
更新:
我能够完成的代码,它是完美的工作!感谢拜伦为我指明了正确的方向
以下是新的工作代码,以防其他人遇到类似问题并需要帮助:
Sub Graphing_for_G350(xval As Range, yval As Range, location As Integer)
Dim height As Double, width As Double, columns As Integer, cht_obj As ChartObject, ser As Series
Dim k As Integer, SIndex As Integer, a As Double, j As Integer, n As Integer
'Determines Chart size and location
height = 300
width = 300
columns = 1
j = 0
k = 0
n = 0
Set cht_obj = ActiveSheet.ChartObjects.Add((1 Mod columns) * width, (1 \ columns) * height, width, height)
'Determines the Series order based on product order in my company's spreadsheet
For SIndex = 1 To 17
If SIndex = 1 And CC2311endrowBR > 801 Then
a = CC2311endrowBR
ElseIf SIndex = 2 And dr22endrowBR > 801 Then
a = dr22endrowBR
ElseIf SIndex = 3 And dr22NCendrowBR > 801 Then
a = dr22NCendrowBR
ElseIf SIndex = 4 And NCYendrowBR > 801 Then
a = NCYendrowBR
ElseIf SIndex = 5 And RE100LendrowBR > 801 Then
a = RE100LendrowBR
ElseIf SIndex = 6 And RE100XLendrowBR > 801 Then
a = RE100XLendrowBR
ElseIf SIndex = 7 And RE105endrowBR > 801 Then
a = RE105endrowBR
ElseIf SIndex = 8 And RE110endrowBR > 801 Then
a = RE110endrowBR
ElseIf SIndex = 9 And RE25endrowBR > 801 Then
a = RE25endrowBR
ElseIf SIndex = 10 And RE80HPendrowBR > 801 Then
a = RE80HPendrowBR
ElseIf SIndex = 11 And RE85endrowBR > 801 Then
a = RE85endrowBR
ElseIf SIndex = 12 And RE85KendrowBR > 801 Then
a = RE85KendrowBR
ElseIf SIndex = 13 And RE85LendrowBR > 801 Then
a = RE85LendrowBR
ElseIf SIndex = 14 And RE85LKendrowBR > 801 Then
a = RE85LKendrowBR
ElseIf SIndex = 15 And RE98endrowBR > 801 Then
a = RE98endrowBR
ElseIf SIndex = 16 And XR4318endrowBR > 801 Then
a = XR4318endrowBR
ElseIf SIndex = 17 And XR4265endrowBR > 801 Then
a = XR4265endrowBR
Else
End If
'This loop for j determines the xval columns of the Series.
If j = 0 Then
j = 103
ElseIf j > 0 Then
j = j + 3
End If
'This loop for n determines the yval columns of the Series.
If n = 0 Then
n = 104
ElseIf n > 0 Then
n = n + 3
End If
'This determines the range with respect to the product just chosen in the If-Then statements above.
Set xval = Range(Cells(802, j), Cells(a, j))
Set yval = Range(Cells(802, n), Cells(a, n))
'Now to add the Series and name it.
Set ser = cht_obj.Chart.SeriesCollection.NewSeries
With ser
ser.ChartType = xlXYScatter
'This loop for k determines the name of the Series.
If k = 0 Then
k = 102
ElseIf k > 0 Then
k = k + 3
End If
'Defines Series Name and Values
ser.Name = Cells(802, k)
ser.Values = yval
ser.XValues = xval
End With
'Iterates the next Series Index to decide the next Series.
Next SIndex
End Sub
在我看来,你可以想一个不同的方法来做这件事,我会怎么做?我会在一个隐藏的工作表中创建一个dinamic表并从中拉一个滑块,从那里,从dinamic表中拉一个dinamic图,我的宏会改变滑块中的选择,这将使我的图成为dinamic,如果你已经知道要显示的列(sumifs(…),您可以简单地使用一系列公式并将图形指向这些公式,而我的宏只会更改公式用于获取关键字(产品)信息的关键字 您的实际代码是否真的有
m
而不是,
在范围内(Cells()m Cells())
bit?这会导致问题。另外,可以使用范围创建图表
,这是使其动态化的首选方法。有关如何使用VBA创建图表的简单说明,请参阅此答案:关于如何使范围
成为动态的,您需要研究范围之类的函数.End()
,范围.Offset()
,和范围.Resize()
,这将允许您“构建”基于代码或电子表格中包含的动态信息的范围。其他技巧包括:在电子表格中使用命名范围并在VBA中引用它们,使用For
或For Each
循环单元格,以基于单元格内容构建范围等。更具体的问题将得到更具体的答案这方面的回答。谢谢拜伦!不,m不在我的实际代码中;这是我遗漏的一个打字错误。谢谢你指出这一点。我将尝试你的建议,看看我能做些什么。祝你周末愉快!我使用你的建议和链接编写了一个新代码。它似乎工作得很好!一旦我对它进行了全面测试,我将在这里发布供参考敬请原谅,以防其他人有类似的问题。再次感谢您!谢谢您的建议!
Sub Read_Data_G350_CC2311(A() as Double, N as Integer, R as Integer, C as Integer)
Dim i as Integer, j as Integer
N = AA
'AA is defined as 'Public AA as Integer' in my code
For i = 802 to N
For j = 103 to 104
A(i, j) = Cells(i+R, j+C)
Next j
Next i
End Sub
Sub Graphing_for_G350(xval As Range, yval As Range, location As Integer)
Dim height As Double, width As Double, columns As Integer, cht_obj As ChartObject, ser As Series
Dim k As Integer, SIndex As Integer, a As Double, j As Integer, n As Integer
'Determines Chart size and location
height = 300
width = 300
columns = 1
j = 0
k = 0
n = 0
Set cht_obj = ActiveSheet.ChartObjects.Add((1 Mod columns) * width, (1 \ columns) * height, width, height)
'Determines the Series order based on product order in my company's spreadsheet
For SIndex = 1 To 17
If SIndex = 1 And CC2311endrowBR > 801 Then
a = CC2311endrowBR
ElseIf SIndex = 2 And dr22endrowBR > 801 Then
a = dr22endrowBR
ElseIf SIndex = 3 And dr22NCendrowBR > 801 Then
a = dr22NCendrowBR
ElseIf SIndex = 4 And NCYendrowBR > 801 Then
a = NCYendrowBR
ElseIf SIndex = 5 And RE100LendrowBR > 801 Then
a = RE100LendrowBR
ElseIf SIndex = 6 And RE100XLendrowBR > 801 Then
a = RE100XLendrowBR
ElseIf SIndex = 7 And RE105endrowBR > 801 Then
a = RE105endrowBR
ElseIf SIndex = 8 And RE110endrowBR > 801 Then
a = RE110endrowBR
ElseIf SIndex = 9 And RE25endrowBR > 801 Then
a = RE25endrowBR
ElseIf SIndex = 10 And RE80HPendrowBR > 801 Then
a = RE80HPendrowBR
ElseIf SIndex = 11 And RE85endrowBR > 801 Then
a = RE85endrowBR
ElseIf SIndex = 12 And RE85KendrowBR > 801 Then
a = RE85KendrowBR
ElseIf SIndex = 13 And RE85LendrowBR > 801 Then
a = RE85LendrowBR
ElseIf SIndex = 14 And RE85LKendrowBR > 801 Then
a = RE85LKendrowBR
ElseIf SIndex = 15 And RE98endrowBR > 801 Then
a = RE98endrowBR
ElseIf SIndex = 16 And XR4318endrowBR > 801 Then
a = XR4318endrowBR
ElseIf SIndex = 17 And XR4265endrowBR > 801 Then
a = XR4265endrowBR
Else
End If
'This loop for j determines the xval columns of the Series.
If j = 0 Then
j = 103
ElseIf j > 0 Then
j = j + 3
End If
'This loop for n determines the yval columns of the Series.
If n = 0 Then
n = 104
ElseIf n > 0 Then
n = n + 3
End If
'This determines the range with respect to the product just chosen in the If-Then statements above.
Set xval = Range(Cells(802, j), Cells(a, j))
Set yval = Range(Cells(802, n), Cells(a, n))
'Now to add the Series and name it.
Set ser = cht_obj.Chart.SeriesCollection.NewSeries
With ser
ser.ChartType = xlXYScatter
'This loop for k determines the name of the Series.
If k = 0 Then
k = 102
ElseIf k > 0 Then
k = k + 3
End If
'Defines Series Name and Values
ser.Name = Cells(802, k)
ser.Values = yval
ser.XValues = xval
End With
'Iterates the next Series Index to decide the next Series.
Next SIndex
End Sub