czwartek, 23 stycznia 2014

Wypełnianie tablicy Array określoną wartością

Tablice Array, podobnie zresztą jak wszystkie zmienne, w momencie ich deklaracji uzyskują wartość domyślną dla danego typu. I tak np. poniższe tablice przyjmą następujące wartości początkowe:

a. liczby całkowite, wartość początkowa równa 0 (zero)
1Dim intTBL(10) As Byte
2Debug.Print intTBL(0), TypeName(intTBL)   '>> wynik:  0 Integer()

b. ciągi tekstowe, wartość początkowa- pusty ciąg tekstowy
1Dim strTBL(10) As String
2Debug.Print strTBL(0), TypeName(strTBL)   '>> wynik:   String()

c. tablica wariant, wartość początkowa- pusta (Empty)
1Dim varTBL(10)
2Debug.Print varTBL(0); TypeName(varTBL)   '>> wynik: Empty Variant()

Co należałoby zrobić aby utworzyć tablicę, której elementy zostaną zainicjowane z inną niż domyślna (zerowa) wartość przyjmując jednocześnie założenie, że nie chcemy w tym celu korzystać z pętli? Poniżej kilka z możliwych rozwiązań.

1. Funkcja API FillMemory dla tablic typu Byte
Jeżeli naszą tablicę chcemy wypełnić wartościami z przedziału - do 255 możemy posłużyć się następującym rozwiązaniem opartym o funkcję API:
01'deklaracja funkcji w górnej części modułu
02Private Declare Sub FillMemory Lib "kernel32" Alias "RtlFillMemory" _
03        (dest As Any, ByVal size As Long, ByVal fill As Byte)
04 
05'wypełnienie tablicy wewnątrz procedury, dla tablicy jednowymiarowej każdy element wypełniamy wartością 10, dla tablicy dwuwymiarowej każdy jej element wypełniamy wartością 200
06    Dim byTBL(10) As Byte
07        FillMemory byTBL(0), 11, 10
08        Debug.Print byTBL(10)
09    
10    Dim loTBL(1, 10) As Byte
11        FillMemory loTBL(0, 0), 2 * 11, 200
12        Debug.Print loTBL(1, 1)

Składnia funkcji FillMemory:

FillMemory Destination, Length, Fill
gdzie:
Destination to punkt startowy w pamięci deklarowany jako dolny indeks (indeksy) naszej tablicy,
Length to ilość elementów tablicy
Fill to wartość jaką będziemy wypełniać tablicę

2. Evaluate i funkcja arkuszowa
Dla każdego innego rozwiązania możemy posłużyć się poniższą kombinacją funkcji Evaluate, funkcji arkuszowych i deklaracji tablicowych. Poszczególne kroki tej metody zostały opisane w postaci komentarzy w poniższym kodzie.
Uwaga! Rozwiązanie to tworzy tablice z dolnym indeksem równym 1 (a nie 0, co jest wartością domyślną)

01    'tablica liczb rzeczywistych
02Dim sngTBL() As Variant
03    'tablicę jednowymiarową tworzy zakres wskazany w _
04     relacji do komórek A1:A10.
05    'elementy tablicy wypełniamy wartościami 99.99
06sngTBL = Evaluate("=IF(ISERROR(Transpose(A1:a10)), 99.99, 99.99)")
07    'testowanie funkcji
08Debug.Print sngTBL(1), sngTBL(10)
09    'wynik>> 99.99  99.99
10 
11 
12Dim strTBL() As Variant
13    'tablicę dwuwymiarową tworzy zakres wskazany w _
14     relacji do komórek A1:C10.
15    'elementy tablicy wypełniamy wartościami 99.99
16strTBL = Evaluate("=IF(ISERROR(A1:C100), ""test"", ""test"")")
17    'testowanie funkcji
18Debug.Print strTBL(1, 1), strTBL(10, 3)
19    'wynik>> test   test

3. Kombinacja funkcji arkuszowej i funkcji VBA
W wariancie tym tworzymy tymczasowy ciąg tekstowy składający się z zadanej ilości powtórzeń. Następnie konwertujemy ten ciąg na tablice z wykorzystaniem funkcji Split.
1Dim tmpVal As Variant
2tmpVal = WorksheetFunction.Rept("99.99,", 100)
3tmpVal = Left(tmpVal, Len(tmpVal) - 1)
4 
5Dim tmpArr As Variant
6tmpArr = Split(tmpVal, ",")
7 
8Debug.Print tmpArr(1), tmpArr(10)

Uwaga końcowa! Po powyższe rozwiązania warto sięgać w sytuacji, kiedy ilość elementów w tablicy przekracza około 10 tyś. W przeciwnym wypadku wystarczy posłużyć się zwykłą pętlą co, choć nie jest efektowne, będzie rozwiązaniem efektywnym.

Brak komentarzy:

Prześlij komentarz