Ouverture fichier Excel - fermeture fichier - le fichier reste "utilisé"

Bonjour à tous,

Dans mon module Outlook je fais appel à un fichier excel, je l'ouvre et je fais 3 manipulations dessus, jusque là tout va bien.

Mon souci est que, pour une raison que j'ignore, lorsque je quitte mon fichier Excel, et que j'essaie de relancer la macro pour un autre mail, mon fichier est toujours repris comme "déjà utilisé par un autre programme", même chose si j'essaie de l'ouvrir par mon arborescence. Il y a donc quelque chose dans ce que j'ai écris qui fait que le fichier reste utilisé, même si je l'ai fermé, et même si je ferme Excel via les gestionnaire des tâches (là ça devient tordu mais si j'essaie alors de redémarrer mon PC il me dit qu'Excel est ouvert, alors que non, et que le gestionnaire des tâches ne me l'indique pas non plus).

J'ai pas mal épluché internet, essayé plusieurs choses, mais pour l'instant je n'ai pas encore trouvé de solution (probablement parce que je ne comprends pas ce qui se passe). Ca doit se produire via mon CreateObject ou dans l'Open du fichier, mais je ne trouve pas ce qui manque, et manifestement le set final à Nothing n'y change rien.

Pouvez-vous m'aider ?

Si le coeur vous en dit je cherche aussi comment créer un lien vers le mail que je viens de sauvegarder en cellule B (xExcelRange2) (mais ça serait du bonus, je continue de chercher )

Sub enregistrer()

Dim nomfichier As String
Dim Explorer As Outlook.Explorer
Dim NS As Outlook.NameSpace
Dim CurrentItem As Object
Dim Sender As Outlook.AddressEntry
Dim utilisateur As String, User_sans_espace As String
Dim LastRw As Long

Dim xExcelFile As String
Dim xExcelApp As Excel.Application
Dim xwb As Excel.Workbook
Dim xws As Excel.Worksheet
Dim xExcelRange As Excel.Range, xExcelRange2 As Excel.Range, xExcelRange3 As Excel.Range

Set NS = Application.GetNamespace("MAPI")
Set Explorer = Application.ActiveExplorer
utilisateur = NS.CurrentUser
User_sans_espace = Replace(NS.CurrentUser, " ", vbNullString)

xExcelFile = "C:\Users\" & User_sans_espace & "\adresse.xlsm"

If Explorer.Selection.Count Then

Set CurrentItem = Explorer.Selection(1)
Set Sender = CurrentItem.Sender

nomfichier = InputBox("Quel est le nom du candidat ?", "Enregistrer le CV de " & Sender)
If Not nomfichier = "" Then
CurrentItem.SaveAs ("C:\Users\" & User_sans_espace & "\adresse\CV de " & nomfichier & ".msg")

End If
End If

Set xExcelApp = CreateObject("Excel.Application")
Set xwb = xExcelApp.Workbooks.Open(xExcelFile)
Set xws = xwb.Sheets("Candidatures à traiter")
xws.Activate
xExcelApp.Visible = True

LastRw = Sheets("Candidatures à traiter").Cells(Rows.Count, 1).End(xlUp).Row
Set xExcelRange = xws.Range("A" & LastRw + 1)
Set xExcelRange2 = xws.Range("B" & LastRw + 1)
Set xExcelRange2 = xws.Range("D" & LastRw + 1)
If MsgBox("Souhaites-tu créer une nouvelle ligne pour ce candidat ?", vbOKCancel, "Nouveau candidat") = vbYes Then
xExcelRange.Value = Now

'xExcelRange2.Value = Lien (c'est ici que je cherche à insérer le lien vers le mail que je viens de sauvegarder

xExcelRange3.Value = nomfichier
End If

Set NS = Nothing
Set Explorer = Nothing
Set CurrentItem = Nothing
Set Sender = Nothing
Set xExcelApp = Nothing
Set xwb = Nothing
Set xws = Nothing
Set xExcelRange = Nothing
Set xExcelRange2 = Nothing
End Sub

Merci à tous pour votre aide précieuse.

Alors ! Voici où j'en suis :

Tout fonctionne à merveille, sauf si le fichier est déjà ouvert. Ca me génère une erreur (fichier déjà utilisé), je pensais pourtant être dans le bon, mais manifestement insuffisamment

Sub Enregistrer()

On Error GoTo erreur

Dim nomfichier As String
Dim Explorer As Outlook.Explorer
Dim NS As Outlook.NameSpace
Dim CurrentItem As Object
Dim Sender As Outlook.AddressEntry
Dim utilisateur As String, User_sans_espace As String
Dim LastRw As Long

Dim xExcelFile As String
Dim xExcelApp As Excel.Application
Dim xwb As Excel.Workbook
Dim xws As Excel.Worksheet
Dim xExcelRange As Excel.Range, xExcelRange2 As Excel.Range, xExcelRange3 As Excel.Range

Set NS = Application.GetNamespace("MAPI")
Set Explorer = Application.ActiveExplorer
utilisateur = NS.CurrentUser
User_sans_espace = Replace(NS.CurrentUser, " ", vbNullString)

xExcelFile = "C:\Users\" & User_sans_espace & "\fichier.xlsm"

If Explorer.Selection.Count Then

Set CurrentItem = Explorer.Selection(1)
Set Sender = CurrentItem.Sender

nomfichier = InputBox("Quel est le nom du candidat ?", "Enregistrer le CV de " & Sender, Sender)
If Not nomfichier = "" Then
CurrentItem.SaveAs ("C:\Users\" & User_sans_espace & "\fichier\CV de " & nomfichier & ".msg")

End If
End If

If MsgBox("Souhaites-tu créer une nouvelle ligne pour ce candidat ?", vbYesNo, "Nouveau candidat") = vbYes Then

On Error Resume Next
    Set xExcelApp = GetObject(, "Excel.Application")
    On Error GoTo erreur
    If xExcelApp Is Nothing Then
    Set xExcelApp = CreateObject("Excel.Application")
    End If

On Error Resume Next
    Set xwb = xExcelApp.Workbooks.Item(ExtractFileName(xExcelFile))
    On Error GoTo erreur

    If xwb Is Nothing Then
        Set xwb = xExcelApp.Workbooks.Open(xExcelFile)
    End If

Set xws = xwb.Sheets("Candidatures à traiter")
xExcelApp.Visible = True

LastRw = xws.Cells(Rows.Count, 1).End(xlUp).Row
With xws
.Range("A" & LastRw + 1).Value = Format(Now, "d mmmm yyyy hh:nn")
.Range("B" & LastRw + 1).Value = "CV reçu"
.Range("C" & LastRw + 1).Value = "Mail de candidature"
.Hyperlinks.Add Range("C" & LastRw + 1), Address:="C:\Users\" & User_sans_espace & "\fichier " & nomfichier & ".msg", ScreenTip:="Ouvrir le mail", TextToDisplay:="Mail de candidature"
.Range("D" & LastRw + 1).Value = nomfichier
End With

xExcelApp.Visible = True
'xwb.Close True
'xExcelApp.Quit

MsgBox "Le candidat est enregistré dans l'outil de recrutement"
End If

Set NS = Nothing
Set Explorer = Nothing
Set CurrentItem = Nothing
Set Sender = Nothing
Set xExcelApp = Nothing
Set xwb = Nothing
Set xws = Nothing
Set xExcelRange = Nothing
Set xExcelRange2 = Nothing

Exit Sub

erreur:  MsgBox (Err.Description)
End Sub

Public Function ExtractFileName(ByVal FilePath As String) As String
        ExtractFileName = Mid(FilePath, InStrRev(FilePath, "\") + 1)
End Function

Pourriez-vous m'indiquer ce qui coince ? Merci beaucoup.

Bonjour Lorence,

Je viens de tomber sur ce fil, avez-vous pu avancer depuis le 02/11 je l'espère

Mais pour moi votre erreur est normale puisqu'un fichier Excel déjà ouvert n'est qu'en lecture seule

A+

Bonjour Bruno,

Oui j'ai pu trouver comment y parvenir. Ca fonctionne maintenant.

D'ailleurs pour les éventuelles personnes qui atterriraient sur ce fil, voici la macro et les 3 fonctions qui vont avec :

Option Explicit
Option Compare Text

Sub Enregistrer()

On Error GoTo erreur

Dim nomfichier As String
Dim Explorer As Outlook.Explorer
Dim NS As Outlook.NameSpace
Dim CurrentItem As Object
Dim Sender As Outlook.AddressEntry
Dim utilisateur As String, User_sans_espace As String
Dim LastRw As Integer, LastRw2 As Integer
Dim xExcelFile As String
Dim xws As Excel.Worksheet
Dim xExcelRange As Excel.Range, xExcelRange2 As Excel.Range, xExcelRange3 As Excel.Range
Dim MailExpediteur As String
Dim objFolder As Outlook.Folder
Dim trouve As Boolean
Dim i As Integer
Dim appExcel As Object
Dim wb As Object
Dim xwl As Excel.Worksheet
Dim foundWorkbook As Workbook
Dim cheminFichier As String
Dim fichier As String
Dim fichierOuvert As Boolean
Dim fichierBXL As String, fichierWAL As String, Agence As String
Dim fichierBXLLocal As String, fichierWALLocal As String

Set NS = Application.GetNamespace("MAPI")
Set Explorer = Application.ActiveExplorer
utilisateur = NS.CurrentUser
User_sans_espace = Replace(NS.CurrentUser, " ", vbNullString)

fichierBXL = "https://adressesharepointdufichier
fichierWAL = "https://adressesharepointdufichier

'si un email est sélectionné on débute la procédure

If Explorer.Selection.Count Then

    Set CurrentItem = Explorer.Selection(1)
    Set Sender = CurrentItem.Sender
    MailExpediteur = Sender.Address
    nomfichier = InputBox("Quel est le nom du candidat ?", "Enregistrer le CV de " & Sender, Sender)
    Agence = MsgBox("C'est un candidat pour Bruxelles ?", vbYesNoCancel, "Choix de l'agence")

        If Agence = vbYes Then

            'on enregistre le CV dans le fichier CV de Bruxelles
            CurrentItem.SaveAs ("C:\Users\" & User_sans_espace & "\adressedufichier\CV de " & nomfichier & ".msg")

            ' on vérifie si Excel est déjà ouvert
            On Error Resume Next
            Set appExcel = GetObject(, "Excel.Application")
            ' Si Excel n'est pas ouvert, l'erreur va être 1 et on crée une nouvelle instance, sinon pas d'erreur = excel est ouvert
                If Err.Number <> 0 Then
                Set appExcel = CreateObject("Excel.Application")
                appExcel.Visible = False ' on n'affiche pas encore excel
                End If
            On Error GoTo erreur

    ' Convertit l'URL en chemin local
    fichierBXLLocal = ConvertirURLenCheminLocal(fichierBXL)

'    ' Vérifie si le fichier Excel est ouvert
'If EstFichierExcelOuvert(fichierBXLLocal) Then
'    'MsgBox "Le fichier est ouvert.", vbInformation
'    Set wb = appExcel.Workbooks(GetNomClasseurFromPath(fichierBXLLocal))
'Else
'    'MsgBox "Le fichier n'est pas ouvert, je l'ouvre.", vbInformation
'    Set wb = appExcel.Workbooks.Open(fichierBXL)
'End If

'on convertit le fichier en local

fichierWALLocal = ConvertirURLenCheminLocal(fichierWAL)

Dim wbBruxelles As Object
Dim wbWallonie As Object

On Error Resume Next
Set wbBruxelles = appExcel.Workbooks(GetNomClasseurFromPath(fichierBXLLocal))
Set wbWallonie = appExcel.Workbooks(GetNomClasseurFromPath(fichierWALLocal))
On Error GoTo 0

If Not wbBruxelles Is Nothing And Not wbWallonie Is Nothing Then
    ' Les deux fichiers sont ouverts. Active le classeur de Bruxelles.
    appExcel.Workbooks(GetNomClasseurFromPath(fichierBXLLocal)).Activate
    Set wb = appExcel.ActiveWorkbook
ElseIf Not wbBruxelles Is Nothing Then
    ' Le fichier Bruxelles est ouvert
    Set wb = wbBruxelles
Else
    ' Aucun des fichiers n'est ouvert, j'ouvre Bruxelles par défaut
    Set wb = appExcel.Workbooks.Open(fichierBXL)
End If

Set xws = wb.Sheets("Candidatures à traiter")
Set xwl = wb.Sheets("Listing des CV reçus")

LastRw = xws.Cells(xws.Rows.Count, 1).End(xlUp).Row
LastRw2 = xwl.Cells(xwl.Rows.Count, 1).End(xlUp).Row

'vérifier si le candidat est dans la liste rouge, si oui on sort sans sauvegarder

    ' Parcourir la colonne C pour vérifier si l'expéditeur est présent
    trouve = False
    For i = 1 To xwl.Cells(xwl.Rows.Count, "C").End(-4162).Row ' -4162 correspond à xlUp
        If LCase(Trim(xwl.Cells(i, "C").Value)) = LCase(Trim(nomfichier)) And xwl.Cells(i, "F").Value = "Oui" Then
            trouve = True
            Exit For
        End If
    Next i

    If trouve Then
    MsgBox "Le candidat est dans la liste rouge, j'annule son enregistrement."
    'wb.Close SaveChanges:=False
    'appExcel.Quit
    Set appExcel = Nothing
    Exit Sub
    End If

'si le candidat n'est pas sur liste rouge on l'enregistre

With xws
.Range("A" & LastRw + 1).Value = Format(Now, "d mmmm yyyy hh:nn")
.Range("B" & LastRw + 1).Value = "CV reçu"
.Range("C" & LastRw + 1).Hyperlinks.Add xws.Range("C" & LastRw + 1), Address:="C:\Users\" & User_sans_espace & "\adressedudossier\CV de " & nomfichier & ".msg", ScreenTip:="Ouvrir le mail", TextToDisplay:="Mail de candidature"
.Range("D" & LastRw + 1).Value = nomfichier
.Range("G" & LastRw + 1).Value = MailExpediteur
End With

With xwl
.Range("A" & LastRw2 + 1).Value = Format(Now, "d mmmm yyyy hh:nn")
.Range("B" & LastRw2 + 1).Hyperlinks.Add xwl.Range("B" & LastRw2 + 1), Address:="C:\Users\" & User_sans_espace & "\adressedudossier\CV de " & nomfichier & ".msg", ScreenTip:="Ouvrir le mail", TextToDisplay:="Mail de candidature"
.Range("C" & LastRw2 + 1).Value = nomfichier
.Range("D" & LastRw2 + 1).Value = MailExpediteur
End With

'wb.Close True
'appExcel.Quit
MsgBox "Le candidat est enregistré dans l'outil de recrutement de Bruxelles"
appExcel.Visible = True

ElseIf Agence = vbNo Then

            'on enregistre le CV dans le fichier CV de la Wallonie
            CurrentItem.SaveAs ("C:\Users\" & User_sans_espace & "\adressedossier\CV de " & nomfichier & ".msg")

            ' on vérifie si Excel est déjà ouvert
            On Error Resume Next
            Set appExcel = GetObject(, "Excel.Application")
            ' Si Excel n'est pas ouvert, l'erreur va être 1 et on crée une nouvelle instance, sinon pas d'erreur = excel est ouvert
                If Err.Number <> 0 Then
                Set appExcel = CreateObject("Excel.Application")
                appExcel.Visible = False ' on n'affiche pas encore excel
                End If
            On Error GoTo erreur

    ' Convertit l'URL en chemin local
    fichierWALLocal = ConvertirURLenCheminLocal(fichierWAL)

'convertir le fichier en local

fichierBXLLocal = ConvertirURLenCheminLocal(fichierBXL)

On Error Resume Next
Set wbBruxelles = appExcel.Workbooks(GetNomClasseurFromPath(fichierBXLLocal))
Set wbWallonie = appExcel.Workbooks(GetNomClasseurFromPath(fichierWALLocal))
On Error GoTo 0

If Not wbBruxelles Is Nothing And Not wbWallonie Is Nothing Then
    ' Les deux fichiers sont ouverts. Active le classeur de la Wallonie.
    appExcel.Workbooks(GetNomClasseurFromPath(fichierWALLocal)).Activate
    Set wb = appExcel.ActiveWorkbook
ElseIf Not wbWallonie Is Nothing Then
    ' Le fichier Wallonie est ouvert
    Set wb = wbWallonie
Else
    ' Aucun des fichiers n'est ouvert, j'ouvre la Wallonie par défaut
    Set wb = appExcel.Workbooks.Open(fichierWAL)
End If

Set xws = wb.Sheets("Candidatures à traiter")
Set xwl = wb.Sheets("Listing des CV reçus")

LastRw = xws.Cells(xws.Rows.Count, 1).End(xlUp).Row
LastRw2 = xwl.Cells(xwl.Rows.Count, 1).End(xlUp).Row

'vérifier si le candidat est dans la liste rouge, si oui on sort sans sauvegarder

    ' Parcourir la colonne C pour vérifier si l'expéditeur est présent
    trouve = False
    For i = 1 To xwl.Cells(xwl.Rows.Count, "C").End(-4162).Row ' -4162 correspond à xlUp
        If LCase(Trim(xwl.Cells(i, "C").Value)) = LCase(Trim(nomfichier)) And xwl.Cells(i, "F").Value = "Oui" Then
            trouve = True
            Exit For
        End If
    Next i

    If trouve Then
    MsgBox "Le candidat est dans la liste rouge, j'annule son enregistrement."
    'wb.Close SaveChanges:=False
    'appExcel.Quit
    Set appExcel = Nothing
    Exit Sub
    End If

'si le travailleur n'est pas sur liste rouge on l'enregistre

With xws
.Range("A" & LastRw + 1).Value = Format(Now, "d mmmm yyyy hh:nn")
.Range("B" & LastRw + 1).Value = "CV reçu"
.Range("C" & LastRw + 1).Hyperlinks.Add xws.Range("C" & LastRw + 1), Address:="C:\Users\" & User_sans_espace & "\Maison-Net\Maison-Net - Documents\1. Gestion agences Maison Net\RECRUTEMENT\Wallonie/CV\CV de " & nomfichier & ".msg", ScreenTip:="Ouvrir le mail", TextToDisplay:="Mail de candidature"
.Range("D" & LastRw + 1).Value = nomfichier
.Range("G" & LastRw + 1).Value = MailExpediteur
End With

With xwl
.Range("A" & LastRw2 + 1).Value = Format(Now, "d mmmm yyyy hh:nn")
.Range("B" & LastRw2 + 1).Hyperlinks.Add xwl.Range("B" & LastRw2 + 1), Address:="C:\Users\" & User_sans_espace & "\adressedudossier\CV de " & nomfichier & ".msg", ScreenTip:="Ouvrir le mail", TextToDisplay:="Mail de candidature"
.Range("C" & LastRw2 + 1).Value = nomfichier
.Range("D" & LastRw2 + 1).Value = MailExpediteur
End With

'wb.Close True
'appExcel.Quit

MsgBox "Le candidat est enregistré dans l'outil de recrutement de la Wallonie"
appExcel.Visible = True

ElseIf Agence = vbCancel Then MsgBox "Enregistrement annulé": Exit Sub

End If

Set objFolder = Nothing
Set NS = Nothing
Set Explorer = Nothing
Set CurrentItem = Nothing
Set Sender = Nothing
Set xwl = Nothing
Set xws = Nothing
Set xExcelRange = Nothing
Set xExcelRange2 = Nothing
Set appExcel = Nothing
Set wb = Nothing

End If

Exit Sub

erreur:  MsgBox (Err.Description)
End Sub

Function ConvertirURLenCheminLocal(url As String) As String
    ' Remplacez les caractères spéciaux dans l'URL
    ConvertirURLenCheminLocal = Replace(url, "%20", " ")
End Function

Function EstFichierExcelOuvert(cheminFichier As String) As Boolean
    Dim GetObjectExcel As Object

    On Error Resume Next
    ' Tente d'obtenir une référence au fichier Excel
    Set GetObjectExcel = GetObject(, "Excel.Application")
    On Error GoTo 0

    ' Vérifie si le fichier Excel est ouvert
    If Not GetObjectExcel Is Nothing Then
        ' Vérifie si le classeur est ouvert en comparant le nom du classeur
        If Not GetObjectExcel.ActiveWorkbook Is Nothing Then
            If StrComp(GetObjectExcel.ActiveWorkbook.Name, GetNomClasseurFromPath(cheminFichier), vbTextCompare) = 0 Then
                EstFichierExcelOuvert = True
            End If
        End If
        ' Ferme l'application Excel
        'GetObjectExcel.Application.Quit
    End If
End Function

Function GetNomClasseurFromPath(cheminFichier As String) As String
    ' Récupère le nom du classeur à partir du chemin du fichier
    Dim elementsChemin() As String
    elementsChemin = Split(cheminFichier, "/")
    GetNomClasseurFromPath = elementsChemin(UBound(elementsChemin))
End Function

Bonne journée ;)

Bonjour Lorence et merci pour ce partage de solution

Bonne journée

Rechercher des sujets similaires à "ouverture fichier fermeture reste utilise"