VBA ArrayList

Cuprins

Un obiect ArrayList este similar cu un obiect Colecție, dar are mult mai multe metode și proprietăți și, prin urmare, o flexibilitate mult mai mare din punct de vedere al programării.

Un obiect Colecție are doar două metode (Adăugare, Eliminare) și două proprietăți (Număr, Element) în timp ce o listă de matrice are multe altele. De asemenea, obiectul Colecție este numai în citire. Odată ce valorile au fost adăugate, valoarea indexată nu poate fi modificată, în timp ce pe o listă de matrice, editarea este posibilă.

Multe dintre metodele Array List folosesc parametri. Spre deosebire de multe dintre metodele standard VBA, niciunul dintre acești parametri nu este opțional. De asemenea, unele dintre metode și proprietăți nu se valorifică întotdeauna atunci când sunt introduse în același mod ca în Excel VBA. Cu toate acestea, ei încă funcționează.

Obiectul ArrayList se extinde și se contractă ca mărime în funcție de câte articole conține. Nu trebuie dimensionat înainte de a fi folosit ca un Array.

Lista de matrice este unidimensională (la fel ca obiectul Colecție) și tipul de date implicit este Variant, ceea ce înseamnă că va accepta orice tip de date, fie că sunt numerice, text sau date.

În multe moduri, lista de matrice abordează o serie de neajunsuri ale obiectului Colecție. Cu siguranță este mult mai flexibil în ceea ce poate face.

Obiectul Array List nu face parte din biblioteca VBA standard. Îl puteți utiliza în codul dvs. Excel VBA utilizând legarea tardivă sau timpurie

1234 Sub LateBindingExample ()Diminuează lista mea ca obiectSetați MyList = CreateObject ("System.Collections.ArrayList")Sfârșitul Sub
123 Sub EarlyBindingExample ()Dim MyList ca nou ArrayListSfârșitul Sub

Pentru a utiliza exemplul de legare timpurie, trebuie mai întâi să introduceți o referință în VBA la fișierul „mscorlib.tlb”

Faceți acest lucru selectând „Instrumente | Referințe ‘din fereastra Visual Basic Editor (VBE). Va apărea o fereastră pop-up cu toate referințele disponibile. Derulați în jos până la „mscorlib.dll” și bifați caseta de lângă acesta. Faceți clic pe OK și biblioteca respectivă face acum parte din proiectul dvs.:

Unul dintre dezavantajele mari ale unui obiect Array List este că nu are „Intellisense”. În mod normal, în cazul în care utilizați un obiect în VBA, cum ar fi un interval, veți vedea o listă pop-up cu toate proprietățile și metodele disponibile. Nu obțineți acest lucru cu un obiect Array List și uneori este nevoie de verificare atentă pentru a vă asigura că ați scris corect metoda sau proprietatea.

De asemenea, dacă apăsați F2 în fereastra VBE și căutați pe „arraylist”, nu va fi afișat nimic, ceea ce nu este foarte util pentru un dezvoltator.

Codul dvs. va rula considerabil mai rapid cu legarea timpurie, deoarece este compilat în față. Cu legarea târzie, obiectul trebuie să fie compilat pe măsură ce rulează codul

Distribuirea aplicației Excel care conține o listă de matrice

După cum sa menționat deja, obiectul ArrayList nu face parte din Excel VBA. Aceasta înseamnă că oricare dintre colegii dvs. la care distribuiți aplicația trebuie să aibă acces la fișierul „mscorlib.tlb”

Acest fișier se află în mod normal în:

C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319

Ar putea merita să scrieți un cod (folosind metoda Dir) pentru a verifica dacă acest fișier există atunci când un utilizator încarcă aplicația, astfel încât să experimenteze o „aterizare ușoară” dacă nu este găsită. Dacă nu este prezent și codul rulează, atunci vor apărea erori.

De asemenea, utilizatorul trebuie să aibă instalată versiunea corectă .Net Framework. Chiar dacă utilizatorul are o versiune ulterioară, V3.5 trebuie instalat altfel aplicația dvs. nu va funcționa

Scopul unui obiect de listă de matrice

În ceea ce privește domeniul de aplicare, obiectul Array List este disponibil numai în timp ce registrul de lucru este deschis. Nu se salvează când este salvat registrul de lucru. Dacă registrul de lucru este redeschis, atunci obiectul Array List trebuie recreat cu ajutorul codului VBA.

Dacă doriți ca lista dvs. de matrice să fie disponibilă pentru tot codul din modulul dvs. de coduri, atunci trebuie să declarați obiectul Lista matrice în secțiunea Declarați din partea de sus a ferestrei modulului.

