Je suis novice en vba et je n'ai pas été capable de trouver une solution à mon problème malgré de nombreuses discussions sur le sujet.
J'ai une grande base données (plus de 100000 lignes) et je voudrais trouver un moyen de tirer aléatoirement et sans doublon un nombre variable sur une colonne (1000 par exemple) pour les travailler indépendamment dans un autre onglet en copiant les colonnes correspondants.
Je vous joint un exemple du format de ma fiche de travail: je voudrais tirer 300 dossiers sur la colonne C ( référence) aléatoire sans doublons parmi plus de 700 dossiers au total, et après copier coller dans un autre onglet ''feuil2" qui est en même format que "feuil1".
comme j'ai une grande base de donnée, il faudrait peut-être optimiser le temps de tourne le macro.
Re : Tirage sur un colonne sans doublons (grd base données )
Re, Bonjour Bebere
Job75
J'essaie juste de savoir si on peut faire strictement la même chose avec RemoveDuplicate qu'avec Filtre élaboré Extraction sans doublons coché.
D’après tes réponses, j'en déduis que c'est non, non ?
Re : Tirage sur un colonne sans doublons (grd base données )
Re,
S'il n'y a jamais de doublon en colonne K ma macro du post #12 se simplifie :
Code:
Sub TiragesAléatoires()
Dim n&, derlig&, P As Range
n = 300 '1000 'nombre de lignes à retenir, à adapter
Application.ScreenUpdating = False
derlig = ActiveSheet.Cells.Find("*", , xlValues, , xlByRows, xlPrevious).Row
With Feuil2 'CodeName de la feuille de restitution
.Rows("4:" & .Rows.Count).Delete 'RAZ
ActiveSheet.Rows("4:" & derlig).Copy .[A4]
Set P = Intersect(.UsedRange, .Rows("4:" & derlig))
With P.Columns(P.Columns.Count + 1) 'colonne auxiliaire à droite
.Formula = "=RAND()"
.Value = .Value 'supprime les formules
.Cells(1) = 0
Union(P, .Cells).Sort .Cells, xlAscending 'tri
.EntireColumn.Delete 'suppression de la colonne auxiliaire
End With
.Rows(n + 5 & ":" & .Rows.Count).Delete
n = .UsedRange.Rows.Count 'ajuste la barre de défilement verticale
.Columns.AutoFit 'ajustement de la largeur des colonnes
.Activate
End With
End Sub
Fichier (3).
Sur 200000 lignes la macro s'exécute en 4,7 secondes.
PS pour JM : tu n'as qu'à tester ce que tu veux faire.
Edit : attention le fichier (3) est en mode de calcul manuel
Je viens de m'en rendre compte en le rouvrant pour rédiger mon post #50.
Re : Tirage sur un colonne sans doublons (grd base données )
Bonjour Julie, Laetitia, Bebere, Job, Staple...
Une comparaison des trois codes : Job75 post n°22, laetitia90_post n°17, KD post n°13 (2ème code). Ces codes sont adaptés à la présentation du fichier exemple fourni au post n°7, c'est pourquoi n'est pas inclus le code Bebere du post n°20. Trois mesures à chaque fois en variant l'ordre des procédures. BDD 203.951 lignes.
Ces trois codes partent du principe que le 'sans doublons' demandé correspond au tirage et que la BDD ne contient pas de doublons. Si la BDD contient des doublons se reporter à Job post n°14.
Le code de Job75 est remarquablement stable quelque soit la taille de l'échantillon. Toutefois si les échantillons sont toujours nettement inférieur à 5000 il semblerait que le code du n°13 soit plus rapide.
Ton code est de loin le plus rapide pour toutes les tailles d'échantillons.
J'ai revu mon code en tablant dès le premier passage et en restituant également avec transpose en espérant être plus rapide, puisque pas d'objets dictionary, j'obtiens :
E(300): Bebere 1s & 1s, KD 1s & 1s
E(1000): Bebere 1s & 1s, KD 1s & 1s
E(5000): Bebere 1s & 1s, KD 2s & 2s
E(10000): Bebere 1s & 2s, KD 3s & 2s
E(20000): Bebere 4s & 3s, KD 3s & 4s
E(50000): Bebere 14s & 13s, KD 8s & 8s
Il semblerait que ton code reste plus rapide pour des petits échantillons et le mien pour des gros. Ceci dit Julie souhaite des échantillons d'ordre de grandeur 1000 pas 50000...
Je poste quand même au cas ou il y aurait impossibilité d'activer Scripting.Runtime.
Cordialement
KD
VB:
Sub Echantillon2()
Dim r&, a$(), p#, i&, c&, b&, d%, w As Worksheet, e%, j%, n&
Application.ScreenUpdating = False: Application.Calculation = xlCalculationManual
Worksheets("BDD").Activate
b = 4: d = 11: n = 300 'ligne de titres/colonne sans éléments vides/nb de dossiers demandés
r = Cells(Rows.Count, d).End(xlUp).Row - b
e = Cells(b, Columns.Count).End(xlToLeft).Column 'pas d'intitulés de colonnes vides
If n > r Then Exit Sub
ReDim a(1 To n, 1 To e): p = n / r: Randomize
For i = 1 To r - 1
If Not Rnd > p Then
c = c + 1: n = n - 1
For j = 1 To e: a(c, j) = Cells(i + b, j): Next j
End If
p = n / (r - i)
Next i
If n = 1 Then a(UBound(a)) = r
Set w = ActiveSheet: Sheets.Add: w.Cells.Copy Destination:=[A1]
Range(Cells(b + 1, 1), Cells(Rows.Count, Columns.Count)).ClearContents
Cells(b + 1, 1).Resize(UBound(a), e) = a
Application.ScreenUpdating = True: Application.Calculation = xlCalculationAutomatic
End Sub
Pour éviter les problèmes lié à la référence Scripting.Runtime.
On peut modifier le code de Bebere ainsi pour ne pas avoir à cocher la référence
(sur ces deux lignes, faire les modifs ci-dessous)
Dim dico As Object, mondico As Object
puis
Set mondico = CreateObject("Scripting.dictionary")
PS: L'avantage du code de Kendev c'est qu'il fonctionne sous Windows et Mac, celui de Bebere uniquement sous Windows.