Export avec objet OLE vers powerpoint et cellules déverouillées

Bonjour à tous,

Je me permets de me tourner vers vous car je suis un peu perdu. En effet, je ne suis pas développeur et mes connaissances en VBA sont très minimes. Malgré cela, une demande d'un supérieur hiérarchique m'est tombée dessus et je dois bidouiller un script VBA.... N'ayant pas les compétences nécessaires, je me suis orienté vers les IA, qui me font tourner en bourrique car elles ne me fournissent pas le rendu espéré. De base, le script doit exporter des zones définies de mon fichier excel en objet OLE dont certaines cellules doivent être modifiables "editableCells". Seulement le script ne vérrouille aucune cellule dans mon export Pwp. Pourriez-vous m'aider à trouver la solution car, personnellement, j'ai épuisé toutes mes cartouches... D'avance je vous remercie

Option Explicit

Sub ExportToPowerPoint()
    Dim pptApp As Object
    Dim pptPres As Object
    Dim ws As Worksheet
    Dim slideCount As Long
    Dim cellB1Value As String
    Dim sourceFile As String
    Dim errorsList As String
    Dim createdSlides As Long
    Dim errorLocation As String
    Dim editableCells As String

    ' Constantes pour late binding
    Const ppLayoutBlank As Long = 12
    Const msoFalse As Long = 0
    Const msoTrue As Long = -1

    ' Définir les cellules qui doivent être modifiables
    editableCells = "G4:I6,N4:O6,G48:I50,N48:O50,G74:I74,N74:O75,J75,G100:I101,N100:O101,I125:K128,I8,I14,I20,I54,I61,I67,I78,I89,I92,I130,I136,I142"

    Application.ScreenUpdating = False
    Application.DisplayAlerts = False

    On Error GoTo ErrHandler
    errorLocation = "Initialisation"

    ' === VÉRIFICATION: Existence de la feuille "Business Meetings" ===
    On Error Resume Next
    Set ws = ThisWorkbook.Sheets("Business Meetings")
    If ws Is Nothing Then
        MsgBox "Erreur : La feuille 'Business Meetings' n'existe pas dans ce classeur.", vbCritical, "Feuille manquante"
        Exit Sub
    End If
    On Error GoTo ErrHandler

    ' Activer la feuille Excel pour assurer la visibilité
    ws.Activate
    sourceFile = ThisWorkbook.Name

    errorLocation = "Préparation visuelle"
    ' === IMPORTANT: NE PAS PROTÉGER LA FEUILLE AVANT L'EXPORT ===
    ' Retirer toute protection existante pour permettre la modification dans PowerPoint
    On Error Resume Next
    ws.Unprotect
    ws.Cells.Locked = False  ' Déverrouiller toutes les cellules
    On Error GoTo ErrHandler

    ' Mettre en surbrillance les cellules modifiables (optionnel - aide visuelle)
    Call HighlightEditableCells(ws, editableCells)

    errorLocation = "Lecture des valeurs"
    ' Lecture de la cellule C1 pour le titre
    cellB1Value = ""
    On Error Resume Next
    cellB1Value = Trim(ws.Range("C1").Value)
    On Error GoTo ErrHandler
    If cellB1Value = "" Then cellB1Value = "Business Meeting"

    errorLocation = "Création PowerPoint"
    ' === Création de l'application PowerPoint ===
    On Error Resume Next
    Set pptApp = CreateObject("PowerPoint.Application")
    If pptApp Is Nothing Then
        MsgBox "Erreur : Impossible de démarrer PowerPoint." & vbCrLf & _
               "Vérifiez que PowerPoint est installé sur cet ordinateur.", vbCritical, "PowerPoint indisponible"
        Call RemoveHighlight(ws, editableCells)
        Exit Sub
    End If
    On Error GoTo ErrHandler

    ' Configuration PowerPoint
    pptApp.Visible = True
    pptApp.WindowState = 1 ' Maximiser
    Set pptPres = pptApp.Presentations.Add(msoTrue)

    ' Activer PowerPoint pour assurer la visibilité
    pptApp.Activate
    DoEvents

    slideCount = 0
    errorsList = ""
    createdSlides = 0

    ' === Export des zones SANS PROTECTION pour permettre la modification ===

    errorLocation = "Export zone A2:P26"
    Application.StatusBar = "Export en cours... Zone 1/5 (Objets modifiables)"
    ws.Activate
    createdSlides = createdSlides + CopyZoneToSlideSafe(ws, "A2:P26", pptPres, pptApp, slideCount, sourceFile, cellB1Value, errorsList, editableCells)

    errorLocation = "Export zone A44:P71"
    Application.StatusBar = "Export en cours... Zone 2/5 (Objets modifiables)"
    ws.Activate
    createdSlides = createdSlides + CopyZoneToSlideSafe(ws, "A44:P71", pptPres, pptApp, slideCount, sourceFile, cellB1Value, errorsList, editableCells)

    errorLocation = "Export zone A72:P97"
    Application.StatusBar = "Export en cours... Zone 3/5 (Objets modifiables)"
    ws.Activate
    createdSlides = createdSlides + CopyZoneToSlideSafe(ws, "A72:P97", pptPres, pptApp, slideCount, sourceFile, cellB1Value, errorsList, editableCells)

    errorLocation = "Export zone A123:P147"
    Application.StatusBar = "Export en cours... Zone 4/5 (Objets modifiables)"
    ws.Activate
    createdSlides = createdSlides + CopyZoneToSlideSafe(ws, "A123:P147", pptPres, pptApp, slideCount, sourceFile, cellB1Value, errorsList, editableCells)

    errorLocation = "Export zone A152:P167"
    Application.StatusBar = "Export en cours... Zone 5/5 (Objets modifiables)"
    ws.Activate
    createdSlides = createdSlides + CopyZoneToSlideSafe(ws, "A152:P167", pptPres, pptApp, slideCount, sourceFile, cellB1Value, errorsList, editableCells)

    ' === Retirer la surbrillance après l'export ===
    Call RemoveHighlight(ws, editableCells)

    ' === Activer PowerPoint et positionner sur la première slide ===
    If pptPres.Slides.Count > 0 Then
        pptPres.Slides(1).Select
        pptApp.Activate
    End If

    ' Nettoyage
    Application.CutCopyMode = False
    Application.StatusBar = False

    ' Libération des objets (mais garder PowerPoint ouvert)
    Set pptPres = Nothing
    Set pptApp = Nothing
    Set ws = Nothing

    Application.ScreenUpdating = True
    Application.DisplayAlerts = True

    ' === Message de confirmation avec instructions détaillées ===
    Dim msg As String
    If createdSlides > 0 Then
        msg = "Export terminé avec succès !" & vbCrLf & vbCrLf & _
              "Slides créées : " & createdSlides & " sur 5" & vbCrLf & vbCrLf & _
              "POUR MODIFIER LES OBJETS EXCEL :" & vbCrLf & _
              "1. Double-cliquez sur l'objet Excel dans PowerPoint" & vbCrLf & _
              "2. Les cellules suivantes sont modifiables :" & vbCrLf & _
              "   • Lignes 4-6 : Colonnes G-I et N-O" & vbCrLf & _
              "   • Lignes 48-50 : Colonnes G-I et N-O" & vbCrLf & _
              "   • Ligne 74-75 : Colonnes G-I, N-O et J75" & vbCrLf & _
              "   • Lignes 100-101 : Colonnes G-I et N-O" & vbCrLf & _
              "   • Lignes 125-128 : Colonnes I-K" & vbCrLf & _
              "   • Cellules individuelles : I8, I14, I20, I54, I61, I67, I78, I89, I92, I130, I136, I142" & vbCrLf & vbCrLf & _
              "3. Cliquez en dehors de l'objet pour terminer l'édition" & vbCrLf & vbCrLf & _
              "Utilisez 'Fichier > Enregistrer sous' pour sauvegarder."
        If errorsList <> "" Then
            msg = msg & vbCrLf & vbCrLf & "Avertissements :" & vbCrLf & errorsList
        End If
        MsgBox msg, vbInformation, "Export PowerPoint réussi"
    Else
        MsgBox "Aucune slide n'a pu être créée. Vérifiez les plages de données.", vbExclamation, "Export incomplet"
    End If
    Exit Sub