Acest lucru vă va asigura că tot codul dvs. din acel modul poate accesa lista de matrice. Dacă doriți ca orice modul din registrul dvs. de lucru să acceseze obiectul Array List, atunci definiți-l ca obiect global

1 MyCollection globală ca nouă listă Array

Popularea și citirea din lista dvs. de matrice

Cea mai de bază acțiune pe care doriți să o întreprindeți este să creați o listă de matrice, să puneți niște date în ea și apoi să demonstrați că datele pot fi citite. Toate exemplele de cod din acest articol presupun că utilizați legarea timpurie și ați adăugat „mscorlib.tlb” la referințele VBA, așa cum este descris mai sus

123456789101112 Sub ArrayListExample ()‘Creați un nou obiect de listă de matriceDim MyList ca nou ArrayList‘Adăugați elemente la listăMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3"‘Iterează prin lista de matrice pentru a demonstra valorilePentru N = 0 În lista mea.Count - 1MsgBox MyList (N)Următorul NSfârșitul Sub

Acest exemplu creează un nou obiect ArrayList, îl populează cu 3 elemente, și iterează prin lista care afișează fiecare element.

Rețineți că indexul ArrayList începe de la 0, nu de 1, deci trebuie să scădeți 1 din valoarea Count

De asemenea, puteți utiliza o buclă „Pentru… Fiecare” pentru a citi valorile:

123456789101112 Sub ArrayListExample ()‘Creați un nou obiect listă matriceDim MyList ca nou ArrayList‘Adăugați elemente la listăMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3"‘Iterează prin lista de matrice pentru a demonstra valorilePentru fiecare I din lista meaMsgBox I.Apoi euSfârșitul Sub

Editarea și modificarea elementelor dintr-o listă de matrice

Un avantaj major al unei liste de matrice față de o colecție este că articolele din listă pot fi editate și modificate în codul dvs. Obiectul Colecție este citit numai în timp ce obiectul Array List este citit / scris

123456789101112131415 Sub ArrayListExample ()‘Creați un nou obiect de listă de matriceDim MyList ca nou ArrayList‘Adăugați elemente la listăMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3"„Schimbați articolul 1 din„ Element2 ”în„ Modificat ”MyList (1) = "Modificat"‘Iterează prin lista de matrice pentru a dovedi că schimbarea a funcționatPentru fiecare I din Lista mea‘Afișați numele articoluluiMsgBox I.Apoi euSfârșitul Sub

În acest exemplu, al doilea element, „Item2” este modificat la valoarea „Modificat” (rețineți că indexul începe de la 0). Când iterația este executată la sfârșitul codului, va fi afișată noua valoare

Adăugarea unei matrice de valori la o listă de matrice

Puteți introduce valori în lista dvs. de matrice utilizând o matrice care conține o listă a acestor valori sau referințe la valorile celulei dintr-o foaie de lucru

123456789101112131415161718 Sub AddArrayExample ()‘Creați obiectul listei ArrayDim MyList ca nou ArrayList‘Iterați prin valorile matricei adăugându-le la lista matricelorPentru fiecare v În matrice („A1”, „A2”, „A3”)‘Adăugați fiecare listă de valori la listăMyList.Add vUrmătorul‘Iterați prin valorile matricei cu referințe de foaie de lucru adăugându-le la lista matriceiPentru fiecare matrice v In (Range ("A5"). Valoare, Range ("A6"). Value)MyList.Add vUrmătorul‘Iterează prin lista de matrice pentru a demonstra valorilePentru N = 0 În lista mea.Count - 1‘Afișați elementul listeiMsgBox MyList.Item (N)Următorul NSfârșitul Sub

Citirea / preluarea unei game de articole dintr-o listă de matrice

Utilizând metoda GetRange pe o listă de matrice, puteți specifica o furie de articole consecutive care trebuie recuperate. Cei doi parametri necesari sunt poziția indexului inițial și numărul de elemente care trebuie recuperate. Codul completează un al doilea obiect Array List cu subsetul de articole care pot fi apoi citite separat.

123456789101112131415161718 Sub ReadRangeExample ()‘Definiți obiecteDim MyList Ca nou ArrayList, MyList1 ca obiect„Adăugați elemente la obiectul„ Lista mea ”MyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3"MyList.Add "Item6"MyList.Add "Item4"MyList.Add "Item7"„Capturați 4 articole din„ Lista mea ”începând cu poziția indexului 2Setați MyList1 = MyList.GetRange (2, 4)„Iterează prin obiectul„ Lista mea 1 ”pentru a afișa subsetul de articolePentru fiecare I din Lista mea1‘Afișați numele articoluluiMsgBox I.Apoi euSfârșitul Sub

