在下面的代码中,可以自行更改图表标题或其位置,但更改其位置后更改其标题不起作用,如标准错误记录所示。
根据What is error code 0x800A01A8 coming out of Excel ActiveX call?,0x800a01a8表示“需要对象。”,但我认为#{chart.ole_obj_help.name}
表示对象存在。
出了什么问题?
代码后面是日志记录。
require "win32ole"
class ExcelOutputter
def initialize(workbook_filename)
@workbook_filename = workbook_filename
# Create an instance of the Excel application object
@excel = WIN32OLE.new('Excel.Application')
# Make Excel visible
@excel.Visible = 1
# Add a new Workbook object
@workbook = @excel.Workbooks.Add
end
def create_chart(title)
# http://rubyonwindows.blogspot.com/2008/06/automating-excel-creating-charts.html
chart = @workbook.Charts.Add
# Select a worksheet for source data
worksheet = @workbook.Worksheets("Sheet1")
# Excel insists on having source data, even if it's empty. Picky, isn't it?
chart.SetSourceData('Source' => worksheet.Range("$A$1:$B$6"))
chart.HasTitle = true
STDERR.puts "#{__method__}: Before renaming the freshly created #{chart.ole_obj_help.name}, the title is #{chart.ChartTitle.Characters.Text.inspect}"
chart.ChartTitle.Characters.Text = title
STDERR.puts "#{__method__}: The chart has been created, and is still a #{chart.ole_obj_help.name} and now has a title of #{chart.ChartTitle.Characters.Text.inspect}"
chart
end
def change_chart_title(chart, new_title)
STDERR.puts "#{__method__}: Apparently the chart object is still a #{chart.ole_obj_help.name}"
old_title = chart.ChartTitle.Characters.Text
chart.ChartTitle.Characters.Text = new_title
STDERR.puts "#{__method__}: The chart object is still a #{chart.ole_obj_help.name} and has been renamed from #{old_title.inspect} to #{chart.ChartTitle.Characters.Text.inspect}"
end
def move_chart(chart, target_worksheet_name)
xlLocationAsObject = 2
chart.Location("Where" => xlLocationAsObject, "Name" => target_worksheet_name)
STDERR.puts "#{__method__}: The chart object is still a #{chart.ole_obj_help.name} and has been moved to #{target_worksheet_name.inspect}"
end
def write_to_file
# Save the workbook
@workbook.SaveAs(@workbook_filename)
# Close the workbook
@workbook.Close
# Quit Excel
@excel.Quit
end
def self.show_everything_works_if_you_do_not_change_a_moved_chart
STDERR.puts "#{__method__}: Starting"
excel_outputter = ExcelOutputter.new("chart_location_confusion.xlsx")
chart = excel_outputter.create_chart("If you saw this it would mean change_chart_title never worked")
excel_outputter.change_chart_title(chart, "Show that change_chart_title works")
excel_outputter.move_chart(chart, "Sheet2")
# Don't change the chart title after changing its location
# excel_outputter.change_chart_title(chart, "If you saw this it would mean change_chart_title works after you called move_chart")
another_chart = excel_outputter.create_chart("If you saw this it would mean change_chart_title never worked")
excel_outputter.change_chart_title(another_chart, "Check that change_chart_title or move_chart isn't broken permanently")
excel_outputter.move_chart(another_chart, "Sheet3")
excel_outputter.write_to_file
STDERR.puts "#{__method__}: Finishing"
STDERR.puts("\n\n")
end
def self.try_renaming_after_moving_the_same_chart
STDERR.puts "#{__method__}: Starting"
excel_outputter = ExcelOutputter.new("chart_location_confusion.xlsx")
chart = excel_outputter.create_chart("If you saw this it would mean change_chart_title never worked")
excel_outputter.change_chart_title(chart, "change_chart_title works before you call move_chart")
excel_outputter.move_chart(chart, "Sheet2")
begin
# This will raise an exception
excel_outputter.change_chart_title(chart, "Will not get here")
rescue
STDERR.puts "#{__method__}: It didn't work"
raise
else
STDERR.puts "#{__method__}: It worked after all!"
end
end
end
if __FILE__ == $0
ExcelOutputter.show_everything_works_if_you_do_not_change_a_moved_chart
ExcelOutputter.try_renaming_after_moving_the_same_chart
end
产生
show_everything_works_if_you_do_not_change_a_moved_chart: Starting
create_chart: Before renaming the freshly created _Chart, the title is ""
create_chart: The chart has been created, and is still a _Chart and now has a title of "If you saw this it would mean change_chart_title never worked"
change_chart_title: Apparently the chart object is still a _Chart
change_chart_title: The chart object is still a _Chart and has been renamed from "If you saw this it would mean change_chart_title never worked" to "Show that change_chart_title works"
move_chart: The chart object is still a _Chart and has been moved to "Sheet2"
create_chart: Before renaming the freshly created _Chart, the title is ""
create_chart: The chart has been created, and is still a _Chart and now has a title of "If you saw this it would mean change_chart_title never worked"
change_chart_title: Apparently the chart object is still a _Chart
change_chart_title: The chart object is still a _Chart and has been renamed from "If you saw this it would mean change_chart_title never worked" to "Check that change_chart_title or move_chart isn't broken permanently"
move_chart: The chart object is still a _Chart and has been moved to "Sheet3"
show_everything_works_if_you_do_not_change_a_moved_chart: Finishing
try_renaming_after_moving_the_same_chart: Starting
create_chart: Before renaming the freshly created _Chart, the title is ""
create_chart: The chart has been created, and is still a _Chart and now has a title of "If you saw this it would mean change_chart_title never worked"
change_chart_title: Apparently the chart object is still a _Chart
change_chart_title: The chart object is still a _Chart and has been renamed from "If you saw this it would mean change_chart_title never worked" to "change_chart_title works before you call move_chart"
move_chart: The chart object is still a _Chart and has been moved to "Sheet2"
change_chart_title: Apparently the chart object is still a _Chart
try_renaming_after_moving_the_same_chart: It didn't work
chart_location_confusion_replication.rb:30:in `method_missing': ChartTitle (WIN32OLERuntimeError)
OLE error code:0 in <Unknown>
<No Description>
HRESULT error code:0x800a01a8
from chart_location_confusion_replication.rb:30:in `change_chart_title'
from chart_location_confusion_replication.rb:75:in `try_renaming_after_moving_the_same_chart'
from chart_location_confusion_replication.rb:87
修改:如果我将图表创建更改为以下内容:
def create_chart(title)
# Select a worksheet for source data
worksheet = @workbook.Worksheets("Sheet1")
# http://rubyonwindows.blogspot.com/2008/06/automating-excel-creating-charts.html
chart = worksheet.Shapes.AddChart.Chart
# Excel insists on having source data, even if it's empty. Picky, isn't it?
chart.SetSourceData('Source' => worksheet.Range("$A$1:$B$6"))
chart.HasTitle = true
STDERR.puts "#{__method__}: Before renaming the freshly created #{chart.ole_obj_help.name}, the title is #{chart.ChartTitle.Characters.Text.inspect}"
chart.ChartTitle.Characters.Text = title
STDERR.puts "#{__method__}: The chart has been created, and is still a #{chart.ole_obj_help.name} and now has a title of #{chart.ChartTitle.Characters.Text.inspect}"
chart
end
并将excel_outputter.write_to_file
添加到try_renaming_after_moving_the_same_chart
的末尾并关闭show_everything_works_if_you_do_not_change_a_moved_chart
,然后我
try_renaming_after_moving_the_same_chart: Starting
create_chart: Before renaming the freshly created _Chart, the title is ""
create_chart: The chart has been created, and is still a _Chart and now has a title of "If you saw this it would mean change_chart_title never worked"
change_chart_title: Apparently the chart object is still a _Chart
change_chart_title: The chart object is still a _Chart and has been renamed from "If you saw this it would mean change_chart_title never worked" to "change_chart_title works before you call move_chart"
move_chart: The chart object is still a _Chart and has been moved to "Sheet2"
change_chart_title: Apparently the chart object is still a _Chart
change_chart_title: The chart object is still a _Chart and has been renamed from "change_chart_title works before you call move_chart" to "Will not get here"
try_renaming_after_moving_the_same_chart: It worked after all!
但是当我在Excel中查看时,图表的标题为change_chart_title works before you call move_chart
,而不是Will not get here
。但是,以下VBA有效:
Sub Tester3()
Dim cht As Object
Debug.Print "Start"
Set cht = Sheet2.Shapes.AddChart.Chart
Debug.Print TypeName(cht) 'Chart
cht.SetSourceData Sheet1.Range("B4:C15")
Debug.Print TypeName(cht) 'Chart
cht.ChartTitle.Characters.Text = "Second title"
cht.Location Where:=xlLocationAsObject, Name:="Sheet2"
cht.ChartTitle.Characters.Text = "Third title"
Debug.Print TypeName(cht) 'Chart
Debug.Print cht.Name 'Sheet2 Chart 7
End Sub
答案 0 :(得分:1)
如果我没记错的话,工作表中嵌入的图表和图表之间存在一些差异。这些差异可能会破坏您的“图表”参考,使其在移动后不再指向“相同”对象。一点VBA显示同样的事情:
Sub Tester()
Dim cht As Object
Set cht = ThisWorkbook.Charts.Add()
cht.SetSourceData Sheet1.Range("B4:C15")
Debug.Print TypeName(cht) 'Chart
cht.Location Where:=xlLocationAsObject, Name:="Sheet1"
Debug.Print TypeName(cht) 'Object
Debug.Print cht.Name 'Error: object required
End Sub
编辑:将嵌入图表移动到另一张图表也不起作用:
Sub Tester2()
Dim cht As Object
Set cht = Sheet1.Shapes.AddChart.Chart
cht.SetSourceData Sheet1.Range("B4:C15")
Debug.Print TypeName(cht) 'Chart
cht.Location Where:=xlLocationAsObject, Name:="Sheet2"
Debug.Print TypeName(cht) 'Chart
Debug.Print cht.Name 'Error: Method 'Name' of object _chart failed
End Sub
是否有某些原因需要将图表创建为图表而不直接在工作表上创建?