ErrHandler:
    Application.ScreenUpdating = True
    Application.DisplayAlerts = True
    Application.CutCopyMode = False
    Application.StatusBar = False

    ' Retirer la surbrillance en cas d'erreur
    If Not ws Is Nothing Then Call RemoveHighlight(ws, editableCells)

    ' Nettoyer PowerPoint en cas d'erreur
    If Not pptApp Is Nothing Then
        On Error Resume Next
        If Not pptPres Is Nothing Then pptPres.Close
        pptApp.Quit
        Set pptApp = Nothing
        On Error GoTo 0
    End If

    MsgBox "Erreur lors de l'export PowerPoint" & vbCrLf & vbCrLf & _
           "Étape : " & errorLocation & vbCrLf & _
           "Description : " & Err.Description & vbCrLf & _
           "Code erreur : " & Err.Number, vbCritical, "Export annulé"
End Sub

' === NOUVELLE FONCTION: Mettre en surbrillance les cellules modifiables ===
Private Sub HighlightEditableCells(ws As Worksheet, editableCells As String)
    On Error Resume Next
    ' Sauvegarder les couleurs originales sera fait manuellement si nécessaire
    With ws.Range(editableCells).Interior
        .Color = RGB(255, 255, 200) ' Jaune clair
        .Pattern = xlSolid
    End With
    On Error GoTo 0
