Forum des développeurs  

Le forum de référence en programmation et développement. Articles, cours et tutoriels du débutant au chef de projet et DBA confirmé.
Précédent   Forum des développeurs > Hardware, Systèmes et Logiciels > Microsoft Office > Powerpoint > VBA PowerPoint

Réponse
 
Outils de la discussion
Vieux 19/08/2008, 20h10   #1 (permalink)
Invité de passage
 
Date d'inscription: août 2008
Localisation: Pyrénées Atlantiques
Âge: 29
Messages: 8
Par défaut PPT2007 : problème de mise à jour du masque de diapositive

Bonjour à tous,

J'ai développé récemment un petit programme en VB2005 qui, grâce à la plateforme .NET, me permet d'afficher une sorte de timer sur mes diapositives. Ce timer est en réalité une barre que j'affiche en bas de l'écran et dont la longueur correspond au temps restant.

Pour des raisons d'affichage, je crée cette barre sur le masque de diapositive, et sa longueur est ajustée toutes les 10 secondes. Tout marchait parfaitement bien sous Office 2003... Mais la nouvelle version 2007 me pose un problème.

En effet, lorsque PowerPoint 2007 affiche la diapositive i, il prépare également la diapositive i+1. Si plus de 10 secondes passent lorsque la diapositive i est affichée, ma barre de progression se réduit (jusque là tout va bien). Mais quand je passe à la diapositive i+1, la barre de progression s'affiche avec la longueur qu'elle avait au début de la diapositive i, c'est à dire sa longueur avant la réduction. Au prochain tick du timer qui contrôle tout cela, sa longueur est réajustée correctement, mais au final, ça donne l'impression d'une barre de progression qui joue au yoyo.

Ce problème est dû à la mise en cache de la diapositive suivante. C'est une fonctionnalité intéressante de PowerPoint pour fluidifier les présentations, mais dans mon cas, ça pose un problème. Savez-vous s'il est possible de désactiver cette mise en cache par programmation ?

Merci d'avance,

Merhandir
merhandir est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 19/08/2008, 21h00   #2 (permalink)
Responsable PowerPoint
 
Avatar de Philippe JOCHMANS
 
Date d'inscription: mai 2005
Localisation: Loir et Cher et Touraine
Âge: 40
Messages: 9 938
Envoyer un message via MSN à Philippe JOCHMANS
Par défaut

Bonjour

Ce n'est pas évident de te réponde sans faire de test.

Pourrais-tu nous donner un petit bout de programme (la partie pilotage de PPT) pour faire des tests, car comme cela sans plus d'indications je ne peux vraiment pas te répondre.

En VBA on a une instruction DoEvents, elle permet d'attendre la fin d'un processus avant d'en lancer un autre, cela règle souvent les problèmes d'affichage.

Je t'avoue que je n'ai pas regardé VB2005 depuis un moment, j'avais fait des tests sur la version Express, mais peut-être qu'une instruction de ce type existe.

Regarde la définition dans l'aide VBA pour comprendre à quoi cela sert, et trouver un équivalent sous VB2005.

Starec
__________________
En cas de questions techniques par MP ou message visiteur
Office : :Les Cours, Les FAQs
VB : Les Cours, Les FAQs
Mes articles : ici
Me connaitre
Philippe JOCHMANS est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 20/08/2008, 11h16   #3 (permalink)
Invité de passage
 
Date d'inscription: août 2008
Localisation: Pyrénées Atlantiques
Âge: 29
Messages: 8
Par défaut DoEvents or Not DoEvents

Bonjour,

Je ne pense pas qu'un DoEvents soit la solution ici. En effet, sauf erreur de ma part, cette instruction sert habituellement à redonner la main au système de temps en temps pour qu'il puisse gérer les événements en attente lorsque le programme est "bloqué" dans une boucle un peu gourmande en temps machine.
Dans mon cas, je n'utilise pas ce type de boucle. Le .NET permet de gérer les threads, et le timer que j'utilise pour réduire ma barre de progression toutes les 10 secondes est géré par un thread indépendant. De ce fait, le programme ne reste jamais "bloqué" dans une procédure, et je ne vois pas du tout où je pourrais insérer un DoEvents pour améliorer mon affichage.

