2011-10-27 35 views
0

在下面的代码中,可以自行更改图表标题或其位置,但更改其位置后更改标题不起作用,如标准错误日志记录所示。更改图表属性在更改其位置后会中断

根据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 
+0

我认为你最后一个VBA示例是可行的,因为它并没有真正移动图表:将它添加到Sheet2,然后将它“移动”到同一张表。如果您尝试将其移动到其他工作表,它会在最后一行发生错误。 –

回答

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 

是有一些原因,你需要创建图表作为图表,不要直接在工作表上创建它?

+0

谢谢。现在它以不同的方式失败。我不知道它失败的新方式是否与旧方式有关。 –

+0

在进一步的测试中,似乎即使将嵌入式图表移动到不同的工作表也会打破引用:本质上它似乎创建了一个新的图表(具有相同的属性)并删除旧图表。底线似乎是,如果你需要保留对图表的工作参考,那么你不能移动它... –