Ett ArrayList -objekt liknar ett samlingsobjekt men det har mycket fler metoder och egenskaper, och därför en mycket större flexibilitet ur programmeringssynpunkt.
Ett samlingsobjekt har bara två metoder (Lägg till, ta bort) och två egenskaper (räkna, objekt) medan en matrislista har många fler. Samlingsobjektet är också skrivskyddat. När värden har lagts till kan det indexerade värdet inte ändras, medan redigering på en matrillista är möjlig.
Många av Array List -metoderna använder parametrar. Till skillnad från många av de vanliga VBA -metoderna är ingen av dessa parametrar valfria. Några av metoderna och egenskaperna aktiveras inte alltid när de anges på samma sätt som de gör i Excel VBA. De fungerar dock fortfarande.
ArrayList -objektet expanderar och dras ihop i storlek beroende på hur många objekt det innehåller. Det behöver inte dimensioneras före användning som en matris.
Arraylistan är endimensionell (samma som samlingsobjektet) och standarddatatypen är Variant, vilket innebär att den accepterar alla typer av data, oavsett om det är numeriskt, text eller datum.
På många sätt tar Array List upp ett antal brister i Collection -objektet. Det är verkligen mycket mer flexibelt vad det kan göra.
Array List -objektet är inte en del av det vanliga VBA -biblioteket. Du kan använda den i din Excel VBA -kod genom att använda sen eller tidig bindning
1234 | Sub LateBindingExample ()Dim MyList som objektStäll in MyList = CreateObject ("System.Collections.ArrayList")Avsluta Sub |
123 | Sub EarlyBindingExample ()Dim MyList As New ArrayListAvsluta Sub |
För att använda det tidiga bindningsexemplet måste du först ange en referens i VBA till filen ‘mscorlib.tlb’
Du gör detta genom att välja "Verktyg | Referenser från fönstret Visual Basic Editor (VBE). Ett popup-fönster visas med alla tillgängliga referenser. Rulla ner till ‘mscorlib.dll’ och markera rutan bredvid. Klicka på OK och biblioteket är nu en del av ditt projekt:
En av de stora nackdelarna med ett Array List -objekt är att det inte har "Intellisense". Normalt, där du använder ett objekt i VBA som ett intervall, kommer du att se en popup-lista med alla tillgängliga egenskaper och metoder. Du får inte detta med ett Array List -objekt, och det krävs ibland noggrann kontroll för att se till att du har stavat metoden eller egenskapen korrekt.
Om du också trycker på F2 i VBE -fönstret och söker på "arraylist", kommer ingenting att visas, vilket inte är till stor hjälp för en utvecklare.
Din kod körs betydligt snabbare med tidig bindning, eftersom den är sammanställd på förhand. Med sen bindning måste objektet kompileras när koden körs
Distribuera din Excel -applikation som innehåller en matrislista
Som redan påpekats är ArrayList -objektet inte en del av Excel VBA. Det betyder att alla dina kollegor som du distribuerar applikationen till måste ha åtkomst till filen ‘mscorlib.tlb’
Denna fil finns normalt i:
C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319
Det kan vara värt att skriva en kod (med Dir -metoden) för att kontrollera att den här filen finns när en användare laddar programmet så att de upplever en "mjuk landning" om de inte hittas. Om den inte finns och koden körs kommer det att uppstå fel.
Användaren måste också ha rätt .Net Framework -version installerad. Även om användaren har en senare version måste V3.5 installeras annars fungerar din applikation inte
Räckvidd för ett Array List -objekt
När det gäller omfattning är objektet Array List bara tillgängligt medan arbetsboken är öppen. Det sparas inte när arbetsboken sparas. Om arbetsboken öppnas igen måste Array List-objektet återskapas med VBA-kod.
Om du vill att din Array List ska vara tillgänglig för all kod i din kodmodul, måste du deklarera Array List -objektet i Declare -avsnittet högst upp i modulfönstret
Detta säkerställer att all din kod inom den modulen kan komma åt Array List. Om du vill att någon modul i din arbetsbok ska komma åt objektet Array List definierar du det som ett globalt objekt
1 | Global MyCollection Som New ArrayList |
Befolkning och läsning från din matrislista
Den mest grundläggande åtgärden du vill vidta är att skapa en matrislista, lägga in lite data i den och sedan bevisa att data kan läsas. Alla kodexempel i den här artikeln förutsätter att du använder tidig bindning och har lagt till 'mscorlib.tlb' till VBA -referenserna, enligt beskrivningen ovan
123456789101112 | Sub ArrayListExample ()"Skapa ett nytt arraylistobjektDim MyList As New ArrayList"Lägg till objekt i listanMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3""Upprepa genom matrislista för att bevisa värdenFör N = 0 till MyList.Count - 1MsgBox MyList (N)Nästa NAvsluta Sub |
I det här exemplet skapas ett nytt ArrayList -objekt, det fylls med tre objekt och det upprepas genom listan som visar varje objekt.
Observera att ArrayList -indexet börjar med 0, inte 1, så du måste subtrahera 1 från Count -värdet
Du kan också använda en "För … Varje" slinga för att läsa värdena:
123456789101112 | Sub ArrayListExample ()"Skapa ett nytt arraylistobjektDim MyList As New ArrayList"Lägg till objekt i listanMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3""Upprepa genom matrislista för att bevisa värdenFör varje I In MyListMsgBox INästa jagAvsluta Sub |
Redigera och ändra objekt i en matrislista
En stor fördel med en matrillista framför en samling är att objekten i listan kan redigeras och ändras i din kod. Samlingsobjektet är skrivskyddat medan objektet Array List läses / skrivs
123456789101112131415 | Sub ArrayListExample ()"Skapa ett nytt arraylistobjektDim MyList As New ArrayList"Lägg till objekt i listanMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3""Ändra artikel 1 från" Artikel2 "till" Ändrad "MyList (1) = "Ändrad""Upprepa genom matrislista för att bevisa att förändringen fungeradeFör varje I In MyList"Visa objektnamnMsgBox INästa jagAvsluta Sub |
I det här exemplet ändras det andra objektet "Artikel2" till värdet "Ändrat" (kom ihåg att indexet börjar med 0). När iterationen körs i slutet av koden kommer det nya värdet att visas
Lägga till en array med värden till en matrislista
Du kan ange värden i din Array List med hjälp av en array som innehåller en lista över dessa värden eller referenser till cellvärden i ett kalkylblad
123456789101112131415161718 | Sub AddArrayExample ()‘Skapa Array list -objektDim MyList As New ArrayList'Iterera genom matrisvärden och lägga till dem i matarlistanFör varje v i matris ("A1", "A2", "A3")"Lägg till varje arrayvärde i listanMyList.Add vNästa'Iterera genom matrisvärden med kalkylbladshänvisningar som lägger till dem i matarlistanFör varje v i matris (intervall ("A5"). Värde, intervall ("A6"). Värde)MyList.Add vNästa"Upprepa genom matrislista för att bevisa värdenFör N = 0 till MyList.Count - 1"Visa listobjektMsgBox MyList.Item (N)Nästa NAvsluta Sub |
Läsa / hämta en rad objekt från en matrislista
Genom att använda GetRange -metoden på en Array List kan du ange ett ilska av på varandra följande objekt som ska hämtas. De två parametrar som krävs är startindexpositionen och antalet objekt som ska hämtas. Koden fyller i ett andra Array List -objekt med delmängden objekt som sedan kan läsas separat.
123456789101112131415161718 | Sub ReadRangeExample ()"Definiera objektDim MyList As New ArrayList, MyList1 As Object"Lägg till objekt i objektet" MyList "MyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3"MyList.Add "Item6"MyList.Add "Item4"MyList.Add "Item7""Fånga 4 objekt i" MyList "från indexposition 2Ange MyList1 = MyList.GetRange (2, 4)"Iterera genom objektet" MyList1 "för att visa underuppsättningen med objektFör varje I In MyList1"Visa objektnamnMsgBox INästa jagAvsluta Sub |
Söka efter objekt inom en matrislista
Du kan testa om ett namngivet objekt finns i din lista med metoden "Innehåller". Detta returnerar True eller False
1 | MsgBox MyList.Contains ("Item2") |
Du kan också hitta den faktiska indexpositionen genom att använda 'IndexOf' -metoden. Du måste ange startindex för sökningen (vanligtvis 0). Returvärdet är indexet för den första instansen av det hittade objektet. Du kan sedan använda en loop för att ändra startpunkten till nästa indexvärde för att hitta fler instanser om det finns flera dubblettvärden.
Om värdet inte hittas returneras värdet -1
Det här exemplet visar att du använder "Innehåller", objekt som inte hittats och går igenom matrislistan för att hitta positionen för alla dubblettobjekt:
1234567891011121314151617181920212223242526 | Sub SearchListExample ()"Definiera matrislista och variablerDim MyList As New ArrayList, Sp As Integer, Pos As Integer"Lägg till nya objekt inklusive en kopiaMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3"MyList.Add "Item1""Test för att" Item2 "finns i listan - returnerar TrueMsgBox MyList.Contains ("Item2")"Få index för obefintligt värde -avkastning -1MsgBox MyList.IndexOf ("Artikel", 0)'Ställ in startpositionen för sökningen till nollSp = 0"Upprepa listan för att få alla positioner för" Artikel1 "Do"Få indexpositionen för nästa" Item1 "baserat på positionen i variabeln" Sp "Pos = MyList.IndexOf ("Item1", Sp)"Om inga ytterligare förekomster av" Item1 "hittas lämnar du slinganOm Pos = -1 Avsluta Do"Visa nästa instans som hittats och indexpositionenMsgBox MyList (Pos) & "vid index" & Pos"Lägg till 1 till det senast hittade indexvärdet - detta blir nu den nya startpositionen för nästa sökningSp = Pos + 1SlingaAvsluta Sub |
Observera att söktexten som används är skiftlägeskänslig och jokertecken inte accepteras.
Infoga och ta bort objekt
Om du inte vill lägga till dina objekt i slutet av listan kan du infoga dem på en viss indexposition så att det nya objektet är mitt i listan. Indexnumren justeras automatiskt för de följande artiklarna.
123456789101112131415 | Sub InsertExample ()"Definiera array -listobjektDim MyList As New ArrayList"Lägg till objekt i matarlistanMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3"MyList.Add "Item1""Sätt in" Artikel 6 "på indexposition 2MyList.Insert 2, "Item6""Upprepa objekt i array -listan för att visa ny ordning och indexpositionFör N = 0 till MyList.Count - 1MsgBox MyList (N) & "Index" & NNästa NAvsluta Sub |
I det här exemplet läggs "Item6" till i listan vid indexposition 2, så "item3" som var på indexposition 2 flyttar nu till indexposition 3
Ett enskilt objekt kan tas bort med hjälp av "Ta bort" -metoden.
1 | MyList.Remove "Item" |
Observera att det inte uppstår något fel om artikelnamnet inte hittas. Alla efterföljande indexnummer kommer att ändras för att passa borttagningen.
Om du känner till objektets indexposition kan du använda metoden ‘RemoveAt’ t.ex.
1 | MyList.RemoveAt 2 |
Observera att om den angivna indexpositionen är större än antalet objekt i matarlistan kommer ett fel att returneras.
Du kan ta bort en rad värden från listan med hjälp av metoden ‘RemoveRange’. Parametrarna är startindex och sedan antalet objekt som ska tas bort t.ex.
1 | MyList.RemoveRange 3, 2 |
Observera att du får ett fel i din kod om antalet objekt som förskjutits från startvärdet är större än antalet objekt i matarlistan.
I både "RemoveAt" och "RemoveRange" -metoderna skulle någon kod vara tillrådligt för att kontrollera om de angivna indexnumren är större än det totala antalet objekt i matrislistan för att fånga eventuella fel. Egenskapen 'Count' ger det totala antalet objekt i matarlistan.
12345678910111213141516171819202122232425 | Sub RemoveExample ()"Definiera array -listobjektDim MyList As New ArrayList"Lägg till objekt i matrislistanMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3"MyList.Add "Item1"MyList.Add "Item4"MyList.Add "Item5""Sätt in" Artikel 6 "på indexposition 2MyList.Insert 2, "Item6""Ta bort" Item2 "MyList.Remove "Item2""Ta bort" artikel " - det finns inte i matarlistan men det är inget felMyList.Remove "Item"'Ta bort objektet på indexposition 2MyList.RemoveAt 2"Ta bort två på varandra följande artiklar från indexposition 2MyList.RemoveRange 3, 2"Gå igenom matrislistan för att visa vad som är kvar och vilken indexposition den nu befinner sig iFör N = 0 till MyList.Count - 1MsgBox MyList (N) & "Index" & NNästa NAvsluta Sub |
Observera att om du använder ‘RemoveAt’ för att ta bort ett objekt på en specifik position, så ändras alla efterföljande indexpositioner så snart objektet tas bort. Om du har flera borttagningar som använder indexpositionen är det en bra idé att börja med det högsta indexnumret och gå bakåt till position noll så att du alltid kommer att ta bort rätt objekt. På detta sätt kommer du inte att ha problemet
Sortera en matrislista
En annan stor fördel jämfört med en samling är att du kan sortera föremålen i stigande eller fallande ordning.
Array List -objektet är det enda objektet i Excel VBA med en sorteringsmetod. Sorteringsmetoden är mycket snabb och detta kan vara en viktig faktor för att använda en matrislista.
I samlingsobjektet krävdes lite "out of the box" -tänkande för att sortera alla objekt, men med en matrislista är det väldigt enkelt.
Metoden "Sortera" sorterar i stigande ordning och "Omvänd" -metoden sorterar i fallande ordning.
12345678910111213141516171819202122 | Sub ArrayListExample ()‘Skapa Array List -objektDim MyList As New ArrayList"Lägg till objekt i en icke-sorterad ordningMyList.Add "Item1"MyList.Add "Item3"MyList.Add "Item2"’Sortera objekten i stigande ordningMyList.Sort"Återgå genom objekten för att visa stigande ordningFör varje I In MyList"Visa objektnamnMsgBox INästa jag’Sortera objekten i fallande ordningMyList.Omvänd"Återgå genom objekten för att visa fallande ordningFör varje I In MyList"Visa objektnamnMsgBox INästa jagAvsluta Sub |
Kloning av en matrislista
En matrislista har möjlighet att skapa en klon eller kopia av sig själv. Detta är användbart om en användare gör ändringar i objekten med hjälp av en frontend och din VBA -kod, men du måste behålla en kopia av objekten i sitt ursprungliga tillstånd som en säkerhetskopia.
Detta kan ge användaren en "Ångra" -funktion. De kan ha gjort ändringarna och vill återgå till den ursprungliga listan.
123456789101112131415 | Sub CloneExample ()"Definiera två objekt - matrislista och ett objektDim MyList As New ArrayList, MyList1 As Object"Fyll i det första objektet med objektMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3"‘Kopiera Mylist till MyList1Ställ in MyList1 = MyList.Clone'Iterera genom MyList1 för att bevisa kloningFör varje I In MyList1"Visa objektnamnMsgBox INästa jagAvsluta Sub |
"MyList1" innehåller nu alla objekt från "MyList" i samma ordning
Kopiera en listmatris till ett konventionellt VBA -arrayobjekt
Du kan använda en enkel metod för att kopiera arraylistan till en vanlig VBA -array:
123456789101112131415 | Sub ArrayExample ()'Skapa matrislistaobjekt och ett standardmatrisobjektDim MyList As New ArrayList, NewArray As Variant"Fyll i matarlista med objektMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3"'Kopiera matrislistan till den nya matrisenNewArray = MyList.ToArray'Iterera genom den nya matrisen - notera att antalet matarlistor ger det maximala indexetFör N = 0 till MyList.Count - 1"Visa objektnamnMsgBox NewArray (N)Nästa NAvsluta Sub |
Kopiera en listmatris till ett arbetsbladsområde
Du kan kopiera din array -lista till ett specifikt kalkylblad och cellreferens utan att behöva iterera genom array -listan. Du behöver bara ange den första cellreferensen
123456789101112131415 | DelområdeExempel ()"Skapa ett nytt arraylistobjektDim MyList As New ArrayList"Lägg till objekt i listanMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3"'Rensa målbladetSheets ("Sheet1"). UsedRange.Clear"Kopiera objekt över en radArk ("Ark1"). Område ("A1"). Ändra storlek (1, MyList.Count) .Value = MyList.toArray"Kopiera objekt ner i en kolumnSheets ("Sheet1"). Range ("A5"). Ändra storlek (MyList.Count, 1) .Value = _WorksheetFunction.Transpose (MyList.toArray)Avsluta Sub |
Töm alla objekt från en matrislista
Det finns en enkel funktion (Clear) för att rensa arraylistan helt
1234567891011121314 | Sub ClearListExample ()'Skapa matrislistaobjektDim MyList As New ArrayList"Lägg till nya objektMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3""Visa antal objektMsgBox MyList.Count"Rensa alla objektMyList.Clear"Visa antal artiklar för att bevisa att klart har fungeratMsgBox MyList.CountAvsluta Sub |
Detta exempel skapar objekt i en matrislista och rensar sedan matrislistan. Meddelandefält bevisar före och efter antalet objekt i matarlistan.
Array List Methods Summary för Excel VBA
Uppgift | Parametrar | Exempel |
Lägg till / redigera objekt | Värde | MyList.Lägg till "Item1" |
MyList (4) = “Item2” | ||
Klona en matrislista | Ingen | Dim MyList som objekt |
Ställ in MyList2 = MyList.Clone | ||
Kopiera till Array | Ingen | Dim MyArray som variant |
MyArray = MyList.ToArray | ||
Kopiera till ett kalkylblad (rad) | Ingen | Ark ("Ark1"). Omfång ("A1"). Ändra storlek (1, MyList.Count) .Value = MyList.ToArray |
Kopiera till ett kalkylblad (kolumn) | Ingen | Ark ("Ark1"). Omfång ("A3"). Ändra storlek (MyList.Count, 1) .Value = WorksheetFunction.Transpose (MyList.ToArray) |
Skapa | "System.Collections.ArrayList" | Dim MyList som objekt |
Ställ in MyList = CreateObject (“System.Collections.ArrayList”) | ||
Deklarera | Ej tillgängligt | Dim MyList som objekt |
Hitta / kontrollera om objektet finns | Objekt att hitta | MyList.Contains (“Item2”) |
Hitta positionen för ett objekt i ArrayList | 1. Objekt att hitta. | Dim IndexNo As Long |
2. Position att börja söka från. | IndexNo = MyList.IndexOf (“Item3”, 0) | |
IndexNo = MyList.IndexOf (“Item5”, 3) | ||
Få antal objekt | Ingen | MsgBox MyList.Count |
Infoga objekt | 1. Index - position att infoga vid. | MyList.Insert 0, “Item5” |
2 Värde - objekt eller värde att infoga. | MyList.Insert 4, “Item7” | |
Läs objektet | Index - långt heltal | MsgBox MyList.Item (0) |
MsgBox MyList.Item (4) | ||
Läs artikeln tillagd senast | Index - långt heltal | MsgBox MyList.Item (list.Count - 1) |
Läs objektet tillagt först | Index - långt heltal | MsgBox MyList.Item (0) |
Läs alla artiklar (för varje) | Ej tillgängligt | Dim element Som variant |
För varje element i MyList | ||
MsgBox -element | ||
Nästa element | ||
Läs alla artiklar (för) | Index - långt heltal | Dim i As Long |
För i = 0 Till MyList.Count - 1 | ||
MsgBox i | ||
Nästa i | ||
Ta bort alla objekt | Ingen | MyList.Clear |
Ta bort objektet på position | Indexposition där objektet är | MyList.RemoveAt 5 |
Ta bort objektet med namn | Objektet som ska tas bort från ArrayList | MyList.Ta bort "Item3" |
Ta bort en rad artiklar | 1. Index - startposition. | MyList.RemoveRange 4,3 |
2. Räkna - antalet objekt som ska tas bort. | ||
Sortera i fallande ordning | Ingen | MyList.Omvänd |
Sortera i stigande ordning | Icke | MyList.Sort |