Откройте PowerPoint из каталога и возобновите макрос

Я пытаюсь открыть PPTX из определенной папки, используя функцию в Sub. Цель функции состоит в том, чтобы выбрать файл, который будет выполнять остальная часть кода макроса (по сути, чтобы сделать его ActivePresentation). Проблема в том, что когда я вызываю функцию PickDir(), чтобы получить путь к файлу и открыть его, макрос перестает работать. Итак, я просто получаю открытую презентацию, а не выполняю действие, которое хочу сделать.

Проблема возникает примерно через 5 строк после того, как все переменные Dim'd.

Sub ExtractImagesFromPres()
On Error GoTo ErrorExtract
Dim oSldSource As Slide
Dim oShpSource As Shape
Dim ImgCtr As Integer
Dim SldCtr As Integer
Dim ShapeNameArray() As String
Dim oPP As Object
Dim SrcDir As String
Dim SrcFile As String
'File naming variables
Dim PPLongLanguageCode As String
Dim PPShortLanguageCode As String
Dim FNShort As String
Dim FNLong As String
Dim PPLanguageParts1() As String
Dim PPLanguageParts2() As String
Dim FNLanguageParts() As String

SrcDir = PickDir()      'call the PickDir() function to choose a directory to work from
If SrcDir = "" Then Exit Sub

SrcFile = SrcDir & "\" & Dir(SrcDir + "\*.pptx")    'complete directory path of ppt to be split

Set oPP = CreateObject("Powerpoint.Application")      'open ppt containing slides with images/text to be exported
ActivePresentation = oPP.Presentations.Open(SrcFile, False, False, True)

ImgCtr = 0  'Image and Slide counter for error messages
SldCtr = 1

ReDim ShapeNameArray(1 To 1) As String  'initialize ShapeNameArray to avoid null array errors

For Each oSldSource In ActivePresentation.Slides
    For Each oShpSource In oSldSource.Shapes    'loop each shape within each slide
        If oShpSource.Type <> msoPlaceholder Then   'if shape is not filename placeholder then add it's name to ShapeNameArray
            ShapeNameArray(UBound(ShapeNameArray)) = oShpSource.Name
            ReDim Preserve ShapeNameArray(1 To UBound(ShapeNameArray) + 1) As String    'need to add one to array for new shape name
            ElseIf oShpSource.Type = msoPlaceholder Then    'is shape is filename placeholder then check to see if not empty
                If oShpSource.TextFrame.TextRange.Length = 0 Then
                    MsgBox "The filename is missing on Slide:" & SldCtr & vbNewLine & _
                    "Please enter the correct filname and re-run this macro"
                    Exit Sub
                End If
                PPLanguageParts1 = Split(ActivePresentation.Name, ".")  'extract language code from PowerPoint filename
                PPLongLanguageCode = PPLanguageParts1(LBound(PPLanguageParts1))
                PPLanguageParts2 = Split(PPLongLanguageCode, "_")
                PPShortLanguageCode = PPLanguageParts2(UBound(PPLanguageParts2))
                FNLanguageParts = Split(oShpSource.TextFrame.TextRange.Text, "_")   'insert PowerPoint filename language code into image filename language code
                FNShort = FNLanguageParts(LBound(FNLanguageParts))
                FNLong = FNShort & "_" & PPShortLanguageCode
                oShpSource.TextFrame.TextRange.Text = FNLong

        End If
    Next oShpSource
        ReDim Preserve ShapeNameArray(1 To UBound(ShapeNameArray) - 1) As String    'ShapeNameArray has one too many elements, so subtract one
        Call oSldSource.Shapes.Range(ShapeNameArray).Export(FNLong & ".jpg", ppShapeFormatJPG)  'export images with proper filenames
        ReDim ShapeNameArray(1 To 1) As String
        ImgCtr = ImgCtr + 1
        SldCtr = SldCtr + 1
Next oSldSource

If ImgCtr = 0 Then  'error message if no images
    MsgBox "There were no images found in this presentation", _
            vbInformation, "Image extraction failed."
End If
Exit Sub
ErrorExtract:

If Err.Number <> 0 Then 'error message log
    MsgBox Err.Description, vbCritical, "Error #" & Err.Number
End If
End Sub

Private Function PickDir() As String
Dim FD As FileDialog

    PickDir = ""

    Set FD = Application.FileDialog(msoFileDialogFolderPicker)      'initialize default MS directory picker
    With FD
        .Title = "Pick the folder where your files are located"     'title for directory picker dialog box
        .AllowMultiSelect = False
        .Show
        If .SelectedItems.Count <> 0 Then
            PickDir = .SelectedItems(1)
        End If
    End With

3 ответа

Решение

Вы запускаете это изнутри PowerPoint? Если да, вам не нужно создавать другой объект Application: вы можете просто открыть ppt напрямую. И вы можете использовать возвращаемое значение из Open(), чтобы получить ссылку на презентацию (вместо использования "activePresentation")

Dim ppt as Presentation
Set ppt = Application.Presentations.Open(SrcFile, False, False, True)
'do stuff with ppt

Эта строка, вероятно, доставляет вам некоторые неприятности:

ActivePresentation = oPP.Presentations.Open(SrcFile, False, False, True)

Я не знаю, как активировать окно в PPT, но по крайней мере вам нужно будет использовать следующее:

Set ActivePresentation = oPP.Presentations.Open(SrcFile, False, False, True)

Что касается активации презентации, вам может понадобиться доступ к коллекции окон или что-то подобное? Мы надеемся, что это заставит вас задуматься.

application.Presentations(1).Windows(1).Activate

Наконец, вам может фактически не понадобиться активировать презентацию, если у вас нет других открытых презентаций, то та, которую вы открываете, скорее всего будет активной по умолчанию, если вы откроете ее видимой. Я подозреваю, что это так, учитывая, что вы создаете объект приложения Powerpoint. Если это правильно, то вам просто нужно сделать следующее:

oPP.Presentations.Open(SrcFile, False, False, True)
debug.print oPP.ActivePresentation.Name

Редактировать: я бы также рекомендовал установить ссылку на библиотеку объектов powerpoint и объявить oPP следующим образом:

Dim oPP as Powerpoint.Application

Затем при создании экземпляра приложения:

Set oPP = New Powerpoint.Application

Если вы не хотите беспокоиться о том, какая презентация активна, вы можете сделать:

Dim oPres as Presentation
Set oPres = oPP.Presentations.Open(SrcFile, False, False, True)

Затем в остальной части кода используйте oPres вместо ActivePresentation

Другие вопросы по тегам