2012-08-16 13 views
3

J'utilise cette formule pour copier des enregistrements uniques de la colonne A dans la colonne B.Comment copier une plage filtrée dans un tableau? (Excel VBA)

Range("A1", Range("A100").End(xlUp)).AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Range("B1"), Unique:=True 

lieu de le copier dans la colonne B comment mettez-vous les résultats filtrés dans un tableau dans Excel VBA?

+1

Il n'existe pas de méthode intégrée pour cela. Vous pouvez copier vers un emplacement temporaire (tel qu'une feuille masquée) et de là transférer vers un tableau. –

+0

Ah ok. Est-il possible d'obtenir le même résultat en utilisant uniquement du code et non des cellules sur une feuille de calcul masquée? C'est-à-dire, le résultat étant de trouver tous les enregistrements uniques dans la plage A1: A100 (éviter les valeurs en double) et les mettre dans un tableau. – phan

Répondre

0

Vous voulez Read this et il vous diriger dans la bonne direction

Il dit:

  1. Utilisez la méthode AdvancedFilter pour créer la plage filtrée dans une zone inutilisée d'une feuille de calcul
  2. Affectez la propriété Value de cette plage à un Variant pour créer un tableau à deux dimensions
  3. Utilisez la méthode ClearContents de t gamme de chapeau pour se débarrasser
+0

S'il vous plaît poster les étapes, ou au moins une capture d'écran de ce lien plutôt que juste un lien nu. – brettdj

+0

Sorceri, le code tout en bas de ce lien est la réponse exacte dont j'avais besoin. Il réplique le filtre dans un tableau – phan

+0

Performance sage ne serait-il pas mieux de mettre l'ensemble des données dans un tableau puis de construire le tableau que vous voulez de cela plutôt que de le déployer dans une feuille de calcul Excel, en le relisant dans un tableau puis effacer ces données de la feuille de calcul? – MorkPork

0

Ce qui suit prend des informations de la colonne A et donne une liste. Il suppose que vous avez un "Sheet3" qui est disponible pour la saisie de données (vous pouvez changer cela).

Sub test() 

    Dim targetRng As Range 
    Dim i As Integer 

    Set targetRng = Sheets(3).Range("a1") 
    Range("A1", Range("A999").End(xlUp)).AdvancedFilter Action:=xlFilterCopy, CopyToRange:=targetRng, Unique:=True 

    Dim numbElements As Integer 
    numbElements = targetRng.End(xlDown).Row 
    Dim arr() As String 

    ReDim arr(1 To numbElements) As String 

    For i = 1 To numbElements 
     arr(i) = targetRng.Offset(i - 1, 0).Value 
    Next i 

End Sub 
1
Sub tester() 

    Dim arr 
    arr = UniquesFromRange(ActiveSheet.Range("A1:A5")) 
    If UBound(arr) = -1 Then 
     Debug.Print "no values found" 
    Else 
     Debug.Print "got array of unique values" 
    End If 

End Sub 


Function UniquesFromRange(rng As Range) 
    Dim d As Object, c As Range, tmp 
    Set d = CreateObject("scripting.dictionary") 
    For Each c In rng.Cells 
     tmp = Trim(c.Value) 
     If Len(tmp) > 0 Then 
      If Not d.Exists(tmp) Then d.Add tmp, 1 
     End If 
    Next c 
    UniquesFromRange = d.keys 
End Function 
7

Il a été exactement un an que cette question a été posée, mais je couru aujourd'hui dans le même problème et est ici ma solution pour elle:

Function copyFilteredData() As Variant 
    Dim selectedData() As Variant 
    Dim aCnt As Long 
    Dim rCnt As Long 

    Range("A1").CurrentRegion.SpecialCells(xlCellTypeVisible).Select 
    On Error GoTo MakeArray: 
    For aCnt = 1 To Selection.Areas.Count 
     For rCnt = 1 To Selection.Areas(aCnt).Rows.Count 
      ReDim Preserve SelectedData(UBound(selectedData) + 1) 
      selectedData(UBound(selectedData)) = Selection.Areas(aCnt).Rows(rCnt) 
     Next 
    Next 

    copyFilteredData = selectedData 
    Exit Function 

MakeArray: 
    ReDim selectedData(1) 
    Resume Next 

End Function 

Cela laissera l'élément 0 du tableau vide mais UBound (SelectedData) renvoie le nombre de lignes dans la sélection

+0

Redim est une action très coûteuse. Je ne l'utiliserais pas dans une boucle comme celle-ci, à moins que le nombre d'itérations attendues soit très faible. –

+0

@MorSagmon Pouvez-vous expliquer de quelle manière le redim est coûteux? –

+0

Vous devez également [éviter d'utiliser select] (https://stackoverflow.com/questions/10714251/how-to-avoid-using-select-in-excel-vba-macros) et déclarer une plage à opérer à la place de 'Sélection'. Autre que cela, bonne méthodologie – Wolfie

3

Juste au cas où quelqu'un regarderait encore ceci ... J'ai créé cette fonction pour travailler sur un 1-D gamme, mais il va aussi écrire un plage de dimension supérieure à un tableau 1D; il ne devrait pas être trop difficile à modifier pour écrire une gamme de dimensions multiples dans un tableau de "même forme". Vous devez avoir une référence à scrrun.dll pour créer l'objet dictionnaire. Mise à l'échelle peut être un problème car un « pour chaque » boucle est utilisée, mais si vous utilisez ce EXCEL est rien probable que vous êtes sur le point inquiet:

Function RangeToArrUnique(rng As Range) 
    Dim d As Object, cl As Range 
    Set d = CreateObject("Scripting.Dictionary") 
    For Each cl In rng 
     d(cl.Value) = 1 
    Next cl 
    RangeToArrUnique = d.keys 
End Function 

Je l'ai testé ce de cette façon:

Dim dat as worksheet 
set dat = sheets("Data") 
roomArr = Array("OR01","OR02","OR03") 
dat.UsedRange.AutoFilter field:=2, criteria1:=roomArr, operator:=xlFilterValues 
fltArr = RangeToArrUnique(dat.UsedRange.SpecialCells(CellTypeVisible)) 

J'espère que ça aide quelqu'un!

Questions connexes