5

我在尝试设置图表的 plotarea.width 属性的子例程中遇到错误。

在此处输入图像描述

如果我注释掉前面的行,其他维度也会导致此错误。没有ActiveChart,没有选择等。具体的错误信息是这样的:“-2147467259 (80004005) Method 'Width' of object 'PlotArea' failed”

这让我很困惑,原因有几个:

  • 在调试模式下,F8 单步执行代码不会发生错误。
  • AFAIK“宽度”不是“方法”,而是图表绘图区域的“属性”,因此即使错误消息也相当模糊。

有什么想法吗?这是我可以分享的尽可能多的代码,完整的 ChartSizeMedium 子例程,以及一个虚拟片段,向您展示我如何建立图表并将其传递给在传递给另一个函数之前设置大小和其他一些属性的子程序将系列数据添加到图表中。

    Option Explicit
    Private Sub EstablishChartObject()
    Dim cObj as ChartObject
    Set cObj = ActiveSheet.ChartObjects.Add(Left:=30, Top:30, Width:=740, Height:=300)
        ChartSizeMedium cObj.Chart, "Integer", "Example Chart Title"
    End Sub
    Private Sub ChartSizeMedium(cht As Chart, NumType As String, Optional chtTitle As String)
    'Subroutine to make a consistent size chart
    Dim s As Long
    With cht
    'Add a chart title if one exists.
        If Len(chtTitle) > 0 Then
        .HasTitle = True
        .chartTitle.Characters.Text = chtTitle
        End If
    'Create the default chart Legend
        .HasLegend = True
        With .Legend
        .Position = xlTop
        .Font.Size = 11
        .Font.Bold = True
        End With
    'Format the axes
        .Axes(xlValue).MajorGridlines.Format.Line.Visible = msoFalse
        .Axes(xlValue).MinorGridlines.Format.Line.Visible = msoFalse

    'Format the size of the chart
        With .Parent
        .Width = 740
        .Height = 396
        End With

        With .PlotArea
        .Width = 640    '<---- THIS LINE TRIGGERS THE ERROR
        .Height = 280
        .Left = 30
        .Top = 30
        End With
    End With
    'Some charts start with more than one series container, so make sure they're gone:
    With cht
    Do Until .SeriesCollection.Count = 0
    s = .SeriesCollection.Count
    .SeriesCollection(s).Delete
    Loop
    End With
    End Sub

2012 年 12 月 12 日更新

我删除了所有无问题的代码并仅使用带有块的 PlotArea,在同一例程中,我还尝试设置图表类型(几个值),如本示例所示,在尝试设置之前手动添加一系列数据PlotArea 尺寸,但错误仍然存​​在:

Option Explicit
Private Sub EstablishChartObject2()
    Dim cObj As ChartObject
    Dim sh As Worksheet

    Set sh = ActiveSheet
    Dim srs As Series
    Set cObj = sh.ChartObjects.Add(Left:=30, Top:=30, Width:=740, Height:=300)
    Set srs = cObj.Chart.SeriesCollection.NewSeries

    srs.Values = "={1,3,5,7,4}"
    cObj.Chart.ChartType = 57

    With cObj.Chart.PlotArea
        .Width = 100   '<---- THIS LINE TRIGGERS THE ERROR
        .Height = 280
        .Left = 30
        .Top = 30
    End With

End Sub
4

6 回答 6

4

我有一个类似的问题。它绝对是一个优秀的问题(有 2013 年)。

With .PlotArea 
    .Select 'err if delete this line of code
    .Top = 0
    .Left = 0
    .width = 40
    .Height = 40 
End With

如果删除该.select行,将导致下一行出错。请注意,我没有使用 < with selectiondo stuff>。.select使它工作,不使用选择,这显然是一个 excel 错误(来自以前的版本?)

于 2016-06-10T15:50:48.133 回答
3

两种似乎有效的解决方案,都不是我想要的“优雅”(我希望有一种方法可以通过选择图表或其任何部分来做到这一点)。

选项 1 - 选择绘图区域,然后取消选择它。 这似乎是最可靠/最有效的解决方案。

