Autofilter VBA Excel tutto tranne tre

Nella saga continua della mia analisi dei dati ( prima domanda ), voglio eliminare tutte le righe i cui dipartimenti (campo 7) non sono 101, 102 o 103 (i nomi sono stati modificati per proteggere gli innocenti). Ci sono circa un centinaio di reparti nei dati, quindi l’uso di Criteria1:=Array("104", "105", "106", ecc. Non è pratico.

Mi piacerebbe fare qualcosa di simile a questo:

myrange.AutoFilter Field:=7, Criteria1:="101", Operator:=xlOr, Criteria2:="102", Operator:=xlOr, Criteria3:="103"

ma Excel non riconosce più di 2 criteri. Potrei aggiungere una colonna helper e far passare la macro attraverso ogni riga (se 101, 102 o 103, quindi valore = Sì), filtrare i sì e cancellare tutto ciò che rimane, ma lo sto salvando come ultimo ricorrere.

C’è un modo per il filtro automatico Criteria1 essere non uguale a un array? Qualcosa di simile a:

myrange.AutoFilter Field:=7, Criteria1:="" & Array("101", "102", "103")

Ricorda che l’objective è eliminare le righe non corrispondenti; AutoFilter è solo uno strumento per raggiungere l’objective. Se AutoFilter non soddisfa le tue esigenze, scegli un altro metodo. Prendere in considerazione:

 Sub AllBut() Dim rTable As Range, r As Range Dim rDelete As Range Set rTable = Selection Set rDelete = Nothing For Each r In rTable.Columns(7).Cells v = r.Value If v <> "101" And v <> "102" And v <> "103" Then If rDelete Is Nothing Then Set rDelete = r Else Set rDelete = Union(r, rDelete) End If End If Next If Not rDelete Is Nothing Then rDelete.EntireRow.Delete End Sub 

Qui selezioniamo il blocco di dati da elaborare (esclusa la riga di intestazione). La macro spazza giù la colonna # 7 di quel blocco ed elimina qualsiasi riga che non corrisponde ai criteri.

Tutto ciò che rimarrà sono i 101, i 102 e i 103.

Poiché si trattava del metodo AutoFilter , offrirò questo metodo che implica l’utilizzo di un object Scripting.Dictionary per simulare la procedura che verrebbe utilizzata se questa fosse stata eseguita manualmente nel foglio di lavoro.

Nel foglio di lavoro, l’utente applica un filtro automatico, quindi utilizza il menu a discesa della colonna G per “distriggersre” i valori 101, 102 e 103. Ciò che restava sarebbe stato cancellato. In VBA, possiamo afferrare tutta la colonna G e popolare un object dizionario con i valori che non sono 101, 102 o 103 e usarlo come criterio per l’operazione di filtro.

 Sub filterNotThree() Dim d As Long, dDELs As Object, vVALs As Variant Set dDELs = CreateObject("Scripting.Dictionary") With Worksheets("Sheet6") If .AutoFilterMode Then .AutoFilterMode = False With .Cells(1, 1).CurrentRegion 'grab all of column G (minus the header) into a variant array vVALs = .Resize(.Rows.Count - 1, 1).Offset(1, 6).Value2 'populate the dictionary object with the values that are NOT 101, 102, or 103 For d = LBound(vVALs, 1) To UBound(vVALs, 1) Select Case vVALs(d, 1) Case 101, 102, 103 'do not add Case Else 'not a match, add it to the delete list 'the AutoFilter criteria needs to be text ' so we set the Keys as text and the Items as numbers dDELs.Item(CStr(vVALs(d, 1))) = vVALs(d, 1) End Select Next d 'check to make sure there is something to filter on If CBool(dDELs.Count) Then 'filter on the dictionary keys .AutoFilter field:=7, Criteria1:=dDELs.keys, Operator:=xlFilterValues 'delete the visible rows (there has to be some) .Resize(.Rows.Count - 1, .Columns.Count).Offset(1, 0).EntireRow.Delete End If End With If .AutoFilterMode Then .AutoFilterMode = False End With dDELs.RemoveAll: Set dDELs = Nothing End Sub 

filterNotThree_before
Dati prima della sottotitolazione filterNotThree

filterNotThree_after
Dati dopo la sottoprocedura filterNotThree

Stavo facendo qualcosa di simile ma per due campi e questa syntax ha funzionato per me:

 myrange.AutoFilter Field:=7, Criteria1:="<>101", Operator:=xlAnd, Criteria2:="<>102", Operator:=xlAnd 

Spero che sia d’aiuto.