web-dev-qa-db-fra.com

Attendez la fin du processus ActiveWorkbook.RefreshAll - VBA

J'ai un sous qui appelle ActiveWorkbook.RefreshAll pour importer de nouvelles données à partir d'une source XML, puis lui apporte de nombreuses modifications. Le problème est que le temps imparti à la commande RefreshAll est insuffisant. Les sous-programmes et fonctions suivants ne s'exécutent donc pas correctement, ce qui a pour conséquence que des lignes répétées ne sont pas correctement effacées.

J'ai essayé d'utiliser Application.Wait et la fonction Sleep , mais ils semble mettre en pause le processus d'actualisation aussi. Je veux simplement que le reste du code attende la fin du processus d'actualisation avant d'exécuter le reste du code.

Des idées sur la façon de mettre en œuvre cela? Pour le moment, je n'ai pu résoudre le problème qu'en n'utilisant pas RefreshAll, ce qui me donne l'idée de mettre en œuvre un deuxième flux à exécuter par la suite, mais ce n'est pas une bonne solution de contournement.

S'il vous plaît laissez-moi savoir si tout cela n'était pas clair. Merci

[~ # ~] éditer [~ # ~] J'ai donc essayé quelques suggestions tirées des publications ci-dessous, et voici ce que j'ai pu afficher avec. Faire une "macro d'enregistrement" puis UNCHECKING "Activer l'actualisation de l'arrière-plan" dans les propriétés de la table n'a rien donné. J'ai aussi fait un rafraichissement après. C'était le résultat de la macro enregistrée:

With ActiveWorkbook.Connections("XMLTable")
        .Name = "XMLTable"
        .Description = ""
End With
ActiveWorkbook.Connections("XMLTable").refresh

La classe ActiveWorkbook.Connections N'A PAS d'option BackgroundQuery de sorte que je peut le définir sur False. Des idées?

Juste pour être clair. Il s’agit d’un fichier XML hébergé sur un site Web que Excel va importer dans un tableau. J'appelle ensuite ces données dans un pivot et d'autres choses. L'objectif ici est de permettre au processus d'importation du site Web vers la table de se terminer AVANT d'exécuter toute autre commande. Merci

EDIT2: Après un peu plus de recherches, j'ai trouvé cette page: http://www.mrexcel.com/forum/Excel- questions/564959-exécuter-code-après-connexion-données-rafraîchir-finish.html Il semble qu'un type de connexion XML n'a pas de BackgroundQuery booléen. Cette option est uniquement disponible pour ODBC et les connexions OLEDB, qui sont de types xlConnectionTypeODBC et xlConnectionTypeOLEDB, respectivement. La connexion XML que j’utilise est de type xlConnectionTypeXMLMAP qui n’a pas de BackgroundQuery option. Est-ce que quelqu'un a une idée de l'endroit où aller à partir de maintenant? La seule solution que je me propose maintenant est de créer deux boutons macro distincts sur la feuille Excel, un pour rafraîchissant et un pour la modification des données, mais je préfère garder cette option pour la dernière.

34
Mo2

Comme commenté:

'~~> your code here before refresh

Activeworkbook.RefreshAll
DoEvents

'~~> rest of your code here after refresh

Ce que DoEvents fait c'est permettre momentanément à Windows de faire une pause dans Macro pour traiter tous les événements en attente avant de revenir à la macro.
Ainsi, lorsque vous actualisez votre classeur et que vous mettez DoEvents après, il ne reprendra pas la macro tant que l'actualisation n'est pas terminée.

21
L42

J'ai eu le même problème, cependant DoEvents ne m'a pas aidé, car l'actualisation de l'arrière-plan de mes connexions de données était activée. Au lieu de cela, en utilisant la réponse de Wayne G. Dunn comme point de départ, j'ai créé la solution suivante, qui fonctionne parfaitement pour moi;

Sub Refresh_All_Data_Connections()

    For Each objConnection In ThisWorkbook.Connections
        'Get current background-refresh value
        bBackground = objConnection.OLEDBConnection.BackgroundQuery

        'Temporarily disable background-refresh
        objConnection.OLEDBConnection.BackgroundQuery = False

        'Refresh this connection
        objConnection.Refresh

        'Set background-refresh value back to original value
        objConnection.OLEDBConnection.BackgroundQuery = bBackground
    Next

    MsgBox "Finished refreshing all data connections"

End Sub

La MsgBox sert uniquement à tester et peut être supprimée une fois que vous êtes satisfait du code attend.

De plus, je préfère ThisWorkbook à ActiveWorkbook car je sais que ce dernier ciblera le classeur où réside le code, juste au cas où le focus changerait. Neuf fois sur dix, cela n'aura aucune importance, mais j'aime pécher par excès de prudence.

EDIT: Vous venez de voir votre modification concernant l'utilisation d'une connexion xlConnectionTypeXMLMAP qui ne dispose pas d'une option BackgroundQuery, désolée. Je laisserai ce qui précède à quiconque (comme moi) à la recherche d'un moyen d'actualiser les types de connexion OLEDBConnection.

46
Valiante

Bien que @Wayne G. Dunn ait donné du code. Voici l'endroit où vous ne voulez pas coder. Et décochez pour désactiver l'actualisation en arrière-plan.

enter image description here

12
subro

AVERTISSEMENT: le code ci-dessous aurait provoqué des plantages! À utiliser avec précaution.

selon CETTE réponse dans Excel 2010 et les versions ultérieures CalculateUntilAsyncQueriesDone arrête les macros jusqu'à ce que l'actualisation soit terminée
ThisWorkbook.RefreshAll
Application.CalculateUntilAsyncQueriesDone

6
robotik

Vous devez désactiver "l'actualisation en arrière-plan" pour toutes les requêtes. Si l'actualisation en arrière-plan est activée, Excel fonctionne en avance pendant l'actualisation et vous avez des problèmes.

Données> Connexions> Propriétés> (décochez) pour activer l'actualisation en arrière-plan

4
tim.s

Voici une solution trouvée sur http://www.mrexcel.com/forum/Excel-questions/510011-fails-activeworkbook-refreshall-backgroundquery-%3Dfalse.html :

Définissez la valeur False sur toutes les propriétés de la requête d'arrière-plan des pivots de fichiers pivotcaches ou parcourez tous les pivots de cache du classeur:

Code:
    For Each pc In ActiveWorkbook.PivotCaches
       pc.BackgroundQuery = False
       pc.Refresh
    Next 

cela laissera toutes les propriétés de la requête d'arrière-plan de pivotcaches comme étant fausses. Vous pouvez conserver les réglages de chacun avec:

Code:

For Each pc In ActiveWorkbook.PivotCaches
  originalBGStatus = pc.BackgroundQuery
  pc.BackgroundQuery = False
  pc.Refresh
  pc.BackgroundQuery = originalBGStatus
Next
1
Wayne G. Dunn

Cela peut ne pas être idéal, mais essayez d’utiliser "Application.OnTime" pour suspendre l’exécution du code restant jusqu’à ce que le délai imparti soit écoulé pour que tous les processus d’actualisation soient terminés.

Que se passera-t-il si la dernière table de votre liste d'actualisation était une fausse table composée uniquement d'un indicateur indiquant que l'actualisation est terminée? Cette table serait supprimée au début de la procédure, puis, à l'aide de "Application.OnTime", un sous-traitant serait exécuté toutes les 15 secondes environ pour vérifier si la table erronée avait été remplie. S'il est rempli, arrêtez le vérificateur "Application.OnTime" et poursuivez la procédure.

Un peu waché, mais ça devrait marcher.

1
Scott

Cela a fonctionné pour moi:

ActiveWorkbook.refreshall
ActiveWorkbook.Save

Lorsque vous enregistrez le classeur, il est nécessaire de terminer l'actualisation.

0
MostFire

J'ai essayé quelques-unes des suggestions ci-dessus. La meilleure solution pour moi était de désactiver backgroundquery pour chaque connexion.

With ActiveWorkbook.Connections("Query - DL_3").OLEDBConnection
    .BackgroundQuery = False
    End With
0
James Koch

J'avais ce même problème et j'ai essayé toutes les solutions ci-dessus sans succès. J'ai finalement résolu le problème en supprimant l'intégralité de la requête et en en créant une nouvelle.

La nouvelle avait exactement les mêmes paramètres que celle qui ne fonctionnait pas (littéralement, la même définition de requête que celle que j'avais copiée précédemment).

Je ne sais pas pourquoi cela a résolu le problème, mais ça l'a été.

0
Jennifer

Essayez d'exécuter:

ActiveSheet.Calculate

Je l'utilise dans une feuille de calcul dans laquelle les boutons de contrôle changent les valeurs d'un ensemble de données. À chaque clic, Excel exécute cette commande et le graphique est mis à jour immédiatement.

0
rwb

Si vous n'êtes pas marié à utiliser Excel Web Query, vous pouvez essayer d'ouvrir l'URL en tant que classeur séparé. Cette route vous permet de travailler sur les données résultantes une fois la requête Web terminée, comme si vous désactiviez "Activer l'actualisation en arrière-plan".

La bonne chose est cependant, Excel affiche une barre de progression lors de la demande, au lieu de simplement geler/afficher un message de chargement dans la cellule de destination.

Voir ma réponse à cette question: Comment puis-je post-traiter les données d'une requête Web Excel lorsque la requête est terminée?

Le compromis de cette approche est que vous devez gérer vous-même le traitement des données que vous récupérez - Excel ne les placera pas dans une destination donnée.

Nous avons fini par emprunter cette voie après avoir essayé quelque chose de très similaire à ce que vous semblez avoir fait.

0
mcw0933