如果您运行以下代码,您将获得非常有趣的结果(仅运行PowerPoint,在运行之前关闭所有Excel实例):
'Optional - Include the "Microsoft Excel 16.0 Object Library"
Option Explicit
Public Sub test()
Dim oslide As slide
Set oslide = ActivePresentation.Slides.add(1, ppLayoutBlank)
Dim oshape As Shape
Set oshape = oslide.Shapes.AddOLEObject(30, 30, 50, 50, "Excel.Sheet")
oshape.OLEFormat.Object.Sheets(1).ListObjects.add(1) 'xlSrcRange
oshape.OLEFormat.Object.Sheets(1).Cells(1, 1) = "fewewq"
oshape.OLEFormat.Object.Close
End Sub
成功创建嵌入对象,并且表与指定数据一起出现。但是,单击嵌入对象时会出现以下错误:
没有足够的内存可供阅读工作表。
无法再以任何其他方式访问此对象,并且在关闭/打开文档并重新启动时,对象的损坏性质仍然存在。我已经验证了这个问题发生在我测试过的所有系统上(PowerPoint / Excel 2016,Windows 7 X64)。
所以我的问题是,其他人是否可以重现这一点,如果是这样,为什么会发生这种情况呢?如果将“单元格(1,1)”行更改为“单元格(2,1)”没有问题,就好像编辑表格的头部会导致某种特殊行为与编辑行或其他细胞。
关于这一点真的没有写过,大部分内容都没有 与此特定问题有关。
This post声称这是一个太多字体的问题 安装(大于600)。我测试了这个,我只安装了241 ...
有some posts完全不相关,也不是 分配给那里。
我在MS Word中测试了相同的代码,似乎工作正常,问题似乎 隔离到PowerPoint
我尝试在代码(破碎对象)中执行一个版本,另一个手动(工作对象),保存它们并比较二进制输出(of only the embedded objects)。这听起来很酷,但它并没有给我任何更深刻的见解。我无法单独使用Excel打开嵌入对象,因为对象似乎存储在proprietary format中。二进制的中心区域看起来不同,但我不确定如何或为什么。到目前为止,我还没有找到将其解码为人类可读信息的方法。
After a significant delay and with proper attribution,我已将其发布到the Microsoft forums。也许有人对那里有一些见解。我会积极维护这两个职位。如果我100%确信这是一个错误,我甚至可以考虑opening an issue here。
您可以通过不关闭OLEObject来完全避免此问题,这会导致2010年出现问题,尤其是当与关联的图表行为结合使用时,您会显示孤立的Excel窗口。不是一个好的用户体验。我想我可以在后台打开一个隐藏的Excel窗口,然后在我完成嵌入式工作时终止...
我正在运行版本:Microsoft Office 365 ProPlus:版本1705(Build 8201.3103即点即用),但我也看到了Microsoft Office Standard 2010版本14.0.7015.1000(32位)的问题)。该表的问题似乎与其他每个版本的办公室相同,但我想知道这是否会影响2010年以前的办公室版本?
我用图表尝试了同样的事情:
'Include the "Microsoft Excel 16.0 Object Library"
Option Explicit
Sub test()
Dim sld As slide
Dim shp As Shape
Dim pptWorkbook As Workbook
Set sld = ActivePresentation.Slides.Add(1, ppLayoutBlank)
Set shp = sld.Shapes.AddChart
Set pptWorkbook = shp.Chart.ChartData.Workbook
pptWorkbook.Close SaveChanges:=True
Set pptWorkbook = shp.Chart.ChartData.Workbook
pptWorkbook.Sheets(1).Cells(1, 2) = "fewewq"
Application.ActivePresentation.Save
pptWorkbook.Close SaveChanges:=True
End Sub
如果更改标题行值,则无法再访问嵌入对象(“Cells(1,2)”),如果更改其他值(“Cells(2,1)”),则运行正常。我认为这是同样的问题,我无法在运行此代码后打开图表数据。如果我尝试以编程方式访问它,我会收到以下错误:
运行时错误'-2147467259(80004005)':
对象'ChartData'的方法'工作簿'失败
2016年只是一个问题,我在2010年尝试了一些略有不同的事情,并没有看到任何问题。
我终于弄清楚为什么我无法在另一个系统上重现这个问题。仅在进行更改后关闭所有excel实例时才会出现此问题。这意味着如果在运行此代码时打开一个单独的(不相关的)Excel窗口,则不会看到问题。
此问题只能在PowerPoint单独运行时才能重现,而不会打开任何其他Excel电子表格。
答案 0 :(得分:1)
我发现了一个真正“非常棒”的解决方法,至少对于表格而言:
Public Sub CreateTable()
'Create a dummy excel object in the background(run this before working with OLE objects)
Dim xlApp As Object
Set xlApp = CreateObject("Excel.Application")
xlApp.Workbooks.Add
Dim slide As slide: Set slide = ActivePresentation.Slides.Add(1, ppLayoutBlank)
Dim shp As Shape: Set shp = slide.Shapes.AddOLEObject(30, 30, 50, 50, "Excel.Sheet")
shp.OLEFormat.Object.Sheets(1).ListObjects.Add (1) 'xlSrcRange
shp.OLEFormat.Object.Sheets(1).Cells(1, 1) = "fewewq"
shp.OLEFormat.Object.Close
'Kill it when the work is done
xlApp.Application.Quit
End Sub
图表版本:
Public Sub CreateChart()
'Create a dummy excel object in the background(run this before working with OLE objects)
Dim xlApp As Object
Set xlApp = CreateObject("Excel.Application")
xlApp.Workbooks.Add
Dim sld As slide
Dim shp As Shape
Dim pptWorkbook As Workbook
Set sld = ActivePresentation.Slides.Add(1, ppLayoutBlank)
Set shp = sld.Shapes.AddChart
Set pptWorkbook = shp.Chart.ChartData.Workbook
pptWorkbook.Close SaveChanges:=True
'Use the Activate code to open the worksheet, typically only need for 2010
xlApp.Application.Wait Now + TimeValue("0:00:01")
shp.Chart.ChartData.Activate
shp.Chart.ChartData.Workbook.Windows(1).Visible = False
Set pptWorkbook = shp.Chart.ChartData.Workbook
pptWorkbook.Sheets(1).Cells(1, 2) = "fewewq"
Application.ActivePresentation.Save
'Added a wait condition before closing the document, not sure why this works...
Excel.Application.Wait Now + TimeValue("0:00:01")
pptWorkbook.Close SaveChanges:=True
'Kill it when the work is done
xlApp.Application.Quit
End Sub
当然,我对答案并不满意,因为它只是避免了问题,而不是解决根本原因。我仍然希望更好地了解导致此行为的原因。尽管如此,以真正的VBA方式失败,这可能是唯一可行的选择。
答案 1 :(得分:1)
我可以在Windows10-64 / Excel2013-64上一致地重现您的问题。这是一个错误,我们只能尝试检查究竟出了什么问题。
通过VBA更改表格标题时,ListColumn
顽固地拒绝更新其名称。无论是更改标题单元格还是显式更改ListColumn的名称,都会发生这种情况!它只会在您编辑工作簿并手动更改单元格时更新,但不能从VBA中更新:
Public Sub Test()
Dim oslide As Slide
Set oslide = ActivePresentation.Slides.Add(1, ppLayoutBlank)
Dim oshape As Shape
Set oshape = oslide.Shapes.AddOLEObject(30, 30, 250, 250, "Excel.Sheet")
With oshape.OLEFormat.Object
.Sheets(1).ListObjects.Add 1, .Sheets(1).Range("B2:D5") ' <-- put it anywhere
.Sheets(1).ListObjects(1).ListColumns(1).Name = "fewewq" ' <-- whether like this
'.Sheets(1).Range("B2").Value = "fewewq" ' <-- or like this
Debug.Print .Sheets(1).ListObjects(1).ListColumns(1).Range.Cells(1).Value 'fewewq
Debug.Print .Sheets(1).ListObjects(1).ListColumns(1).Name
''''''''''''''' Still prints Column1 ! ''''''''''''''''''
.Close
End With
End Sub
结果很明显:ListObject
表被破坏,因为它内部保存了在标题中找不到的列名(即Column1
)(标题为fewewq
) 。这导致观察到的错误,遗憾的是,显示的错误消息并不总是准确的。
当Excel实例已在运行时,行为会更改,ListColumn
的名称会更新。似乎在编辑标题时更新表内部数据的“组件”在PowerPoint VBA内部编辑时“未加载”。只有在以下情况之一:
您可以在PPT中就地编辑工作簿,手动
您正在运行Excel实例
常见的因素是加载了一些编辑器组件,这个编辑器是在编辑标题时更新内部表数据的编辑器。
您在答案中找到的好的解决方法,即在操作之前打开xlApp,然后在之后关闭它,与这些观察结果一致。
重要的是,Chart
对象(在 Update 1 中)发生的“其他”问题确实与您正确假设的问题相同(“我认为它是同样的问题“)。创建的图表链接到工作表中的ListObject
表,该表的第一行包含其标题。因此,当您更改标题中的单元格时,ListColumn
的名称不会更新,从而导致同样的损坏问题。
更新:另一种轻量级解决方法
在评论引发了与打开先前Excel应用程序的解决方法有关的问题之后,我试图找到一个“更轻松”的解决方法并找到了一个。
确信问题是由于未能更新表中的ListColumn
名称,我找到了一种“强迫它”更新名称的方法。解决方法包括两个步骤:
将表格的范围向右扩展一列,然后立即将其缩小回原始范围。
此操作只是强制表重新计算其列名称,就是这样!现在表的列名是正确的,问题就消失了。
Public Sub Workaround()
Dim oslide As Slide: Set oslide = ActivePresentation.Slides.Add(1, ppLayoutBlank)
Dim oshape As Shape: Set oshape = oslide.Shapes.AddOLEObject(30, 30, 250, 250, "Excel.Sheet")
With oshape.OLEFormat.Object.Sheets(1)
.ListObjects.Add 1 ' xlRange
.Range("A1").Value = "fewewq"
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Expand the table one column to the right than shrink it back
'
With .ListObjects(1)
.Resize .Range.Resize(, .Range.Columns.Count + 1)
.Resize .Range.Resize(, .Range.Columns.Count - 1)
End With
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
End With
With oshape.OLEFormat.Object
Debug.Print .Sheets(1).ListObjects(1).ListColumns(1).Range.Cells(1).Value ' fewewq
Debug.Print .Sheets(1).ListObjects(1).ListColumns(1).Name ' Now prints fewewq !
.Close
End With
End Sub
执行此操作后,您可以验证嵌入式工作表是否可编辑,然后关闭然后打开演示文稿,您将不会发现任何问题。我希望这会有所帮助:)
答案 2 :(得分:0)
下面的工作正常(没有添加Excel引用和Excel常量的实际值,在Win7x64上使用PowerPoint 2010x86):
Option Explicit
Sub test()
Dim sld As Slide
Dim shp As Shape
Set sld = ActivePresentation.Slides.Add(1, ppLayoutBlank)
Set shp = sld.Shapes.AddOLEObject(30, 30, 50, 50, "Excel.Sheet")
Dim listObject As Object ' listObject
Set listObject = shp.OLEFormat.Object.Sheets(1).ListObjects.Add(1) 'xlSrcRange = 1
shp.OLEFormat.Object.Sheets(1).Cells(1, 1) = "fewewq"
shp.OLEFormat.Object.Close
End Sub
不确定为什么设置对象但不使用它们。