Mon code vba marche une fois sur deux!
flateur18
Messages postés
39
Statut
Membre
-
Patrice33740 Messages postés 8930 Statut Membre -
Patrice33740 Messages postés 8930 Statut Membre -
Bonjour chers amis programmeurs,
J'ai un souci concernant l'execution de mon programme vba.
Depuis vba access, j'ouvre un fichier Excel, j'effectue des modifications dessus, et je le lie avec ma base access. quand je souhaite faire la même manip une deuxième fois (avec le même fichier ou un fichier différent) l'application excel plante.
ça fait des mois que ca dure!!! j'ai vu dans plein de forums que je dois declarer chaque objet (excel application, workbook, worksheet) et que je dois le detruir à la fin, c'est ce que je fait mais ça ne marche toujours pas !!!
voilà mon code : (en gras où ca plante)
Merci pour votre aide
J'ai un souci concernant l'execution de mon programme vba.
Depuis vba access, j'ouvre un fichier Excel, j'effectue des modifications dessus, et je le lie avec ma base access. quand je souhaite faire la même manip une deuxième fois (avec le même fichier ou un fichier différent) l'application excel plante.
ça fait des mois que ca dure!!! j'ai vu dans plein de forums que je dois declarer chaque objet (excel application, workbook, worksheet) et que je dois le detruir à la fin, c'est ce que je fait mais ça ne marche toujours pas !!!
voilà mon code : (en gras où ca plante)
Private Sub fichier1()
On Error GoTo Error_
Dim xlApp1 As Excel.Application
Dim xlWb1 As Excel.Workbook
Dim xlSh1 As Excel.Worksheet
If Text11 <> "" Then
Set xlApp1 = CreateObject("Excel.Application")
Set xlWb1 = xlApp1.Workbooks.Open(Text11) 'text11 contient le chemin
Set xlSh1 = xlWb1.Sheets(1) 'une seule feuille dans le fichier
With xlApp1
.DisplayAlerts = False
.Visible = True
.ActiveWorkbook.Save
.Calculation = xlAutomatic
.MaxChange = 0.001
.ActiveWorkbook.PrecisionAsDisplayed = False
If .ActiveSheet.Range("A1") <> "PO+PN" Then GoTo AddPOPN
AddPOPN: ' Ajout du PO+PN
.Columns("A").Select
.ActiveSheet.Columns("A:A").Insert Shift:=xlToRight
.Range("A1") = "PO+PN"
.ActiveSheet.Range("A2").Select
.ActiveCell.FormulaR1C1 = "=CONCATENATE(RC[38],RC[9])"
.Selection.AutoFill Destination:=xlSh1.Range("A2:A" & Range("A2").end(xlDown).Row), Type:=xlFillDefault
.Columns("A:A").Select
.Selection.NumberFormat = "@"
If .ActiveSheet.Range("A1") = "PO+PN" Then GoTo Type_
Exit Sub
End With
End If
'fermeture du processus excel, sauvegarde et liberationdes objets
Set xlSh1 = Nothing
Set xlWb1 = Nothing
xlApp1.Quit
Set xlApp1 = Nothing
Exit Sub
End Sub
'======================================================
Private Sub fichier2()
On Error GoTo Error_
Dim xlApp2 As Excel.Application
Dim xlWb2 As Excel.Workbook
Dim xlSh2 As Excel.Worksheet
If Text21 <> "" Then
Set xlApp2 = CreateObject("Excel.Application")
Set xlWb2 = xlApp2.Workbooks.Open(Text21)
Set xlSh2 = xlWb2.Sheets(1)
With xlApp2
.DisplayAlerts = False
.Visible = True
.ActiveWorkbook.Save
.Calculation = xlAutomatic
.MaxChange = 0.001
.ActiveWorkbook.PrecisionAsDisplayed = False
If .ActiveSheet.Range("A1") <> "PO+PN" Then GoTo AddPOPN
AddPOPN: ' Ajout du PO+PN
.Columns("A").Select
.ActiveSheet.Columns("A:A").Insert Shift:=xlToRight
.Range("A1") = "PO+PN"
.ActiveSheet.Range("A2").Select
.ActiveCell.FormulaR1C1 = "=CONCATENATE(RC[38],RC[9])"
.Selection.AutoFill Destination:=xlSh2.Range("A2:A" & Range("A2").end(xlDown).Row), Type:=xlFillDefault
.Columns("A:A").Select
.Selection.NumberFormat = "@"
.ActiveWorkbook.Save
Exit Sub
End With
End If
'fermeture du processus excel et liberationdes objets
Set xlSh2 = Nothing
Set xlWb2 = Nothing
xlApp2.Quit
Set xlApp2 = Nothing
End Sub
Merci pour votre aide
A voir également:
- Mon code vba marche une fois sur deux!
- Code ascii - Guide
- Code puk bloqué - Guide
- Comment faire deux colonnes sur word - Guide
- Comment déverrouiller un téléphone quand on a oublié le code - Guide
- Code activation windows 10 - Guide
3 réponses
Bonsoir,
Difficile de répondre, le code est incomplet !
Le Exit Sub situé avant le End With est probablement un résidu de tentative de débogage.
il manque les labels correspondant à :
On Error GoTo Error_
If .ActiveSheet.Range("A1") = "PO+PN" Then GoTo Type_
Il manque la gestion d'erreur
Il y a une erreur sur la ligne :
.Selection.AutoFill Destination:=xlSh1.Range("A2:A" & _
Range("A2").End(xlDown).Row), Type:=xlFillDefault
Remplacer par
.Selection.AutoFill Destination:=xlSh1.Range("A2:A" & _
xlSh1.Range("A2").End(xlDown).Row), Type:=xlFillDefault
J'espère que cela suffit à régler le problème
Patrice
Difficile de répondre, le code est incomplet !
Le Exit Sub situé avant le End With est probablement un résidu de tentative de débogage.
il manque les labels correspondant à :
On Error GoTo Error_
If .ActiveSheet.Range("A1") = "PO+PN" Then GoTo Type_
Il manque la gestion d'erreur
Il y a une erreur sur la ligne :
.Selection.AutoFill Destination:=xlSh1.Range("A2:A" & _
Range("A2").End(xlDown).Row), Type:=xlFillDefault
Remplacer par
.Selection.AutoFill Destination:=xlSh1.Range("A2:A" & _
xlSh1.Range("A2").End(xlDown).Row), Type:=xlFillDefault
J'espère que cela suffit à régler le problème
Patrice
Cher Patrice,
J'ai fait exactement ce que tu m'a dit, donc de référencer tous les .columns, .rows et .cells à mon objet xlSh1, et cela marche parfaitement, le processus se termine sans probleme après l'execution de toutes les commandes, et permet au suivant de s'ouvrir proprement, c'est nikel, j'ai même oté ma fonction "killProcess" car j'ai maintenant confiance en mon code.
Merci infiniment, et à de nouvelles aventures,
Cordialement
Manu
J'ai fait exactement ce que tu m'a dit, donc de référencer tous les .columns, .rows et .cells à mon objet xlSh1, et cela marche parfaitement, le processus se termine sans probleme après l'execution de toutes les commandes, et permet au suivant de s'ouvrir proprement, c'est nikel, j'ai même oté ma fonction "killProcess" car j'ai maintenant confiance en mon code.
Merci infiniment, et à de nouvelles aventures,
Cordialement
Manu
.ActiveWorkbook.Save devrait se situer juste avant le End With
En effet, pour la gestion des erreurs, j'ai tronqué les label "Error_:" et "Type_" car trop longs, mais ils sont bien dans mon code d'origine.
Quand je met le "Exit Sub" après "End With", mon code plante quand je ne rentre pas dans le label "AddPOPN:".
J'ai trouvé une "astuce" pour fermer systématiquement et "physiquement" toute application Excel avant de la réutiliser à nouveau, car c'est là d'où vennait le problème, des"objets" restaient actifs malgré la fermeture du processus Excel et la liberation des objets qu'on a créé.
Pour ceux qui sont intéressés voici la fonction à mettre dans un module :
Option Compare Database Public Function KillProcess(ByVal ProcessName As String) As Boolean On Error GoTo err Dim svc As Object Dim sQuery As String Dim oproc Set svc = GetObject("winmgmts:root\cimv2") sQuery = "select * from win32_process where name='" & ProcessName & "'" For Each oproc In svc.execquery(sQuery) oproc.Terminate Next Set svc = Nothing err: Set svc = Nothing 'MsgBox err.Description & " " & err.Number & " " & err.Source End Functionet dans le code VB, écrire avant le "End Sub" de chaque procédure qui appelle Excel :
Ca permet de repartir "Proprement" en ouvrant une autre application Excel.
Chez moi ça marche bien.
===========================================================================
"Ce qu'il y a de plus difficile à apprécier et à comprendre, c'est ce qui ce passe sous nos yeux !!!"
Ce code est intéressant pour éliminer un processus qui ne s'est pas fermé correctement..
Concernant le problème que tu avais évoqué, il est très probable que cela vienne d'une ou plusieurs erreurs dans ton code qui entrainent un plantage du processus et donc l'empêchent de se fermer normalement.
Ta solution est très radicale mais elle ne résout pas l'origine du problème, avec toutes les conséquences que cela peut avoir sur la confiance accordée à ton code.
Après avoir corrigé ton code, je l'ai exécuté des dizaines de fois sans jamais avoir le moindre problème.
Corrections à faire :
- référencer chaque range et column par rapport à l'objet WorkSheet (xlSh1) au lieu de l'objet Application (xlApp1)
- Traiter entièrement le If .ActiveSheet.Range("A1") <> "PO+PN" Then en ajoutant un Else et un End if de façon à ne passer par AddPOPN: (qui devient inutile) que lorsque c'est nécessaire.
- supprimer le Exit Sub qui empêche la destruction des variables instanciées.
Cordialement
Patrice