With .PlotArea
    Application.ScreenUpdating = False
   .Select
    With Selection
        .Width = paWidth
        .Height = paHeight
        .Left = paLeft
        .Top = paTop
        ActiveSheet.Range("A1").Activate
    End With
    Application.ScreenUpdating = True
End With

选项 2 - 禁用循环中的错误处理(这来自 Doug 的链接)。这似乎不是一个非常可靠或有效的方法,虽然它似乎有效,但我知道在该循环中,它在每个属性上都失败了一次,然后它在后续传递中成功设置它们。

With .PlotArea
    For pLoop = 1 To 5
        On Error Resume Next
        .Width = paWidth
        .Height = paHeight
        .Left = paLeft
        .Top = paTop
        On Error GoTo 0
    Next
End With
于 2012-12-11T16:32:58.327 回答
1

我知道这是旧的,这个解决方案似乎很糟糕,但它有效。当您提到逐步完成工作时,我只是想这样做。

Option Explicit

Sub chart()

Dim cObj As ChartObject
Dim sh As Worksheet

Set sh = ActiveSheet
Dim srs As Series
Set cObj = sh.ChartObjects.Add(Left:=30, Top:=30, Width:=740, Height:=300)
cObj.chart.ChartType = 57
Set srs = cObj.chart.SeriesCollection.NewSeries
    srs.Values = "={1,3,5,7,4}"
Application.Wait Now + TimeValue("00:00:01") '<~~ Added This line
With cObj.chart.PlotArea
    .Width = 100
    .Height = 280
    .Left = 30
    .Top = 30
End With
End Sub
于 2013-04-16T15:56:29.107 回答
1

希望您的工作表和图表能够获得最大宽度640。如果是这样,请尝试显式引用。还建议您将width, height值更改为较低的值并查看程序如何响应。既然你说,当你select工作时,

  • 这也意味着,您cht正在包装正确的图表对象 - 除非您使用ActiveChart.PlotArea.Width. 因此,我想明确的参考可能是一个潜在的尝试。

,

cht.PlotArea.Width = 640
cht.PlotArea.Height = 280
cht.PlotArea.Left = 30
cht.PlotArea.Top = 30

此外,检查Aspect Ratio锁定或解锁。如果这些都不起作用,则将图表添加到您的工作表中并使用最简单的图表格式代码来检查widht, height, left, top更改。


更新二

让我们尝试在第二个中指定图表类型并设置图表对象sub。我最终尝试了它并且它正在工作。尝试以下更改的代码。

代码:从工作表中显示的按钮调用此子程序。

Option Explicit

  Public Sub EstablishChartObject()
  Dim mySheet As Worksheet
  Dim cObj As ChartObject

    Application.ScreenUpdating = False
    Application.StatusBar = "Chart is coming soon..."

    Set mySheet = Sheets(2) '-- set according to yours
    '-- create chart with some source data first, which you can change later
    Set cObj = mySheet.ChartObjects.Add(Left:=30, Top:=30, Width:=400, Height:=200)
    ChartSizeMedium cObj, "Integer", "Example Chart Title"
        
  End Sub


  'Subroutine to make a consistent size chart
  Private Sub ChartSizeMedium(chtObj As ChartObject, NumType As String, _
                                  Optional chtTitle As String)
    
  Dim myChart As Chart
  Dim s As Long
    
     Set myChart = chtObj.Chart '-- specify chart type
     myChart.SetSourceData Source:=Sheets(2).Range("B3:C12")  '-- set to what you have
     myChart.ChartType = xlXYScatterLines  '-- set to the type you want 
                                          'and make sure to **use correct properties**

        With myChart
            If .HasTitle Then
                .ChartTitle.Characters.Text = chtTitle
            End If
        
            'Create the default chart Legend
            If .HasLegend Then
                With .Legend
                    .Position = xlTop
                    .Font.Size = 11
                    .Font.Bold = True
                End With
            End If
            
            'Format the axes
            With .Axes(xlValue)
                .HasMajorGridlines = False
            End With
                    
            'Format the size of the chart
            With .Parent
                .Width = 400 '-- change to yours
                .Height = 250 '-- change to yours
            End With
    
            With .PlotArea
                .Width = 300 '-- change to yours
                .Height = 180 '-- change to yours
                .Left = 30
                .Top = 30
            End With
    End With

    Application.ScreenUpdating = True
    Application.StatusBar = "Chart is Here!"

