środa, 22 lipca 2015

Przekazywanie tablic pomiędzy procedurami i zmiennymi

Praca z tablicami może bywać problematyczna szczególnie dla początkujących programistów VBA. W niniejszym blogu powstało już wiele wpisów dot. pracy z tablicami. Ostatnio jednak trafiłem na pytanie dot. przekazywania tablicy stałoelementowej pomiędzy różnymi procedurami, innymi zmiennymi, itp. Myślę, że warto krótko podsumować obowiązujące zasady szczególnie, że nie są to zasady skomplikowane. Zacznijmy od prostej definicji bazowej tablicy:
1Dim arrStart(8) As Double
2'oraz w celu kontroli z wykorzystaniem okna Locals
3'ustawiamy jeden element tablicy na określoną wartość
4    arrStart(8) = 1
Problem 1. Jak przekazać powyższą tablice do innej zmiennej? Istnieją dwa i tylko dwa dostępne scenariusze:
1'przekazyjemy tablicę do zmiennej typu Variant
2'jednocześnie nie deklarujemy tej zmiennej jako tablicy
3Dim arrVariant As Variant
4    arrVariant = arrStart
oraz wariant drugi:
1'deklarujemy zmienną tablicową dynamiczną nie określając ilości elementów
2'w tym wariancie tablica może być określonego typu (tu: double)
3Dim arrEmpty() As Double
4    arrEmpty = arrStart
Problem 2. Jak przekazać tablicę do funkcji, procedury parametryzowanej lub właściwości? Tu obowiązują identyczne zasady jak w przekazywaniu tablicy pomiędzy zmiennymi:
1'na początek definicja funkcji
2Function FunctionArray(arrInternal() As Double, arrOtherInternal As Variant)
3    '...tu nasze obliczenia i zwracany wynik
4End Function
5 
6'wywołanie funkcji i pobranie jej wyniku
7'z wykorzystaniem uprzednio utworzonych zmiennych
8Dim arrFunction() As Double
9    arrFunction = FunctionArray(arrStart, arrVariant)
Problem 3. Jak utworzyć funkcję, która będzie zwracać tablicę o określonej ilości elementów? W praktyce nie ma takiej możliwości. Jeżeli jednak przypiszemy do zwracenj wartości odpowiednią tablicę to funkcja stanie się funkcją tablicową.
1'przykład na bazie powyższych fragmentów kodu
2Function FunctionArray(arrInternal() As Double, arrOtherInternal As Variant) As Variant
3    FunctionArray = arrInternal
4End Function

piątek, 3 lipca 2015

Względna pozycja komórki wewnątrz zakresu Range

W jaki sposób odnaleźć w najprostszy sposób informację o numerze wiersza i kolumny dla określonej komórki lecz nie w relacji do arkusza, a w relacji do innego wskazanego zakresu? Zaprezentuję Państwu dwa przykładowe rozwiązania dla tak postawionego zadania. Zagadnienie to pojawiło się ostatnio na forum programistycznym i myślę, że warto przypomnieć szczególnie drugą technikę pracy z zakresami.

Wspólne założenia do projektu prezentuje poniższy startowy kod wraz z komentarzami:
1Dim Zakres As Range
2Dim Komorka As Range
3'przykładowy zakres
4Set Zakres = Range("E5:J20")
5Set Komorka = Range("G10")
6'wartości oczekiwane: wiersz = 6, kolumna = 3
7 
8'warto upewnić się, że Komorka jest wewnątrz Zakres
9If Intersect(Komorka, Zakres) Is Nothing Then Exit Sub


Wariant 1. Najprostszy, w którym wykorzystamy różnicę pomiędzy numerami wierszy zakresu odniesienia i wskazanej komórki:
1Debug.Print Komorka.Row - Zakres.Row + 1
2Debug.Print Komorka.Column - Zakres.Column + 1


Wariant 2. W którym tworzymy tymczasowy zakres od początku zakresu odniesienia do wskazanej komórki i wyliczamy odpowiednio ilość kolumn i wierszy zakresu tymczasowego:
1Debug.Print Range(Zakres.Cells(1), Komorka).Rows.Count
2Debug.Print Range(Zakres(1), Komorka).Columns.Count
3'zapis Zakres.Cells(1) i Zakres(1) są tożsame