在下面的代碼中,可以自行更改圖表標題或其位置,但更改其位置後更改標題不起作用,如標準錯誤日誌記錄所示。更改圖表屬性在更改其位置後會中斷
根據What is error code 0x800A01A8 coming out of Excel ActiveX call?,0x800a01a8表示「Object Required」,但我認爲#{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
我認爲你最後一個VBA示例是可行的,因爲它並沒有真正移動圖表:將它添加到Sheet2,然後將它「移動」到同一張表。如果您嘗試將其移動到其他工作表,它會在最後一行發生錯誤。 –