Vba 需要帮助制作动态图表吗

Vba 需要帮助制作动态图表吗,vba,excel,dynamic,charts,Vba,Excel,Dynamic,Charts,下午好!我是一名大学生,整个夏天都在为一家化工公司合作。我已经完成了Excel VBA编程中的一个非常基础的课程,所以我缺乏语言的工作基础。 最近,我的任务是在我的一位前任编写的代码的基础上进行构建,目的是生成动态图形 目标是:编写一个代码,在4个不同的图表(每个反应堆一个)上显示我公司2年内的17种不同产品。该工作簿大约有六张不同的数据表,其中一张有一个按钮,用户可以按下该按钮启动所有必要的数据计算、单元格填充和图形生成 由于这取决于客户需求,因此无法知道我们将在两年内生产17种产品中的每种产

下午好!我是一名大学生,整个夏天都在为一家化工公司合作。我已经完成了Excel VBA编程中的一个非常基础的课程,所以我缺乏语言的工作基础。 最近,我的任务是在我的一位前任编写的代码的基础上进行构建,目的是生成动态图形

目标是:编写一个代码,在4个不同的图表(每个反应堆一个)上显示我公司2年内的17种不同产品。该工作簿大约有六张不同的数据表,其中一张有一个按钮,用户可以按下该按钮启动所有必要的数据计算、单元格填充和图形生成

由于这取决于客户需求,因此无法知道我们将在两年内生产17种产品中的每种产品多少批次。我的代码需要动态地说明这一点

我复习了两年前的课堂材料,并购买了John Walkenbach的2015 VBA Power编程书。我正在自学VBA代码,但仍然不完全理解其中一些代码是如何工作的。我希望这里的人能够解释为什么我的代码不起作用,以及我应该如何修复它

我开始的时候非常简单,目的是使用制作每个批次所需的总时间(周期时间)和批次完成的日期分别作为y和x值来绘制单个产品的两个批次。代码如下所示:

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