2011-10-27 67 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

在進一步的測試中,似乎即使將嵌入式圖表移動到不同的工作表也會打破引用:本質上它似乎創建了一個新的圖表(具有相同的屬性)並刪除舊圖表。底線似乎是,如果你需要保留對圖表的工作參考,那麼你不能移動它... –