0

I have a script that I would like to bulk edit powerpoint files with. If I edit files one by one with it, it works great. If I bulk edit them, it fails. I assume this is because the application is not closing before the next file attempts to load, but I could, and most likely am, wrong.

The code:

import win32com.client, sys, glob


folder = (glob.glob('*.ppt'))

print("="*20)
print(folder)
print("="*20)

if folder:
    for files in folder:
        print("Current File: " + files)
        try:
            Application = win32com.client.Dispatch("PowerPoint.Application")
            Application.Visible = True
            Presentation = Application.Presentations.Open("c:/pptpy/testfolder/" + files)
            for Slide in Presentation.Slides:
                for Shape in Slide.Shapes:
                    try:
                        Shape.TextFrame.TextRange.Font.Name = "Arial"
                        Shape.TextFrame.TextRange.Font.Size = "14"
                        Shape.TextFrame.TextRange.Font.Color.RGB = "000000"
                    except:
                        pass
            Presentation.Save()
            Application.Quit()
                #Adding a time.sleep(1) here pauses the Application.Quit()
        except:
            print("Error in: " + files)
            pass

The error (when not passing exceptions):

Traceback (most recent call last):
  File "C:\pptpy\testfolder\convert.py", line 19, in <module>
    for Shape in Slide.Shapes:
  File "C:\Python33\lib\site-packages\win32com\client\dynamic.py", line 247, in __getitem__
    return self._get_good_object_(self._enum_.__getitem__(index))
  File "C:\Python33\lib\site-packages\win32com\client\util.py", line 37, in __getitem__
    return self.__GetIndex(index)
  File "C:\Python33\lib\site-packages\win32com\client\util.py", line 53, in __GetIndex
    result = self._oleobj_.Next(1)
pywintypes.com_error: (-2147023174, 'The RPC server is unavailable.', None, None)

Details:

Python3.3

Powerpoint2007

If you need any more details, I would be happy to provide them! Thanks!

joojaa
  • 4,354
  • 1
  • 27
  • 45
Eric
  • 323
  • 4
  • 20
  • 1
    Adding a `time.sleep(1)` after processing each presentation changes anything? Anyway, *never* use a bare `except:`. You should always specify which exception to catch. In your example you should really specify to catch only that `com_error`. (Minor remark doing `if folder: for file in folder` is exactly the same as a simple `for file in folder`. When `folder` is empty the `for` is never executed.) – Bakuriu Jun 04 '13 at 14:34
  • Thank you for the best practices advice. I'm very new to python still. I've added a time.sleep(1) at the start and end of the processing and it just seems to stall the application.quit. I've tried adding a 10 second sleep and it just waits 10 seconds and then closes the ppt window. – Eric Jun 04 '13 at 14:59
  • 1
    Why do you need to close the application just load a new file then close after every file is processed. Its also faster that way. – joojaa Jun 04 '13 at 20:13
  • I don't need to close the application, I was just looking at that one solution and didn't back up to look for another way around. I'm not exactly sure how to go about doing that though. I'm looking over the win32com documentation, but haven't found anything that seems like it would help yet. – Eric Jun 04 '13 at 21:07

1 Answers1

1

Try something like this (building on previous question). You should really invest time in designing your code before you ask questions like this:

import win32com.client
import sys # <- obsolete not used
import os
import glob # style guide one import per line


Application = win32com.client.Dispatch("PowerPoint.Application")
Application.Visible = True

ppt_files = glob.glob('*.ppt')

for file in ppt_files:
    file = os.path.abspath(file)
    Presentation = Application.Presentations.Open(file)
    for Slide in Presentation.Slides:
        for Shape in Slide.Shapes:
            try:
                Shape.TextFrame.TextRange.Font.Name = "Arial"
                Shape.TextFrame.TextRange.Font.Size = "12"
                Shape.TextFrame.TextRange.Font.Color.RGB = "000000"
            except:
                pass
    Presentation.Save()
    Presentation.Close()

Application.Quit()
Community
  • 1
  • 1
joojaa
  • 4,354
  • 1
  • 27
  • 45
  • Thank you! You're right, I should have spent more time on this issue before asking. I am still in the early stages of learning python and finding documentation on PowerPoint + Python development was difficult (or my google-fu is lacking). I appreciate all the help you've given me on this subject! – Eric Jun 05 '13 at 10:22
  • 1
    This has nothing to do with python but COM, you would have the exact same code (more or less) in visual basic, C, C# etc. Com just defines a language neutral way to negotiate an API. So programs only documents the COM interface. Unfortunately, most of the time COM interfaces is badly documented, butt you can search for visual basic same thing same interface. Start with something like: http://www.powershow.com/view/974b7-YzE2Y/Automating_Windows_Applications_with_win32com_powerpoint_ppt_presentation or http://starship.python.net/~skippy/conferences/tools99/html/ppframe.htm – joojaa Jun 05 '13 at 10:39
  • 1
    just to add you can find the reference for presentation object hare: http://msdn.microsoft.com/en-us/library/ff745984%28v=office.14%29.aspx Along with all the other objects. – joojaa Jun 05 '13 at 10:50