У меня проблема с приложением, которое было создано в Excel 2003 в моей компании. Приложение извлекает данные из источника и обновляет диаграмму с помощью SetSourceData
в процедуре VBA, передавая диапазон, содержащий ячейки, в которых записаны соответствующие данные.
Приложение отлично работает в Office 2003, но когда приложение выполняется в Office 2010, оно вызывает эту ошибку:
Ошибка времени выполнения '1004': не удалось выполнить метод SetSourceData объекта object_Chart.
Я создал цикл For
в простом файле Excel в Office 2010 и в зависимости от количества столбцов, переданных в диапазоне до диаграммы, ошибка будет возникать рано или поздно. Чем больше столбцов передается в Range, тем скорее оно появится. Я предполагаю, что это должно быть связано с количеством серий в Диаграмме (больше столбцов больше серий).
Является ли это каким-то механизмом/буфером в объекте или серии диаграммы, реализованным в Office 2010, которого не было в Office 2003? Тот же цикл For
никогда не показывает проблемы, когда он запущен в Office 2003, и я не уверен, как решить эту проблему.
До сих пор мне удавалось удалять все серии, управляющие ошибкой с помощью команды Goto, чтобы удалить все серии в серии SeriesCollection с помощью цикла For Each
, чтобы выбрать все объекты в наборе SeriesCollection диаграммы. Если я это сделаю и возобновит выполнение приложения, когда я передаю диапазон снова, все данные будут правильно покрашены в объект диаграммы.
Пример для воспроизведения ошибки. Следующий код должен быть помещен в модуль VBA в новую книгу Excel 2010. Запустите Sub setDataChart
, и приложение запустится до появления сообщения об ошибке.
Sub setDataChart()
Call createAColValues
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlXYScatterSmoothNoMarkers
ActiveChart.SetSourceData Source:=Range("A1:FA6"), PlotBy:=xlColumns
ActiveSheet.ChartObjects(1).Activate
With ActiveChart.Parent
.Height = 325
.Width = 900
.Top = 120
.Left = 10
End With
Call updateValues
Call sendData
End Sub
Sub sendData()
Dim cht As ChartObject
Set cht = ActiveSheet.ChartObjects(1)
'On Error GoTo delSeries:
For i = 0 To 1000
cht.Chart.SetSourceData Source:=ActiveSheet.Range("A1:FA6"), PlotBy:=xlColumns
Next i
End Sub
Sub createAColValues()
Range("A1").Select
ActiveCell.FormulaR1C1 = "1"
Range("A2").Select
ActiveCell.FormulaR1C1 = "2"
Range("A1:A2").Select
Selection.AutoFill Destination:=Range("A1:A6"), Type:=xlFillDefault
Range("A1:A6").Select
End Sub
Sub updateValues()
Range("B1").Select
ActiveCell.FormulaR1C1 = "=RANDBETWEEN(0,10)"
Range("B1").Select
Selection.AutoFill Destination:=Range("B1:B6"), Type:=xlFillDefault
Range("B1:B6").Select
Selection.AutoFill Destination:=Range("B1:FA6"), Type:=xlFillDefault
Range("B1:FA6").Select
End Sub
Это не касается причины возникновения ошибки. Это обходное решение.
Перед вызовом SetSourceData
удалите всю существующую серию, находящуюся в данный момент на диаграмме, и код будет работать как ожидалось.
For j = cht.Chart.SeriesCollection.Count To 1 Step -1
cht.Chart.SeriesCollection(j).Delete
Next j
Я не уверен, почему ошибка возникает в первую очередь, но это заставляет ее уйти.
Другая возможность заключается в определении именованного диапазона для данных, которые определяются с помощью формулы Offset
и соответствующих опорных ячеек. Для этого необходимо, чтобы данные были смежными, а не изменяли начальную строку и столбец, в которых она начиналась, и для установки по крайней мере одной ссылочной формулы (=COUNTA()
в столбце/строке, содержащей данные), которая может использоваться для установки высоты /width диапазона смещения.
В противном случае очень удобная небольшая работа, чтобы вывести это из макросов и поместить в логику рабочего листа.
For j = cht.Chart.SeriesCollection.Count To 1 Step -1 : cht.Chart.SeriesCollection(j).Delete : Next j
), тогда он работает нормально ,