J'ai un fichier et dans celui ci j'ai un code VBA qui permet de transférer notamment des données d'un TS vers un autre TS,
Le code enregistré manuellement va plus vite que celui joint, il doit surement avoir quelque chose qui m'échappe car je trouve qu'il n'est pas assez rapide,
Pourriez vous également comment faire pour actualiser également la requête T_GB avant la requête ECHEANCE ?, je ne souhaite pas passer par ResfreshAll.
Et avec ce code on passe à 0.02 seconde sur mon PC
VB:
Option Explicit
Sub valid_analyse()
Application.ScreenUpdating = False
Dim i As Integer, n As Long, j As Integer 'déclaration des variables
If CDate(Range("D_BASE")) <> CDate(Range("D_MODIF")) Then 'analyse date
MsgBox ("Date Base différente de date modif")
Exit Sub
End If
For n = 1 To [HISTO_T_GB].Rows.Count 'analyse si sauvegarde déjà effectuée
If [HISTO_T_GB].Item(n, 1) = Sheets("ANALYSE").Range("E4").Value Then
MsgBox ("Sauvegarde déjà effectuée")
Exit Sub
End If
Next
Range("T_GB_2").ListObject.DataBodyRange.Copy Range("HISTO_T_GB").ListObject.ListRows.Add.Range
End Sub
Le code enregistré manuellement va plus vite que celui joint, il doit surement avoir quelque chose qui m'échappe car je trouve qu'il n'est pas assez rapide,
Le code enregistré manuellement "Macro1" copie tout en vrac sans aucun contrôle et ton 2eme code "valid_analyse" fait plein de contrôle de tout et n'importe quoi et puis copie une cellule par une cellule les 3289 cellules tu m'étonnes que cela soit long !!!
Sur mon PC
La "macro1" s’exécute en 0.13 seconde
La macro "valid_analyse" s’exécute en 16.76 secondes
Et si je rajoute seulement cette ligne sur la macro "valid_analyse"
Et avec ce code on passe à 0.02 seconde sur mon PC
VB:
Option Explicit
Sub valid_analyse()
Application.ScreenUpdating = False
Dim i As Integer, n As Long, j As Integer 'déclaration des variables
If CDate(Range("D_BASE")) <> CDate(Range("D_MODIF")) Then 'analyse date
MsgBox ("Date Base différente de date modif")
Exit Sub
End If
For n = 1 To [HISTO_T_GB].Rows.Count 'analyse si sauvegarde déjà effectuée
If [HISTO_T_GB].Item(n, 1) = Sheets("ANALYSE").Range("E4").Value Then
MsgBox ("Sauvegarde déjà effectuée")
Exit Sub
End If
Next
Range("T_GB_2").ListObject.DataBodyRange.Copy Range("HISTO_T_GB").ListObject.ListRows.Add.Range
End Sub
La partie du code placé au début ne fait pas n'importe quoi :
il vérifie la cohérence de deux dates nommées dans le fichier puis vérifie si une sauvegarde a déjà été effectuée,
Ceci dit le code que vous proposez va évidemment bien plus vite que la boucle For...Next
Pourriez vous me confirmer et me corriger sur trois points :
1 : le fait de faire référence au tableau structuré ("Histo_T_GB) par la méthode Range nous dispense de vérifier qu'il y a bien une ligne car par défaut il y a toujours une ligne vide dans un tableau structuré?
2 : ne connaissant pas très bien le langage VBA même si je comprends aisément ce que fait la procédure, je souhaite réellement comprendre ces deux parties :
VB:
Range("T_GB_2").ListObject.DataBodyRange.Copy
copie du tableau structuré, ListObject.DataBodyRange permet d'enlever la ligne d'en tête ?
Code:
Range("HISTO_T_GB").ListObject.ListRows.Add.Range
on fait appel au tableau structuré HISTO_T_GB, ListObject.listRows (permet de connaitre la dernière ligne) .Add (ajouter à la suite).Range et la je ne sais pas comment il sait que c'est le tableau structuré (T_GB_2) qu'on vient coller ?
3 : j'ai lu que pour faire référence à un tableau structuré on peut faire référence à l'objet "ListObject" ou à la référence structuré Range ("")
J'ai donc tenté de remplacer par expérimentation votre code par :
Fonctionnera mieux.
Pourquoi (1,1): parceque ListRow peut contenir plusieurs cellules et qu si vous copiez dans une région qui n'a pas la même forme que la destination, vous aurez un message d'erreur. En copiant dans une cellule unique vba se débrouiller tout seul.
ListObject est un type et une propriété mais pas une fonction. C'est ListObjects qui existe en tant que collection, et qu'on peut donc faire suivre du nom d'un de ses membres entre parenthèses pour l'obtenir.
Message d'erreur normal car mauvaise syntaxe
Il faut spécifier la feuille ou le nom du tableau
Voir ce petit test
Pour tester : avoir un tableau nommé Tableau1 sur la feuille active
VB:
Sub testPAOK()
MsgBox ListObjects("Tableau1").Name
End Sub
Sub testOK()
MsgBox ActiveSheet.ListObjects("Tableau1").Name
End Sub
Sub testOK_B()
MsgBox Range("Tableau1").ListObject.Name
End Sub
On ne peut pas écrire juste
ListObjects("NomDuTableau").DataBodyRange.Copy
[Précision]
Je parle de la syntaxe utilisée par @ZZ59264
Pourquoi vouloir se faire du mal alors que mon code fonctionne quelque soit l’endroit ou se trouve les 2 tableaux (y compris si on les déplace sur une autre feuille et/ou la même feuille)
Message d'erreur normal car mauvaise syntaxe
Il faut spécifier la feuille ou le nom du tableau
Voir ce petit test
Pour tester : avoir un tableau nommé Tableau1 sur la feuille active
VB:
Sub testPAOK()
MsgBox ListObjects("Tableau1").Name
End Sub
Sub testOK()
MsgBox ActiveSheet.ListObjects("Tableau1").Name
End Sub
@Dranreb précise : ListObject est un type et une propriété mais pas une fonction. C'est ListObjects qui existe en tant que collection, et qu'on peut donc faire suivre du nom d'un de ses membres entre parenthèses pour l'obtenir.
Je comprends bien que c'est un problème de rédaction, je pourrais me dire ok c'est comme ca et pas autrement mais j'essaye de comprendre,
Qu'elle est la différence entre ListObject et LisObjects : le premier est un type et une propriété : c'est à dire et LisObjects une fonction : c'est à dire? pourriez vous me rendre concret ces termes?
Pourquoi vouloir se faire du mal alors que mon code fonctionne quelque soit l’endroit ou se trouve les 2 tableaux (y compris si on les déplace sur une autre feuille et/ou la même feuille)