excel - 使用 VBA 复制图表:无法删除或无法修改副本
问题描述
我在 MacOS 上使用 Excel。“关于”信息告诉我它是 16.16.5 版本,显然对应于 Office 2016。如果您查看此处的代码并认为“嘿,这对我有用”,如果您可以发表评论,那就太好了包括您正在使用的 Excel 版本。
我有一个电子表格,我想将图表从“模板”工作表复制到大约。80 个其他工作表,然后修改它们以引用目标工作表上的数据而不是原始工作表(通过系列上的简单搜索和替换)。
乍一看,这似乎并不难,在 Stack Overflow 和其他地方都有很多潜在的解决方案,但我似乎一直遇到意想不到的行为。
对于下面的示例,代码只是将图表从一个工作表复制到另一个工作表,而不是遍历所有可用的工作表,因为这样可以在失败时更轻松地进行清理。到目前为止,始终如此。
尝试#1
我的第一次尝试是这样的:
Sub Copy_Charts()
Dim DataSheetName1 As String, DataSheetName2 As String
Dim chartObj as ChartObject, chartObjCopy as ChartObject
Dim sourceChartSheet as Worksheet, destChartSheet as Worksheet
DataSheetName1 = "CU-2"
DataSheetName2 = "CU-8"
Set sourceChartSheet = Sheets(DataSheetName1)
Set destChartSheet = Sheets(DataSheetName2)
For Each chartObj In sourceChartSheet.ChartObjects
chartObj.Copy
destChartSheet.Range(chartObj.TopLeftCell.Address).PasteSpecial xlPasteAll
chartIndex = chartIndex + 1
Set chartObjCopy = destChartSheet.ChartObjects(chartIndex)
chartObjCopy.Left = chartObj.Left
chartObjCopy.Top = chartObj.Top
Next chartObj
End Sub
这几乎可行:它实际上将图表复制到目标工作表。但是,它在这一行失败了:
Set chartObjCopy = destChartSheet.ChartObjects(chartIndex)
错误是“运行时错误'1004':应用程序定义的或对象定义的错误”。
事实上,如果您此时查看 destChartSheet.ChartObjects.Count,它仍然显示为0
. 此外,如果您尝试使用以下代码删除图表:
Sub Delete_Charts()
Dim sht As Worksheet
For Each sht In ActiveWorkbook.Worksheets
If sht.Name <> "CU-2" Then
If sht.ChartObjects.Count >= 1 Then
sht.ChartObjects.Delete
End If
End If
Next sht
End Sub
它实际上不会删除图表。如果您手动复制和粘贴图表,相同的删除代码也可以正常工作。
总之:这段代码确实复制了图表,但我无法获得对副本的引用来修改它,也不能删除它。
尝试#2
我决定将复制粘贴扔出窗口并尝试使用该Duplicate
方法。我最终得到以下结果:
Sub Copy_Charts()
Dim DataSheetName1 As String, DataSheetName2 As String
Dim sourceChartSheet As Worksheet, destChartSheet As Worksheet
Dim chartObj As ChartObject, newChartObj As ChartObject
Dim chartObjCopy As ChartObject
Dim chSeries As Series
Dim chartIndex As Integer
DataSheetName1 = "CU-2"
DataSheetName2 = "CU-8"
Set sourceChartSheet = Sheets("CU-2")
Set destChartSheet = Sheets("CU-8")
For Each chartObj In sourceChartSheet.ChartObjects
' No idea why chartObj.Duplicate returns something other
' than a ChartObject.
Set newChartObj = chartObj.Duplicate.Chart.Parent
newChartObj.Top = chartObj.Top
newChartObj.Left = chartObj.Left
newChartObj.Chart.Location xlLocationAsObject, destChartSheet.Name
For Each chSeries In newChartObj.Chart.SeriesCollection
chSeries.FormulaR1C1 = Replace(chSeries.FormulaR1C1, DataSheetName1, DataSheetName2)
Next
Next chartObj
End Sub
这与第一个解决方案的工作方式(并且失败)不同:它还将图表复制到目标工作表中,并且与前面的示例不同,可以使用该Delete_Charts
子例程删除这些图表。
不幸的是,此代码在以下位置失败:
For Each chSeries In newChartObj.Chart.SeriesCollection
并且错误再次是“运行时错误'1004':应用程序定义的或对象定义的错误”。
实际上,newChartObj
此时尝试使用调试器进行检查只会使 Excel 崩溃。
因此,我有两个部分解决方案,这两个解决方案似乎都以与我在其他地方看到的示例或文档不匹配的方式失败。我将不胜感激任何帮助使其中任何一个工作。
解决方案
我认为当图表位置移动时,会更改对图表对象的引用,从而导致系列集合失败。
我能够重现该问题,并且下面的代码确实有效,但是我在 PC 上,所以如果需要任何进一步的更改才能在 Mac 上启动和运行,我不是 100%。如果您移动此行:
newChartObj.Chart.Location xlLocationAsObject, destChartSheet.Name
在SeriesCollection
循环之后它工作,但不是之前。
Option Explicit
Sub Copy_Charts()
Dim DataSheetName1 As String, DataSheetName2 As String
Dim sourceChartSheet As Worksheet, destChartSheet As Worksheet
Dim chartObj As ChartObject, newChartObj As ChartObject
Dim chartObjCopy As ChartObject
Dim chSeries As Series
DataSheetName1 = "CU-2"
DataSheetName2 = "CU-8"
Set sourceChartSheet = ThisWorkbook.Sheets(DataSheetName1)
Set destChartSheet = ThisWorkbook.Sheets(DataSheetName2)
For Each chartObj In sourceChartSheet.ChartObjects
Set newChartObj = chartObj.Duplicate.Chart.Parent
'Set newChartObj = chartObj 'Reference the sheet, good if you are cut/pasting the chart
For Each chSeries In newChartObj.Chart.SeriesCollection
chSeries.FormulaR1C1 = Replace(chSeries.FormulaR1C1, DataSheetName1, DataSheetName2)
Next
newChartObj.Top = chartObj.Top
newChartObj.Left = chartObj.Left
'Move this after the SeriesCollection loop
newChartObj.Chart.Location xlLocationAsObject, destChartSheet.Name
Next
End Sub
推荐阅读
- typescript - 使用打字稿迭代枚举并分配给枚举
- r - R- merging two data sets within time duration/intervals
- javascript - 使用javascript替换文本中的关键字
- php - 从 SQL for PHP 网页获取列名
- r - 在更大的 data.table 中处理分组的 data.tables
- flutter - 无法从 Cloud Firestore 归档处于初始状态的单个数据
- node.js - 尝试在 Cipher.update 中添加处于不受支持状态的数据
- android - 如何使用opencv检测白色背景上的白皮书
- php - Laravel - 从表单输入设置会话
- git - 推到分离的头上,没有显示我的推或提交