下午好!我是一名大学生,在夏天合作一家化学公司。我已经完成了Excel VBA编程的一门非常基础的课程,所以我缺乏语言运作方式的坚实基础。
最近,我的任务是建立在我的前任编写的代码之上,目的是生成动态图。
目标是:编写一个代码,在4个不同的图表(每个反应堆一个)上显示我公司在2年内的17种不同产品。该工作簿有大约六种不同的数据表,其中一个数据库有一个按钮,用户可以按下该按钮来启动所有必要的数据计算,单元格填充和图形生成。
由于这取决于客户的需求,因此我们无法知道我们将在2年内生产的17种产品中的每批产品。我的代码需要动态地解释这一点。
我已经从两年前查看了我的课程材料并购买了John Walkenbach的2015 VBA Power Programming Book。我正在教自己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分别是数据选择的第一行和最后一行。它们是使用一个简单的公式计算出来的,我验证了它是正确的,并且是基于前Co-op学生编写的一段代码。数据输入是垂直的,因此列数将保持不变,而行数将根据我们为每个产品制作的批次数而变化。
这不起作用,所以我把变量拿出来并重新输入特定的引用802到803.令我惊讶的是,这也没有用。从那以后我就学会了Excel VBA将数据读取为Series Collection的数组,所以我知道我必须通过强制它来读取一个Range来为自己设置失败。
然而,它也不适用于我的阵列。以下是我的新代码:
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 Data_Series
Dim XRange as Range, YRange as Range, Result as Variant, s as Series
'AA is calculated like the xyz example above and provides a good value
'AA and CC2311endrowBR are defined as 'Public AA as Integer' and _
'Public CC2231endrowBR as Integer' in my code
AA = CC2311endrowBR
ReDim A(802 To AA, 103 To 104)
Call Read_Data_G350_CC2311(A, N, 0, 0)
Set s = ActiveSheet.ChartObjects.Chart.SeriesCollection
Result = A(s)
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlXYScatter
Set XRange = Range(Result())
Set YRange = Range(Result())
s.XValues = XRange
s.Values = YRange
End Sub
'' '' '' '' '' '' '' '' '' '' '' '' '' '''
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
不幸的是,无论我做什么,我都会继续收到“下标超出范围”,“用户定义错误”,“对象丢失”等错误消息。是否有办法动态编码这样的图表?有没有人建议我接下来应该尝试什么?
更新:
我能够完成代码并且完美运行!感谢Byron指出我正确的方向!
以下是新的工作代码,以防其他人遇到类似问题并需要帮助:
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
答案 0 :(得分:0)