Căutarea articolelor dintr-o listă de matrice

Puteți testa dacă un element numit se află în lista dvs. utilizând metoda „Conține”. Acest lucru va readuce adevărat sau fals

1 MsgBox MyList.Contains („Item2”)

De asemenea, puteți găsi poziția reală a indexului utilizând metoda „IndexOf”. Trebuie să specificați indexul de început pentru căutare (de obicei 0). Valoarea returnată este indicele primei instanțe a elementului găsit. Puteți utiliza apoi o buclă pentru a schimba punctul de plecare la următoarea valoare a indexului pentru a găsi instanțe suplimentare dacă există mai multe valori duplicat.

Dacă valoarea nu este găsită, atunci se returnează o valoare -1

Acest exemplu demonstrează utilizarea „Conține”, elementul nu a fost găsit și parcurgerea listei matrice pentru a găsi poziția tuturor elementelor duplicate:

1234567891011121314151617181920212223242526 Sub SearchListExample ()‘Definiți lista matricelor și variabileleDim MyList Ca nou ArrayList, Sp Ca Integer, Pos As Integer‘Adăugați elemente noi, inclusiv un duplicatMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3"MyList.Add "Item1"‘Testul pentru„ Item2 ”aflat în listă - returnează TrueMsgBox MyList.Contains („Item2”)‘Obțineți un indice de valoare inexistentă - returnează -1MsgBox MyList.IndexOf („Articol”, 0)‘Setați poziția de pornire pentru căutare la zeroSp = 0‘Iterează prin listă pentru a obține toate pozițiile‘ Elementului 1 ’Do„Obțineți poziția index a următorului„ Item1 ”pe baza poziției din variabila„ Sp ”Pos = MyList.IndexOf ("Item1", Sp)„Dacă nu se găsesc alte instanțe de„ Item1 ”, ieșiți din buclăDacă Pos = -1, apoi ieșiți din Do‘Afișați următoarea instanță găsită și poziția indexuluiMsgBox MyList (Pos) & "la index" & Pos‘Adăugați 1 la ultima valoare a indexului găsit - aceasta devine acum noua poziție de început pentru următoarea căutareSp = Pos + 1BuclăSfârșitul Sub

Rețineți că textul de căutare utilizat este sensibil la majuscule și minuscule și nu sunt acceptate cardurile wild.

Introducerea și eliminarea articolelor

Dacă nu doriți să adăugați articolele la sfârșitul listei, le puteți insera într-o anumită poziție de index, astfel încât noul articol să fie în mijlocul listei. Numerele index vor fi ajustate automat pentru articolele următoare.

123456789101112131415 Sub InsertExample ()‘Definiți obiectul listei matriceDim MyList ca nou ArrayList‘Adăugați elemente la lista de matriceMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3"MyList.Add "Item1"„Introduceți„ Item6 ”în poziția index 2MyList.Insert 2, „Item6”‘Iterează prin elementele din lista de matrice pentru a afișa o nouă ordine și poziția indexuluiPentru N = 0 În lista mea.Count - 1MsgBox MyList (N) & "Index" & NUrmătorul NSfârșitul Sub

În acest exemplu, „Item6” este adăugat în listă la poziția index 2, astfel încât „item3” care se afla la poziția index 2 trece acum la poziția index 3

Un articol individual poate fi eliminat folosind metoda „Eliminați”.

1 MyList.Eliminați „Elementul”

Rețineți că nu se produce nicio eroare dacă nu se găsește numele articolului. Toate numerele de index ulterioare vor fi modificate pentru a se potrivi eliminării.

Dacă cunoașteți poziția index a articolului, puteți utiliza metoda „RemoveAt”, de ex.

1 MyList.RemoveAt 2

Rețineți că, dacă poziția indică dată este mai mare decât numărul de articole din lista matrice, atunci va fi returnată o eroare.

Puteți elimina o serie de valori din listă utilizând metoda „RemoveRange”. Parametrii sunt indicele de pornire și apoi numărul de articole de eliminat de ex.

1 MyList.RemoveRange 3, 2

Rețineți că veți primi o eroare în codul dvs. dacă numărul de articole decalate de la valoarea de pornire este mai mare decât numărul de articole din lista de matrice.

Atât în ​​metodele „RemoveAt”, cât și în „RemoveRange”, un anumit cod ar fi recomandabil pentru a verifica dacă numerele de index specificate sunt mai mari decât numărul total de articole din lista matricii, pentru a surprinde eventualele erori. Proprietatea „Numără” va indica numărul total de articole din lista de matrice.

