[VBA] Makro beim Speichern ausführen

Moderator: ModerationP

[VBA] Makro beim Speichern ausführen

Beitragvon Tolados » 15. Mär 2017, 08:39

Hallo zusammen,

in Anlehnung an Word (wo es funktioniert) habe ich ein Makro für meine PowerPointVorlage (*.potm, Office Vers. 2010) ein Makro erstellt bzw. aus Foren zusammengesucht, was beim Speichern einen bestimmten Pfad und eine Systematik des Dateinamens vorgibt. Das Makro habe ich in 2 Makros unterteilt:
1. Teil, der die Anweisung durchführt als Sub SaveMeAs(). Das funktioniert auch, wenn ich das Makro über VB starte.
2. Teil, der eigentlich beim Klick auf Speichern oder Strg+S das Makro SaveMeAs ausführen soll. Das funktioniert leider nicht.
Folgender Code:

Code: Alles auswählen
Sub FileSave_PresentationBeforeSave(ByVal Pres As Presentation, cancel As Boolean)

     Set Pres = ActivePresentation
     
     If Pres.Path = "" Then    'Falls Präsentation noch nie gespeichert wurde
         SaveMeAs

         Exit Sub
     End If
     ActivePresentation.Save

 End Sub


Kann mir bitte jemand helfen, was ich ändern muss.
Vielen Dank schon im Voraus!
Tolados
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 29
Registriert: 15. Mär 2017, 08:29

Re: [VBA] Makro beim Speichern ausführen

Beitragvon DerHoepp » 15. Mär 2017, 13:06

Hallo Tolados,

In Powerpoint sind Präsentationen keine Objekte, die eigene Events bereitstellen, auf die du reagieren könntest (Es gibt, anders als in Word oder Excel, zum Beispiel kein Objekt ThisPresentation). Das Event vor dem Speichern lautet (wie von dir schon herausgefunden) PresentationBeforeSave. Dieses befindet sich jedoch auf Application-Ebene. Um auf Application-Events reagieren zu können, musst du ein Objekt in einem Klassenmodul vom Typ application mit WithEvents einbinden und in der Klasse auf dieses Event reagieren. Instanzieren kannst du die Klassen aber wiederum nur in einem allgemeinen Modul. Weil es aber wiederum keine Events auf Präsentationsebene gibt, kannst du das benötigte Objekt im Allgemeinen Modul nicht automatisch beim Öffnen einer Datei instanzieren. Es gäbe nun den Workaround, die AutoOpen-Makros zu verwenden, aber die sind ab PPT 2007 nur noch in AddIns zulässig.

Die Alternative ist es, das allgemeine Makro im XML-Code schon zu hooken. Eine Beschreibung findest du zum Beispiel hier: http://www.pptalchemy.co.uk/PowerPoint_Auto_Open_Code.html.

Die Klasse könnte dann in etwa so aussehen:
Code: Alles auswählen
Option Explicit

Private WithEvents app As Application
Private EnableEvents As Boolean
Private Sub app_PresentationBeforeSave(ByVal Pres As Presentation, Cancel As Boolean)
    If Me.EnableEvents Then
        If Pres.Path = "" Then
            Me.SaveThePresAs Pres
            Cancel = True
        End If
    Else
        'nixtun
    End If
End Sub


Private Sub SaveThePresAs(ByRef thePres As Presentation)
    Me.EnableEvents = False
        thePres.SaveAs "C:\Daten\FixerName.pptm"
    Me.EnableEvents = True
End Sub

Private Sub Class_Initialize()
    EnableEvents = True
End Sub


Das ganze ist leider nicht ganz trivial (was mit den vielen PPT-Viren aus den 2000er Jahren zusammenhängt).

Viele Grüße
derHöpp
DerHoepp
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 4547
Registriert: 14. Mai 2013, 11:08

Re: [VBA] Makro beim Speichern ausführen

Beitragvon Tolados » 15. Mär 2017, 16:38

Hallo derHöpp,

vielen Dank für Deine ausführliche Antwort.
Von Klassenmodulen habe ich leider keine Ahnung. Daher bin ich dem Link gefolgt. Das Beispiel konnte ich auch nachstellen, aber nur in einer pptm-Datei, nicht in einer potm Vorlage, wo ich es brauche.

Deinen Code habe ich noch in ein Klassenmodul kopiert, doch beim Speichern bleibt es wirkungslos.

Könntest Du vllt. bitte nochmal genauer beschreiben, was ich wo reinkopieren muss? - Ist mein erstes PPT-VB Projekt...

Danke
Tolados
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 29
Registriert: 15. Mär 2017, 08:29

Re: [VBA] Makro beim Speichern ausführen

Beitragvon DerHoepp » 15. Mär 2017, 20:08

Hallo noch einmal,

ich habe dir mal eine Beispieldatei hochgeladen. Wenn du diese öffnest und Makros aktivierst, dann irgendwas an der ersten Folie änderst, und versuchst zu speichern, solltest du eine Fehlermeldung erhalten.

Wenn du dann eine neue Präsentation erstellst (während die Datei noch läuft) und diese speicherst, wird das akzeptiert. Wenn du dir dann im VBA-Editor das Direktfenster anschaust, sollte da ein bisschen was protokolliert worden sein.
Wie das ganze nun in eine Vorlage mit Makros eingebaut werden kann, muss ich selbst erstmal überlegen und austesten. Ich glaube, es könnte sein, dass das CustomUI als Ribbon dort nicht geladen wird. Dann wird der Workaround nicht funktionieren.