Je pense vraiment que le problème vient de PowerPoint 2007 qui calcule à l'avance le fond de la diapositive suivante, basé sur le masque. Or, comme il y a un élément dynamique dans le mien, ça pose un problème. Il faut reconnaître qu'un masque de diapositive n'est pas spécialement conçu pour évoluer au cours de la présentation ! C'est mon besoin qui crée le problème, j'en suis conscient. Mais ça marchait si bien sous PowerPoint 2003 !

Bref, pour l'instant, je ne vois que les solutions suivantes :
- soit je trouve une instruction qui permette de désactiver le pré-calcul de la diapositive suivante (mais rien ne dit qu'elle existe...),
- soit je trouve une instruction qui permette de rafraîchir le fond d'une diapo avant de l'afficher (mais je n'ai trouvé aucun QuelqueChose.Refresh ou autre),
- soit je reprends tout mon code pour créer une barre sur les diapos et non sur le masque. J'ai déjà commencé à y réfléchir, mais je vois déjà se profiler quelques problèmes...

Enfin, pour ceux qui voudraient essayer sur VB2005 ou le retranscrire sous VBA, voici quelques pistes.
Je crée tout d'abord une instance d'une application PowerPoint, avec l'option WithEvents pour pouvoir récupérer les événements de cet objet.

Code :
Private WithEvents m_objAppPowerPoint As Microsoft.Office.Interop.PowerPoint.Application
La création de la barre de progression se fait au lancement du diaporama, dans la procédure qui gère l'événement m_objAppPowerPoint.SlideShowBegin :

Code :
 With m_objAppPowerPoint.ActivePresentation.SlideMaster
            m_objEcran.Largeur = .Width
            m_objEcran.Hauteur = .Height
            m_objCallout = .Shapes.AddCallout(MsoCalloutType.msoCalloutFour,   0, m_objEcran.Hauteur - 5, m_objEcran.Largeur, 5)
	End With
 
        With m_objCallout
            .Callout.Border = MsoTriState.msoFalse
            .Fill.ForeColor.RGB = RGB(0, 255, 0)
            .Fill.Transparency = 0
        End With
 
(L'objet m_objEcran est une structure personnelle contenant deux champs de type Single)

Ensuite, je crée un timer :

Code :
Private WithEvents m_tmrCompteur As New System.Timers.Timer
initialisé comme suit :

Code :
 With m_tmrCompteur
            .Interval = 10000
            .AutoReset = True
            .Start()
        End With
Enfin, j'adapte la longueur de ma barre de progression à chaque tick du timer :

Code :
 Private Sub m_tmrCompteur_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs)                                                                            Handles m_tmrCompteur.Elapsed
 
        Dim intDureeSec As Integer
 
        intDureeSec = CInt(DateDiff(DateInterval.Second, m_datT0, Now))
        m_objCallout.Width = CSng(m_objEcran.Largeur * (1 - intDureeSec / (m_intDureeMax * 60)))
 
    End Sub
 
(La variable m_datT0, du type Date, contient la date de lancement du diaporama. La variable m_intDureeMax, du type Integer, contient la durée totale de la présentation en minutes).

Je vous rappelle que pour faire apparaître le problème, il faut utiliser PowerPoint 2007, et attendre que la barre de progression se réduise (10 sec dans mon cas, ou changez la valeur de m_tmrCompteur.Interval) avant de passer à la diapo suivante.

Cordialement,

Merhandir

Dernière modification par Philippe JOCHMANS ; 20/08/2008 à 11h18 Motif: Ajout des balises codes (sélection du code + #), ce n'est pas facultatif
merhandir est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 20/08/2008, 11h25   #4 (permalink)
Responsable PowerPoint
 
Avatar de Philippe JOCHMANS
 
Date d'inscription: mai 2005
Localisation: Loir et Cher et Touraine
Âge: 40
Messages: 9 938
Envoyer un message via MSN à Philippe JOCHMANS
Par défaut

Bonjour

Citation:
- soit je trouve une instruction qui permette de désactiver le pré-calcul de la diapositive suivante (mais rien ne dit qu'elle existe...),
Je t'avoue que je ne vois pas à ce sujet, il faut que je cherche.

Code :
- soit je trouve une instruction qui permette de rafraîchir le fond d'une diapo avant de l'afficher (mais je n'ai trouvé aucun QuelqueChose.Refresh ou autre),
 
A priori il n'existe pas ce type d'instruction, tu peux essayer cela, mais je ne l'ai pas testé :

Code :
Sub RefreshSlide()
Dim lSlideIndex As Long
lSlideIndex = SlideShowWindows(1).View.CurrentShowPosition
SlideShowWindows(1).View.GotoSlide lSlideIndex
End Sub
Cependant cela rafraichirait un slide


Code :
- soit je reprends tout mon code pour créer une barre sur les diapos et non sur le masque. J'ai déjà commencé à y réfléchir, mais je vois déjà se profiler quelques problèmes...
Peut-être la solution à envisager, car comme ta barre de progression est sur le masque, ce n'est pas le top.

Cependant, PPT 2007 permet de créer un masque, mais aussi des sortes de sous-masques, peut-être une piste de ce coté, avec chargement d'un sous-masque, à voir.

Starec
__________________
En cas de questions techniques par MP ou message visiteur
Office : :Les Cours, Les FAQs
VB : Les Cours, Les FAQs
Mes articles : ici
Me connaitre
Philippe JOCHMANS est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 20/08/2008, 16h48   #5 (permalink)
Invité de passage
 
Date d'inscription: août 2008
Localisation: Pyrénées Atlantiques
Âge: 29
Messages: 8
Par défaut Barre de progression sur les diapositives

Bonjour,

Suite à mes difficultés précédentes, j'ai opté pour un changement dans mon algorithme. Au lieu de tracer ma barre de progression sur le masque des diapositives, je la dessine directement sur la diapositive i, ainsi que sur les diapositives i-1 et i+1 pour anticiper sur le choix de l'utilisateur qui voudrait avancer ou reculer dans sa présentation.
Maintenant, l'évolution de ma barre de progression est celle qui est attendue...

Mais j'ai un nouveau problème. Lorsque le timer de 10 secondes souhaite modifier la taille de la barre, cette modification graphique réinitialise les animations éventuelles sur la diapositive en cours, ce qui est très gênant...

Existe-t-il un moyen pour que ma modification n'influe pas sur les animations ?

Merci d'avance,

Merhandir
merhandir est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 21/08/2008, 07h13   #6 (permalink)
Responsable PowerPoint
 
Avatar de Philippe JOCHMANS
 
Date d'inscription: mai 2005
Localisation: Loir et Cher et Touraine
Âge: 40
Messages: 9 938
Envoyer un message via MSN à Philippe JOCHMANS
Par défaut

Bonjour

Est-il possible d'avoir un bout de code VBA pour voir (et même un bout de fichier PPT 2007 pour tester).

Starec
__________________
En cas de questions techniques par MP ou message visiteur
Office : :Les Cours, Les FAQs
VB : Les Cours, Les FAQs
Mes articles : ici
Me connaitre
Philippe JOCHMANS est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 21/08/2008, 10h42   #7 (permalink)
Invité de passage
 
Date d'inscription: août 2008
Localisation: Pyrénées Atlantiques
Âge: 29
Messages: 8
Par défaut Echantillon de code + PPT

Bonjour,

Ci-joint, vous trouverez une présentation (d'une diapo seulement) qui montre le problème que j'ai mentionné au sujet des animations qui sont réinitialisées. Ce problème ne se manifeste pas non plus sous PPT 2003, mais uniquement sous PPT 2007.

Voici un exemple de programme pour la création de la barre de progression et du timer associé, en VB 2005 :

Code :
Imports Microsoft.Office.Interop
Imports Microsoft.Office.Core
 
 
Public Class CompteurPowerPoint
 
    Private Structure TailleEcran
        Dim Largeur As Single
        Dim Hauteur As Single
    End Structure
 
    Private WithEvents m_objAppPowerPoint As PowerPoint.Application
    Private WithEvents m_tmrCompteur As New System.Timers.Timer
    Private m_objCallout As PowerPoint.Shape
    Private m_objEcran As New TailleEcran
    Private m_datT0 As Date
    Private Const m_intDureeMax As Integer = 1 ' Durée de la présentation = 1 min
 
 
    Public Sub New()
 
        m_objAppPowerPoint = New PowerPoint.Application
 
    End Sub
 
 
    Private Sub m_objAppPowerPoint_SlideShowBegin(ByVal Wn As Microsoft.Office.Interop.PowerPoint.SlideShowWindow) _
                                                  Handles m_objAppPowerPoint.SlideShowBegin
 
        With m_objAppPowerPoint.ActivePresentation.SlideMaster
            m_objEcran.Largeur = .Width
            m_objEcran.Hauteur = .Height
        End With
 
        ' Création de la barre de progression au lancement du diaporama
 
        m_objCallout = m_objAppPowerPoint.ActivePresentation.Slides(1).Shapes.AddCallout(MsoCalloutType.msoCalloutFour, 0, m_objEcran.Hauteur - 5, _
                                          m_objEcran.Largeur, 5)
 
        With m_objCallout
            .Callout.Border = MsoTriState.msoFalse
            .Fill.ForeColor.RGB = RGB(0, 255, 0)
            .Fill.Transparency = 0
            .Fill.Visible = MsoTriState.msoTrue
        End With
 
        ' Lance le timer de rafraîchissement de la barre de progression
        With m_tmrCompteur
            .Interval = 2000    ' Rafraîchir toutes les 2 sec
            .AutoReset = True
            .Start()
        End With
        m_datT0 = Now
 
    End Sub
 
 
    Private Sub objAppPowerPoint_SlideShowEnd(ByVal Pres As Microsoft.Office.Interop.PowerPoint.Presentation) _
                                              Handles m_objAppPowerPoint.SlideShowEnd
        ' Arrête le timer
        m_tmrCompteur.Stop()
 
        ' Supprime les objets créés par le compteur sur le fichier PPT
        m_objCallout.Delete()
 
        ' Empeche l'apparition du requester de sauvegarde de fichier
        m_objAppPowerPoint.ActivePresentation.Saved = MsoTriState.msoTrue
 
    End Sub
 
 
    Private Sub m_tmrCompteur_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles m_tmrCompteur.Elapsed
 
        Try
            Dim intDureeSec As Integer
 
            ' Ajustement de la largeur de la barre de progression
            intDureeSec = CInt(DateDiff(DateInterval.Second, m_datT0, Now))
 
            m_objCallout.Width = CSng(m_objEcran.Largeur * (1 - intDureeSec / (m_intDureeMax * 60)))
 
        Catch ex As Exception
            ' Gestionnaire d'erreur au cas où l'objet m_objCallout serait déjà détruit lors de l'exécution du thread
            Debug.Print("Erreur du timer m_tmrCompteur : " & ex.Message)
        End Try
    End Sub
 
End Class
Je ne me rappelle plus si la notion de classe existe sous VBA. Je ne crois pas, mais vous pourrez facilement l'adapter je pense. Dans mon programme principal, je crée une instance de CompteurPowerPoint :

Code :
Private objCompteurPowerPoint As New CompteurPowerPoint
A partir de là, l'objet gère tout de lui-même. Si vous reproduisez le code sous VB, il suffit de lancer l'exécutable puis la présentation. Lorsque l'utilisateur appuie sur F5 pour lancer le diaporama, une barre verte doit apparaître en bas de l'écran ; elle est remise à jour toutes les 2 secondes et engendre une réinitialisation de l'animation de la courbe (cf. fichier *.ppt joint).
Fichiers attachés
Type de fichier : zip EchantillonPresentation.zip (211,3 Ko, 3 affichages)
merhandir est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 22/08/2008, 09h50   #8 (permalink)
Responsable PowerPoint
 
Avatar de Philippe JOCHMANS
 
Date d'inscription: mai 2005
Localisation: Loir et Cher et Touraine
Âge: 40
Messages: 9 938
Envoyer un message via MSN à Philippe JOCHMANS
Par défaut

Bonjour

Il faudra attendre ce week-end, pour que je teste sur PPT 2007, et il faut que je réinstalle vb2005 Express.

Starec
__________________
En cas de questions techniques par MP ou message visiteur
Office : :Les Cours, Les FAQs
VB : Les Cours, Les FAQs
Mes articles : ici
Me connaitre
Philippe JOCHMANS est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 22/08/2008, 12h59   #9 (permalink)
Invité de passage
 
Date d'inscription: août 2008
Localisation: Pyrénées Atlantiques
Âge: 29
Messages: 8
Par défaut

Merci Starec,

C'est sympa de m'accorder tout ce temps :-)
Le modèle objet de PowerPoint sous VBA n'est donc pas le même ? Ca fait longtemps que je n'ai pas touché au VBA, et à l'époque je ne connaissais pas grand chose de la programmation objet...

Encore merci,

Merhandir
merhandir est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 27/08/2008, 04h38   #10 (permalink)
Responsable PowerPoint
 
Avatar de Philippe JOCHMANS
 
Date d'inscription: mai 2005
Localisation: Loir et Cher et Touraine
Âge: 40
Messages: 9 938
Envoyer un message via MSN à Philippe JOCHMANS
Par défaut

Bonjour

Je t'avoue que je coince un peu
__________________
En cas de questions techniques par MP ou message visiteur
Office : :Les Cours, Les FAQs
VB : Les Cours, Les FAQs
Mes articles : ici
Me connaitre
Philippe JOCHMANS est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 27/08/2008, 11h12   #11 (permalink)
Invité de passage
 
Date d'inscription: août 2008
Localisation: Pyrénées Atlantiques
Âge: 29
Messages: 8
Par défaut Problème insoluble ?

Bonjour à tous, bonjour Starec,

Encore merci d'avoir essayé de régler mes problèmes. Pour ma part, j'ai également essayé d'apporter des solutions aux deux :
- comment rafraîchir le masque avant l'affichage de la diapo suivante (ou bien empêcher la mise en cache de la diapo suivante),
- comment empêcher les animations de se réinitialiser lors de la modification d'un élément graphique sur ma diapo.

J'ai parcouru l'arborescence du modèle objet de PowerPoint dans tous les sens, je ne vois rien qui permette de faire ce que je veux. De plus, les modifications du modèle par rapport au modèle PowerPoint 2003 ne sont pas nombreuses, et aucune ne semble concerner les fonctionnalités que je recherche.

Aussi, puisque j'ai besoin d'un programme fonctionnel d'ici la fin de la semaine pour un congrès, ai-je opté pour une toute nouvelle piste. Je n'en suis encore qu'au début car je n'ai eu l'idée qu'hier soir, mais cette voie semble prometteuse.
Voici l'idée : j'utilise un formulaire Windows (classe Form) en guise de barre de progression, en fixant sa propriété TopMost à True. Ainsi, elle reste toujours en avant-plan, et je n'ai plus qu'à modifier sa largeur. De plus, je n'ai plus besoin d'apporter de modifications aux diapositives comme je le faisais avant. Cette méthode me semble plus "respectueuse" du document PowerPoint

Je vous tiens au courant du déroulement de l'opération.
Bien cordialement,

Merhandir
merhandir est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 28/08/2008, 15h05   #12 (permalink)
Invité de passage
 
Date d'inscription: août 2008
Localisation: Pyrénées Atlantiques
Âge: 29
Messages: 8
Par défaut Ca marche !!!

Bonjour,

Ma nouvelle technique fonctionne à merveille ! J'ai enfin le résultat voulu.
En fin de compte, j'utilise le composant COM de PowerPoint uniquement pour détecter le lancement du diaporama et sa fermeture. Tout le reste est géré en VB.

Cordialement,

Merhandir
merhandir est déconnecté   Envoyer un message privé Réponse avec citation
Réponse

Précédent   Forum des développeurs > Hardware, Systèmes et Logiciels > Microsoft Office > Powerpoint > VBA PowerPoint

 
Offres d' emploi informatique sur Lesjeudis.com


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are non
Pingbacks are non
Refbacks are non
Navigation rapide