Søger du en specifik kategori?

 



Oprettet tir. d. 03. februar 2009 kl. 00:42

bak
bak (94.635 point)
Guidens karaktér
1
2
3
4
5

Ekstra hastighed med array’s i Excel-VBA

Brugen af arrays til indlæsning af og skrivning til celler i Excel kan give betragtelige hastighedsforøgelser af VBA-koder med en relativ lille indsats.
Ekstra hastighed med array's i Excel-VBA

Mange koder i excel består af et loop gennem er mængde celler. Dette bruges ofte til at søge gennem cellerne eller lave diverse ændringer. Dette virker også fint normalt på mindre områder. Når området bliver større begynder koden at blive langsom pga. de mange læsninger og skrivninger. Selve det, man laver i loopet, er sjældent langsom. Den store tidsrøver i den forbindelse er at skrive til regnearket. Indlæsning er normalt relativ hurtigt.

At løbe et array igennem går derimod meget hurtigt. Ideen går derfor ud på at læse alle cellerne ind i et array på én gang, gennemløbe loopet og skrive hele arrayet tilbage til regnearket i et hug..

Der er i princippet flere slags array's der kan bruges, men de fælles for dem er at det kun er én- og todimensionelle, der umiddelbart kan bruges. 

Én-dimensionelle arrays
Kunne være et eget defineret array som fx:
MyArray = Array("Jan", "Feb", "Mar", "Apr", "Maj", "Jun")

For at skrive dette array til et regneark kan man bruge standardmetoden

MyArray = Array("Jan", "Feb", "Mar", "Apr", "Maj", "Jun")
For x = 0 to 5
    Cells(1,x+1) = MyArray(x)
Next



Dette giver 6 skrivninger til arket
Et alternativ er at skrive alle på én gang.


Range("A1:F1") = MyArray


Skal de skrives I en kolonne istedet skal vi lige have dem vendt engang. Dette kunne gøres i loopet men lidt enklere således:

Range("A1:A6") = Application.Transpose(MyArray)


To-dimensionelle arrays:
For at hente data fra et regneark er det nemmest at bruge et to-dimensionelt variantarray.
Et variantarray behøver ikke dimensiones først men kan bruges direkte på arket
I  dette eksempel hentes data fra alle celler området A1:C5000, altså 15.000 celler

Dim MyArray as Variant
MyArray = Range("A1:C5000")


Tidsforbruget er så lavt at det næsten ikke kan måles
Hvis man nu undersøger MyArray nærmere i Local's vinduet vil man se at arrayet er en nøjagtig kopi af de data der er i A1:C5000, men UDEN formler. Der kommer altså kun rå data over.
MyArray vil være automatisk dimensioneret således MyArray(5000, 3), hvilket betyder at rækkerne ligger i 1. dimension og kolonnerne i 2. dimension. Dvs. samme system som cellerne og værdier kan nu kaldes enkeltvis efter samme system

MyArray(10, 2) vil være data fra række 10, kolonne 2 (B10)
MyArray(100, 3) vil være data fra række 100, kolonne 3 (C100)

For at gennemløbe alle elementer i arrayet findes laveste elementnummer og højeste elementnummer for henholdsvis 1. dimension og 2. dimension


For x = Lbound(MyArray, 1) to Ubound(MyArray, 1)
    For y = Lbound(MyArray, 2) to Ubound(MyArray, 2)
          MyArray(x, y) = MyArray(x, y) * 10
    Next
Next   


Lbound(MyArray, 1) giver laveste elementnummer i 1. dimension, Ubound højeste.
Lbound(MyArray, 2) giver laveste elementnummer i 2. dimension.

Et sådant array er meget hurtigt at gennemløbe, da alt befinder sig i maskinens hukommelse og ikke først skal læses.

At skrive tilbage til et regneark,  er lige så enkelt, som at hente data.


Range("A1:C5000") = MyArray


Dette skriver alle 15.000 celler I et hug og tidsforbruget er uhyre lille.
Man behøver selvfølgelig ikke at skrive sammested som man hentede data.

'Hent:
MyArray = Worksheets(1).Range("A1:C5000")

'Indsæt:
Worksheets(2).Range("D1:F5000") = MyArray

Hvis man ønsker at placere arrayet et andet sted og kun kender startcellen kan Resize-kommandoen bruges. Her placeres arrayet i F20, som øverste, venstre celle.

Range("F20").Resize(Ubound( MyArray, 1), Ubound( MyArray, 2)) = MyArray

Resize kommandoen udvider rangen F20 til samme størrelse som arrayet.

Her er hele koden :

Dim MyArray As Variant
MyArray = Range("A1:C5000")
For x = LBound(MyArray, 1) To UBound(MyArray, 1)
    For y = LBound(MyArray, 2) To UBound(MyArray, 2)
          MyArray(x, y) = MyArray(x, y) & "xxx"
    Next
Next
Range("F20").Resize(UBound(MyArray, 1), UBound(MyArray, 2)) = MyArray
Set MyArray = Nothing


Bemærk en sidste linie er til for at fjerne arrayet fra hukommelsen igen. Dette vil ske automatisk ved kodens afsluttelse (End Sub) da MyArray er lokal - defineret, men man kan jo få brug for ekstra hukommelse før og det er en god regel at "rydde op" efter en kode..
Koden kører på under 0,4 sek. på en ældre 300 Mhz labtop.

Almindeligt Array
Man kan ikke tildele et range til et almindelig array.
Men man kan godt gøre det omvendte, altså indsætte et array i et range. Man bruger samme metode som med variant-arrayet.



Dim MyArray(5000, 3)
Dim x As Long, y As Long
For x = 1 To 5000
    For y = 1 To 3
        MyArray(x, y) = x * y
    Next
Next

Range("F1:H5000") = MyArray



Ligesom ved den en-dimensionelle array en det muligt at vende et to-dimensionelt array med Application.WorksheetFunction.transpose


Dim MyArray as Variant
MyArray = Range("A1:C30")
Range("A1:AD3") = Application.WorksheetFunction.Transpose(MyArray)


Afslutning.

Brugen af array's giver muligvis et par kodelinier ekstra, men den hastighed koden afvikles med kan være op til en faktor 100 større end med direkte læsning og skrivning til celler i et regneark.
Med lidt øvelse er det faktisk nemt at bruge dem, men husk at  man kun kan overføre rå data og ikke formler, formater, valideringer mv.

Skrevet tir. d. 23. november 2004 kl. 09:30| #1

miko67 (14.736 point)
kompetent og overskuelig artikel der holder sig fint til et begrænset emne.

Skrevet ons. d. 24. november 2004 kl. 10:06| #2

jpvj (92.613 point)
Hej Bak,

Rigtig flot artikel. Du beskriver grundigt og samtidigt enkelt hvordan man overkommer et muligt performance problem i Excel.

Alt i alt en lille begrænset problemstilling med en god forklaring og gode eksempler!

/JP

Skrevet fre. d. 26. november 2004 kl. 17:15| #3

mikeot (13.425 point)
Godt fif! - havde ikke tænkt på denne måde at gøre det på.

Skrevet man. d. 29. november 2004 kl. 22:32| #4

webgon (11.722 point)
Vil nu ikke blot kalde denne artikel et 'fif' men en god, uddybende artikel ;-) 5/5 points!

Skrevet søn. d. 05. december 2004 kl. 12:55| #5

skarvenneverdies (14.862 point)
Lækkert stykke arbejde...
Det er artikler af denne kvalitet der burde ligge på E....så behøver jeg vidst ikke sige mere.. :-)

Skrevet lør. d. 15. januar 2005 kl. 12:51| #6

lorentsnv (23.451 point)
Meget nyttig artikkel!!

Skrevet tir. d. 22. februar 2005 kl. 10:11| #7


Skrevet ons. d. 14. september 2005 kl. 14:30| #8

jesperfjoelner (23.608 point)
Denne artikel har løst et specifikt problem, jeg havde med data eksport fra Access til Excel. Herligt.

Skrevet fre. d. 27. januar 2006 kl. 13:35| #9

hnteknik (32.260 point)
Fin artikel

Skrevet tor. d. 28. september 2006 kl. 10:18| #10

mrjh (25.065 point)
Meget forståeligt skrevet for en nybegynder i VBA, og en artikel jeg jævnligt vender tilbage til, for at genopfriske min viden om brug af arrays.

Skrevet ons. d. 07. marts 2007 kl. 10:29| #11

nils_ (9.245 point)
interessante tidsbetragtninger

Skriv en kommentar



Mest populære guides

Guidens karakter
!!!Karaktér: 3
12 stemmer
31/01 - 2011
Af: heinzdmx

Dropbox - gratis online lagerplads

Jeg vil i denne guide forklare lidt om hvad Dropbox er og også hvordan du får mest mulig plads på Dropbox. Dropbox er kort sagt en service hvor du har dine data lagt til backup på både nettet og din egen computer.
Guidens karakter
!!!Karaktér: 4
33 stemmer
02/02 - 2009
Af: jkrons

Dato- og tidsberegninger i Excel

En introduktion til simple beregninger med dato og tid i Excel. Opdateret med afsnit om beregning af tillæg.
Excel  |  Læs »
Guidens karakter
!!!Karaktér: 4
21 stemmer
06/11 - 2011
Af: fromsej

Sådan fjerner du virus og malware

Udviklingen går stærkt på "skidt"fronten, så vi har sammensat en ny og effektiv programpakke til fjernelse af det.
Virus  |  Læs »

Log ind

   

   

Seneste guides

Installer win 7
Den gode bruger


   




Tips & Tricks fra PC World

Teaser billede

Gør dig selv en tjeneste: Køb et ordentligt SD-kort

Der kan være meget stor hastighedsforskel på to umiddelbare ens SD-kort. Se her hvad du skal være opmærksom på, når du køber ekstra hukommelse til din mobil, tablet eller kamera.


Anmeldelser fra PC World

Teaser billede

Test: Denne super-tablet er iPads hårdeste konkurrent

Eee Pad Transformer Prime er frygtindgydende med sin quadcore processor og evne til at trylle sig om til bærbar. Apple bør kigge i bagspejlet, for Asus' tablet-pc kommer buldrende - og gør det...


Seneste blogindlæg

Teaser billede

Tvangslukke spørgsmål: Hvad er den bedste løsning?

Hej Vi har mange åbne spørgsmål på Eksperten. Vi ville gerne tvangslukke dem - så et spørgsmål efter f.eks. 6 måneder lukkes. Men der er et par uklarheder som ville være gode at få lidt input til:...


Nyheder fra PC World

Teaser billede

Gratis flysimulator fra Microsoft

Den legendariske Flight Simulator fra Microsoft genopstår den 29. februar - og denne gang er spillet gratis.


Nyheder fra Computerworld

Teaser billede

Bank: Derfor er login uden NemID helt i orden

Der er ikke hold i påstanden om sikkerhedsproblemer i forbindelse med bankkunders login uden brug af NemID, lyder det fra Nykredit Bank.


Kurser
Samarbejdspartnere

Udgiver · © 2012 IDG Danmark A/S · Hørkær 18 · 2730 Herlev · Tlf.: 77 300 300 · Fax: 77 300 301 · Brug af personoplysninger