XL 2013 Connexion fichier fermé entre excel

JLE

XLDnaute Junior
Bonjour,

Ma question est simple, la réponse dépasse mes capacités.

J'ai 3 fichiers qui communiquent en lecture et écriture entre eux à l'aide de requête VBA+ADODB selon le très bon site https://silkyroad.developpez.com/VBA/ClasseursFermes/.

PLA.xlxm sur le PC1 --> BDD.xlsx sur le SERVEUR <-- OPE.xlsm sur le PC2

Mais quand PLA et OPE essaient de lire ou écrire sur BDD dans cette situation en même temps, la BDD s'ouvre sur le PC 1 ou 2 et crée des problèmes.

Comment peut on faire pour éviter cela ?
Merci pour vos réponses.
JLE
 
Solution
Bonjour à tous,

Je reviens expliquer la solution que j'ai trouvé, selon :

Solution 1 - vérifier si le fichier Excel BDD est ouvert selon la méthode de Kiki29 --> pour moi n'a pas fonctionné.
Solution 2 - partager le classeur Excel BDD selon la méthode de dysorthographie --> pour moi n'a pas fonctionné.
Mais solution 1+2 bizarrement fonctionne plus ou moins bien (lenteur et crash excel parfois).

Je précise que j'ai fait mes tests sur un serveur windows et un nas.

Alors j'ai contourné le problème avec la solution 3 - créer la BDD en Access BDD (fichier .accdb) en utilisant le moteur suivant et ça fonctionne :
With Cn
.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & fichier & ";Persist Security...

JLE

XLDnaute Junior
Re,

C'est une super fonction que tu me donne là et je t'en remercie. Vraiment, elle va pourvoir me servir pour d'autres choses, alors encore merci.

J'ai réussi à faire --> If IsFileOpen(fichieràtester) = trueThen MsgBox "ouvert" pour tester, c'est impec.

Mais je me demandais comment faire pour dire à la macro d'attendre que le fichier soit fermé avant de continuer sa procédure ?

Un doevents ? Ou une boucle ? sachant que ce sont toutes les deux des fonctions que je ne maitrise pas du tout... et j'aurai besoin du coup d'aide pour le faire svp.
 

kiki29

XLDnaute Barbatruc
Re, enfin bref à toi de tester plus a fond, à adapter à ton contexte
Dans un module baptisé mTimer
Code:
Option Explicit

Private Declare Function SetTimer Lib "User32" (ByVal hWnd As Long, _
                                                ByVal nIDEvent As Long, _
                                                ByVal uElapse As Long, _
                                                ByVal lpTimerFunc As Long) As Long

Private Declare Function KillTimer Lib "User32" (ByVal hWnd As Long, _
                                                 ByVal nIDEvent As Long) As Long

Dim TimerID As Long

Sub TimerOff()
    KillTimer 0, TimerID
End Sub

Sub TimerOn(Interval As Long)
    TimerID = SetTimer(0, 0, Interval, AddressOf mTest.Tst)
End Sub

Dans un autre module baptisé mTest
Code:
Option Explicit

Sub Tst()
Dim sFichier As String
    sFichier = "C:\.....\kiki.xls"
    If ExistenceFichier(sFichier) = False Then Exit Sub
    TestIsFileOpen sFichier
End Sub

Private Sub TestIsFileOpen(sFichier As String)
    If IsFileOpen(sFichier) Then
        Application.StatusBar = sFichier & " déjà ouvert"
    Else
        Application.StatusBar = sFichier & " non utilisé en ce moment"
    End If
End Sub

Private Function IsFileOpen(filename As String) As Boolean
Dim filenum As Integer, errNum As Integer

    On Error Resume Next
    filenum = FreeFile()

    Open filename For Input Lock Read As #filenum
    Close filenum
    errNum = Err
    On Error GoTo 0

    Select Case errNum
    Case 0
        IsFileOpen = False
    Case 70
        IsFileOpen = True
    Case Else
        Error errNum
    End Select
End Function

Private Function IsFileOpenLight(filename As String) As Boolean
Dim fichier As Integer
    On Error Resume Next

    fichier = FreeFile()
    Open filename For Input Access Read Lock Read Write As fichier

    If Err.Number = 0 Then
        IsFileOpenLight = False
        Close fichier
    Else
        IsFileOpenLight = True
    End If
End Function

Private Function ExistenceFichier(sFichier As String) As Boolean
    ExistenceFichier = Dir$(sFichier) <> "" And sFichier <> ""
End Function

Dans module ThisWorkbook
VB:
Option Explicit

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    TimerOff
End Sub

Private Sub Workbook_Open()
    TimerOn 2000
End Sub
 

JLE

XLDnaute Junior
Re,

Wahou merci super boulot --> J'ai compris le principe de tes réponses, mais ne suis pas certain que tu as saisi ma demande. Dans le principe, moi j'aurai besoin que la suite de la macro démarre dès que le fichier BDD soit accessible...

