Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

Microsoft 365 Transfert valeurs unique d'un Range dans un Array

seb555

XLDnaute Nouveau
Bonjour,

Je cherche à mettre les valeurs uniques de A3:A8 dans un Array, la façon que j'ai trouvé pour y arriver est

VB:
Sub test()
    Dim vars0() As Variant
    ReDim vars0(0)
    lali1 = 8
    Ini1 = False
    For i = 3 To lali1
        valeur = Cells(i, 1)
        On Error Resume Next
            x = Application.Match(valeur, vars0, 0)
            If Err.Number <> 0 Or x = "Erreur 2042" Then
                If Ini1 = True Then ReDim Preserve vars0(UBound(vars0) + 1)
                vars0(UBound(vars0)) = valeur
                Ini1 = True
            End If
        On Error GoTo 0
    Next
End Sub

Remarque ce cas va de 3 à 8 mais je vais généraliser de 3 à last line, c'est juste pour un test

Y a-t'il une façon plus simple de le faire, sans passer par la variable de passage Ini1 par exemple ?

Seb
 
Dernière édition:

Staple1600

XLDnaute Barbatruc
Bonsoir

Jean-Eric m'a devancé mais j'étais parti sur la même piste

Alors puisque c'est pondu, je poste
VB:
Sub Test_OK()
Dim r As Range: Set r = Cells(1).CurrentRegion
    With Application
        [B1].Resize(UBound(.Unique(r), 1)).Value = .Unique(r)
    End With
End Sub
Ci-dessous macro pour générer des données de test
VB:
Sub Pour_TEST()
Range("A2:A40").FormulaR1C1 = "=INT(ROW(R[-1]C)/RANDBETWEEN(2,5))+1"
Range("A2:A40") = Range("A2:A40").Value
End Sub
 

mapomme

XLDnaute Barbatruc
Supporter XLD
Bonsoir @patricktoulon
en tout cas la demande est confuse
je cite
pour moi ca veut dire les valeurs uniques (celles qui n'ont pas de doublons)
Pour ce cas, on peut parler de singleton.
Le problème est différent. Un exemple dans le fichier joint avec 150 000 lignes dans la source dont 111 valeurs "singletons". La durée d'exécution est d'environ 0,42s.
L'initialisation de la source se fait à l'ouverture du fichier.
Le code est dans le module de Feuil1.
 

Pièces jointes

  • seb555- extraire singleton- v1.xlsm
    22.3 KB · Affichages: 5
Dernière édition:

Jean-Eric

XLDnaute Occasionnel
Bonjour,
Pour donner suite, 2 propositions pour lister les valeurs distinctes et uniques.
Cdlt.

VB:
Public Sub DistinctValues()
'occurence > 1
Dim r As Range, tbl As Variant, i As Long
    With Sheet1
        Set r = .Range("A3:A14")
        tbl = WorksheetFunction.Unique(r)
        For i = LBound(tbl) To UBound(tbl)
            Debug.Print tbl(i, 1)
        Next i
    End With
End Sub

Public Sub UniqueValues()
'occurence = 1
Dim r As Range, tbl As Variant, i As Long
    With Sheet1
        Set r = .Range("A3:A14")
        tbl = WorksheetFunction.Unique(r, , True)
        For i = LBound(tbl) To UBound(tbl)
            Debug.Print tbl(i, 1)
        Next i
    End With
End Sub
 

Pièces jointes

  • seb555 v2.xlsm
    16 KB · Affichages: 0

Cousinhub

XLDnaute Barbatruc
Inactif
Bonjour,
Bien plus rapide qu'un Dictionary...
8 centièmes de seconde sur le fichier @mapomme pour cette fonction Unique, contre 22 centièmes avec 2 Dictionary..
 

Cousinhub

XLDnaute Barbatruc
Inactif
Re-,
Le premier pour charger les valeurs sans doublons, et qui est chargé comme ceci :
Dict(tbl(i,1))=Dict(tbl(i,1)) +1
Ainsi, je récupère le nombre de répétitions de chaque valeur dans les items
Puis le deuxième qui parcourt le 1er, et qui ne récupère que les clés dont l'item est à 1..
Voili, voilou...
 

mapomme

XLDnaute Barbatruc
Supporter XLD
Re @bhbh,
Puis le deuxième qui parcourt le 1er, et qui ne récupère que les clés dont l'item est à 1..
Ok, j'ai compris.
Souvent, je n'en utilise qu'un seul. C'est à cause de mon âge car dans ma jeunesse on devait économiser la quantité de RAM utilisée, c'était rare et précieux la RAM.

Avec un seul dictionary pour fabriquer le tableau (mais non compatible MAC), on pourrait faire:
VB:
Sub Singleton1()
Dim deb, t, dico, x, q&
   deb = Timer
   t = Range(Cells(3, 1), Cells(Rows.Count, 1).End(xlUp))
   Set dico = CreateObject("scripting.dictionary")
   For Each x In t: dico(x) = dico(x) + 1: Next
   For Each x In dico
      If dico(x) = 1 Then q = q + 1 Else dico.Remove x
   Next x
   If q > 0 Then
      ReDim r(1 To q, 1 To 1): q = 0
      For Each x In dico
         If dico(x) = 1 Then q = q + 1: r(q, 1) = x
      Next x
   End If
   MsgBox Format(Timer - deb, "0.00\ sec.")
End Sub
 
Dernière édition:

Discussions similaires

Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…