Résolu! Voir ci-dessous pour la solution!
Je suis dans Excel 2010 en me connectant à plusieurs, séparés db Access 2010 à partir d'Excel via des connexions de données de tableau croisé dynamique.
L'actualisation de toutes mes connexions entraîne l'échec de l'actualisation finale. L'ordre n'a pas d'importance, j'ai rafraîchi manuellement dans différents ordres, même erreur.
Cependant, si je sauvegarde et ferme après en avoir rafraîchi quelques-uns, puis revenez et actualisez le dernier, il n’ya aucun problème.
Cela me porte à croire que je suis en train de mettre en place une sorte de limite de mémoire qui est réinitialisée lorsque je sauvegarde et ferme.
Puis-je recréer cet effet via VBA sans enregistrer/fermer réellement? Existe-t-il une meilleure solution à ce problème?
Messages d'erreur - Ces trois fenêtres apparaissent dans cet ordre:
Code actuel
Private Sub CommandButton1_Click()
On Error GoTo ErrHndlr
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.StatusBar = "Refreshing Data - Please Be Patient"
ActiveWorkbook.Connections("Connection_1").Refresh
ActiveWorkbook.Connections("Connection_2").Refresh
ActiveWorkbook.Connections("Connection_3").Refresh
Application.Calculation = xlCalculationAutomatic
Application.StatusBar = "Ready"
[LastUpdated].Value = FormatDateTime(Now, vbGeneralDate)
Application.ScreenUpdating = True
Exit Sub
ErrHndlr:
Application.StatusBar = "Ready"
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
[LastUpdated].Value = "Update Error"
Exit Sub
End Sub
Chaîne de connexion
Provider=Microsoft.ACE.OLEDB.12.0
;User ID=Admin
;Data Source=C:\Folders\Database_1.accdb
;Mode=Share Deny None
;Extended Properties=""
;Jet OLEDB:System database=""
;Jet OLEDB:Registry Path=""
;Jet OLEDB:Engine Type=6
;Jet OLEDB:Database Locking Mode=0
;Jet OLEDB:Global Partial Bulk Ops=2
;Jet OLEDB:Global Bulk Transactions=1
;Jet OLEDB:New Database Password=""
;Jet OLEDB:Create System Database=False
;Jet OLEDB:Encrypt Database=False
;Jet OLEDB:Don't Copy Locale on Compact=False
;Jet OLEDB:Compact Without Replica Repair=False
;Jet OLEDB:SFP=False
;Jet OLEDB:Support Complex Data=False
;Jet OLEDB:Bypass UserInfo Validation=False
Solutions tentées
ce
ActiveWorkbook.Connections("Connection_1").Refresh
à
With ActiveWorkbook.Connections("Connection_1")
Select Case .Type
Case xlConnectionTypeODBC
With .ODBCConnection
.Refresh
Do While .Refreshing
DoEvents
Loop
End With
Case xlConnectionTypeOLEDB
With .OLEDBConnection
.Refresh
Do While .Refreshing
DoEvents
Loop
End With
Case Else
.Refresh
End Select
End With
SOLUTION!
Remarque secondaire, j'ai quelques connexions supplémentaires que je ne voulais pas mettre à jour via ce code et j'ai ajouté une logique simple supplémentaire pour spécifier les connexions que je voulais mettre à jour. Ce code fonctionne ici pour actualiser chaque connexion de votre classeur:
Dim i As Integer
Dim awc As WorkbookConnection
Dim c As OLEDBConnection
Set awc = ActiveWorkbook.Connections.Item(i)
Set c = awc.OLEDBConnection
c.EnableRefresh = True
c.BackgroundQuery = False
c.Reconnect
c.Refresh
awc.Refresh
c.MaintainConnection = False
Next i
Je ne connais pas les spécificités de pourquoi cela fonctionne. Cette partie de cette opération permet à Excel de dépasser sa propre limitation. J'aimerais entendre davantage si quelqu'un est plus familier!
Ce n'est pas une réponse complète, mais une tentative d'aide au débogage, afin que nous puissions trouver une solution.
Je crois que vous pouvez résoudre ce problème en déboguant Connections. Essayez de remplacer votre code de rafraîchissement ci-dessus (et le remplacement par DoEvents) par le sous-sous suivant. Tout d'abord, il est possible que l'affichage du dialogue entre les actualisations corrige le problème (s'il s'agit d'actualisations simultanées, etc.). Deuxièmement, chaque fois que cela fonctionne, vérifiez attentivement que rien n'a changé. S'il vous plaît rapporter avec des découvertes ou des informations. Si les erreurs persistent, parcourez le code et signalez la ligne qui génère l'erreur.
Sub ShowDebugDialog()
Dim x As Integer
Dim i As Integer, j As Integer
Dim awc As WorkbookConnection
Dim c As OLEDBConnection
For i = 1 To ActiveWorkbook.Connections.Count
'For i = ActiveWorkbook.Connections.Count To 1 Step -1
For j = 1 To ActiveWorkbook.Connections.Count
Set awc = ActiveWorkbook.Connections.Item(j)
Set c = awc.OLEDBConnection
x = MsgBox("ConnectionName: " & awc.Name & vbCrLf & _
"IsConnected: " & c.IsConnected & vbCrLf & _
"BackgroundQuery: " & c.BackgroundQuery & vbCrLf & _
"MaintainConnection: " & c.MaintainConnection & vbCrLf & _
"RobustConnect: " & c.RobustConnect & vbCrLf & _
"RefreshPeriod: " & c.RefreshPeriod & vbCrLf & _
"Refreshing: " & c.Refreshing & vbCrLf & _
"EnableRefresh: " & c.EnableRefresh & vbCrLf & _
"Application: " & c.Application & vbCrLf & _
"UseLocalConnection: " & c.UseLocalConnection _
, vbOKOnly, "Debugging")
Next j
Set awc = ActiveWorkbook.Connections.Item(i)
Set c = awc.OLEDBConnection
c.EnableRefresh = True
c.BackgroundQuery = False
c.Reconnect
c.Refresh
awc.Refresh
c.MaintainConnection = False
Next i
End Sub
Questions supplémentaires auxquelles vous pouvez répondre si vous recevez toujours des erreurs:
Désolé pour toutes les questions, mais vous devez penser à tout lors du débogage de mauvaises erreurs de connexion comme celle-ci.
J'avais donc une erreur similaire lorsque j'essayais de créer un script VBA pour actualiser automatiquement un classeur Excel à un moment donné, et certaines choses que j'ai effectuées dans mon script VBA pour que cela fonctionne. L'un d'eux est désactive l'actualisation en arrière-plan . Cela pourrait être votre problème et vous pouvez facilement le désactiver en accédant à vos propriétés de connexion et en désactivant l'actualisation en arrière-plan.
Voici ce que j'ai fait dans VBA lorsque j'ai eu cette erreur, bien que je dirais que je ne l'utilisais pas avec une base de données MS Access. J'avais un classeur Excel que je utilisais comme «coureur» et il ouvrait les autres livres un par un et rafraîchissait leurs liens. Fondamentalement, j'avais une variable pour les variables path
et extension
et plaçais les noms de chaque classeur dans un tableau et le parcourait en boucle.
J'ai combiné le chemin et l'extension pour me donner le nom de fichier complet du fichier, vous le verrez dans la boucle.
Voici à quoi ressemblait ma boucle:
For i = LBound(testArray) To UBound(testArray)
Dim wb As Workbook
Set wb = Workbooks.Open(path & testArray(i) & ext, 0, False)
'Next I checked to see if the workbook was in protected view and allowed for editing.
If Application.ProtectedViewWindows.Count > 0 Then
Application.ActiveProtectedViewWindow.Edit
End If
'Now comes the part that I believe should help for your case
wb.Connections(testArray(i) & "This is your connection name").OLEDBConnection.BackgroundQuery = False
wb.RefreshAll
wb.Connections(testArray(i) & "This is your connection name").OLEDBConnection.BackgroundQuery = True
wb.SaveAs fileName:= "Thisbook.xlsx"
wb.Close
Next i
Pour obtenir le nom de la connexion, vous pouvez procéder de plusieurs manières, notamment en cherchant simplement à voir ce que c'est manuellement. Pour moi, parce que je voulais faire en sorte que je n’aie pas besoin de mettre manuellement chaque nom de connexion, j’ai utilisé le modèle inhérent que j’ai vu avec les noms de connexions.
Dans mon cas, c'était le baseNameOfWorkbook & " POS Report"
Je pense que les erreurs dues au rafraîchissement de l’arrière-plan risquent de vous causer des erreurs. Donc, si vous n'avez pas besoin de faire cela dans VBA, je vous suggère simplement d'aller dans les propriétés de connexion et de le désactiver.
Laissez-moi savoir si cela fonctionne.
Pour effacer la mémoire système, vous pouvez toujours exécuter quelque chose comme ceci:
Sub ClearUndo()
Range("A1").Copy Range("A1")
End Sub
Cela effacera la pile d'annulation contenant toutes les mises à jour de vos tableaux croisés dynamiques, ce qui vous permettra de les annuler. Si vous faites cette référence entre les deux, cela peut vous aider à garder l'utilisation de la mémoire sous contrôle.
Ne tenez pas compte de ma suggestion précédente, car je pensais à une solution qui m'a aidé dans Access.
Vous pouvez utiliser VBA pour appeler vos actualisations individuellement via l'objet activeworkbook . Connections. Voir cet article Stack Overflow pour quelques indices sur cette méthode. Une approche plus atomistique peut permettre une meilleure compréhension et un meilleur contrôle. Par exemple, une fois que toutes les étapes sont en place, vous pouvez essayer d'insérer DoEvents
dans résoudre le problème.