End Sub

输出:

在此处输入图像描述

确保为每种图表类型使用正确的属性。请注意,上面的代码不会从您的工作表中删除任何剩余的旧图表。

.MajoreGridlines.Format.Lines.Visible失败。所以设置.MajorGridlines = False以确保您不想显示网格线。您想做的任何其他事情都可以在以后完成。最初只需尝试对尺寸进行更改。

参考自:MSDN Gridlines 属性

于 2012-12-11T13:07:58.280 回答
1

编辑:这似乎适用于某些图表类型,但对于其他图表类型仍然失败。我继续使用 5x 循环,On Error Resume Next这似乎是 - 不幸的是 - 迄今为止最“可靠”的解决方案。

原文:这是基于上面 User2140261 的建议答案:

https://stackoverflow.com/a/16041640/1467082

由于最初发布了该问题,因此该应用程序现在驻留在 PowerPoint 中,因此我无法使用Applicaiton.Wait. 我遇到了一些间歇性错误,停顿 1 秒,而 3 秒的停顿太长了,所以我构建了以下错误陷阱。相同的想法可以在 Excel 中与Application.Wait.

正是这段代码让我很适应,所以我在 Powerpoint 中添加了这个错误处理来模仿Application.Wait.

RetryChartDimensions:
On Error GoTo ErrChartDimensions
With .PlotArea
    .Width = paWidth
    .Height = paHeight
    .Left = paLeft
    .Top = paTop
End With
On Error GoTo 0

' More code
' more code

Exit Sub 'gracefully exit this subroutine before the error-handling.'

ErrChartDimensions:
Err.Clear
'Pause before setting the PlotArea dimensions:'
Dim wtTime As Double
Dim startTime As Long

'A maximum 3 second delay should be more than enough time.
If wtTime < 3 Then
    wtTime = wtTime + 0.5
    startTime = Timer
    While Timer < startTime + wtTime
        DoEvents
    Wend
End If
Resume RetryChartDimensions

End Sub
于 2013-04-16T16:46:30.197 回答
0

我没有足够的声誉来添加评论,因此使用上述解决方案我已经解决了我在 VB.Net 2010 和 Excel 2013 中的饼图问题。xlLine 图表从未引起问题,但我的代码会在相同代码时崩溃在 Excel 2013 上针对 xlPie 图表运行(在 Excel 2007 上一切正常)。

我现在的工作代码:

    appExcel.Visible = False
    xlchart_for_96_Well_Plate_Source = appExcel.Charts.Add(After:=wkbExperiment_Details.Sheets(wkbExperiment_Details.Sheets.Count))
    appExcel.ScreenUpdating = False

    With xlchart_for_96_Well_Plate_Source
            .SetSourceData(Source:=wksData.Range(wksData.Cells(2, byteCharts_added), wksData.Cells(intUsed_Rows, byteCharts_added)), PlotBy:=Microsoft.Office.Interop.Excel.XlRowCol.xlColumns)
            .ChartType = objChart_Type
            .PlotArea.Select() 
            .PlotArea.Top = 2
            .PlotArea.Select()
            .PlotArea.Left = 2
            .SeriesCollection(.SeriesCollection.count).xvalues = wksData.Range(wksData.Cells(2, 1), wksData.Cells(intUsed_Rows, 1)).Value ' Scale - wavelength for line chart
            .SeriesCollection(.SeriesCollection.count).Values = wksData.Range(wksData.Cells(2, byteCharts_added + 1), wksData.Cells(intUsed_Rows, byteCharts_added + 1)).Value
            .SeriesCollection(.SeriesCollection.count).Name = wksData.Cells(1, .SeriesCollection.count + 1).value
    End With
appExcel.ScreenUpdating = True
于 2015-06-24T10:10:34.893 回答