End Sub

' === NOUVELLE FONCTION: Retirer la surbrillance ===
Private Sub RemoveHighlight(ws As Worksheet, editableCells As String)
    On Error Resume Next
    With ws.Range(editableCells).Interior
        .Pattern = xlNone ' Retirer la couleur de fond
    End With
    On Error GoTo 0
End Sub

' === Wrapper sécurisé pour copie (avec indication des cellules modifiables) ===
Private Function CopyZoneToSlideSafe(ws As Worksheet, plage As String, pptPres As Object, pptApp As Object, _
                                    ByRef slideCount As Long, sourceFile As String, cellB1Value As String, _
                                    ByRef errorsList As String, editableCells As String) As Long
    On Error GoTo SlideError

    ' Vérifier que la plage existe
    Dim testRange As Range
    On Error Resume Next
    Set testRange = ws.Range(plage)
    If testRange Is Nothing Then
        errorsList = errorsList & "- Zone " & plage & " : Plage invalide" & vbCrLf
        CopyZoneToSlideSafe = 0
        Exit Function
    End If
    On Error GoTo SlideError

    CopyZoneToSlideSafe = 0
    Call CopyZoneToSlide(ws, plage, pptPres, pptApp, slideCount, sourceFile, cellB1Value, editableCells)
    CopyZoneToSlideSafe = 1
    Exit Function

SlideError:
    errorsList = errorsList & "- Zone " & plage & " : " & Err.Description & vbCrLf
    Err.Clear
    CopyZoneToSlideSafe = 0
End Function