Es tu sur que c'est bien cette direction que prend tes macro ?

EDIT : 10:26 je pense avoir trouvé, si je fais une boucle, ça l'air de fonctionné :
Do While IsFileOpen(fichier) = True
DoEvents
Loop

EDIT : 10:36 finalement elle ne fonctionne que si BDD est ouvert mannuellement car j'ai mis cette instruction dans les deux procédures qui communiquent avec la BDD à partir de PLA et OPE; et visiblement ça ne change pas le problème lors de l'éxécution de la macro, bizarre...
 
Dernière édition:

JLE

XLDnaute Junior
Bonjour,

Déjà testé même avec l'activation du partage de classeur, ça ne fonctionne pas.

Pour info, j'utilise ce connecteur :
VB:
    With Cn
        .Provider = "MSDASQL"
        .Open "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};" & "DBQ=" & fichier & "; ReadOnly=False;"
    End With
 

JLE

XLDnaute Junior
A tous les deux,

Je viens de tester sur des fichiers tous vierge en xls. avec une seule macro issue directement de https://silkyroad.developpez.com/VBA/ClasseursFermes/.

Avec classeur partagé BDD sur le serveur, classeur non partagé OPE sur le PC1, classeur non partagé PLA sur le PC2. Rien à faire ça passe pas. J'ai essayé avec et sans ReadOnly=true ou false, ca passe pas non plus.

Dans OPE et PLA, il y a les même macro que je lance sur 2 PC distinct à quasiment en même temps... et ça plante.

Ci-joint les fichiers.
J'ai besoin de vos lumières.
 

Pièces jointes

  • BDD - Copie.xls
    30 KB · Affichages: 10
  • OPE - Copie.xls
    35 KB · Affichages: 3
  • PLA - Copie.xls
    36 KB · Affichages: 2

dysorthographie

XLDnaute Accro
en classeur partagé ça fonctionne!
1626182117637.png

1626182264870.png


Placer un fichier excel sur un répertoire partager du réseau ne fait pas pour autant qu'un fichier excel soit partagé entre plusieurs utilisateurs {lecture seule ou multi utilisateurs}!
 

Pièces jointes

  • BDD.xls
    23.5 KB · Affichages: 4
Dernière édition:

JLE

XLDnaute Junior
dysorthographie,

Je te crois, mais je viens de refaire le test à l'instant sur mon PC et celui d'un collègue quand on lance la macro sur les deux PC en même temps, ton fichier BDD (placé sur le serveur) s'ouvre (je remarque en même temps que tu as un Excel 2007, est ce la raison ?) :

On est d'accord que tu essaie bien de lancer les macros sur deux fichiers et sur 2 pcs différents ?


Capture.JPG
 

JLE

XLDnaute Junior
Voici ma manipulation qu'on se comprenne bien :

Les fichiers ci-dessous sont placés sur un serveur.
Sur le PC1 j'ouvre OPE
Sur le PC2 j'ouvre PLA
BDD reste fermé mais il est multiutilisateur comme l'indique dysorthographie ci-avant dans le menu révision, et je coche multiutilisateur...je valide et je ferme le fichier.
Je lance la macro sur le fichier OPE
Je lance tout de suite après la macro sur PLA pour provoquer tester

Résultat : chez moi je confirme que le fichier BDD s'ouvre sur un des deux PC ou les deux :
grrrrrrr
 

dysorthographie

XLDnaute Accro
la version d'excel n'y change rien!
VB:
 Cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & fichier & ";Extended Properties=""Excel 12.0;HDR=YEs;"""
   

    'Les données doivent être indiquées dans le même ordre que les champs dans la base de données.
    strSQL = "INSERT INTO [" & Feuille & "$] " _
        & "VALUES (#" & LaDate & "#, " & _
        "'" & leNom & "', " & _
        "'" & lePrenom & "', " & _
        PrixUnit & ")"
   
    For i = 1 To 10000
        Cn.Execute strSQL
    Next i
 

JLE

XLDnaute Junior
la version d'excel n'y change rien!
VB:
 Cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & fichier & ";Extended Properties=""Excel 12.0;HDR=YEs;"""
  

    'Les données doivent être indiquées dans le même ordre que les champs dans la base de données.
    strSQL = "INSERT INTO [" & Feuille & "$] " _
        & "VALUES (#" & LaDate & "#, " & _
        "'" & leNom & "', " & _
        "'" & lePrenom & "', " & _
        PrixUnit & ")"
  
    For i = 1 To 10000
        Cn.Execute strSQL
    Next i
Il y a du changement, maintenant ce n'est plus BDD qui s'ouvre, mais OPE ou PLA dont le fichier se coupe. comme si on avait quitter Excel...
 

Statistiques des forums

Discussions
312 088
Messages
2 085 203
Membres
102 818
dernier inscrit
NeoMaint