12345678910111213141516171819202122232425 Sub RemoveExample ()‘Definiți obiectul listei matriceDim MyList ca nou ArrayList‘Adăugați elemente la lista de matriceMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3"MyList.Add "Item1"MyList.Add "Item4"MyList.Add "Item5"„Introduceți„ Item6 ”în poziția 2 a indexuluiMyList.Insert 2, „Item6”„Eliminați„ Item2 ”MyList.Eliminați „Item2”„Eliminați„ Element ”- acest lucru nu există în lista de matrice, dar nu eroareMyList.Eliminați „Elementul”‘Eliminați elementul în poziția index 2MyList.RemoveAt 2‘Eliminați 2 articole consecutive începând de la poziția 2 a indexuluiMyList.RemoveRange 3, 2‘Iterează prin lista de matrice pentru a arăta ce a rămas și în ce poziție de index se află acumPentru N = 0 În lista mea.Count - 1MsgBox MyList (N) & "Index" & NUrmătorul NSfârșitul Sub

Rețineți că, dacă utilizați „RemoveAt” pentru a elimina un articol într-o anumită poziție, de îndată ce elementul respectiv este eliminat, toate pozițiile indexului ulterioare sunt modificate. Dacă aveți mai multe eliminări folosind poziția indexului, atunci o idee bună este să începeți cu cel mai mare număr index și să faceți un pas înapoi în jos până la poziția zero, astfel încât să eliminați întotdeauna elementul corect. În acest fel nu veți avea problema

Sortarea unei liste de matrice

Un alt mare avantaj față de o colecție este că puteți sorta articolele în ordine crescătoare sau descendentă.

Obiectul Array List este singurul obiect din Excel VBA cu o metodă de sortare. Metoda de sortare este foarte rapidă și aceasta poate fi o considerație importantă pentru utilizarea unei Array List.

În obiectul de colecție, a fost necesară o gândire „din cutie” pentru a sorta toate articolele, dar cu o listă de matrice, este foarte simplu.

Metoda „Sortare” sortează în ordine crescătoare, iar metoda „Reverse” sortează în ordine descrescătoare.

12345678910111213141516171819202122 Sub ArrayListExample ()‘Creați obiectul Array ListDim MyList ca nou ArrayList‘Adăugați articole într-o ordine ne-sortatăMyList.Add "Item1"MyList.Add "Item3"MyList.Add "Item2"‘Sortați articolele în ordine crescătoareMyList.Sort‘Iterează articolele pentru a afișa ordinea crescătoarePentru fiecare I din Lista mea‘Afișați numele articoluluiMsgBox I.Apoi eu‘Sortați articolele în ordine descrescătoareMyList.Reverse‘Repetați articolele pentru a afișa ordinea descendentăPentru fiecare I din Lista mea‘Afișați numele articoluluiMsgBox I.Apoi euSfârșitul Sub

Clonarea unei liste de matrice

O listă de matrice are posibilitatea de a crea o clonă sau o copie a sa. Acest lucru este util dacă un utilizator modifică articolele folosind un front-end și codul dvs. VBA, dar trebuie să păstrați o copie a articolelor în starea lor originală ca o copie de rezervă.

Acest lucru ar putea oferi utilizatorului o caracteristică „Anulare”. Este posibil să fi făcut modificările și doresc să revină la lista originală.

123456789101112131415 Sub CloneExample ()‘Definiți două obiecte - lista de matrice și un obiectDim MyList Ca nou ArrayList, MyList1 ca obiect‘Populați primul obiect cu elementeMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3"‘Copiază Mylist în MyList1Setați MyList1 = MyList.Clone‘Iterează prin MyList1 pentru a dovedi clonareaPentru fiecare I din Lista mea1‘Afișați numele articoluluiMsgBox I.Apoi euSfârșitul Sub

„MyList1” conține acum toate articolele din „MyList” în aceeași ordine

Copierea unei matrice de liste într-un obiect matricial VBA convențional

Puteți utiliza o metodă simplă pentru a copia lista de matrice într-o matrice VBA normală:

123456789101112131415 Sub ArrayExample ()‘Creați un obiect listă matrice și un obiect matrice standardDim MyList as New ArrayList, NewArray as Variant‘Completați lista de matrice cu elementeMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3"‘Copiați lista de matrice în noua matriceNewArray = MyList.ToArray‘Iterează prin noua matrice - rețineți că numărul de liste de matrice oferă indicele maximPentru N = 0 În lista mea.Count - 1‘Afișați numele articoluluiMsgBox NewArray (N)Următorul NSfârșitul Sub