' === Copie OLE SANS PROTECTION pour permettre la modification ===
Private Sub CopyZoneToSlide(ws As Worksheet, plage As String, pptPres As Object, pptApp As Object, _
                           ByRef slideCount As Long, sourceFile As String, cellB1Value As String, editableCells As String)
    Dim pptSlide As Object
    Dim pptWindow As Object
    Dim rng As Range
    Dim slideW As Double, slideH As Double
    Dim footer As Object, header As Object
    Dim pastedShape As Object
    Dim objW As Double, objH As Double
    Dim scaleRatio As Double
    Dim maxWidth As Double, maxHeight As Double
    Dim centerX As Double, centerY As Double
    Dim shapeCount As Long
    Dim success As Boolean

    ' Constantes
    Const ppLayoutBlank As Long = 12
    Const ppPasteOLEObject As Long = 10
    Const ppPasteDefault As Long = 0
    Const HEADER_HEIGHT As Double = 40
    Const FOOTER_HEIGHT As Double = 35
    Const MARGIN As Double = 20

    On Error GoTo LocalError

    ' Créer nouvelle slide
    slideCount = slideCount + 1
    Set pptSlide = pptPres.Slides.Add(slideCount, ppLayoutBlank)

    ' Sélectionner la slide pour assurer qu'elle est active
    pptSlide.Select
    Set pptWindow = pptApp.ActiveWindow

    ' Dimensions slide
    slideW = pptPres.PageSetup.SlideWidth
    slideH = pptPres.PageSetup.SlideHeight

    ' Calculer l'espace disponible
    maxWidth = slideW - (2 * MARGIN)
    maxHeight = slideH - HEADER_HEIGHT - FOOTER_HEIGHT - (2 * MARGIN)

    ' === COPIE DE LA PLAGE SANS PROTECTION ===
    Set rng = ws.Range(plage)

    ' S'assurer que la feuille n'est pas protégée avant la copie
    On Error Resume Next
    ws.Unprotect
    On Error GoTo LocalError

    ' S'assurer que Excel est actif et la plage est sélectionnée
    Application.Visible = True
    ws.Activate
    rng.Select
    DoEvents

    ' Copier la sélection (sans protection, toutes les cellules seront modifiables)
    Selection.Copy
    DoEvents

    ' Pause pour assurer que la copie est dans le presse-papiers
    Application.Wait Now + TimeValue("00:00:01")

    ' Activer PowerPoint et la slide
    pptApp.Activate
    pptSlide.Select
    DoEvents

    ' Compter les shapes avant le collage
    shapeCount = pptSlide.Shapes.Count

    ' === COLLAGE AVEC PLUSIEURS TENTATIVES ===
    success = False

    ' Tentative 1: PasteSpecial OLE (préféré pour la modification)
    On Error Resume Next
    pptWindow.View.PasteSpecial DataType:=ppPasteOLEObject, Link:=False
    DoEvents
    Application.Wait Now + TimeValue("00:00:01")
    If pptSlide.Shapes.Count > shapeCount Then success = True
    On Error GoTo LocalError

    ' Tentative 2: Si échec, essayer Paste normal
    If Not success Then
        On Error Resume Next
        pptWindow.View.Paste
        DoEvents
        Application.Wait Now + TimeValue("00:00:01")
        If pptSlide.Shapes.Count > shapeCount Then success = True
        On Error GoTo LocalError
    End If

    ' Tentative 3: Si toujours échec, utiliser CommandBars
    If Not success Then
        On Error Resume Next
        pptApp.CommandBars.ExecuteMso "PasteSourceFormatting"
        DoEvents
        Application.Wait Now + TimeValue("00:00:01")
        If pptSlide.Shapes.Count > shapeCount Then success = True
        On Error GoTo LocalError
    End If

    ' Si un objet a été collé avec succès
    If success And pptSlide.Shapes.Count > shapeCount Then
        Set pastedShape = pptSlide.Shapes(pptSlide.Shapes.Count)

        ' === Redimensionnement et centrage optimal ===
        On Error Resume Next
        With pastedShape
            ' Obtenir les dimensions actuelles
            objW = .Width
            objH = .Height

            If objW > 0 And objH > 0 Then
                ' Calculer le ratio optimal
                Dim scaleW As Double, scaleH As Double
                scaleW = maxWidth / objW
                scaleH = maxHeight / objH

                ' Utiliser le plus petit ratio pour garder les proportions
                If scaleW < scaleH Then
                    scaleRatio = scaleW
                Else
                    scaleRatio = scaleH
                End If

                ' Limiter l'agrandissement pour éviter la déformation
                If scaleRatio > 2 Then scaleRatio = 2

                ' Appliquer le redimensionnement
                .LockAspectRatio = True
                .Width = objW * scaleRatio
                .Height = objH * scaleRatio

                ' Centrer l'objet dans l'espace disponible
                centerX = (slideW - .Width) / 2
                centerY = HEADER_HEIGHT + ((maxHeight - .Height) / 2)

                .Left = centerX
                .Top = centerY
            End If
        End With
        On Error GoTo LocalError
    End If

    ' === Ajouter Header ===
    On Error Resume Next
    Set header = pptSlide.Shapes.AddTextbox(1, MARGIN, 10, slideW - (2 * MARGIN), 25)
    With header.TextFrame
        .MarginLeft = 0
        .MarginRight = 0
        .TextRange.Text = cellB1Value & " - Slide " & slideCount & " (Double-clic pour éditer)"
        .TextRange.Font.Size = 16
        .TextRange.Font.Bold = True
        .TextRange.Font.Name = "Arial"
        .TextRange.ParagraphFormat.Alignment = 2 ' Centre
    End With
    On Error GoTo LocalError

    ' === Ajouter Footer avec indication des cellules modifiables ===
    On Error Resume Next
    Set footer = pptSlide.Shapes.AddTextbox(1, MARGIN, slideH - FOOTER_HEIGHT, slideW - (2 * MARGIN), 25)
    With footer.TextFrame
        .MarginLeft = 0
        .MarginRight = 0
        If success Then
            .TextRange.Text = "Zone : " & plage & " | " & Format(Now, "dd/mm/yyyy hh:mm") & _
                            " | Toutes les cellules sont modifiables après double-clic"
        Else
            .TextRange.Text = "Zone : " & plage & " | Échec du collage"
        End If
        .TextRange.Font.Size = 10
        .TextRange.Font.Italic = True
        .TextRange.Font.Name = "Arial"
        .TextRange.Font.Color = RGB(100, 100, 100) ' Gris
        .TextRange.ParagraphFormat.Alignment = 2 ' Centre
    End With
    On Error GoTo LocalError

    ' Retourner le focus à Excel
    ws.Parent.Activate

    ' Nettoyage
    Application.CutCopyMode = False
    Set pastedShape = Nothing
    Set footer = Nothing
    Set header = Nothing
    Set rng = Nothing
    Set pptSlide = Nothing
    Set pptWindow = Nothing
    Exit Sub

LocalError:
    ' Gestion locale des erreurs
    Application.CutCopyMode = False
    Resume Next
End Sub
Rechercher des sujets similaires à "export objet ole powerpoint deverouillees"