Powerpoint VBA - Editing a table column name in an embedded Excel OLE object

If you run the following code, you will get a rather interesting result (only with PowerPoint running, close all Excel instances before running):

'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 

The embedded object is created successfully, and the table is present with the specified data. However, when you click on an embedded object, the following error appears:

enter image description here

There is not enough memory to read the worksheet.

This object can no longer be inverted in any other way, and the damaged nature of the object is preserved when the document is closed / opened and restarted. I tested this problem on all but one of the systems I tested on (PowerPoint / Excel 2016, Windows 7 X64).

Question

So my question is: can anyone else reproduce this, and if so, why is this happening? If you change the line "Cells (1, 1)" to "Cells (2, 1)", then there is no problem, it seems that editing the head of the table causes some special behavior, other than editing rows or other cells.

Study

  • This is not really said about it, most things are not related to this particular problem.

  • This post claims to be a problem with too many fonts installed (> 600). I tested this, I only have 241 installed ...

  • There are many unanswered messages ( this , this , this , and this ) should not go there.

  • There are some messages that are completely unrelated, again, do not select there.

  • I tested the same code in MS Word, it seems to work fine, the problem seems to be isolated from PowerPoint

  • I tried to make one version in the code (broken object) and the other manually (work object), saving them and comparing binary output ( only built-in objects ). That sounds cool, but it doesn't give me a deeper understanding. I cannot open the built-in objects with Excel separately, because the objects seem to be stored in the corporate format . The central area of ​​the binary system looks different, but I'm not sure how and why. So far, I have not found a way to decode this into human-readable information.

  • After considerable delay and proper attribution , I cross-posted this on Microsoft forums . Maybe someone has an understanding. I will actively support both posts. If I were 100% sure that it was a mistake, I could even consider opening the problem here .

  • You can completely avoid this problem by never closing OLEObject, this causes problems in 2010, especially in combination with the diagram behavior associated with this, you get excol windows displayed. Not a very good user interface. I think I could open a hidden excel window in the background and then finish when I finish working on the built-in things ...

  • I am running version: Microsoft Office 365 ProPlus: version 1705 (build 8201.3103 to run), but I also saw this problem in Microsoft Office Standard 2010, version 14.0.7015.1000 (32-bit version)). The problem with the table seems to be the same in every other version of the office, although I am wondering if this affects the versions prior to 2010?

Update 1

I tried the same with charts:

 '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 

If you change the value of the title bar, you can no longer access the built-in object ("Cells (1, 2)"), if you change another value ("Cells (2, 1)"), it works fine. I assume the same problem, I cannot open the chart data after running this code. If I try to access it programmatically, I get the following error:

Runtime Error '-2147467259 (80004005)':

Failed to execute "Workbook" of object "ChartData"

Only problem in 2016, although I tried something a little different in 2010 and did not see any problems.

Update 2

I finally understood why I could not reproduce this problem in another system. This problem only appears after closing all excel instances after making the changes. This means that if you run a separate (unrelated) excel window when you run this code, you will not see a problem.

This problem can only be reproduced if PowerPoint works alone, without opening any other Excel spreadsheets.

+5
source share
3 answers

I could sequentially reproduce your problem on Windows10-64 / Excel2013-64. This is a mistake, we can only try to verify what exactly is going wrong.

When changing the table title via VBA, ListColumn stubbornly refuses to update its name. This happens whether you change the header cell or explicitly the name of the ListColumn! It is updated only if you edit the Workbook and change the cell manually, but not from 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 

The result is obvious: the ListObject table is corrupted because it has internally stored column names (i.e. Column1 ) that it does not find in the header ( fewewq header). This leads to an observed error, the displayed error messages are not always accurate, unfortunately.

When the Excel instance is already running, behavior changes and updating the ListColumn name . It seems that the “component” that updates the internal data of the table when editing the header “does not load” when editing inside PowerPoint VBA. Only if:

  • You edit the workbook in place in PPT, manually

  • You have an Excel instance with

A common factor is that some component of the editor is loaded there, and this editor is the one that updates the internal data of the table when editing the header.

The good workaround you found in your answer, which is to open xlApp before the action, then close it after, is consistent with these observations.

It is important to note that the “other” problem that occurs with the Chart object (in Update 1 ) is indeed the same problem that you are correct (“I assume the same problem”). The created chart is bound to the ListObject table on the sheet, and this table has its own title in the first row. Therefore, when you change the cell in the title, the ListColumn name ListColumn not updated, which leads to the same corruption problem.

UPDATE: Another Lightweight Workaround

After I had problems commenting on a workaround for a previous Excel application, I tried to find a “lighter” workaround and found it.

After making sure that the problem is due to the inability to update the ListColumn name in the table, I found a way to "force it" to update my names. The workaround consists of two stages:

Expand the range of the table one column to the right, and then immediately return it to the original range.

This operation simply causes the table to recalculate the column names and what it is! Now the table column names are correct and the problem has disappeared.

 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 

After this operation, you can verify that the built-in worksheet is editable, and you can close and then open the presentation and you will not find any problems. Hope this helps :)

+1
source

I found a really “awesome” workaround, at least for tables:

 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 

Chart Version:

 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 

Of course, I am not satisfied with the answer, because it simply avoids the problem, and does not eliminate the root cause. I would still like to better understand what causes this behavior. Otherwise, in a true VBA mode, this may be the only viable option.

+1
source

It works fine with below (without adding the Excel link and the actual value of Excel constants using PowerPoint 2010x86 on Win7x64):

 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 

Just not sure why you are setting objects but not using them.

0
source

Source: https://habr.com/ru/post/1269000/


All Articles