VBA ArrayList

Innehållsförteckning

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
wave wave wave wave wave