Wstęp
Dzisiaj chciałem pokazać trochę teorii na temat tworzenia rozwiazań w MsAccess. Chodzi o aspekt generowania niepotrzebnej ilości kodu, zamiast starać się zamykać wszystko we wspólnych kawałkach. Częściowo wynika to z tego, że rozwiązania sa pisane przez osoby dopiero zaczynające przygodę z programowaniem, częściowo wynikają z braku znajomości samego Access’a.
Problem
Część osób generuje nadmiarowy kod VBA, który służy do robienia czegoś w taki sam sposób, albo podobny nie wyodrębniając funkcji, modułów czy klas. Każdy doświadczony programista wie, że redundancja to nie jest nic dobrego i taki kod staje się koszmarny w utrzymaniu i rozbudowie. Posłużymy się tu przykładem, prostego formularza, na którym będzie prostokąt i trzy przyciski opcji do zmiany jego tła:
a kod wygląda tak:
Private Sub toggCzarny_Click() Me.prostokat.BackColor = vbBlack End Sub Private Sub toggCzerwony_Click() Me.prostokat.BackColor = vbRed End Sub Private Sub toggZielony_Click() Me.prostokat.BackColor = vbGreen End Sub
Zmiany
Efekt pracy już mamy, teraz rozpoczynamy testy i zauważamy, że każdy z przycisków po naciśnięciu pozostaje naciśnięty lub nie, zależnie od stanu początkowego.
To wymusza na nas wprowadzenie zmian w kodzie. Chleb powszedni każdego developera, no to nie pozostaje nam nic innego jak zmodyfikować kod dla przycisków, aby odznaczały inne przyciski.
Efektem tego będzie taki o to kod
Private Sub toggCzarny_Click() Me.prostokat.BackColor = vbBlack Me.toggCzarny = True Me.toggCzerwony = False Me.toggZielony = False End Sub Private Sub toggCzerwony_Click() Me.prostokat.BackColor = vbRed Me.toggCzarny = False Me.toggCzerwony = True Me.toggZielony = False End Sub Private Sub toggZielony_Click() Me.prostokat.BackColor = vbGreen Me.toggCzarny = False Me.toggCzerwony = False Me.toggZielony = True End Sub
Zmiany, zmiany
Zbiegiem czasu pojawiła się potrzeba dodania zmiany na kolor biały, więc dodajemy kolejny przycisk i modyfikujemy kod:
Private Sub toggBialy_Click() Me.prostokat.BackColor = vbWhite Me.toggCzarny = False Me.toggCzerwony = False Me.toggZielony = False Me.toggBialy = True End Sub Private Sub toggCzarny_Click() Me.prostokat.BackColor = vbBlack Me.toggCzarny = True Me.toggCzerwony = False Me.toggZielony = False Me.toggBialy = False End Sub Private Sub toggCzerwony_Click() Me.prostokat.BackColor = vbRed Me.toggCzarny = False Me.toggCzerwony = True Me.toggZielony = False Me.toggBialy = False End Sub Private Sub toggZielony_Click() Me.prostokat.BackColor = vbGreen Me.toggCzarny = False Me.toggCzerwony = False Me.toggZielony = True Me.toggBialy = False End Sub
Czyli ręcznie musieliśmy wprowadzić zmiany w trzech procedurach zdarzenia. I dopisać kolejną. I tak w ramach zmian to będzie rosło.
Powielamy strasznie dużo kodu, oczywiście przykład zawiera tylko 4 kontrolki, ale w razie ich większej ilości mamy naprawdę coś takiego, że jak usłyszymy o dodaniu kolejnego koloru to będziemy się bronić przed tym nogami i rękami.
Rozwiązanie
Tutaj trochę uproszczę i nie będę pokazywał etapów pośrednich, ale możemy wychwycić jedno: każdy z tych przycisków zmienia kolor i wyłącza zaznaczenie pozostałych.
To ubierzmy to w jedną funkcję, która będziemy wywoływać z kodu każdego przycisku. W końcu potrzebujemy tylko dwóch rzeczy aby to zrobić:
1. Kolor do zmiany
2. Nazwa kontrolki którą zostawiamy zaznaczoną
Więc scalmy to do takiej postaci:
Private Sub toggBialy_Click() ZmienKolor vbWhite, "toggBialy" End Sub Private Sub toggCzarny_Click() ZmienKolor vbBlack, "toggCzarny" End Sub Private Sub toggCzerwony_Click() ZmienKolor vbRed, "toggCzerwony" End Sub Private Sub toggZielony_Click() ZmienKolor vbGreen, "toggZielony" End Sub Function ZmienKolor(kolor As Long, kontrolka As String) Dim c As Control Me.prostokat.BackColor = kolor For Each c In Me.Controls If c.ControlType = acToggleButton Then c.Value = (c.ControlName = kontrolka) End If Next End Function
Tutaj ujawnia się mój skrót, oczywiście mógłbym wypisać literalnie przyciski w funkcji i przypisywać im wartość włączony/wyłączony, ale wtedy przy dodaniu nowego koloru, musiałbym także zmieniać jej kod, a tak wystarczy dodać odpowiednie wywołanie i pętla sama wyłączy odpowiednie buttony.
Podsumowanie
Dążenie do wyodrębniania wspólnych fragmentów kodu ma naprawdę sporo zalet i wspomina o tym chyba każda książka programistyczna.
Wbrew pozorom to nie wszystko co możemy uprościć.
Access ma jeszcze jedną fajną zaletę, ze we właściwościach zdarzeń możemy odwołać sie bezpośrednio do funkcji w module formularza w taki o to sposób:
=ZmienKolor(65280;"toggZielony")
Wtedy dodanie nowego koloru nie będzie od nas wymagało nawet wchodzenia w edytor VBA.
Odwołanie się poprzez właściwość do funkcji w module nie pozwala użyć stałych języka VBA, stąd zmiana vbGreen na 65280 itd. Doatkowo argumeny funkcji rozdzielamy średnikiem (;).
Dla zainteresowanych przykładowa baza z opisywanymi formularzami
0 Comments.