Ostatnio w pracy trochę siedziałem nad usprawnieniem jednego pliku excela tworzącego pewne raporty. W związku z tym napotykałem na różne problemy. Jednym z nich było porównywanie danych w dwóch kolumnach i oznaczenie tych rekordów w kolumnie A które nie występują w kolumnie B. Oczywiście sposobów na rozwiązanie tego zadania jest pewnie mnóstwo, i pewnie mnóstwo takich które nie potrzebują do tego VBA. Ja jednak pokaże Wam jak to można załatwić poprzez makro w VBA.
Wyszukanie rekordów jednej kolumnie które nie występują w drugiej kolumnie
Moje przykładowe dane wyglądają tak:
Kod który załatwi nam sprawę:
Sub porownaj_kolumny() Dim kol_A As Range 'zmienna kol_A jako zakres dla kolumny A Dim kol_B As Range 'zmienna kol_A jako zakres dla kolumny B 'rozpoczynamy pętlę gdzie w zamiast "A2:A100" wpisujemy zakres własnych danych (dla pierwszej kolumny) For Each kol_A In Range("A2:A100") i = 0 ' ustawiamy flagę i = 0 If kol_A <> Empty Then 'sprawdzamy tylko niepuste komórki w zakresie 'rozpoczynamy drugą pętlę gdzie w zamiast "B2:B100" wpisujemy zakres własnych danych (dla drugiej kolumny) For Each kol_B In Range("B2:B100") If kol_A.Value = kol_B.Value Then ' zmieniamy flagę i na wartość 1 w przypadku gdy rekord w kolumnie A występuje w kolumnie B i = 1 If i = 0 Then ' jesli flaga zmieni sie na 1 to odrazu kończymy dalsze poszukiwania Exit For End If End If Next If i = 0 Then ' jeśli flaga po przeszukaniu kolumny B się nie zmieniła oznaczamy bieżący rekord na żółto kol_A.Select With Selection.Interior .Pattern = xlSolid .PatternColorIndex = xlAutomatic .Color = 65535 .TintAndShade = 0 .PatternTintAndShade = 0 End With End If End If Next End Sub
Program działa w sposób następujący:
- Najpierw ustalamy zakres przeszukiwania kolumny A – dla której chcemy wiedzieć jakie wartości nie występują w kolumnie B
- Ustawiamy sobie przykładową “flagę” i na 0
- Dodajemy warunek aby program przeszukiwał nam tylko pełne wartości (nie zajmował się pustymi komórkami)
- Uruchamiamy następna pętlę, – która sprawdzi dla każdego pojedynczego rekordu kolumny A wszystkie rekordy w kolumnie B (w ustalonym zakresie – oczywiście)
- Jeśli pętla znajdzie w kolumnie B taka samą wartość bieżącego rekordu w kolumnie A to zmieni flagę na 1
- Jeśli flaga zmieni się na 1 od razu kończymy dalsze przeszukiwania – żeby nie tracić czasu
- Po zakończeniu pętli kol_B – sprawdzamy czy flaga i została bez zmian – jesli tak – oznaczamy bieżący rekord w kolumnie A na żółto
- Pętla przechodzi tak przez wszystkie rekordy w kolumnie A – za każdym razem resetując flagę i na 0
Zamiast kolorowania wyszukanego rekordu można by się pokusić aby w trzeciej kolumnie dać informację ze w rekord w tym wierszu nie występuje w kolumnie B
czyli zamiast tego:
kol_A.Select With Selection.Interior .Pattern = xlSolid .PatternColorIndex = xlAutomatic .Color = 65535 .TintAndShade = 0 .PatternTintAndShade = 0 End With
wpisujemy to:
kol_A.Offset(0, 2).Value = "nie występuje"
Prawda, że proste:)