Преобразовать код ранней привязки в позднюю привязку - PullRequest
0 голосов
/ 11 мая 2018

Мне трудно преобразовать код ранней привязки в позднюю привязку.Я пробовал несколько раз, но это не работает должным образом.Когда дело доходит до раннего связывания, это работает хорошо.Вот мой код, и я хотел бы попросить вас показать мне, как он должен выглядеть и в каких местах я должен вносить изменения и для чего.

Sub PrezentacjaPP()

    Dim PowerPointA As PowerPoint.Application 'aplikacja PowerPoint
    Dim PrezentacjaPP As PowerPoint.Presentation 'prezentacja PowerPoint
    Dim NazwaPP As String 'nazwa pliku z szablonem prezentacji
    Dim SlajdPP As PowerPoint.Slide 'slajd prezentacji PowerPoint
    Dim WykresPP As PowerPoint.Shape 'wykres w formacie obrazu
    Dim Lista As String 'lista marek
    Dim Tekst As String 'tekst z info o marce i statystykami
    Dim i As Long 'numer marki
    Dim Wiersz As Long 'numer pierwszego wiersza dla danej marki

    Application.ScreenUpdating = False 'Wyłącz odświeżanie ekranu


        '1.Usunięcie starych prezentacji
        NazwaPP = Dir(ThisWorkbook.Path & "\" & "Prezentacja_*.pptx")
        If NazwaPP <> "" Then
            If MsgBox("Czy usunąć istniejące pliki z prezentacjami PowerPoint?", _
                vbYesNo + vbInformation) = vbYes Then
                Do While NazwaPP <> ""
                    Kill ThisWorkbook.Path & "\" & NazwaPP
                    NazwaPP = Dir()
                Loop
            Else
                MsgBox "Zmień nazwę istniejących prezentacji i ponownie uruchom procedurę."
                CzyZakonczyc = True
                Exit Sub
            End If
        End If

        '2. Wczytanie zmiennych
        ChDrive Left(ThisWorkbook.Path, 1) 'domyślny dysk
        ChDir ThisWorkbook.Path 'domyślny katalog
        NazwaPP = Application.GetOpenFilename(FileFilter:="Prezentacje programu PowerPoint (*.pptx), *.pptx", Title:="Zaznacz plik z szablonem prezentacji PowerPoint")
        If NazwaPP = "False" Then
            CzyZakonczyc = True
            Exit Sub
        End If

        '3. Wczytanie i otwarcie szablonu prezentacji PowerPoint
        Set PowerPointA = New PowerPoint.Application
        Set PrezentacjaPP = PowerPointA.Presentations.Open(NazwaPP) '<-- tylko w celach poglądowych podczas testowania makra

        '4. Stworzenie prezentacji
        With PrezentacjaPP

            '4.1. Uzupełnienie slajdów wstępnych
            .Slides(1).Shapes(1).TextFrame.TextRange = Cells(NrWiersza, "B").Value 'Slajd nr 1
            .Slides(2).Shapes(1).TextFrame.TextRange = "Lista marek" 'Slajd nr 2
            For i = 1 To Cells(Rows.Count, 18).End(xlUp).Row - 1
               Lista = Lista & Cells(i + 1, "R") & vbNewLine
            Next i
            .Slides(2).Shapes(2).TextFrame.TextRange = Lista

                '4.1.1. Stworzenie slajdów z aktywami
                 For i = 1 To Cells(Rows.Count, 18).End(xlUp).Row - 1
                     'Dodanie nowego slajdu (typ ppLayoutText: tytuł oraz pole tekstowe)
                     Set SlajdPP = .Slides.Add(.Slides.Count + 1, ppLayoutText)
                     With SlajdPP
                     'Wstawienie tytułu slajdu
                     .Shapes(1).TextFrame.TextRange = Cells(i + 1, "R")

            '4.2. Dodanie wykresów

                '4.2.1. Wykres 1
                ActiveSheet.Shapes.Range(Array("Picture" & " " & i * 2 - 1)).Select 'wykres w formacie obrazu w Excel'u
                Selection.Copy
                .Shapes.Paste
                Set WykresPP = .Shapes(SlajdPP.Shapes.Count)

                '4.2.2. Pozycjonowanie wykresu na slajdzie
                With WykresPP
                    .Left = 40
                    .Top = 110
                    .LockAspectRatio = msoFalse 'odblokowanie wsp. proporcji
                    .Width = 400
                    .Height = 195
                End With

                '4.2.3. Wykres 2
                ActiveSheet.Shapes.Range(Array("Picture" & " " & i * 2)).Select 'wykres w formacie obrazu w Excel'u
                Selection.Copy
                .Shapes.Paste
                Set WykresPP = .Shapes(SlajdPP.Shapes.Count)

                '4.2.4. Pozycjonowanie wykresu na slajdzie
                With WykresPP
                    .Left = 40
                    .Top = 315
                    .LockAspectRatio = msoFalse 'odblokowanie wsp. proporcji
                    .Width = 400
                    .Height = 195
                End With

            '4.3. Doddanie statystyk

                '4.3.1. Wyznaczenie numeru pierwszego wiersza dla danej marki
                Wiersz = NrWiersza + 3 + 25 * (i - 1)

                '4.3.2 Wczytanie statystyk
                Tekst = Cells(Wiersz, 2) & " " & Cells(Wiersz, 3) & vbNewLine & _
                    Cells(Wiersz + 20, 2) & " " & FormatNumber(Cells(Wiersz + 20, 4), 2) & vbNewLine & _
                    Cells(iersz + 21, 2) & " " & Cells(iersz + 21, 4) & vbNewLine & _
                    Cells(Wiersz + 22, 2) & " " & Cells(Wiersz + 22, 4) & vbNewLine & _
                    Cells(Wiersz + 22, 2) & " " & Cells(Wiersz + 22, 4) & vbNewLine & _
                    vbNewLine & _
                    Cells(Wiersz + 20, 6) & " " & FormatNumber(Cells(Wiersz + 20, 9), 2) & vbNewLine & _
                    Cells(Wiersz + 21, 6) & " " & Cells(Wiersz + 21, 9) & vbNewLine & _
                    Cells(Wiersz + 22, 6) & " " & Cells(Wiersz + 22, 9) & vbNewLine & _
                    vbNewLine & _
                    Cells(Wiersz + 20, 11) & " " & Cells(Wiersz + 20, 13) & vbNewLine & _
                    Cells(Wiersz + 21, 11) & " " & Cells(Wiersz + 21, 13)

                '4.3.3. Pozycjonowanie pola
                .Shapes(2).Top = 110
                .Shapes(2).Left = 500
                .Shapes(2).Width = 330
                .Shapes(2).Height = 410
                .Shapes(2).TextFrame.TextRange = Tekst

        End With
        Next i

        '4.4. Stworzenie slajdu końcowego

            '4.4.1. Dodanie slajdu
            Set SlajdPP = PowerPointA.Presentations(1).Slides.Add _
                (PowerPointA.Presentations(1).Slides.Count + 1, ppLayoutText)
            SlajdPP.Shapes(1).Delete

            '4.4.2. Uzupełnienie slajdu
            With SlajdPP.Shapes(1)
                .TextFrame.TextRange = "DZIĘKUJĘ ZA UWAGĘ"
                .TextFrame.HorizontalAnchor = msoAnchorCenter
                .TextFrame.VerticalAnchor = msoAnchorMiddle
                .TextEffect.FontBold = msoCTrue
                .TextEffect.FontSize = 24
                .TextFrame2.TextRange.Font.Fill.ForeColor.RGB = RGB(0, 100, 170)
            End With

        End With

        '5. Zapisanie prezentacji PowerPoint
        PrezentacjaPP.SaveAs Excel.ActiveWorkbook.Path & "\Prezentacja_PP_" & Date & ".pptx"

    Application.ScreenUpdating = True 'Włącz odświeżanie ekranu

End Sub

1 Ответ

0 голосов
/ 11 мая 2018

Позднее связывание означает, что VBA знает только время выполнения о соответствующих типах. Это поздно:

Dim PowerPointA As Object

Это объявление будет компилироваться с указанием библиотеки типов PowerPoint или без нее.

Поскольку VBA не знает (не может) знать, какие члены PowerPointA имеют, вы не получите IntelliSense во время разработки, и это с радостью скомпилируется ...

PowerPointA.SomeMemberThatDoesNotExist

... и взорвать во время выполнения с ошибкой 438 «Объект не поддерживает это свойство или метод».

Любой вызов участника, сделанный против Object или Variant, имеет позднюю привязку; во время выполнения VBA необходимо запросить интерфейс, чтобы определить местонахождение члена и определить его существование: это означает, что код с поздней привязкой влечет за собой небольшую нагрузку, которая не требуется для кода с ранней привязкой.


Раннее связывание означает, что VBA обладает знаниями во время компиляции соответствующих типов. Это рано:

Dim PowerPointA As PowerPoint.Application

Это объявление может быть скомпилировано только при обращении к библиотеке типов PowerPoint.

Поскольку VBA знает, какие элементы есть у PowerPointA, вы получаете IntelliSense (и автозаполнение) во время разработки, и это будет , если не скомпилируется:

PowerPointA.SomeMemberThatDoesNotExist

... однако Application - это, вероятно, расширяемый COM-интерфейс (Excel.Application is); если это так, тогда VBA скомпилирует код, и SomeMemberThatDoesNotExist будет вызовом с поздней привязкой, который будет взорван во время выполнения с ошибкой 438 «Объект не поддерживает это свойство или метод».


Когда вы хотите «преобразовать код с ранней привязкой в ​​код с поздней привязкой», вы действительно имеете в виду, что вы хотите удалить ссылку на библиотеку типов из вашего проекта и при этом иметь возможность компилировать и запускать код .

Предполагая, что ссылка является библиотекой типов PowerPoint, это означает, что вам нужно заменить все в своем коде, который определен в этой библиотеке - потому что, как только вы удалите ссылку, классы, такие как PowerPoint.Application, PowerPoint.Presentation, PowerPoint.Slide и PowerPoint.Shape больше не будут определяться, и перестанут что-либо значить для VBA. Поэтому:

  1. Заменить декларации As [PowerPoint.][ClassName] на As Object
  2. Заменить New [PowerPoint.][ClassName] на CreateObject("ProgIdForThatClass")
  3. Удалить ссылку на библиотеку типов PowerPoint
  4. Скомпилируйте проект. Не компилируется? Вернуться к 1.

ProgId для PowerPoint.Application бывает "PowerPoint.Application", так что вы можете заменить это:

Set PowerPointA = New PowerPoint.Application

С этим:

Set PowerPointA = CreateObject("PowerPoint.Application")

И это все, что вам нужно сделать.

Если в другом месте есть код, который ссылается на константы, определенные в библиотеке типов PowerPoint, вам нужно либо заменить их на их базовое значение, либо определить эквивалентные константы самостоятельно, поэтому вместо этого:

foo = ppEffectFade

У вас будет это:

foo = 1793 'PowerPoint.PpEntryEffect.ppEffectFade=1793

или это:

Const ppEffectFade As Long = 1793
foo = ppEffectFade

Или это:

Public Enum PpEntryEffect
    ppEffectAppear = 3844
    ppEffetFade = 1793
    '...
End Enum
foo = ppEffectFade

Вы можете найти все константы, их значения и все, что определено в любой библиотеке ссылочных типов, используя Object Browser ( F2 ):

object browser showing definition of PowerPoint.PpEntryEffect.ppEffectAppear

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...