在Excel,VBA中设置PlotArea.Width错误(Excel 2010)

Error setting PlotArea.Width in Excel, VBA (Excel 2010)

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

enter image description here

如果我注释掉前面的行,其他尺寸也会导致此错误。
没有ActiveChart,没有选择等。特定的错误消息是:" -2147467259(80004005)对象'PlotArea'的方法'Width'失败"

这让我很沮丧,原因有几个:

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

有什么想法吗?这是我可以共享的代码,完整地包含ChartSizeMedium子例程,以及一个虚拟代码段,向您展示如何建立图表并将其传递给该子集,该子集设置大小和其他一些属性,然后再传递给另一个函数,将系列数据添加到图表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
    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尺寸,但错误仍然存??在:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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


我也有类似的问题。而这绝对是一个出色的问题(2013年)。

1
2
3
4
5
6
7
With .PlotArea
    .Select 'err if delete this line of code
    .Top = 0
    .Left = 0
    .width = 40
    .Height = 40
End With

如果删除.select行,则在下一行将导致错误。
请注意,我不使用<< x15> do stuff>。
.select使它工作,而无需使用选择,它显然是一个excel错误(来自以前的版本?)


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

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

1
2
3
4
5
6
7
8
9
10
11
12
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的链接)。这似乎不是一个非常可靠或有效的方法,尽管它似乎可以工作,但我知道在该循环中,每个属性在一次成功地将它们设置为下一个传递之前均会失败一次。

1
2
3
4
5
6
7
8
9
10
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


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

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

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

由于问题最初是发布的,因此该应用程序现在位于PowerPoint中,因此我无法使用Applicaiton.Wait。我有一些间歇性错误,暂停时间为1秒,而3秒的暂停时间太多,因此我建立了以下错误陷阱。相同的想法可以在Excel中与Application.Wait结合使用。

正是这段代码适合我,因此我在Powerpoint中添加了此错误处理以模仿Application.Wait

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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

我知道这很旧,这种解决方案似乎很差,但是可以用。当您提到逐步完成工作时,我只是想这样做。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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


希望您的工作表和图表具有最大宽度为640的功能。如果是这样,请尝试使用显式参考。还建议您将width, height值更改为较低的值,并查看程序如何响应。既然您说过,当您select它起作用时,

  • 这也意味着您的cht包装了正确的图表对象-除非您另外使用ActiveChart.PlotArea.Width选择了图表。因此,我想显式引用可能是一个潜在的尝试。

1
2
3
4
cht.PlotArea.Width = 640
cht.PlotArea.Height = 280
cht.PlotArea.Left = 30
cht.PlotArea.Top = 30

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


更新两个

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

码:
从表单中显示的按钮调用此子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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

奥特普特:

enter image description here

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

.MajoreGridlines.Format.Lines.Visible失败。因此,设置.MajorGridlines = False以确保您不想显示网格线。
您想做的其他事情都可以在以后完成。刚开始尝试更改尺寸。

参考来自:MSDN Gridlines属性


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

我现在正在工作的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    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