Aber schau es dir erstmal an. Wenn du das ganze mit einer Vorlage hinbekommst, sag doch bitte Bescheid!

Viele Grüße
derHöpp
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
DerHoepp
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 4547
Registriert: 14. Mai 2013, 11:08

Re: [VBA] Makro beim Speichern ausführen

Beitragvon Tolados » 20. Mär 2017, 17:40

Hallo derHöpp,

schon mal vielen Dank für Deine Mühe.
Bin ein Office-Anwender, der sich mal ein Buch ausgeliehen hat und sich VBA für Excel selbst beigebracht hat, dabei allerdings mit Hilfe von Internetrecherche inzwischen zu ganz guten Ergebnissen kommt. Aber auch nicht mit Application-Start Elementen.

Klassenmodule sind für mich komplett unbekannt. Habe das Beispiel wie von Dir beschrieben in normaler PowerPoint durchgeführt und da ist auch im Direktfenster entsprechend sinnvoll etwas protokolliert worden. Aber die Code-Befehle im Gesamtzusammenhang nachzuvollziehen, will mir irgendwie nicht gelingen. Bei Excel habe ich viel gelernt, weil dort Kommentare im Code hinterlegt waren.

Habe das Modul und Klassenmodul dann in meine *.potm kopiert, dort ergibt sich aber keine Auswirkung auf den Speichervorgang, nachdem ich mit Doppelklick eine neue *.pptx erzeuge.
Tolados
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 29
Registriert: 15. Mär 2017, 08:29

Re: [VBA] Makro beim Speichern ausführen

Beitragvon DerHoepp » 21. Mär 2017, 14:13

Hallo,

danke für die Rückmeldung, ich kann dir aber leider im Ergebnis auch nicht weiterhelfen. Mir fällt keine Möglichkeit ein, auf Events in Vorlagen zuzugreifen.
Ich schildere aber gerne noch einmal das grundsätzliche Problem / Vorgehen in meiner Beispieldatei:
Wenn du aus der Excelumgebung kommst, weißt du ja, dass es dort Events gibt, die zum Beispiel beim Öffnen einer Arbeitsmappe automatisch ausgeführt werden. Hierzu benötigt Excel jeweils mindestens ein Objekt der Klasse, die das Event anbietet. Das Workbook_Open-Event ist ein Event der Workbook-Klasse. Im Unterschied zu Powerpoint stellt Excel für das Workbook-Objekt (das ja der Datei entspricht) schon ein Objekt und ein Codemodul in der Programmierumgebung bereit. Dies nennt sich DieseArbeitsmappe. Im Codemodul DieseArbeitsmappe kannst du dann direkt auf die Events zugreifen; auch auf das Open-Event. Neben dem Open-Event gibt es in Excel auch noch ein BeforeSave-Event, dass du ebenfalls direkt in das Codemodul zu "DieseArbeitsmappe" abgreifen kannst. Du musst hier nichts weiter tun, Excel stellt dir automatisch die benötigten Objekte bereit und ruft die Event-Prozeduren selbstständig auf.

In Powerpoint gibt es natürlich ebenfalls einige Events. Allerdings stellt Powerpoint kein Objekt mit Codemodul zur Verfügung, in dem du die Events einfach abgreifen könntest (in der Programmierumgebung siehst du nur das VBA Projekt). Allgemeine Module können jedoch keine Events abgreifen, das können nur Klassenmodule. Also musst du ein Klassenmodul erstellen, dass auf Events reagiert. Eine Klasse selbst kann jedoch nichts. Nur ein Objekt, dass aus einer Klasse abgeleitet wird, kann tatsächlich "arbeiten". Leider beisst sich die Katze da aber in den Schwanz. Denn, wenn es kein Event gibt, dass beim Öffnen einer Präsentation ausgeführt wird, kannst du auch nicht beim Öffnen einer Präsentation ein Objekt erstellen, dass auf diese Events reagiert.
Der Umweg ist es eben, einen Trigger zu benutzen, der nicht in VBA liegt, sondern im Ribbon. Mit dem Öffnen der Datei werden auch alle CustomUI-Elemente geladen. Und mit dem Laden der CustomUI-Elemente werden die Aktionen ausgeführt, die im Attribut onLoad angegeben sind.
Das macht sich meine Beispieldatei zu nutze und erstellt in der Prozedur, die von onLoad aufgerufen wird, ein Objekt, das auf Events der Application-Klasse reagieren kann. Eines der Events lautet dabei PresentationBeforeSave. Und genau auf dieses Event reagieren wir, in dem geprüft wird, ob das dort übergebene Presentation-Objekt dem Presentation-Objekt entpsricht, das nicht gespeichert werden soll.

Bei mir verhindern es die Sicherheitseinstellungen, das gleiche auch für Vorlagendateien zu erledigen. Da hilft wohl nur ein Button, der die Objektinitialisierung übernimmt.

Zusatzinfo: Die Presentation-Klasse scheint gar keine Events offenzulegen, auf die man reagieren könnte.

Viele Grüße noch einmal!
derHöpp
DerHoepp
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 4547
Registriert: 14. Mai 2013, 11:08

Re: [VBA] Makro beim Speichern ausführen

Beitragvon Tolados » 27. Mär 2017, 07:27

Hallo derHöpp,

ganz vielen Dank für Deine Mühe und Erläuterung. Dann muss ich damit wohl leben...

VG, Tolados
Tolados
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 29
Registriert: 15. Mär 2017, 08:29


Zurück zu PowerPoint Forum (provisorisch)

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste