Arrays og range-formler i Excel VBA
På siden Arrays og ranges har jeg beskrevet, hvordan man kan få betragtelige hastighedsforøgelser ved at kopiere et range til et array og så manipulere data i arrayet, før arrayet indsættes som en tabel i ét hug.
Ranget (området) kopieres til et array således:
vMitArray() = rMitRange.Value
Men den metode kopierer kun værdierne, ikke formlerne. Hvad gør man, hvis man skal have formlerne med, fordi de skal indsættes et andet sted? Man skriver:
vMitArray() = rMitRange.Formula
Det benyttede jeg mig af, da jeg forleden skulle sammenstykke en ny tabel, hvor cellerne skulle beholde de originale cellereferencer.
For det første går det lynhurtigt ved at bruge et array som tabel, og til sammenligning med andre kopieringsmetoder skal man ikke bekymre sig om, hvorvidt den nye celle stadig peger på den originale eller ej.
Du ved, hvis du fx kopierer B1 til D2, og celle B1 har formlen "= A1", ja så vil formlen i D2 blive "= C2", medmindre der er brugt dollartegn: "= $A$1".
Det følgende lille kodeeksempel illustrerer forskellen på at kopiere med ".Value" og ".Formula". Du kan markere koden med musen, kopiere (CTRL+C) og sætte ind i et VBA-modul med CTRL+V.
Eksemplet forudsætter, at der står noget i cellerne A1:A10, og at celle B1:B10 har formlen "=A1", "=A2" osv. nedefter.
Først kopieres B1:B10 ind i et array med brugen af ".Value". Værdierne kopieres i omvendt rækkefølge til et nyt array, som indsættes i celle E2:E11. Dernæst gentages øvelsen med brug af ".Formula" og indsættes i G2:G11.
Du vil se, at med ".Value" er det kun værdierne og ikke formlerne, der kopieres.
Sub FormlerTilArray()
Dim vInArray()
Dim vOutArray()
Dim rMyRange As Range
Dim lCount As Long
Dim lRow As Long
On Error GoTo ErrorHandle
Set rMyRange = Range("B1:B10")
vInArray() = rMyRange.Value
ReDim vOutArray(1 To UBound(vInArray), 1 To 1)
For lCount = UBound(vInArray) To 1 Step -1
lRow = lRow + 1
vOutArray(lRow, 1) = vInArray(lCount, 1)
Next
vInArray() = rMyRange.Formula
Set rMyRange = Range("E2:E11")
rMyRange.Value = vOutArray()
lRow = 0
For lCount = UBound(vInArray) To 1 Step -1
lRow = lRow + 1
vOutArray(lRow, 1) = vInArray(lCount, 1)
Next
Set rMyRange = Range("G2:G11")
rMyRange.Value = vOutArray
Range("E1").Value = "Værdier"
Range("G1").Value = "Formler"
BeforeExit:
On Error Resume Next
Set rMyRange = Nothing
Erase vInArray
Erase vOutArray
Exit Sub
ErrorHandle:
MsgBox Err.Description
Resume BeforeExit
End Sub
Til mindre opgaver kan denne metode være overkill, men den er virkelig smart, hvis der fx skal håndplukkes i store datamængder for at lave en ny tabel, som skal indsættes et andet sted med de originale formler og cellereferencer.
Relateret:
|