Copierea unei matrice de liste într-un interval de foi de lucru

Puteți copia lista de matrice într-o anumită foaie de lucru și referință de celulă fără a fi nevoie să iterați prin lista de matrice. Trebuie doar să specificați prima referință de celulă

123456789101112131415 Sub RangeExample ()‘Creați un nou obiect de listă de matriceDim MyList ca nou ArrayList‘Adăugați elemente la listăMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3"‘Ștergeți foaia țintăFoi („Sheet1”). UsedRange.Clear‘Copiați elementele pe un rândFoi de calcul („Sheet1”). Range („A1”). Redimensionare (1, MyList.Count) .Value = MyList.toArray‘Copiați elementele într-o coloanăFoi de calcul („Sheet1”). Interval („A5”). Redimensionare (Lista mea.Count, 1) .Value = _WorksheetFunction.Transpose (MyList.toArray)Sfârșitul Sub

Goliți toate articolele dintr-o listă de matrice

Există o funcție simplă (Clear) pentru a șterge complet lista de matrice

1234567891011121314 Sub ClearListExample ()‘Creați un obiect listă matriceDim MyList ca nou ArrayList‘Adăugați elemente noiMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3"‘Afișează numărul de articoleMsgBox MyList.Count‘Ștergeți toate articoleleMyList.Clar‘Afișați numărul de articole pentru a demonstra că a funcționat clarMsgBox MyList.CountSfârșitul Sub

Acest exemplu creează elemente într-o listă de matrice și apoi șterge lista de matrice. Casetele de mesaje se dovedesc înainte și după numărul de articole din lista matrice.

Rezumatul metodelor listei de matrice pentru Excel VBA

Sarcină Parametrii Exemple
Adăugați / Editați element Valoare MyList.Add „Item1”
MyList (4) = „Item2”
Clonați o listă de matrice Nici unul Diminuează lista mea ca obiect
Setați MyList2 = MyList.Clone
Copiați în matrice Nici unul Dim MyArray Ca Variant
MyArray = MyList.ToArray
Copiați într-un interval de foi de lucru (rând) Nici unul Foi de calcul („Sheet1”). Range („A1”). Redimensionare (1, MyList.Count) .Value = MyList.ToArray
Copiați într-un interval de foi de lucru (coloană) Nici unul Foi („Sheet1”). Range („A3”). Redimensionare (MyList.Count, 1) .Value = WorksheetFunction.Transpose (MyList.ToArray)
Crea „System.Collections.ArrayList” Diminuează lista mea ca obiect
Setați MyList = CreateObject („System.Collections.ArrayList”)
Declara N / A Diminuează lista mea ca obiect
Găsiți / verificați dacă există un element Element de găsit MyList.Contains („Item2”)
Găsiți poziția unui articol în ArrayList 1. Element de găsit. Dim Index Nu atât de lung
2. Poziție pentru a începe căutarea. IndexNo = MyList.IndexOf („Item3”, 0)
IndexNo = MyList.IndexOf („Item5”, 3)
Obțineți un număr de articole Nici unul MsgBox MyList.Count
Introduceți elementul 1. Index - poziția de inserat la. MyList.Insert 0, „Item5”
2 Valoare - obiect sau valoare de inserat. MyList.Insert 4, „Item7”
Citiți articolul Index - număr întreg lung MsgBox MyList.Item (0)
MsgBox MyList.Item (4)
Citiți articolul adăugat ultima dată Index - număr întreg lung MsgBox MyList.Item (list.Count - 1)
Citiți elementul adăugat mai întâi Index - număr întreg lung MsgBox MyList.Item (0)
Citiți toate articolele (pentru fiecare) N / A Dim element Ca variantă
Pentru fiecare element din MyList
Element MsgBox
Următorul element
Citiți toate articolele (pentru) Index - număr întreg lung Dim i As Long
For i = 0 To MyList.Count - 1
MsgBox i
Apoi eu
Eliminați toate articolele Nici unul MyList.Clar
Scoateți elementul în poziție Poziția indexului în care se află elementul MyList.RemoveAt 5
Eliminați articolul după nume Elementul de eliminat din ArrayList MyList.Eliminați „Item3”
Eliminați o gamă de articole 1. Index - poziția inițială. MyList.RemoveRange 4,3
2. Numărați - numărul de articole de eliminat.
Sortați în ordine descrescătoare Nici unul MyList.Reverse
Sortați în ordine crescătoare Non MyList.Sort
wave wave wave wave wave