Quantcast
Channel: Malinowy Excel
Viewing all 291 articles
Browse latest View live

Lista wielokrotnego wyboru (odsłona 1)

$
0
0

Czyli wybieranie z listy więcej niż jednej pozycji

Wiele razy korzystałam z list w formie formantów formularza, aby pobrać z nich wartość i wpisać do komórki. Nigdy jednak nie potrzebowałam wybrać z takiej listy kilku wartości i wpisać ich do komórki. Z taką potrzebą zgłosił się do mnie Wojtek. Temat mega mnie zaciekawił i pomyślałam, że Was też może.

Czyli sytuacja jest taka, że z listy rozwijanej chcemy wybrać kilka wartości i chcemy wpisać je do komórki tak, żeby każda pozycja listy była w nowym wierszu tej samej komórki. Nie jest to może zgodne ze „sztuką”, natomiast życie jest życiem i tak czasem chcemy albo jesteśmy zmuszeni. BTW: i tak cała trudność będzie w pobraniu wartości z listy, a samo wpisanie ich to już pikuś ;).

Całość będzie miała taki efekt:

 

Oczywiście bez VBA się tutaj nie obędzie, więc bez zbędnego przedłużania… do dzieła!

Tworzenie formatki

Formatka tutaj składa się z 3 elementów:

  1. komórki docelowej, w której mają wylądować wartości z listy
  2. listy wielokrotnego wyboru
  3. przycisku

U mnie komórka docelowa to komórka C3 i nazwałam ją Wynik. Żeby nazwać komórkę należy ją zaznaczyć i w polu nazwy (po lewej stronie obok paska formuły) wpisać wybraną nazwę: Wynik. Całość zatwierdzić Enterem.

Listę natomiast wstawimy sobie jako formant formularza. Czyli ze wstążki wybieramy kartę Deweloper (jeśli jej nie masz – tutaj pokazuję jak ją dodać), a w niej, w sekcji Formanty, klikamy ikonkę Wstaw i wybieramy formant Pole listy. Jest to kontrolka listy, która umożliwia zaznaczanie więcej niż jednej opcji. Niestety nie jest rozwijana, ale o takiej napiszę w innym wpisie :).

Wstawianie listy

Wstawianie listy

Kolejny krok to rysowanie jej – tak, jak każdy autokształt. Ja jeszcze lubię zmieniać domyślne nazwy wstawianych obiektów. Robimy to tak samo, jak zmiana nazwy komórki, czyli zaznaczamy naszą świeżo wstawioną listę, idziemy do pola nazwy i wpisujemy nazwę ListaDane (takiej potem używam w kodzie).

Teraz jeszcze tylko podpięcie źródła listy. Źródłem będzie u mnie tabela, która znajduje się w arkuszu Lista. Aby podpiąć źródło do formantu lista, należy kliknąć na niego prawym przyciskiem myszy. Z menu kontekstowego wybrać następnie Formatuj formant. Tam, w zakładce Formant zaznaczamy zakres wejściowy (po prostu wskazujemy go myszką):

Podpinanie źródła do listy

Podpinanie źródła do listy

U mnie zakres wejściowy jest tabelą w arkuszu Lista:

Źródło do listy

Źródło do listy

Wstawienia przycisku jest bardzo podobne do wstawiania listy. Dokładny opis wstawiania przycisku znajdziesz tutaj. Po wszystkim powstaje nam taka formatka:

Gotowa formatka

Gotowa formatka

Możemy więc brać się za wymyślanie logiki, a potem samego kodu.

Logika zadania

Logika naszego zadania jest taka, że najpierw przelecimy pętlą po wszystkich elementach listy i sprawdzimy, czy są zaznaczone. Jeśli tak – zapiszemy te elementy w zmiennej tekstowej. Po zakończeniu pętli wartość zmiennej wpiszemy do komórki.

Po drodze będzie jeszcze zmienna robocza, która sprawdzi, czy wybrano więcej niż jedną wartość – jeśli tak, będzie doklejała do wyniku „enter”, czyli znak końca linii.

Kod VBA

Teraz zostało nam już „tylko” oprogramowanie tego wszystkiego.

Wyszłam z założenia, że najlepszym i najmniej irytującym rozwiązaniem będzie, jak wartości z listy będą wpisywane do komórki dopiero po naciśnięciu przycisku. To ze względu na fakt, że tych wartości może być kilka i niekoniecznie użytkownik je wszystkie zna od razu, przez co chce się chwilę zastanowić. Z tego powodu makro będzie pdpięte do przycisku, czyli będzie najzwyczajniejszą w świecie procedurą.

Dlatego wstawmy sobie nowy moduł  (tutaj opisywałam jak to zrobić), a w nim stwórzmy procedurę PobierzDane.

Zacznijmy od deklaracji zmiennych. Potrzebujemy licznika do pętli, naszą listę, wyniku, arkusza, w którym pracujemy oraz zmiennej roboczej. Tak wyglądają wiersze deklaracji:

Sub PobierzDane()
    Dim Licznik As Long, ListaDane As ListBox, Wynik As String
    Dim Ile As Long, Ark As Worksheet
    
   
End Sub

Teraz przypiszmy wartości do zmiennych obiektowych, czyli ustalmy co ma być arkuszem (Ark) i listą (ListaDane):

Sub PobierzDane()
    Dim Licznik As Long, ListaDane As ListBox, Wynik As String
    Dim Ile As Long, Ark As Worksheet
    
    Set Ark = ThisWorkbook.Sheets("Formularz")
    Set ListaDane = Ark.ListBoxes("ListaDane")
    
End Sub

Zauważ, że nasza lista jest elementem kolekcji ListBoxes w konkretnym arkuszu i odwołujemy się do niej po nazwie (po to ją zmienialiśmy przy tworzeniu formatki).

A teraz już tylko pętla i wpisanie wyniku do komórki:

Sub PobierzDane()
    Dim Licznik As Long, ListaDane As ListBox, Wynik As String
    Dim Ile As Long, Ark As Worksheet
    
    Set Ark = ThisWorkbook.Sheets("Formularz")
    Set ListaDane = Ark.ListBoxes("ListaDane")
    
    For Licznik = 1 To ListaDane.ListCount
        If ListaDane.Selected(Licznik) Then
            Ile = Ile + 1
            If Ile > 1 Then Wynik = Wynik & vbNewLine
            Wynik = Wynik & ListaDane.List(Licznik)
        End If
    Next
    
    Ark.Range("Wynik").Value = Wynik
End Sub

Makro gotowe. Teraz tylko zostało podpięcie makra do przycisku (tutaj opisuję, jak to zrobić), zapisanie pliku jako .xlsm (plik z obsługą makr) i voila! Wszystko!

Mam nadzieję, że sposób opisany tutaj Ci się przyda i będzie do wykorzystania od zaraz 🙂

A teraz wersja wideo:

 

I plik do pobrania (pamiętaj o włączeniu makr):
MalinowyExcel Lista wielokrotnego wyboru dw.xlsm

 


Lista rozwijana wielokrotnego wyboru (odsłona 2)

$
0
0

Czyli wybieranie z listy ROZWIJANEJ więcej niż jednej pozycji

W poprzednim wpisie pokazywałam sposób na stworzenie listy wielokrotnego wyboru. Lista ta była formantem formularza, czyli „pływającym” w arkuszu obiektem, który mogliśmy umieścić w wybranym przez siebie miejscu. Rozwiązanie to było świetne, gdy mieliśmy mało komórek, do których chcieliśmy wpisać wartość z tej listy. Gorzej jest jednak, gdy mamy wiele komórek, w której, o zgrozo!, każda ma inną listę i z każdej z nich chcemy wybierać po kilka wartości do komórki. Masakra!

Sytuacje takie jednak jak najbardziej się zdarzają, więc dziś o tym, jak sobie wtedy radzić. Znów będzie o VBA i to nie takim oczywistym niestety. I znów będą zdarzenia :). Znów, ponieważ już ostatnio o nich pisałam, np. przy otwieraniu pliku na konkretnym arkuszu czy kasowaniu wpisu na zależnej liście rozwijanej.

Teraz więc formatka będzie znacznie łatwiejsza:

Formatka

Formatka

Mamy więc dwa pola, w którym każde ma listę rozwijaną. Dla czytelności wpisu zrobiłam tylko 2 listy. Natomiast jeśli potrzebujesz – możesz mieć ich 5 czy 100 – piękno tego rozwiązania polega na tym, że nie ma to kompletnie żadnego znaczenia :).

O tym, jak zrobić listy rozwijane pisałam tutaj, a jak zrobić dynamiczne listy rozwijane – tutaj.

Założenia

Ogólnie chcemy osiągnąć efekt listy rozwijanej wielokrotnego wyboru przy jak najmniejszym nakładzie pracy. Wykorzystamy więc mechanizm sprawdzania poprawności danych. I może Cię zmartwię, ale ten mechanizm nie oferuje możliwości wielokrotnego zaznaczania. W sumie, to tylko lista z poprzedniego wpisu oferuje taką możliwość. Musimy więc poradzić sobie inaczej. Co najśmieszniejsze, w ogóle nie będziemy tykać list rozwijanych! Skupimy się na wartościach komórki i tym, czy ona w ogóle ma w sobie listę rozwijaną, a konkretnie sprawdzanie poprawności z listą rozwijaną. Do tego koniecznie musimy zrozumieć dwa założenia:

  1. Uwzględniane będą tylko komórki, które mają sprawdzanie poprawności o typie Lista (komórki bez sprawdzania poprawności lub z innym typem sprawdzania nie będą brane pod uwagę)
  2. Po wyborze z listy rozwijanej, wybrana wartość zostać dopisana w nowym wierszu tej komórki

Niby to takie oczywiste, ale koniecznie musimy sobie zdawać z tego sprawę, aby zrozumieć kod VBA, który omówimy za chwilę. Cały trik tego rozwiązania polega na tym, że makro będzie dopisywało najnowszą wartość z listy do poprzedniej wartości komórki.

Warto też wiedzieć, jak w Excelu można zaznaczyć komórki, które mają sprawdzanie poprawności. Służy do tego polecenie Przejdź do…/Specjalnie, które można wywołać np. z menu Narzędzia główne/Znajdź i zaznacz/Przejdź do – specjalnie:

Przejdź do... specjalnie

Przejdź do… specjalnie

Pojawi się wtedy okienko, z którego wybieramy Sprawdzanie poprawności danych (to samo można osiągnąć skrótem klawiszowym Ctrl + g lub F5):

Zaznaczanie komórek ze sprawdzaniem poprawności

Zaznaczanie komórek ze sprawdzaniem poprawności

Excel wtedy zaznaczy nam tylko komórki, które zawierają sprawdzanie poprawności. Tę opcję wykorzystamy w kodzie, ponieważ jakoś musimy sprawdzić, czy które komórki mają owe sprawdzanie poprawności. Na naszej formatce zaznaczy więc zakres C2:C3.

Jak już to wiemy – omówmy sobie logikę naszego zadania.

Logika

Tak, jak wspomniałam na wstępie, nie będziemy ruszać list rozwijanych. Zajmiemy się tylko wartościami komórek.

Nasze makro uruchomi się, jak wykryje zmianę wartości komórki (zdarzenie Change). Pobierze wtedy wartość obecnie wpisaną do komórki (i zapisze ją w zmiennej oczywiście). Problem jednak jest w tym, że poprzednia wartość została właśnie skasowana, gdy user wybrał nową wartość na liście. Tragedii nie ma na szczęście, ponieważ tę operację można cofnąć i tak też zrobimy. Pojawi się wtedy poprzednia wartość, którą też zapiszemy do zmiennej. Jak już mamy jedno i drugie to teraz tylko wpisać obie, odpowiednio połączone do komórki.

Główna logika jest właśnie taka. Niestety, jak za chwilkę zobaczysz, kod będzie musiał poradzić sobie jeszcze z kilkoma innymi rzeczami, które będą w tej logice przeszkadzać. Będą to błędy, które mogą wyskoczyć po drodze, sam fakt tego, że w arkuszu działają zdarzenia (podczas cofania operacji też zmieniamy wartość komórki, więc zdarzenia będzie się chciało ponownie uruchomić!). No i też należy pamiętać o sytuacji, gdy wybieramy pierwszą wartość z listy. Na to wszystko nasz kod będzie musiał być odporny.

Kod VBA

Tak jak wspominałam wcześniej – będziemy działać na zdarzeniu. Konkretnie na zdarzeniu Change. Czyli jeśli wartość jakiejś komórki się zmieni – makro się uruchomi. Zmianą komórki jest oczywiście zmiana jej wartości.

Aby dodać zdarzenie do arkusza, wchodzimy do VBE (Alt + F11) i klikamy dwa razy na naszym arkuszu w okienku Project Explorer. Następnie z lewej listy rozwijanej modułu prywatnego arkusza wybieramy Worksheet, a z prawej: Change. Kroki te dokładnie omówiłam tutaj.

Ok. Cały kod umieścimy w procedurze Worksheet_Change.

Najpierw deklarujemy zmienne. Potrzebne nam będą 3 zmienne tekstowe: dla wartości poprzednio wpisanej do komórki (PoprzedniaWartosc), dla nowej (NowaWartosc) i dla tej wybranej z listy (Wybor). Przyda się jeszcze zmienna, która będzie zakresem wszystkich komórek, które mają sprawdzanie poprawności (ZakresSprPopr). A w kodzie wygląda to tak:

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim PoprzedniaWartosc As String, NowaWartosc As String, Wybor As String
    Dim ZakresSprPopr As Range
    
End Sub

Jeśli ten kod ma być zaimplementowany w arkuszu, w którym istnieje choć cień szansy, że nie będzie żadnego sprawdzania poprawności, należy już na samym początku zabezpieczyć się przed brzydkim, szarym komunikatem, który Excel wyrzuci nam, gdy będziemy próbowali przypisać nieistniejący zakres do zmiennej ZakresSprPopr. Konieczna jest więc tutaj malutka obsługa błędów, która, jak tylko błąd się pojawi, przekieruje nas na sam koniec procedury. Obsługa błędów to polecenie:

On Error GoTo Obsluga

Przy czym Obsluga pojawi się na końcu kodu i jest to miejsce, gdzie będziemy przechodzić (GoTo), gdy błąd się wydarzy.

A teraz już ciekawsza część :). Pobieramy teraz wartość komórki, która się zmieniła (Target) i przypisujemy do zmiennej Wybor. Potem badamy, jaki zakres w arkuszu ma w sobie sprawdzanie poprawności (ZakresSprPopr), a następnie sprawdzamy, czy nasza komórka znajduje się w tym zakresie (czyli, czy ona sama ma sprawdzanie poprawności). Do tego służy polecenie Intersect. Jeśli te dwa zakresy nie będą miały części wspólnej, lub nasza komórka jest pusta (czyli właśnie ktoś skasował wartość z niej) – kończymy procedurę:

    Wybor = Target.Value
    
    Set ZakresSprPopr = Cells.SpecialCells(xlCellTypeAllValidation)
    If Intersect(Target, ZakresSprPopr) Is Nothing Or Wybor = "" Then Exit Sub

No ok. Ale co ma się stać, jeśli wszystko jest ok, czyli jeśli nasza komórka ma sprawdzanie poprawności i jeśli ktoś wpisać do niej wartość? No po pierwsze warto sprawdzić, czy to sprawdzanie poprawności, które komórka posiada to lista rozwijana (czyli typ walidacji to 3). Jeśli tak – działamy dalej, czyli będziemy dopisywać wartości do komórki. Jeśli nie – w komórce ma zostać wpisana ta wartość, która tam była, czyli nic nie ruszamy. To załatwimy prostym if-em.

Dobrze, co natomiast, gdy w naszej komórce jest dobra lista? Wtedy działamy z naszą logiką. Żeby jednak wszystko pięknie poszło – musimy wyłączyć działanie zdarzeń. Dlaczego? Żeby nam się Excel nie zapętlił biedaczek :). Teraz możemy cofnąć operację (czyli de facto zmienić wartość komórki na poprzednią – i tutaj byłoby to zapętlenie), a potem zapamiętać poprzednią wartość komórki:

    If Target.Validation.Type = 3 Then
        Application.EnableEvents = False
        Application.Undo
        PoprzedniaWartosc = Target.Value
    End If

Pytanie tylko, jaka ta poprzednia wartość jest. Bo jeśli jest żadna, czyli komórka była pusta (bo jest to pierwszy wybór z listy), to chcemy, aby docelowa wartość była identyczna jak ta, którą wybraliśmy z listy. Jeśli jednak była inna – będziemy łączyć obie te wartości, przy czym druga ma być w nowym wierszu. Poniższy kod wpisz w poprzednim if-ie:

 If PoprzedniaWartosc = "" Then
     Target.Value = Wybor
 Else
     NowaWartosc = PoprzedniaWartosc & vbNewLine & Wybor
     Target.Value = NowaWartosc
 End If

Na koniec już tylko dokończyć obsługę błędów, czyli:

Obsluga:
    Application.EnableEvents = True

Cały kod wygląda tak:

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim PoprzedniaWartosc As String, NowaWartosc As String, Wybor As String
    Dim ZakresSprPopr As Range

On Error GoTo Obsluga
    Wybor = Target.Value
    
    Set ZakresSprPopr = Cells.SpecialCells(xlCellTypeAllValidation)
    If Intersect(Target, ZakresSprPopr) Is Nothing Or Wybor = "" Then Exit Sub
    
    If Target.Validation.Type = 3 Then
        Application.EnableEvents = False
        Application.Undo
        PoprzedniaWartosc = Target.Value
        
        If PoprzedniaWartosc = "" Then
            Target.Value = Wybor
        Else
            NowaWartosc = PoprzedniaWartosc & vbNewLine & Wybor
            Target.Value = NowaWartosc
        End If
    End If
Obsluga:
    Application.EnableEvents = True
    
End Sub

I pięknie śmiga. Zobaczcie:

Wynik

Wynik

 

Jedyny problem jest taki, że jeśli się pomyliliśmy, to klapa. Trzeba skasować wartość komórki i wybrać wszystko od początku. Pojawią się bowiem dwa problemy:

  1. tabliczka sprawdzania poprawności, że wartość komórki jest nieprawidłowa. Z tym akurat nawet bez kodu łatwo sobie poradzić, jednak, gdy to zrobimy, pojawi się problem nr 2:
  2. wartości w komórce się powtórzą, ponieważ na każdą zmianę w komórce, Excel będzie uruchamiał przed chwilą napisane makro…

Można sobie z tym poradzić, ale o tym jeden z kolejnych wpisów. Jak w serialu normalnie ;).

A tymczasem wersja wideo:

 

I plik do pobrania (pamiętaj o włączeniu makr!:
MalinowyExcel Lista rozwijana wielokrotnego wyboru dw.xlsm

 

 

 

Dodatkowa premia w zależności od stażu pracy

$
0
0

Czyli procenty, JEŻELI i… ułatwienie życia!

Jak pierwszy raz usłyszałam o co chodzi w tym „zadaniu”, pomyślałam: WYSZUKAJ.PIONOWO. W drugim podejściu jednak zobaczyłam, że da się to zrobić inaczej. I dobrze, bo o WYSZUKAJ.PIONOWO już ostatnio było (tutaj czy tutaj). Wszystko zależy oczywiście od danych, jakie mamy, a te bardzo mi pasowały do formuły, o której będzie dzisiaj. A o co w ogóle chodzi?

O rozliczanie dodatkowej premii, którą pracownicy dostają za staż pracy. I za każdy przepracowany rok ten procent jest większy o stałą wartość 20%.

Do dzieła!

Cel zadania

Założenia

Nasze zadanie polega na tym, żeby obliczyć wysokość dodatkowej premii, jaką pracownik otrzymuje po przepracowaniu określonego czasu u nas w firmie. Premię może dostać dopiero wtedy, jak przepracuje minimum 10 lat. Po takim czasie należy mu się 300% kwoty bazowej, od której naliczamy premię (może to być jego wynagrodzenie). Następnie, z każdym przepracowanym rokiem należy mu się o 20% więcej, czyli jeśli przepracowałby np. 11 lat – powinien dostać 320%, 15 lat – 400% itd. Natomiast maksymalnym procentem, jaki może dostać jest 600%, który dostanie po 25 latach pracy. Jeśli przepracuje 26, czego serdecznie mu gratuluję, dostanie taką samą premię, czyli 600% swojej kwoty bazowej.

Formatka do zadania wygląda tak (i dlatego właśnie zrezygnowałam z WYSZUKAJ.PIONOWO):

Formatka

Formatka

Czyli na podstawie lat pracy chcemy obliczyć należny procent premii oraz docelowo – jej wysokość. Oczywiście da się to zrobić WYSZUKAJ.PIONOWO, tylko ona wymagałaby utworzenia tabeli premiowej. Gdybym ją miała – od razu bym szła właśnie w to rozwiązanie.

Natomiast tutaj tabeli premiowej nie ma, natomiast jest pewna zasada. Mianowicie: z każdym rokiem premia przyrasta o stałą wartość 20%. Jeśli tak – możemy napisać prostą formułę, żeby obliczyć wynik. I takie właśnie zrobimy.

Potrzebne nam będą komórki definicyjne, zaznaczone na żółto na formatce:

  1. minimalny staż pracy, za który się należy premia (C3): 10 lat
  2. procent bazowy, czyli taki, od którego startujemy naliczanie (C4): 300%
  3. % wzrostu, czyli przyrost procentów za każdy dodatkowy rok pracy (C5): 20%
  4. Maksymalny procent premii, jaki można dostać (C6): 600%

Z tymi informacjami możemy przejść do formuły.

Formuła

Ograniczenie 10 lat załatwimy sobie funkcją JEŻELI. Po prostu weźmiemy pod uwagę tylko takich pracowników, którzy pracują 10 lat lub dłużej:

=JEŻELI(B9>=$C$3; "tutaj będzie najważniejsza część formuły" ;0)

Minimalny procent i przyrost 20% załatwimy sobie głównym elementem formuły, czyli: zauważmy, że 20% należy się za każdy dodatkowy rok. Czyli każdy, kto przepracował 10 lat lub więcej na pewno dostanie 300%. Super. Do tego więc będziemy dodawać przyrost (20%) pomnożony przez ilość dodatkowych lat. Czyli jak ktoś przepracował 11 lat, to ma jeden dodatkowy rok. Jak 12 – to 2 itd. Czyli Dla 12 lat będzie tak: 300% + (12-10)*20% = 340%. A dla 10? Tak samo, tylko nawias nam się wyzeruje i zostanie samo 300%:

=JEŻELI(B9>=$C$3;$C$4+(B9-$C$3)*$C$5;0)

Gorzej będzie z 26 latami pracy, ponieważ nasza formuła dorzuci nam kolejne 20%, czego nie chcemy, ponieważ ma być ograniczenie 600%. To ograniczenie z kolei załatwimy sobie funkcją MIN (o takim sprytnym jej użyciu pisałam też tutaj). Jest to świetna alternatywa dla JEŻELI, której też moglibyśmy tutaj użyć, ale nie lubię jej w tym zastosowaniu :). Zobaczcie bowiem, że moglibyśmy wrzucić naszą formułę w JEŻELI, które by sprawdzało, czy jej wynik jest większy niż 600%. Jeśli tak – funkcja wyświetlałaby 600%, a jeśli nie – jeszcze raz tę formułę, którą musiałaby ponownie obliczać. Not nice. Działałaby wolniej (choć pewnie bardzo by nas to nie bolało tutaj;)), a my musielibyśmy się powtarzać i w dwóch miejscach formuły pisać to samo. Tego nie cierpię, stąd funkcja MIN :).

Całą formuła wygląda więc tak:

=JEŻELI(B9>=$C$3;MIN($C$6;$C$4+(B9-$C$3)*$C$5);0)

A jej wynik, po skopiowaniu do całej kolumny, wygląda tak:

Obliczone procenty dodatkowe premii

Obliczone procenty dodatkowe premii

Samo obliczenie wysokości premii na tej podstawie to już bułka z masłem. Zwykłe mnożenie, czyli taka formuła w komórce E9:

=C9*D9

I taki jest efekt wszystkiego:

Wynik

Wynik

Tadam! Jak widać trochę matematyki, funkcji JEŻELI i MIN i sprawa z głowy 🙂 Mam nadzieję, że pomogłam!

A tutaj wersja wideo, na której krok po kroku pokazuję co robić:

 

 

 

Konsolidacja danych z wielu arkuszy innego pliku

$
0
0

Czyli ADR.POŚR między plikami

Podobny temat już na blogu poruszałam (zobacz tutaj), natomiast dotyczył on pobierania danych tylko z innych arkuszy. Było tam dodatkowe utrudnienie, dotyczące kolejności kolumn, natomiast dane konsolidowane były z tego samego pliku. Dzisiaj sytuacja będzie nieco inna: będziemy pobierali dane z innego pliku, z różnych jego arkuszy. Też posłużymy się funkcją ADR.POŚR, jednak do formuły „jakoś” dorzucimy nazwę pliku.

Zaczynamy!

Formatka

Mamy 2 pliki:

  1. z danymi źródłowymi
  2. podsumowujący

W pliku z danymi źródłowymi mamy 31 arkuszy, ponumerowanych od 1 do 31. W każdym z nich znajduje się identyczna co do układu tabelka z danymi, które chcemy podsumować w drugim pliku. Dane dotyczą np. liczby pracowników na zmianie dziennej i nocnej w pięciu lokalizacjach: Koło, Września, Luboń. Mosina i Swarzędz.

Tak wyglądają arkusze z danymi źródłowymi (każdy ma identyczny układ, jednak inne dane do pobrania):

Dane do pobrania - układ

Dane do pobrania – układ

A w takiej tabelce będziemy konsolidować dane:

Formatka konsolidacji

Formatka konsolidacji

Formuła

Zaczniemy od wpisania sobie nazwy pliku do żółtej komórki E1, którą nazwiemy Plik (o nazywaniu komórek pisałam min. tutaj).

Teraz sama formuła. Wbrew pozorom nie będzie ona jakoś strasznie skomplikowana. Żeby sobie ułatwić życie, w komórce C4, czyli tej, w której będę pisała uniwersalną formułę, wskażę wartość, któa ma się w niej znaleźć, czyli wartość z komórki C4 w arkuszu 1 pliku Dane.xlsx. Dostanę więc taką formułę:

='[Dane.xlsx]1'!$C$4

Zrobiłam to po to, bo nigdy nie pamiętam składni odwołania się do innego pliku. Mieszają mi się apostrofy i nawiasy kwadratowe ;). Będę więc edytowała wstawioną formułę, a zacznę od tego, że wstawię ją w funkcję ADR.POŚR i sparametryzuję nazwę pliku. Czyli tak:

=ADR.POŚR("'["&Plik&"]1'!$C$4")

Połowa sukcesu za nami. Poważnie.

Teraz trzeba tylko sparametryzować adres komórki. Zacznę od najłatwiejszego, czyli numeru wiersza. Zauważmy, że dane pobieramy zawsze tylko z 4 lub 5 wiersza arkusza. Reguła też jest taka, że zawsze dane dotyczące dnia są w wierszu 4., a nocy w 5. Ten numer załatwimy więc prostym JEŻELI, które również dokleimy, ponieważ funkcja ADR.POŚR chce od nas tekst:

=ADR.POŚR("'["&Plik&"]1'!$C$"&JEŻELI($B4="Dzień";4;5))

Komórkę $B4 zablokowałam przed kolumną B, ponieważ tę funkcję docelowo będę kopiowała, a chcę, żeby wtedy kolumna została taka sama, czyli cały czas B.

OK. Teraz gorsza sprawa: kolumna. W zależności od lokalizacji ta kolumna będzie inna. W sumie najprostszym rozwiązaniem byłoby napisanie 5 formuł, dla każdej lokalizacji oddzielnie. I w sumie to jest bardzo dobre rozwiązanie. Ale post byłby trochę krótki, więc pokażę Wam jak to zrobić w jednej formule :). Do tego celu przyjmę pewne założenie: kolumny lokalizacji są wszędzie takie same: zarówno w pliku podsumowującym jak i w plikach źródłowych (sama tworzę ten plik, więc mogę tak pójść na łatwiznę 😉 ).

Jeśli tak, to np. Koło zawsze będzie w kolumnie C, czyli trzeciej, itd. Ponieważ literkowe kolumny (A,B,C) kiepsko się zwiększa, więc posłużę się ich numerami. Żeby jednak to zrobić, posłużę się funkcją NR.KOLUMNY i dodatkowo powiem funkcji ADR.POŚR, żeby stosowała odwołanie W1K1, zamiast A1. Będzie trochę jak czarna magia, ale w tym typie odwołania podajemy numeryczne odwołanie zarówno do wiersza, jak i kolumny. Czyli komórka W1K1 to nic innego jak komórka w pierwszym wierszu i w pierwszej kolumnie arkusza, czyli A1. Komórka W4K3 to C4 itd. Żeby funkcja ADR.POŚR to zastosowała, w drugim jej argumencie powinniśmy wpisać 0 (lub FAŁSZ). No i oczywiście uwzględnić literki W i K, które są obowiązkowym elementem tego typu odwołań.

Wszystko do kupy wygląda tak:

=ADR.POŚR("'["&Plik&"]1'!W"&JEŻELI($B4="Dzień";4;5)&"K"&NR.KOLUMNY(C3);0)

Funkcja NR.KOLUMNY dostała od nas argument komórki wyżej (najważniejsze, że ta komórka jest w tej samej kolumnie, z której chcemy pobrać numer), z której pobiera numer kolumny. Dla porządku można byłoby ją zablokować tak: C$3, jednak nie jest to konieczne. Jak chcecie.

I jeszcze jedna istotna sprawa: trzeba pobierać wartości z określonych arkuszy. Aby to zrobić odwołamy się do wartości w kolumnie A, czyli:

 

Najważniejsze jest to, że po skopiowaniu tej formuły wszystko ładnie pięknie działa :). Zobaczcie przykładowe wartości:

Wynik konsolidacji

Wynik konsolidacji

I tyle. Takie to proste, a ja mam nadzieję, że Ci pomogłam i że to rozwiązanie Ci się przyda!

A poniżej plik (tylko skonsolidowany) do pobrania. Pamiętaj o pliku z danymi!

MalinowyExcel Konsolidacja danych z wielu arkuszy innego pliku ADR.POŚR dw.xlsx

I film, w którym krok po kroku pokazuję rozwiązanie:

 

 

 

Kiedy następuje przekroczenie progu podatkowego?

$
0
0

Czyli w którym miesiącu będziemy płacić 32% podatku?

W tym artykule pokażę Ci metodę na określenie, w którym miesiącu następuje przekroczenie progu podatkowego. Chodzi tutaj jedynie o wskazanie tego miesiąca, w którym pracownik będzie płacił 32% podatku, a nie 18%. Tak się stanie, kiedy podstawa opodatkowania przekroczy kwotę 85 528 zł. Samo określenie tego miesiąca jest dość proste – użyję tutaj (znowu!) WYSZUKAJ.PIONOWO. Natomiast na uwagę zasługuje droga dojścia do podstawy opodatkowania choćby dlatego, że do jej ustalenia potrzebne jest określenie składek ZUS, a te nie są takie oczywiste…

Opiszę przypadek najbardziej klasycznego zatrudnienia na etat ze standardowymi kosztami uzyskania przychodu. Nie będę brała pod uwagę żadnych profitów czy dodatków, jedynie czystą pensję. Nie uwzględniam tutaj również rozliczeń obcokrajowców.

Etapy dochodzenia do rozwiązania będą więc takie:

  1. Ustalenie podstawy ZUS (z limitem)
  2. Obliczenie niezbędnych składek ZUS
  3. Ustalenie podstawy opodatkowania
  4. Określenie % podatku: 18% czy 32%

Formatka wygląda następująco:

Formatka

Formatka

Zastrzeżenie: Na wstępie zaznaczę również, że dołożyłam wszelkich starań, aby informacje zawarte w tym artykule były kompletne i rzetelne. Nie jestem jednak doradcą podatkowym, nie biorę więc żadnej odpowiedzialności za wykorzystanie tych informacji ani za ewentualne szkody wynikłe z ich wykorzystania. Artykuł ten nie jest poradnikiem podatkowym. Data publikacji artykułu: 30.01.2018

Założenia

Na tym etapie poczynię 5 założeń, na których opierają się obliczenia i zrzuty ekranu w tym artykule:

  1. Płatność 32% następuje w miesiącu po tym, w którym nastąpiło przekroczenie progu podatkowego (np. jeśli przekroczenie nastąpiło w maju – płatność 32% będzie od czerwca)
  2. Limit ZUS = 133 290 zł
  3. Próg podatkowy = 85 528 zł
  4. miesięczne wynagrodzenie: 15 000 zł
  5. koszty uzyskania przychodu = 111,25 zł.

Powyższe kwoty można zmienić oczywiście, natomiast będą one widoczne na dalszych zrzutach ekranu.

To zaczynamy!

Obliczanie składek ZUS

Do wyliczenia procentu podatku, potrzebujemy znać jego podstawę. A żeby poznać podstawę – musimy wysokość składek ZUS i koszty uzyskania przychodu. Te ostatnie znamy – będzie to stała miesięczna wartość 111,25 zł. Składki ZUS, które nas tutaj interesują to:

  1. emerytalne: 9,76% (podstawy ZUS z limitem)
  2. rentowe: 1,5% (podstawy ZUS z limitem)
  3. chorobowe: 2,45%  (podstawy ZUS bez limitu)

Najpierw potrzebna nam będzie podstawa ZUS, czyli w naszym przypadku wynagrodzenie z komórki D8. Gdybyśmy mieli pewność, że w ciągu roku pracownik na pewno nie przekroczy limitu ZUS – można byłoby to tak zostawić. Artykuł ten jednak zakłada, że pracownik będzie płacił 32% podatku, jest więc spora szansa, że przekroczy też limit ZUS ;). Próg ten wynosi obecnie 133 290 zł (2018 rok) i jeśli pracownik go przekroczy – nie płaci już składek emerytalnej i rentowej. Chorobową płaci nadal.

Aby uprościć sobie obliczanie podstawy dla składek emerytalnej i rentowej – policzmy najpierw wynagrodzenie narastająco. Zrobi to formuła wpisana do komórek D9:O9:

=SUMA($D$8:D8)

Można oczywiście poradzić sobie bez dodatkowego wiersza – ja natomiast uważam, że dzięki niemu kolejna formuła jest czytelniejsza i dodatkowo pozwala on łatwiej analizować dane.

Kolejny krok to obliczenie właśnie podstawy ZUS z limitem. Zrobi to sprytna formuła, która odwołuje się limitu ZUS (komórka B4, nazwana jako Limit_ZUS – o nazywaniu komórek możesz przeczytać tutaj) oraz do przed chwilą policzonego narastającego wynagrodzenia. Formuła ta sprawdza, czy suma wynagrodzeń nie przekroczyła limitu – jeśli tak, podstawą ZUS w danym miesiącu jest wynagrodzenie. Jeśli zaś przekroczyła – podstawą jest 0 lub różnica między limitem ZUS a sumą dotychczasowego wynagrodzenia, w zależności która z wartości jest mniejsza (o tym zastosowaniu funkcji MIN też już pisałam, nawet całkiem niedawno). Oto formuła (komórki D11:O11):

=JEŻELI(D9<=Limit_ZUS;D8;MAX(0;Limit_ZUS-C9))

Teraz obliczenie składek emerytalnej i rentowej. Do obu zastosuję jedną formułę (komórki D12:O13):

=ZAOKR($C12*D$11;2)

A teraz chorobowej, liczonej od podstawy ZUS bez limitu, czyli w naszym pliku po prostu od wynagrodzenia:

=ZAOKR(D$8*$C14;2)

Na koniec, dla ułatwienia i czytelności – zwykła SUMA na podsumowanie wszystkich składek ZUS, które mają wpływ na podstawę opodatkowania (komórki D15:O15):

=SUMA(D12:D14)

Tak wygląda obliczona cześć ZUS-owa:

Obliczony ZUS

Obliczony ZUS

Ok, możemy przechodzić do podatku…

Obliczenia podatkowe

No to zacznijmy od naszej kochanej podstawy podatku. Otrzymamy ją po odjęciu od wynagrodzenia ZUSu i kosztów uzyskania przychodu i oczywiśćie zaokrągleniu matematycznemu do pełnych złotych. Komórki D19:O19:

=ZAOKR(D8-D15-D17;0)

I znowu przyda nam się narastająca wartość owej podstawy (D20:O20):

=SUMA($D$19:D19)

No i clue całego tematu: stawka podatku. Tutaj idę na łatwiznę i stosuję WYSZUKAJ.PIONOWO, ale uwaga! Funkcja ta wyszukiwać będzie narastającej wartości z poprzedniego miesiąca. Ponieważ 32% zaczniemy naliczać od następnego miesiąca. Czyli, jeśli przekroczyliśmy próg w maju – to 32% naliczać będziemy od czerwca. Dlatego poszłam na skróty i sprawdzam, czy wartość z poprzedniego miesiąca przekroczyła próg podatkowy, bo i tak dopiero od następnego będę liczyła wyższy podatek. Sama formuła jest taka (D21:O21):

=WYSZUKAJ.PIONOWO(C20;$D$4:$E$5;2)

Fajerwerki, czyli trochę formatowania warunkowego

Na koniec można jeszcze dodać trochę efektów wizualnych i kolorem zaznaczyć miesiąc, w którym jest płatność 32% i pierwsze jego wystąpienie. Aby to osiągnąć posłużę się moim ukochanym formatowaniem warunkowym. W tym celu należy:

  1. zaznaczyć jednocześnie komórki D7:O7 i D21:O21,
  2. wybrać z menu Narzędzia główne/ Formatowanie warunkowe
  3. Nowy warunek/ Użyj formuły do określenia komórek, które należy sformatować…
  4. wpisać następującą formułę i wybrać format:
=ORAZ(C$21<>D$21;C$21<>0)
Reguła formatowania warunkowego

Reguła formatowania warunkowego

Na koniec dostajemy taki efekt:

Wynik

Wynik

Mam nadzieję, że zaprezentowany przeze mnie sposób okaże się przydatny :).

Oto wersja wideo:

 

Lista rozwijana wielokrotnego wyboru – edycja wpisu

$
0
0

Czyli sterowanie zdarzeniem

To będzie chyba najkrótszy post na tym blogu. Niby trudna rzecz, a wymaga 2 linijek kodu VBA i ustawienia jednej opcji w Excelu. O co chodzi?

W tym wpisie pokazywałam jak zrobić listę wielokrotnego wyboru za pomocą narzędzia sprawdzania poprawności. Wszystko pięknie działało, natomiast problem pojawiał się wtedy, kiedy chcieliśmy dokonać zmiany we wcześniej wpisanych wartościach, np. skasować jakąś wartość. Efekt był taki, że ponieważ skorzystaliśmy z mechanizmu sprawdzania poprawności, to Excel nie pozwalał nam wprowadzać do komórki innych wartości, niż pojedynczy wpis na liście rozwijanej. A taką było większość wpisów, które wybraliśmy.

Dlatego dzisiaj pokażę rozwiązanie tego problemu. Najprostsze z możliwych, czyli takie, jak lubię :). Efekt będzie taki:

Do dzieła!

W tym najprostszym rozwiązaniu, które bezczelnie ściągnęłam od Microsoftu, wykorzystuję logikę trybu projektowania. Tryb projektowania jest to tryb, w którym możemy ustawiać wygląd i właściwości kontrolek, bez uruchamiania ich działania. W Excelu wykorzystujemy go np. gdy chcemy zmienić rozmiar pola tekstowego, wstawionego jako kontrolkę ActiveX (których zresztą nie polecam). W Wordzie, gdy tworzymy interaktywny formularz z wykorzystaniem formantów zawartości. Tryb ten jest też w Accessie.

Najlepiej będzie zrozumieć jego działanie i przydatność na przykładzie Power Pointa. Można powiedzieć, że tryb projektowania to ten tryb, w którym tworzymy prezentację. Tworzymy, czyli projektujemy, w nim wszystko: tekst, animacje, dźwięki, interaktywne przyciski i inne. Natomiast, żeby zobaczyć jak to wszystko działa – uruchamiamy prezentację, czyli wychodzimy z trybu projektowania.

Dokładnie to samo zrobimy w naszym przykładzie. Jak włączymy tryb projektowania – ja go tutaj nazwę tryb edycji, ponieważ lepiej mi ta nazwa pasuje do zagadnienia – będziemy mieli możliwość edycji komórki, w której chcemy dokonać zmian, np. usunąć niepotrzebny wpis.

Żeby jednak zadziałało to zgodnie z naszymi oczekiwaniami – trzeba będzie dokonać pewnej zmiany w utworzonych już wcześniej regułach sprawdzania poprawności, konkretnie w naszych listach. I od tego zaczniemy.

Sprawdzanie poprawności – niezbędna modyfikacja

Listy rozwijane są cudowne. Pamiętajmy jednak, że niezależnie od tego, jak cudnie wyglądają, nadal są sprawdzaniem poprawności, czyli służą do tego, aby kontrolować czy użytkownik nam nie wpisuje jakichś bzdur! Jak więc takie wpisze – Excel będzie na niego wrzeszczał, poprzez wyświetlenie takiego o to przyjemnego komunikatu (z dźwiękiem na prawdę można się go przestraszyć!):

Komunikat o niepoprawnych danych

Komunikat o niepoprawnych danych

Można go spersonalizować i wyświetlić inną treść, ale nieważne, ponieważ my i tak chcemy się go pozbyć. Dlaczego? Ponieważ jeśli wciąż się będzie pojawiał, nie dokonamy żadnych zmian, ponieważ nigdy te kilka wartości, które z listy wybieramy nie będą się równać jednej z dozwolonych wartości. To ograniczenie VBA cudownie omija (co zresztą było dla mnie zaskoczeniem, kiedy tworzyłam to rozwiązanie), natomiast użytkownik nie ma takiej szansy – jest sprawdzany przez Excela. Bardzo to mądre, w końcu to sprawdzanie poprawności i po to je stosujemy.

Nam natomiast ten komunikat będzie przeszkadzał, więc go wyłączymy. I to wszędzie, gdzie chcemy mieć możliwość edycji wpisów.

Aby go wyłączyć, należy:

1. zaznaczyć komórki z takim samym sprawdzaniem poprawności,

2. wejść do menu Dane/ Poprawność danych, do zakładki Komunikat o błędzie

3. Odznaczyć checkbox Pokazuj alerty po wprowadzeniu nieprawidłowych danych

Wyłączenie sprawdzania poprawności danych

Wyłączenie sprawdzania poprawności danych

De facto efekt będzie taki, jakbyśmy wyłączyli sprawdzanie poprawności, ale zachowali sobie mechanizm listy rozwijanej. O to chodziło.

Oczywiście należy się liczyć z tym, że od tej pory, jeśli wpiszemy tam jakąś bzdurną wartość (np. aslkdjaldjasl), to Excel się nie zbuntuje i ten wpis przyjmie. Ja natomiast bym to zaryzykowała, ponieważ gdybyśmy mieli się przed tym zabezpieczać – rozwiązanie byłoby nieco bardziej skomplikowane, a myślę, że jest to tutaj sztuką dla sztuki.

Ok. Jak już to mamy – możemy przejść do stworzenia kontrolki, pozwalającej nam wejść do trybu edycji.

Tryb edycji – tworzenie kontrolki

Kontrolką, którą mam na myśli może być sporo elementów. Ja jednak zdecydowałam się na checkbox, ponieważ wydaje mi się tutaj najprostszy. Jak jest zaznaczony – jesteśmy w trybie edycji, jak odznaczony – nie jesteśmy. Proste.

Wstawimy więc sobie checkbox. Potrzebna nam będzie do tego karta Deweloper na wstążce. Jeśli jej nie masz – tutaj opisywałam jak ją dodać.

Teraz w sekcji Formanty klikamy przycisk Wstaw, wybieramy nasz checkbox…

Wstawianie checkboxa

Wstawianie checkboxa

…i rysujemy go w wybranym miejscu arkusza. Ja zrobiłam to na górze, ale nie ma to znaczenia:

Checkbox

Checkbox

(Nazwę Pole wyboru 1 oczywiście można zmienić ;))

Większe znaczenie ma komórka, która będzie przechowywała informację o wyborze użytkownika. Dzięki niej będziemy mogli się zorientować, czy checkbox jest zaznaczony, czy nie. Aby tę komórkę ustalić, należy:

1. kliknąć prawym przyciskiem myszy na checkbox

2. z manu kontekstowego wybrać Formatuj formant

3. w zakładce Kontrolka należy wskazać wybraną komórkę

Tworzenie łącza komórki

Tworzenie łącza komórki

Teraz, gdy checkbox będzie zaznaczony, w komórce tej pojawi się PRAWDA, a gdy będzie odznaczony – FAŁSZ. To nam już wystarczy, by przejść (wreszcie!) do VBA.

Kod VBA

A tutaj będą dosłownie 2,5 linijki.

Logika jest taka, że jeśli jesteśmy w trybie edycji, czyli checkbox jest zaznaczony (komórka D2 ma wartość PRAWDA), makro, które opisałam poprzednio ma po prostu nie zadziałać. Natomiast, gdy checkbox jest odznaczony – wszystko ma działać jak poprzednio.

To wymaga zdefiniowanie zmiennej, np. TrybEdycji, która będzie zmienną logiczną, czyli Boolean. Dopiszemy to w drugiej linijce poprzedniego kodu po przecinku (to jest to pół linijki;)):

Private Sub Worksheet_Change(ByVal Target As Range)
  Dim Wybor As String, PoprzedniaWartosc As String, NowaWartosc As String
  Dim ZakresSprPopr As Range, TrybEdycji As Boolean

A zaraz później, jeszcze zanim włączymy obsługę błędów, wpiszemy te 2 linijki:

 TrybEdycji = Range("D2").Value
 If TrybEdycji Then Exit Sub

Pierwsza pobiera wartość komórki D2 (w niej checkbox wpisuje swoją wartość PRAWDA/FAŁSZ).

Druga sprawdza, czy ta wartość jest prawdziwa. Jeśli tak – kończy tę procedurę.

Na szczęście wersja językowa Excela nie ma znaczenia. VBA cudownie radzi sobie z polskim PRAWDA/FAŁSZ odpowiednio je interpretując. Między innymi dlatego też zdecydowałam się na kontrolkę checkboxa;)

Wszystko w całości wygląda tak:

Private Sub Worksheet_Change(ByVal Target As Range)
 Dim Wybor As String, PoprzedniaWartosc As String, NowaWartosc As String
 Dim ZakresSprPopr As Range, TrybEdycji As Boolean
 
 TrybEdycji = Range("D2").Value
 If TrybEdycji Then Exit Sub
 
On Error GoTo Obsluga
 Wybor = Target.Value
 
 Set ZakresSprPopr = Cells.SpecialCells(xlCellTypeAllValidation)
 If Intersect(Target, ZakresSprPopr) Is Nothing Or Wybor = "" Then Exit Sub
 
 If Target.Validation.Type = 3 Then
 Application.EnableEvents = False
 Application.Undo
 PoprzedniaWartosc = Target.Value
 
 If PoprzedniaWartosc = "" Then
 Target.Value = Wybor
 Else
 NowaWartosc = PoprzedniaWartosc & vbNewLine & Wybor
 Target.Value = NowaWartosc
 End If
 
 End If

Obsluga:
 Application.EnableEvents = True
 
End Sub

Efekt wszystkiego najlepiej zobaczyć tutaj:

Albo na filmie, gdzie krok po kroku opisuję tworzenie tego rozwiązania:

 

 

Wyświetlanie tylko niektórych strzałek autofiltru

$
0
0

Czyli jak zrobić, żeby wyświetlać strzałki autofiltru tylko przy niektórych kolumnach?

Najprostsza odpowiedź to: nie da się :). Bo faktycznie, tak po prostu się nie da. Trzeba do tego zaangażować VBA. Nie wymaga to jednak pisania żadnej procedury, więc nasz plik może mieć zwykłe rozszerzenie .xlsx. Natomiast, żeby osiągnąć żądany efekt, musimy na chwilę wejść do edytora VBA…

Efekt osiągniemy taki:

Efekt końcowy

Efekt końcowy

Zaczynamy!

Najpierw uruchomimy sobie VBE, czyli skrót klawiszowy Alt + F11.

Następnie uruchomimy okienko Immediate, czyli okienko, do którego możemy wpisywać kod VBA, bez umieszczania go w procedurze, aby go szybko wykonać. Aby pokazać to okienko, wystarczy wcisnąć skrót klawiszowy Ctrl + G, lub z menu wybrać View / Immediate window.

Okienko Immediate

Okienko Immediate

A w tym okienku wystarczy tylko wpisać następujący kod:

Range("C4").AutoFilter Field:=1, VisibleDropDown:=False

W powyższym kodzie istotne jest to, żeby jako Field wskazać numer pola, przy którym ma się nie wyświetlić strzałka. Natomiast pamiętajcie, że ten numer jest to numer kolumny zakresu, na którym założony jest autofiltr, a nie numer kolumny arkusza. Czyli identycznie jak w funkcji WYSZUKAJ.PIONOWO, którą tłumaczę np. tutaj.

Natomiast Range(„C4”) to po prostu komórka zakresu, na którym jest ten filtr. Nie musi to być koniecznie C4, ale ona jest pierwszą komórką zakresu, więc przynajmniej wiadomo, o co chodzi.

I to tyle. Cała magia 🙂

Pliku nie załączam, bo nie ma czego, ale za to jest film:

PS O! Ten to dopiero krótki wpis 😉

 

Odzyskiwanie formuły po nadpisaniu jej wartością

$
0
0

Czyli formuła, której nie da się skasować…

Załóżmy, że tworzymy szablon oferty, taki jak na obrazku poniżej. Chcemy wybierać z listy rozwijanej model produktu i na tej podstawie ma się podpowiedzieć cena netto. Cena ta jest pobierana z cennika, który znajduje się w innym arkuszu. To wszystko mamy już gotowe, natomiast chcemy mieć możliwość ręcznego wpisywania cen jednostkowych. TO oczywiście jest możliwe, natomiast jak to zrobimy – bezpowrotnie tracimy formułę, która wcześniej tę cenę podpowiadała.

I w tym zadaniu chodzi o to, aby po skasowaniu tej ręcznie wpisanej wartości, automatycznie wpisywała się formuła, która tam była…

Formatka

Formatka

Bez VBA się nie obejdzie 🙂

Czyli chodzi o to, aby w jakiś sposób wyłapać, że użytkownik skasował wartość w komórce z ceną i wstawić w nią określoną formułę. Musimy zatem znów skorzystać ze zdarzeń arkusza, a konkretnie ze zdarzenia Change, ponieważ będziemy sprawdzać zmiany po tym, jak user coś zmieni (change) w arkuszu.

Określanie komórek do sprawdzania

W tym celu najpierw określimy, jakie komórki będą nas interesowały, czyli do jakich komórek mamy ewentualnie wstawiać formułę. Zakres ten sobie najpierw nazwiemy.

Czyli zaznaczamy komórki z ceną netto, czyli E3:E9, klikamy w polu nazwy i wprowadzamy tam nazwę np. CenaNetto. Wpis zatwierdzamy Enterem.

Pobranie istniejącej formuły

Kolejny krok to przetłumaczenie na angielski formuły, która znajduje się w komórkach z cenami netto. Ta formuła to u mnie:

=JEŻELI.BŁĄD((WYSZUKAJ.PIONOWO(D3;Cennik!$B$3:$D$25;3;0));0)

Na angielski trzeba ją przetłumaczyć dlatego, że VBA potrzebuje jej w takim właśnie języku. Można to zrobić oczywiście „ręcznie”, ale ja polecam prostszą metodę: nagranie makra z wpisywaniem tej formuły do komórki. Skorzystamy z faktu, że ona już tam jest i jedyne co zrobimy podczas nagrywania tego makra, to wejście do edycji tej komórki i zatwierdzenie wpisu w niej. Prościutkie 🙂

Czyli poszczególne koki to:

  1. Zaznacz komórkę E3
  2. W menu Deweloper kliknij przycisk Zarejestruj makro (pokazanie karty Deweloper na wstążce omawiałam tutaj)
  3. Wejdź do edycji komórki E3 (czyli np. klawisz F2)
  4. Naciśnij Enter
  5. Zatrzymaj rejestrowanie makra (Deweloper/ Zatrzymaj rejestrowanie)

Tyle. Teraz w oknie VBE (Alt + F11) powinien pokazać się nowy moduł (np. Module1), a w nim procedura z naszym nagranym makrem:

Sub Makro1()
'
' Makro1 Makro
'
'
    Selection.FormulaR1C1 = _
        "=IFERROR((VLOOKUP(RC[-1],Cennik!R3C2:R25C4,3,0))*R6C7*R7C7,0)"
End Sub

To sobie teraz zostawiamy na później i idziemy do zdarzenia arkusza…

Zdarzenie arkusza

To bowiem jest miejsce, które powie Excelowi, że ma coś wykonać, gdy user zmienić wartość komórki. Oczywiście Excel będzie sprawdzał każdą komórkę w określonym przez nas arkuszu, ale z tym też sobie poradzimy :).

Najpierw określmy, w którym arkuszu w ogóle ma sprawdzać, czyli działać makro. U mnie jest to arkusz o nazwie kalkulator, więc po wejściu do VBE (Visial Basic Editor), w okienku Project Explorer, dwa razy klikam w taki właśnie arkusz. Następnie z list rozwijanych w prawym oknie wybieramy:

(1) Worksheet, i

(2) Change

Oba te kroki dokładnie opisałam tutaj.

Po wyborze Change pojawi się następujący kod:

Private Sub Worksheet_Change(ByVal Target As Range)
       
End Sub

Nasz kod wpiszemy dokładnie pośrodku tych linijek.

Kod VBA

A zaczniemy od deklaracji zmiennej, oznaczającej nasz zakres do sprawdzenia:

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim Zakres As Range
      
End Sub

Od razu możemy dorzucić sobie linijki obsługujące błędy i zabijające zmienną obiektową Zakres:

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim Zakres As Range
    
    On Error GoTo Obsluga
    
Obsluga:
    Set Zakres = Nothing
    
End Sub

Błędy bowiem mogą się pojawić, gdy np. user skasuje więcej niż jedną komórkę. A błędów, objawiających się brzydką, szarą tabliczką nie chcemy… :). Powyższe linijki więc mówią, że jeśli jakiś błąd się pojawi – idziemy na koniec procedury, gdzie następuje jedynie zabicie zmiennej obiektowej i zakończenie makra. Nie chcę tutaj rozmyślać, co ma się stać gdy wyskoczy błąd taki, albo śmaki – wszystkiego nie przewidzę i w tej sytuacji nawet nie chcę. To ma być proste i działać tylko wtedy, gdy user usunie wartość z komórki z ceną netto. Kropka 🙂

Czyli krótko mówiąc: gdy makro napotka błąd, z punktu widzenia użytkownika nic się nie dzieje. I tak ma być :).

Ok, to teraz co, jeśli wszystko odbędzie się zgodnie z planem.

No po pierwsze user może skasować/zmienić dowolną komórkę arkusza. Ale na dowolną nie chcemy reagować, tylko na taką, która znajduje się we wcześniej nazwanym zakresie CenaNetto i dodatkowo właśnie stała się pusta.

Czyli potrzebujemy przypisać do zmiennej obiektowej Zakres – arkuszowy zakres CenaNetto.

    Set Zakres = Me.Range("CenaNetto")

Słówko me oznacza w tym wypadku arkusz, w którym tworzymy zdarzenie.

Kolejny krok to zbadanie, czy zmieniona komórka (Target) znajduje się w naszym Zakresie i czy jest pusta. Zrobi to ten if i obiekt Intersect:

    If Not Intersect(Zakres, Target) Is Nothing And Target.Value = "" Then
        
    End If

A w środku to już prosto: jeśli oba powyższe warunki są spełnione, to formułą w zmienionej komórce ma być ta formuła, dla której wcześniej nagrywaliśmy makro, aby ją przetłumaczyć. Teraz wystarczy sobie ją tylko przekopiować między modułami, aby uzyskać to:

    If Not Intersect(Zakres, Target) Is Nothing And Target.Value = "" Then
        Target.FormulaR1C1 = "=IFERROR((VLOOKUP(RC[-1],Cennik!R3C2:R25C4,3,0)),0)"
    End If

Wszystko do kupy wygląda tak:

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim Zakres As Range
    
    On Error GoTo Obsluga
    
    Set Zakres = Me.Range("CenaNetto")
    
    If Not Intersect(Zakres, Target) Is Nothing And Target.Value = "" Then
        Target.FormulaR1C1 = "=IFERROR((VLOOKUP(RC[-1],Cennik!R3C2:R25C4,3,0)),0)"
    End If
Obsluga:
    Set Zakres = Nothing
    
End Sub

Śmiga pięknie! Uzyskujemy też śmieszny efekt, że formuły nie da się skasować 🙂

Na koniec pamiętaj tylko o zapisaniu pliku z obsługą makr, czyli jako *.xlsm. Bez tego ani rusz!

A jeśli wolisz omówione kroki obejrzeć na filmie, to zachęcam do obejrzenia poniżej:

 

Załączam też plik z gotowcem:

 

 

 


Wzrost czy spadek, czyli Ikony formatowania warunkowego

$
0
0

W tym wpisie pokażę jak zrobić zieloną strzałkę w górę, gdy nasza np. sprzedaż wzrosła o 5% lub więcej w stosunku do poprzedniego roku, i czerwoną strzałkę w dół, gdy ta sprzedaż spadła o 5% lub więcej. Chodzi o coś takiego:

 

Formatka

Formatka

W sumie to te strzałki to bardziej trójkąty, ale wiadomo o co chodzi :). Wykorzystam do tego moje ukochane formatowanie warunkowe.

Bring it on!

1. Zacznijmy od wstawienia w komórkę F4 (i niżej) prostej formuły, która wyświetla identyczną wartość, co komórka obok:

=E4

Robimy to po to, aby w tej komórce wyświetlić strzałkę, ponieważ strzałki chcę widzieć poza tabelką.

2. Teraz zaznacz te formuły i wejdź do Narzędzia główne/ Formatowanie warunkowe/ Zestaw ikon. I wybierz zestaw (najlepiej 3-elementowy), który najbardziej Ci się podoba (ja wybrałam trójkąty):

Wybieranie ikony

Wybieranie ikony

Już po samej tej operacji coś dostajemy, ale jeszcze nie to, co chcemy – Excel sam zdecydował za nas kiedy wyświetlać poszczególne ikony:

Po nadaniu formatowania...

Po nadaniu formatowania…

3. Będziemy więc edytować utworzoną właśnie regułę formatowania warunkowego. W tym celu zaznacz dowolną komórkę zakresu z naszym formatowaniem i wejdź do Narzędzia główne/ Formatowanie warunkowe/ Zarządzaj regułami… i z listy wybierz naszą regułę. Zaznaczenie komórki jest o tyle istotne, że wtedy od razu zobaczymy tę regułę na liście reguł, gdyż Excel domyślnie wyświetla reguły dl bieżącego zaznaczenia. Po wybraniu naszej reguły na liście, kliknij przycisk Edytuj regułę (jak jest tylko jedna reguła na liście, to nawet nie musisz jej zaznaczać):

Otwieranie edycji reguły formatowania warunkowego

Otwieranie edycji reguły formatowania warunkowego

4. Otworzy się wtedy okienko edycji reguły, w której należy wybrać:

  1. Checkbox: Pokaż tylko ikonę (ukrywamy w ten sposób wartość komórki)
  2. W dwóch polach Typ wybrać opcję Liczba (aby ustalić liczbę powyżej i poniżej których ma działać reguła)
  3. Zamienić drugą ikonę (żółtą kreskę) na Brak ikony komórki (nie chcemy trzeciej ikony pośrodku)
  4. W pola z wartościami wpisać odpowiednio: 0,05 i -0,05.

Tak, jak na poniższym obrazku:

Edycja reguły formatowania warunkowego

Edycja reguły formatowania warunkowego

5. Po zatwierdzeniu wszystkich możliwych okienek, otrzymamy taki efekt:

Wynik

Wynik

Takie to prościutkie 🙂

A poniżej sposób na zrobienie tego w wersji wideo:

 

Poniżej plik do pobrania:
I plik z gotowcem do pobrania:MalinowyExcel Ikony formatowania warunkowego dw.xlsx

 

 

WYSZUKAJ.PIONOWO, PODAJ.POZYCJĘ i niewyświetlanie zer

$
0
0

Czyli przyporządkowanie ceny i kodu produktu, na podstawie jego kolekcji i modelu

Załóżmy, że sprzedajemy ubrania. Dzielimy je sobie na kolekcje, które mają różne modele. Wybieramy sobie kolekcję i model i na tej podstawie ma nam się wyświetlić indeks i cena danego ubrania. To jest zadanie na teraz, przy czym formatka wygląda tak:

Formatka

Formatka

Czyli wybieramy najpierw kolekcję z listy rozwijanej w komórce A2 (tak, wiem, że wygląda na to, że nic w niej nie ma, a to dlatego, że zastosowałam do niej takie formatowanie ;)), a następnie model w komórkach kolumny Model. Wpisujemy ilość, a kod produktu i cena same mają się pojawić.

Jak sugeruje tytuł tego posta, użyję do tego dwóch funkcji: WYSZUKAJ.PIONOWO i PODAJ.POZYCJĘ. Natomiast powiem Wam, że najfajniejszym trikiem będzie ukrycie zer (zwracanych przez formuły). Nie użyję do tego bowiem pustego ciągu tekstowego, czyli dwóch cudzysłowów obok siebie („”), tylko formatowania niestandardowego… Warto więc doczytać do końca 🙂

Zrobienie list rozwijanych opisuję tutaj, więc przejdę dalej. Istotne są w naszym ćwiczeniu tabele z danymi: kodami/inddeksami i z cenami. Zauważcie, że nagłówkami kolumn są modele, a nagłówkami wierszy – kolekcje. Kolejność nie ma znaczenia, można zrobić odwrotnie, ale ważne jest, aby nazwy modeli i kolekcji były dokładnie takie same, jak na listach rozwijanych na formatce.

Jak już to jest, to możemy przejść do formuł.

Wyświetlanie kodu

Szukać będziemy kolekcji w tabelce z kodami. Będą to też nasze pierwsze dwa argumenty naszej kochanej WYSZUKAJ.PIONOWO. Szukać będziemy dokładnie, więc w ostatnim argumencie wpiszemy zero (0). Problem pojawia się jedynie przy trzecim argumencie, ponieważ nie wiemy, którą kolumnę wyświetlić.

Tutaj z pomocą przyjdzie nam właśnie funkcja PODAJ.POZYCJĘ, której każemy znaleźć nasz model w wierszu nagłówkowym tabeli. Funkcja ta wyświetli jedynie numer komórki, w której znajduje się nasz model, a będzie to niejednoczenie numer kolumny, którego potrzebuje od nas WYSZUKAJ.PIONOWO. Tadam!

Formułą jest następująca (C4):

=JEŻELI.BŁĄD(WYSZUKAJ.PIONOWO($A$2;$A$16:$D$19;PODAJ.POZYCJĘ($A4;$A$15:$D$15;0);0);0)

Wszystko wrzuciłam jeszcze w funkcję JEŻELI.BŁĄD, jeśli jakiś błąd się pojawi. A takiż może się pojawić, gdy user nie wybierze jeszcze modelu. W przypadku błędu chcę, aby funkcja wyświetliła zero. I tak wiem, że będzie to głupio wyglądało, natomiast poradzę sobie z tym za chwilę :).

Wyświetlanie ceny

Praktycznie identyczna formułkę zastosujemy do wyświetlenia ceny, z tą tylko różnicą, że każemy przeszukiwać tabelkę z cenami, a nie kodami. Oto ona (D4):

=JEŻELI.BŁĄD(INDEKS($B$23:$D$26;PODAJ.POZYCJĘ($A$2;$A$23:$A$26;0);PODAJ.POZYCJĘ(A4;$B$22:$D$22;0));0)

Wartość

Wartość sprzedaży jest już prosta, czyli (E4):

=B4*D4

Choćby dlatego wolę wyświetlać zero w przypadku błędu WYSZUKAJ.PIONOWO: formuły w stylu tej liczącej wartość ładnie się policzą. Gdybym kazała wyświetlać pusty tekst („”) w przypadku błędu – formuła licząca cenę wyświetliłaby błąd (#ARG!) i tak w koło Macieju… A Excel umie pomnożyć jakąś liczbę razy zero, wiec jeden problem mniej :).

Efekt tego jest na razie taki (wpisałam kilka modeli):

Po wpisaniu formuł

Po wpisaniu formuł…

Widać brzydkie zera, ale przynajmniej wszystko się liczy. To pozbądźmy się tych zer…

Alternatywna formuła z INDEKS i PODAJ.POZYCJĘ

To samo można też zrobić wymienionymi wyżej funkcjami. Formuła dla ceny wyglądałaby tak:

=JEŻELI.BŁĄD(INDEKS($B$23:$D$26;PODAJ.POZYCJĘ($A$2;$A$23:$A$26;0);PODAJ.POZYCJĘ(A4;$B$22:$D$22;0));0)

Jak ukryć zera?

Należy do tego użyć formatowania niestandardowego.

1. Czyli zaznaczmy wszystkie komórki, w których chcemy ukryć zera. Ja na razie zaznaczę ceny i wartości (D4:E12), ponieważ przy okazji dorzucę separator tysięcy (nie potrzebuję miejsc dziesiętnych, ale oczywiście można byłoby je też tutaj dorzucić).

2. Następnie wchodzimy do formatowania komórki (skrót klawiszowy Ctrl +1)

3. Z zakładki Liczby wybieramy kategorię Niestandardowe. A w nim wpisujemy następujący typ formatowania:

# ##0;-# ##0;

W okienku wygląda to tak:

Formatowanie niestandardowe

Formatowanie niestandardowe

Zapis ten oznacza, że liczby dodatnie mają być wyświetlone z separatorem tysięcy, ujemne też, ale dodatkowo ze znakiem minus, a zera jako nic. Czyli zera niewyświetlane.

Dla kolumny z kodami z kolei, również w formatowaniu niestandardowym, skorzystam z takiego formatu:

Standardowy;-Standardowy;

To s kolei oznacza, że dodatnie i ujemne mają zostać wyświetlone w formacie ogólnym (nie chcę w żaden sposób ich formatować), a zera, jak poprzednio, nie będą wyświetlane.

W takim zapisie istotna jest kolejność: najpierw definiujemy jak mają wyglądać liczby dodatnie, potem ujemne, potem zero, a na końcu tekst. Ale tekstu akurat teraz nie wykorzystuję.

Wszystko razem wygląda tak:

Wynik

Wynik

I tyle :).

I wersja wideo tego wpisu (pokazuję na nim alternatywę z funkcjami INDEKS i PODAJ.POZYCJĘ):

 

 

 

Suwak zmienia 2 wartości jednocześnie

$
0
0

Czyli o formantach formularza…

Załóżmy, że chcemy wpisywać do arkusza 2 liczby, których suma zawsze wynosi 50. Obie te liczby chcemy wpisywać za pomocą takiego suwaka, jak na formatce:

Formatka

Formatka

Problem jest jednak taki, że suwak może zmienić tylko wartość jednaj komórki, a nie dwie. Na szczęście ze względu na to, że suma tych liczb zawsze ma dać w wyniku 50, wystarczy, że wpiszemy do arkusza jedną z nich, a druga zostanie wyliczona. Dzięki temu za pomocą suwaka wpiszemy wartość tylko do jednej komórki. Problem solved!

Teraz tylko pytanie, jak to zrobić technicznie?

Wstawianie suwaka

Zacznijmy od wstawienia suwaka, czy raczej paska przewijania, jak to się oficjalnie nazywa ;). Aby to zrobić, należy na karcie Deweloper (tutaj pokazuję jak go dodać), w sekcji formanty, nacisnąć przycisk Wstaw i wybrać z niego Pasek przewijania:

Wstawianie suwaka

Wstawianie suwaka

A potem prace plastyczno-techniczne, czyli ręczne rysowanie suwaka takiego, jaki chcemy.

Kolejna sprawa to ustawianie jego właściwości. Czyli klikamy prawym przyciskiem myszy na suwak i z menu kontekstowego wybieramy Formatuj formant.

Ustawianie właściwości suwaka

Ustawianie właściwości suwaka

Wejdziemy do okienka Formatownaie formantu i tam, w zakładce Kontrolka, wybieramy:

  • Wartość maksymalna: 50
  • Zmiana przyrostowa: 1 (czuli o ile ma się zwiększyć/zmniejszyć wartość, gdy user kliknie w strzałki suwaka)
  • Łącze komórki: $D$5 (wskazujemy tę komórkę, do której ma zostać wpisana wartość wybrana za pomocą suwaka)

Wygląda to tak:

Właściwości suwaka

Właściwości suwaka

Po zatwierdzeniu przyciskiem OK nasz suwak będzie pięknie śmigał.

Formuła, licząca drugą wartość

Teraz pozostaje już napisanie formuły, która liczy drugą wartość. Wpiszemy ją do komórki D6:

=50-D5

Czyli od stałej wartości 50 (mogę ją wpisać z palca lub odwołać się do komórki, która ją zawiera) odejmujemy tę wpisaną przez suwak. That’s it!

PS TO chyba najbardziej skomplikowana formuła, jaką zamieściłam na blogu 😉

Teoretycznie mogłabym na tym zakończyć, ale aż się prosi tutaj, aby ochronić ten arkusz, żeby user na np. nie popsuł formuł albo nie skasował suwaka (przydałoby się też ustawić sprawdzanie poprawności danych, jakby postanowił ręcznie wpisać wartość, ale już bez przesady :)).

Ochrona arkusza

Żeby umożliwić userowi, a konkretnie suwakowi, zmianę tylko komórki D5, należy założyć na arkusz ochronę (reszta komórek i suwak! mają być zablokowane do edycji). Zanim jednak to zrobimy, ustawmy tej komórce możliwość edycji. Domyślnie bowiem każda komórka w Excelu jest zablokowana do edycji, gdy arkusz jest chroniony. My akurat chcemy pozwolić na modyfikację komórki D5, więc w tym celu wchodzimy do formatowania tej komórki (Ctrl + 1). Tak formatowania.

I tam, w zakładce Ochrona wystarczy odznaczyć checkbox Zablokuj:

Odblokowywanie komórki

Odblokowywanie komórki

Warto również w komórce D7 ukryć formułę. Tak na wszelki wypadek, żeby user nie zauważył tego skomplikowanego obliczenia matematycznego :). Żeby to zrobić też należy wejść do formatowania komórki, natomiast zaznaczyć oba checkboxy: Zablokuj  Ukryj:

Ukrywanie formuły w komórce

Ukrywanie formuły w komórce

Ukrycie formuły spowoduje, że nawet jak user zaznaczy komórkę, to w pasku formuły nie zobaczy jaka tam jest formuła. Awesome!

Żeby zadziałało, trzeba teraz ochronić arkusz, czyli np. menu Recenzja/Chroń arkusz. BTW: hasło jest opcjonalne.

I to wszystko :). Pomogłam?

A tutaj film wideo z prezentacją powyższych zagadnień krok po kroku:

 

 

 

Funkcja SUMA źle liczy!

$
0
0

… i co zrobić, żeby ją naprawić?

Trochę dziwnie brzmi tytuł tego wpisu, ponieważ oczywiście funkcja SUMA dobrze liczy :). Natomiast nam użytkownikom czasem może się wydawać, że jednak SUMA liczy źle. Nic dziwnego, jak widzimy coś takiego:

Suma liczb w ramce jest zdecydowanie większa niż 61, mimo tego, co twierdzi funkcja SUMA. Co więc jest z nią nie tak? Rozwiązanie tej zagadki jest bardzo proste i ma związek z postawami Excela, a mianowicie z typem danych, jakie przechowujemy w komórce. Te podstawy warto znać 😉

 

Na początku warto zdać sobie sprawę z tego, że to nie z funkcją SUMA jest coś nie tak, tylko z danymi, które dostała.

Przyjrzyj się dokładnie danym: Twój niepokój powinien wzbudzić fakt, że wszystkie wartości w czarnej ramce (czyli sumowane wartości) są wyrównane do prawej strony (specjalnie tak zrobiłam przykład, żeby było to widać, choć zdaję sobie sprawę z tego, że nie zawsze jest to takie oczywiste). Mamy tam zarówno wartości liczbowe, tekstowe jak i logiczne (PRAWDA). Każdy z tych typów danych powinien być wyrównany inaczej, czyli:

  • teksty do lewej
  • liczby do prawej
  • logiczne do środka

A nie są. To znaczy, że user ręcznie zmienił wyrównanie komórek! Grzech!!! Przez to teraz mamy problem :). Co do zasady nie powinno się zmieniać domyślnego wyrównania komórek, właśnie dlatego, że może to wprowadzić w błąd. Wyjątkiem od tej zasady są nagłówki tabel, które możemy wyrównać zgodnie z wyrównaniem zawartości kolumny, której są nagłówkiem.

To są podstawy, ale niestety często o nich zapominamy, albo – co gorsza – nie znamy ich ;(

Przywracanie wyrównania ogólnego

Zmieńmy zatem wyrównanie tych komórek na ogólne. Możesz to zrobić w Narzędziach głównych klikając na ikonkę wyrównania do prawej strony (zobacz, że jest zaznaczona dla tych danych!) lub poprzez okienko formatowania komórek (skrót klawiszowy, Ctrl + 1).  W obu przypadkach najpierw zaznacz dane, które chcesz formatować (czyli w tym przykładzie czarną ramkę):

Przywracanie wyrównania ogólnego

Przywracanie wyrównania ogólnego

Widać na powyższym rysunku wynik przywróconego wyrównania. Liczby do prawej, teksty do lewej i wartości logiczne na środek.

Ale zaraz! Niektóre liczby: 34, 75 i 3 są do lewej! I tutaj jest pies pogrzebany. Te liczby to dla Excela teksty! A on nie umie sumować tekstów. Należy więc, specjalnie dla Excelka, dokonać konwersji tekstu na liczby, czyli przerobić teksty na liczby :).

Wklejanie specjalne z operacją

Aby dokonać takiej konwersji, należy wykonać na tych „liczbach” dowolną operację matematyczną, która nie zmieni ich wartości (tego akurat nie chcemy ;)). Takimi operacjami są dodanie lub odjęcie zera, pomnożenie lub podzielenie liczby przez 1 lub tzw. podwójna negacja, czyli dwukrotne pomnożenie liczby razy -1 (ostatni sposób jest najszybszy w formułach).

Moją ulubioną i jednocześnie najszybszą metodą na zrobienie tego jest wklejanie specjalne z operacją np. mnożenia. Żeby to zrobić:

  1. wpisz liczbę 1 w dowolną komórkę poza zakresem danych,
  2. skopiuj ją (Ctrl + c)
  3. zaznacz zakres danych, który chcesz przekonwertować (u nas: czarna ramka)
  4. kliknij na tym zakresie prawym przyciskiem myszy i z menu podręcznego wybierz opcję Wklej specjalnie…
  5. w okienku, które się pojawi, zaznacz: Wartości i Przemnóż (może być też Podziel – nie ma to znaczenia, ponieważ jeśli liczbę pomnożysz lub podzielisz przez jeden – otrzymasz dokładnie tę szamą liczbę)
Konwersja tekstu na liczby poprzez wklejanie specjalne

Konwersja tekstu na liczby poprzez wklejanie specjalne

Po naciśnięciu OK robota zrobiona!

Wynik jest taki:

Wynik

Wynik

I to tyle – takie proste i jednocześnie zbawienne :). Cała trudność w wykryciu takich baboli. Na szczęście wystarczy sięgnąć do podstaw 🙂

BTW Ten temat już poruszałam na blogu, natomiast kontekst był nieco inny, więc postanowiłam jeszcze raz o tym napisać, omawiając ten nowy kontekst. A raczej inny kontekst…

Poniżej plik z błędnymi danymi do pobrania:

Malinowy Excel Funkcja SUMA źle liczy dw.xlsx

I wersja wideo przedstawionego rozwiązania:

 

 

Odzyskiwanie różnych formuł po nadpisaniu ich wartością

$
0
0

Czyli trudna rzecz rozwiązana prostą metodą

Niedawno opisywałam już podobny przypadek, natomiast dotyczył on trochę łatwiejszej sytuacji. Chodziło bowiem o to, żeby dać użytkownikowi możliwość wpisania do jednej komórki wartości z palca, lub skorzystania z wpisanej tam formuły. Taki switch: chcę wartość, to ją wpiszę, a jak ją skasuję, to na jej miejscu pojawi się formuła. Cudo!

Wtedy jednak opisywałam sytuację, gdy w komórce ma się pojawić tylko jedna, określona formuła. Teraz natomiast chodzi o to, żeby mogły się tam pojawiać różne formuły, w zależności od komórki, którą będę edytowała. Brzmi strasznie, ale jest bardzo proste. Wymaga tylko kolumny pomocniczej i leciutkiej edycji kodu VBA, który napisałam dla poprzedniej sytuacji.

Formatkę i całą magię pokazuje ten rysunek:

Formatka

Formatka

Let’s go!

W rozwiązaniu, które wymyśliłam idę na łatwiznę (jak zwykle ;)). Pomyślałam sobie, że stworzę w arkuszu kolumnę (szara kolumna I), w której będą napisane formuły, które chcę odzyskać, gdy user skasuje wartość w komórce (z kolumny Jednostkowa cena netto). Tę kolumnę roboczą (I) ukryję i jedyne co makro będzie robiło innego niż poprzednio, to podbierało wartość z odpowiedniej komórki tej ukrytej kolumny. Nawet nie trudzę się, żeby wpisywało identyczną formułę. Dla użytkownika i tak to nie ma znaczenia – on chce widzieć określoną wartość :). O rety, ale sprytne 🙂

Całą modyfikacja w kodzie sprowadza się do tej jednej linijki:

Target.FormulaR1C1 = "=RC[4]"

Czyli cały kod, dla przypomnienia, wygląda tak:

Private Sub Worksheet_Change(ByVal Target As Range)
 Dim Zakres As Range
 
 On Error GoTo Obsluga
 
 Set Zakres = Me.Range("Ceny")
 
 If Not Intersect(Zakres, Target) Is Nothing And Target.Value = "" Then
 Target.FormulaR1C1 = "=RC[4]"
 End If
Obsluga:
 Set Zakres = Nothing
 
End Sub

I wszystko. Moim zdaniem efekt jest super, przy minimalnym nakładzie pracy. Czyli to, o co zazwyczaj chodzi 😉

Tutaj znajdziesz plik z rozwiązaniem do pobrania (oczywiście zawiera makra!):

A tutaj wersję wideo:

 

 

Wesołych (wiosennych) Świąt!

Wyróżnianie najmniejszej wartości w wierszu

$
0
0

Czyli sprytne użycie formatowania warunkowego…

Załóżmy, że chcemy dla w każdym wierszu tabeli wyróżnić najmniejszą wartość. Oczywiście chcemy to zrobić możliwie szybko, małym nakładem pracy i jeszcze tak, żeby rozwiązanie było dynamiczne, czyli jeśli zmienimy jakąś wartość – wyróżnienie się do tego dostosuje i na bieżąco sprawdzi, czy owa zmieniona nie jest najmniejsza. Mamy kilka magazynów (może być kilkanaście albo kilkaset dla większego dramatyzmu;)) i w każdym z nich, chcemy wyróżnić najmniejszą wartość w tygodniu:

Formatka 1

Formatka 1

Albo druga sytuacja, na tych samych danych: chcemy zaznaczyć cały wiersz, jeśli w tym wierszu znajdzie się najmniejsza wartość z wybranej kolumny (np. 4). Załóżmy, że w czwartek przychodzi kontrola do magazynu i chcemy wiedzieć, który magazyn tego dnia miał najmniejsze stany. I chcemy podświetlić cały wiersz dla tego magazynu, aby analizować stany jego magazynowe w całym tygodniu:

Formatka 2

Formatka 2

Oczywiście bez formatowania warunkowego tutaj się nie obejdzie. Formatowanie to będzie wymagało też napisania formuły, która zdefiniuje warunek. Czyli coś bardziej skomplikowanego, niż „wyklikanie” formatowania, jak to w wieeelu przypadkach wystarczy…

1. Wyróżnianie najmniejszej wartości w wierszu

W tym przypadku, w każdym wierszu naszego zakresu (C4:I9) chcemy zaznaczyć najmniejszą wartość w danym wierszu. Problem jest taki, że piszemy w tym celu jedną regułę formatowania warunkowego. Musi zatem być uniwersalna dla każdego wiersza zakresu.

W takich sytuacjach koniecznie będziemy musieli działać z adresowaniem komórek, czyli dolarami ($). To tak, jak pisanie jednej formuły dla dwuwymiarowego zakresu, czyli takiego, który składa się z kilku wierszy i kilku kolumn (klasyczny przykład takiego: tabliczka mnożenia).

Tutaj chcemy, aby dla każdej komórki w wierszu, w odpowiednich komórce wierszach, ale zawsze w obrębie kolumn od C do I (czyli np. w zakresie: C4:I4) Excel sprawdzał czy wartość konkretnej komórki jest najmniejszą w tym zakresie. I to mamy sprawdzić dla każdej komórki (stąd analogia do kopiowania formuły do dwuwymiarowego zakresu). W praktyce oznacza to, że każdą komórkę trzeba porównać do wartości minimalnej tego zakresu. Jeśli warunek ten będzie prawdziwy – formatowania warunkowe pokoloruje komórkę. Wartość najmniejszą zbadamy oczywiście funkcją MIN.

Czyli każdą komórkę w całym zakresie będziemy porównywać: niezależnie od tego, gdzie ona w tym zakresie się znajduje. Będziemy porównywać ją natomiast do wartości minimalnych konkretnych wierszy. Czyli warunek formatowania warunkowego będzie wyglądał tak:

=C4=MIN($C4:$I4)

Warto zauważyć, że funkcja MIN szuka najmniejszej wartości w zakresie z zablokowanymi kolumnami i odblokowanymi wierszami. Kolumny są zablokowane, ponieważ funkcja MIN ma szukać wartości minimalnej zawsze od C do I. Zakres tych kolumn jest stały i nie może się przesunąć w prawo (a tak własnie by się stało, gdybyśmy nie blokowali kolumn): czyli zarówno komórkę C4 jak i G4 mamy porównywać do najmniejszej wartości zakresu $C4:$I4. Natomiast dla komórki C5 i G5 ma to być już zakres $C5:$I5. Stąd z kolei zmieniają się wiersze.

To jak już formułę mamy omówioną, to kwestia nadania formatowania warunkowego:

1. Zaznacz zakres C4:I9, zaczynając zaznaczenie od komórki C4 – to bardzo ważne!

 

2. Wybierz z menu: Narzędzia główne/ Formatowanie warunkowe/ Użyj formuły do określenia komórek, które należy sformatować

3. W pole Edytuj opis reguły wpisz wcześniej ustaloną formułę. Jak na obrazku:

Reguła formatowania 1

Reguła formatowania 1

I tyle. Efekt mamy taki:

Najmniejsze wartości w wierszach - wynika

Najmniejsze wartości w wierszach – wynik

2. Wyróżnianie całego wiersza

Drugi case już pójdzie szybciej, po zrozumieniu tego wyżej. Tutaj mamy zaznaczyć cały wiersz, jeśli występuje w nim najmniejsza wartość wybranej kolumny. U nas będzie to kolumna F, czyli czwartek (trochę niefortunnie nazwałam ją cyfrą, ech).

Czyli będziemy teraz szukali wartości minimalnej w kolumnie F, konkretnie w zakresie $F$14:$F$19. Zawsze w nim, dlatego zablokowałam go bezwzględnie. Czyli będzie MIN($F$14:$F$19).

I do tego będziemy porównywać tylko jedną komórkę z wiersza: tę w kolumnie F. Ale, żeby podświetlić cały wiersz, musimy dla każdej komórki sprawdzić ten warunek. Ten, czyli porównujący komórkę w kolumnie F z tego wiersza do wartości minimalnej wspomnianego zakresu. Reguła formatowania warunkowego będzie więc taka:

=$F14=MIN($F$14:$F$19)

A wszystko należy wrzucić do nowej reguły formatowania warunkowego, czyli jeszcze raz:

1. Zaznacz zakres B14:I19 (lub jeśli chcesz wyróżniać też sumę to zakres: B14:J19), zaczynając zaznaczenie od komórki B14 – to bardzo ważne!

2. Wybierz z menu: Narzędzia główne/ Formatowanie warunkowe/ Użyj formuły do określenia komórek, które należy sformatować

3. W pole Edytuj opis reguły wpisz wcześniej ustaloną formułę. Jak na obrazku:

Reguła formatowania 2

Reguła formatowania 2

Po zatwierdzeniu wszystkich okienek otrzymamy taki wynik:

Wiersz z najmniejszą wartością w kolumnie - wynik

Wiersz z najmniejszą wartością w kolumnie – wynik

I wszystko :). Mam nadzieję, że Ci się przyda!

 

Poniżej plik do pobrania:
Tutaj plik z gotowcem do pobrania:Malinowy Excel Najmniejsza wartość w wierszu format war dw.xlsx

A tutaj wersja wideo:

 

 


Wyróżnianie aktywnej komórki kolorem

$
0
0

Czyli coś, o czym marzy każdy użytkownik…

… no, pewnie prawie każdy :). Ja bym się nie obraziła!

Chodzi o coś takiego:

Czyli gdziekolwiek w zakresie klikniemy – ta komórka ma się podświetlać na żółto (albo oczywiście jakikolwiek inny kolor). Tylko tyle i aż tyle, ponieważ, jak zobaczycie, to wcale nie będzie takie banalne… Do stworzenia tej magii użyję nazewnictwa komórek (choć da się bez), zdarzeń w VBA (makra) i oczywiście mojego kochanego formatowania warunkowego, do którego napiszę formułę…

Formatka do zadania wygląda tak:

Formatka

Formatka

1. Nazwanie komórki roboczej

Zacznijmy od nazwania komórki roboczej. Od razu powiem, że może być ona w innym, ukrytym arkuszu. Ja dałam ją w tym samym, aby czarno na białym widać było jej zmianę. Natomiast umiejscowienie jej nie ma znaczenia (tylko trzeba będzie odpowiednio się do niej odwołać w makrze).

Dla wygody nazwiemy tę komórkę np. KomorkaAdresu. Koniecznie to zrób zwłaszcza wtedy, gdy umieścisz ją w innym arkuszu – będzie to miało znaczenie dla formatowania warunkowego.

Aby nazwać komórkę – zaznacz ją, a następnie w polu nazwy (po lewej od paska formuły), wpisz nazwę: KomorkaAdresu. Zatwierdź Enterem i po sprawie.

Nazywanie komórki

Nazywanie komórki

2. Makro (VBA)

Kolejny etap to uzupełnianie przed chwilą nazwanej komórki.

Co powinno się w niej znajdować? Adres aktualnie zaznaczonej komórki. W jakiś sposób musimy określić, która komórka jest obecnie zaznaczona. Jakkolwiek śmiesznie to nie zabrzmi: Excel tego nie wie :). A konkretnie formuła w formatowaniu warunkowym tego nie wie. Ona umie odczytać wartość z komórki, ale nie adres aktywnej. To umie VBA. A żeby było dynamicznie zgodnie ze zmienionym zaznaczeniem, musimy użyć zdarzenia arkusza Selection Change, czyli zmiana zaznaczenia.

Aby je utworzyć, należy wejść do edytora VBA, najlepiej skrótem klawiszowym Alt + F11. Następnie w okienku Project Explorer, należy dwukrotnie kliknąć na nazwę interesującego nas Arkusza (u mnie Dane) i więc po wejściu do VBE (Visial Basic Editor), , dwa razy klikam w taki właśnie arkusz. Następnie z list rozwijanych w prawym oknie wybieramy:

(1) Worksheet, i

(2) SelectionChange (wybrane domyślnie)

Oba te kroki dokładnie opisałam tutaj.

Do procedury, która pojawiła się automatycznie wpisujemy następujący kod:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
 Dim Komorka As Range
 
 Set Komorka = Range("KomorkaAdresu")
 
 Komorka.Value = ActiveCell.Address
 
End Sub

Te kilka linijek robi tyle tyle, że do komórki, którą przed chwilą nazywaliśmy wpisujemy bezwzględny adres aktywnej komórki.

3. Formatowanie warunkowe

To teraz łączymy wszystko do kupy formatowaniem warunkowym.

Najpierw jednak zastanówmy się, kiedy w ogóle komórka zakresu ma się kolorować, czyli podświetlać. Odpowiedź nasuwa się oczywista: kiedy jest aktywna. I super, dokładnie tak jest. A jeszcze dokładniej: ma się podświetlać, kiedy jej adres jest równy wartości nazwanej komórki KomorkaAdresu.

Problem jednak w tym, że nie możemy porównać sobie tak: KomorkaAdresu = A1 (gdzie A1 ma reprezentować aktywną komórkę). To będzie oznaczało bowiem porównanie wartości tych komórek. A my chcemy adresy :).

I dlatego tutaj z pomocą przychodzi funkcja ADRES, która jako swój wynik zwraca właśnie adres komórki, określonej przez wiersz i kolumnę. Jeśli więc podamy jej te dwa argumenty – otrzymamy adres komórki. Dodatkowo podamy też trzeci argument, który określi sposób adresowania – u nas bezwzględne, czyli z dwoma dolarami ($). Pomocne będą jeszcze funkcje WIERSZ, która zwraca numer wiersza komórki, wskazanej w jej argumencie, i NR.KOLUMNY, działająca analogicznie, tylko na kolumny (zwraca numer, nie literę!).

Ale to w formatowaniu warunkowym. Najpierw należy je uruchomić:

1. Zaznacz zakres, który ma być formatowany (czyli ten, w którym aktywna komórka ma się kolorować), zaczynając od pierwszej komóki tego zakresu!!!

2. Wejdź do Narzędzia główne/Formatowanie warunkowe/ Nowa reguła/ Użyj formuły do określenia komórek, które należy sformatować

3. I wpisz następującą regułę:

=ADRES(WIERSZ(B4);NR.KOLUMNY(B4);1)=KomorkaAdresu

4. Następnie kliknij przycisk Fortmatuj i wybierz formatowanie, jakie ma być zastosowane do wyróżniania aktywnej komórki, np. żółte wypełnienie.

5. Zatwierdź wszystko i gotowe!

Powyższe kroki ilustruje rysunek:

Reguła formatowania warunkowego

Reguła formatowania warunkowego

A efekt jest magiczny, nawet, gdy komórka miała już wcześniej kolor! Cudne, prawda? To zasługa formatowania warunkowego 🙂

Koniecznie jeszcze pamiętajcie, aby zapisać plik jako plik z obsługą makr, czyli z rozszerzeniem .xlsm (lub ewentualnie .xlsb – skoroszyt binarny).

I na koniec, jak zwykle, plik z gotowcem do pobrania:
MalinowyExcel Aktywna komórka podświetlona dw.xlsm

I film z rozwiązaniem tego case’a:

 

 

WARUNKI: nowa funkcja logiczna w Excelu

$
0
0

Czyli alternatywa dla zagnieżdżania funkcji JEŻELI

Do tej pory, jeśli mieliśmy do rozwiązania jakiś bardziej złożony problem logiczny, często trzeba było zagnieździć funkcję JEŻELI i to, o zgrozo!, kilka razy. Twórcy Excela postanowili się nad nami zlitować i stworzyli funkcję, która pozwala pominąć owo zagnieżdżanie. Funkcja WARUNKI, ponieważ ją mam na myśli, występuje na tę chwilę w najnowszej wersji Excela, w modelu subskrypcyjnym (artykuł z dnia 2018-05-03).

W tym wpisie pokazuję zastosowanie tej nowej funkcji, na prostym przykładzie badania wzrostów, spadków i braków zmian sprzedaży. Formatka, której użyję ma w sobie jedynie sprzedaż z 2 lat do porównania, i kolumnę, gdzie umieścimy komentarz z wynikiem: wzrost, spadek lub brak zmian:

Formatka

Formatka

Żeby zaprezentować Wam piękno tej funkcji, najpierw omówię sposób, w jaki można było to zrobić do tej pory, a potem pokażę Wam funkcję WARUNKI w akcji 🙂

Logika problemu i „stary” sposób

Zacznę oczywiście od logiki problemu, czyli powiem po co w ogóle kombinować?

Sytuacja bowiem ma się następująco: porównujemy sprzedaż z dwóch lat: 2016 i 2017. Chcemy się dowiedzieć, czy sprzedaż w 2017 wzrosła w stosunku do 2016, spadła, czy może była taka sama? Krótko mówiąc mamy 3 opcje, takie właśnie. Funkcja JEŻELI idealnie nadaje się do tego case’a, ponieważ umie ona ocenić, czy warunek jest prawdziwy, czy fałszywy. W naszej sytuacji warunkiem może być np.: czy sprzedaż 2017 jest większa niż 2016? Problem jednak jest taki, że funkcja JEŻELI rozpatruje tylko dwie sytuacje: spełnienie tego warunku lub niespełnienie. Jak spełnimy ten warunek, to wiadomo, że mamy wzrost. Natomiast jak nie spełnimy, to możemy mieć spadek, albo brak zmian.

Potrzebujemy więc trzech możliwości, a JEŻELI daje nam tylko 2. I dlatego musimy ją zagnieździć w sobie. Sytuację tę przedstawia poniższy obrazek:

Logika

Lewa gałąź „załatwia” nam wzrost, natomiast prawa, gdy warunek jest niespełniony, sprawdza kolejny warunek, tym razem o braku zmian. Jeśli ten warunek jest prawdziwy, to faktycznie mamy brak zmian. Jeśli fałszywy – nie pozostaje już nic innego jak spadek.

Formuła w Excelu wygląda więc następująco:

=JEŻELI(D4>C4;"wzrost";JEŻELI(C4=D4;"brak zmian";"spadek"))

Po skopiowaniu formuły do pozostałych komórek, otrzymujemy następujący wynik:

Wynik zagnieżdżonego JEŻELI

Działa i tak można robić w tych wersjach Excela, w których funkcji WARUNKI nie ma.

„Nowy” sposób

To po prostu użycie funkcji WARUNKI, zamiast tych zagnieżdżonych JEŻELI. Przyjrzyjmy się zatem samej funkcji WARUNKI. Oto jej składnia:

Składnia funkcji WARUNKI

Składnia funkcji WARUNKI

Z obrazka powyżej widać, że funkcja ta potrzebuje od nas par informacji: warunek – co ma się stać, gdy jest prawdziwy. Takich Par może od nas przyjąć aż 127, co wcale nie oznacza, że musimy. Korzystamy z tylu, ilu potrzebujemy.

Czyli w naszym przypadku, schematycznie może to wyglądać tak:

sprzedaż 2017 > sprzedaż 2016; „wzrost”; sprzedaż 2017 < sprzedaż 2016; „spadek”; sprzedaż 2017 = sprzedaż 2016; „brak zmian”

… i pięknie zadziała. Natomiast, jeśli zamiast ostatniego warunku, o równości, wpiszemy „PRAWDA”, funkcja zrozumie, że jeśli żaden wcześniejszy warunek nie będzie spełniony – ma wyświetlić „brak zmian”, czyli wartość dla tej PRAWDY. Czyli możemy napisać tak:

sprzedaż 2017 ; sprzedaż 2016; „wzrost”; sprzedaż 2017 < sprzedaż 2016; „spadek”; PRAWDA; „brak zmian”

A przekładając na formułę Excela:

=WARUNKI(D4>C4;"wzrost";D4<C4;"spadek";PRAWDA;"brak zmian")

Efekt tego będzie identyczny, jak formuły z zagnieżdżonym JEŻELI (dla porównania napisałam w kolumnie obok):

Wynik funkcji WARUNKI

Wynik funkcji WARUNKI

I wersja wideo tego wpisu:

 

Odzyskiwanie formuły po nadpisaniu jej wartością

$
0
0

Czyli formuła, której nie da się skasować…

Załóżmy, że tworzymy szablon oferty, taki jak na obrazku poniżej. Chcemy wybierać z listy rozwijanej model produktu i na tej podstawie ma się podpowiedzieć cena netto. Cena ta jest pobierana z cennika, który znajduje się w innym arkuszu. To wszystko mamy już gotowe, natomiast chcemy mieć możliwość ręcznego wpisywania cen jednostkowych. TO oczywiście jest możliwe, natomiast jak to zrobimy – bezpowrotnie tracimy formułę, która wcześniej tę cenę podpowiadała.

I w tym zadaniu chodzi o to, aby po skasowaniu tej ręcznie wpisanej wartości, automatycznie wpisywała się formuła, która tam była…

Formatka

Formatka

Bez VBA się nie obejdzie 🙂

Czyli chodzi o to, aby w jakiś sposób wyłapać, że użytkownik skasował wartość w komórce z ceną i wstawić w nią określoną formułę. Musimy zatem znów skorzystać ze zdarzeń arkusza, a konkretnie ze zdarzenia Change, ponieważ będziemy sprawdzać zmiany po tym, jak user coś zmieni (change) w arkuszu.

Określanie komórek do sprawdzania

W tym celu najpierw określimy, jakie komórki będą nas interesowały, czyli do jakich komórek mamy ewentualnie wstawiać formułę. Zakres ten sobie najpierw nazwiemy.

Czyli zaznaczamy komórki z ceną netto, czyli E3:E9, klikamy w polu nazwy i wprowadzamy tam nazwę np. CenaNetto. Wpis zatwierdzamy Enterem.

Pobranie istniejącej formuły

Kolejny krok to przetłumaczenie na angielski formuły, która znajduje się w komórkach z cenami netto. Ta formuła to u mnie:

=JEŻELI.BŁĄD((WYSZUKAJ.PIONOWO(D3;Cennik!$B$3:$D$25;3;0));0)

Na angielski trzeba ją przetłumaczyć dlatego, że VBA potrzebuje jej w takim właśnie języku. Można to zrobić oczywiście “ręcznie”, ale ja polecam prostszą metodę: nagranie makra z wpisywaniem tej formuły do komórki. Skorzystamy z faktu, że ona już tam jest i jedyne co zrobimy podczas nagrywania tego makra, to wejście do edycji tej komórki i zatwierdzenie wpisu w niej. Prościutkie 🙂

Czyli poszczególne koki to:

  1. Zaznacz komórkę E3
  2. W menu Deweloper kliknij przycisk Zarejestruj makro (pokazanie karty Deweloper na wstążce omawiałam tutaj)
  3. Wejdź do edycji komórki E3 (czyli np. klawisz F2)
  4. Naciśnij Enter
  5. Zatrzymaj rejestrowanie makra (Deweloper/ Zatrzymaj rejestrowanie)

Tyle. Teraz w oknie VBE (Alt + F11) powinien pokazać się nowy moduł (np. Module1), a w nim procedura z naszym nagranym makrem:

Sub Makro1()
'
' Makro1 Makro
'
'
    Selection.FormulaR1C1 = _
        "=IFERROR((VLOOKUP(RC[-1],Cennik!R3C2:R25C4,3,0))*R6C7*R7C7,0)"
End Sub

To sobie teraz zostawiamy na później i idziemy do zdarzenia arkusza…

Zdarzenie arkusza

To bowiem jest miejsce, które powie Excelowi, że ma coś wykonać, gdy user zmienić wartość komórki. Oczywiście Excel będzie sprawdzał każdą komórkę w określonym przez nas arkuszu, ale z tym też sobie poradzimy :).

Najpierw określmy, w którym arkuszu w ogóle ma sprawdzać, czyli działać makro. U mnie jest to arkusz o nazwie kalkulator, więc po wejściu do VBE (Visial Basic Editor), w okienku Project Explorer, dwa razy klikam w taki właśnie arkusz. Następnie z list rozwijanych w prawym oknie wybieramy:

(1) Worksheet, i

(2) Change

Oba te kroki dokładnie opisałam tutaj.

Po wyborze Change pojawi się następujący kod:

Private Sub Worksheet_Change(ByVal Target As Range)
       
End Sub

Nasz kod wpiszemy dokładnie pośrodku tych linijek.

Kod VBA

A zaczniemy od deklaracji zmiennej, oznaczającej nasz zakres do sprawdzenia:

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim Zakres As Range
      
End Sub

Od razu możemy dorzucić sobie linijki obsługujące błędy i zabijające zmienną obiektową Zakres:

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim Zakres As Range
    
    On Error GoTo Obsluga
    
Obsluga:
    Set Zakres = Nothing
    
End Sub

Błędy bowiem mogą się pojawić, gdy np. user skasuje więcej niż jedną komórkę. A błędów, objawiających się brzydką, szarą tabliczką nie chcemy… :). Powyższe linijki więc mówią, że jeśli jakiś błąd się pojawi – idziemy na koniec procedury, gdzie następuje jedynie zabicie zmiennej obiektowej i zakończenie makra. Nie chcę tutaj rozmyślać, co ma się stać gdy wyskoczy błąd taki, albo śmaki – wszystkiego nie przewidzę i w tej sytuacji nawet nie chcę. To ma być proste i działać tylko wtedy, gdy user usunie wartość z komórki z ceną netto. Kropka 🙂

Czyli krótko mówiąc: gdy makro napotka błąd, z punktu widzenia użytkownika nic się nie dzieje. I tak ma być :).

Ok, to teraz co, jeśli wszystko odbędzie się zgodnie z planem.

No po pierwsze user może skasować/zmienić dowolną komórkę arkusza. Ale na dowolną nie chcemy reagować, tylko na taką, która znajduje się we wcześniej nazwanym zakresie CenaNetto i dodatkowo właśnie stała się pusta.

Czyli potrzebujemy przypisać do zmiennej obiektowej Zakres – arkuszowy zakres CenaNetto.

    Set Zakres = Me.Range("CenaNetto")

Słówko me oznacza w tym wypadku arkusz, w którym tworzymy zdarzenie.

Kolejny krok to zbadanie, czy zmieniona komórka (Target) znajduje się w naszym Zakresie i czy jest pusta. Zrobi to ten if i obiekt Intersect:

    If Not Intersect(Zakres, Target) Is Nothing And Target.Value = "" Then
        
    End If

A w środku to już prosto: jeśli oba powyższe warunki są spełnione, to formułą w zmienionej komórce ma być ta formuła, dla której wcześniej nagrywaliśmy makro, aby ją przetłumaczyć. Teraz wystarczy sobie ją tylko przekopiować między modułami, aby uzyskać to:

    If Not Intersect(Zakres, Target) Is Nothing And Target.Value = "" Then
        Target.FormulaR1C1 = "=IFERROR((VLOOKUP(RC[-1],Cennik!R3C2:R25C4,3,0)),0)"
    End If

Wszystko do kupy wygląda tak:

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim Zakres As Range
    
    On Error GoTo Obsluga
    
    Set Zakres = Me.Range("CenaNetto")
    
    If Not Intersect(Zakres, Target) Is Nothing And Target.Value = "" Then
        Target.FormulaR1C1 = "=IFERROR((VLOOKUP(RC[-1],Cennik!R3C2:R25C4,3,0)),0)"
    End If
Obsluga:
    Set Zakres = Nothing
    
End Sub

Śmiga pięknie! Uzyskujemy też śmieszny efekt, że formuły nie da się skasować 🙂

Na koniec pamiętaj tylko o zapisaniu pliku z obsługą makr, czyli jako *.xlsm. Bez tego ani rusz!

A jeśli wolisz omówione kroki obejrzeć na filmie, to zachęcam do obejrzenia poniżej:

 

Załączam też plik z gotowcem:

 

 

 

Wzrost czy spadek, czyli Ikony formatowania warunkowego

$
0
0

W tym wpisie pokażę jak zrobić zieloną strzałkę w górę, gdy nasza np. sprzedaż wzrosła o 5% lub więcej w stosunku do poprzedniego roku, i czerwoną strzałkę w dół, gdy ta sprzedaż spadła o 5% lub więcej. Chodzi o coś takiego:

 

Formatka

Formatka

W sumie to te strzałki to bardziej trójkąty, ale wiadomo o co chodzi :). Wykorzystam do tego moje ukochane formatowanie warunkowe.

Bring it on!

1. Zacznijmy od wstawienia w komórkę F4 (i niżej) prostej formuły, która wyświetla identyczną wartość, co komórka obok:

=E4

Robimy to po to, aby w tej komórce wyświetlić strzałkę, ponieważ strzałki chcę widzieć poza tabelką.

2. Teraz zaznacz te formuły i wejdź do Narzędzia główne/ Formatowanie warunkowe/ Zestaw ikon. I wybierz zestaw (najlepiej 3-elementowy), który najbardziej Ci się podoba (ja wybrałam trójkąty):

Wybieranie ikony

Wybieranie ikony

Już po samej tej operacji coś dostajemy, ale jeszcze nie to, co chcemy – Excel sam zdecydował za nas kiedy wyświetlać poszczególne ikony:

Po nadaniu formatowania...

Po nadaniu formatowania…

3. Będziemy więc edytować utworzoną właśnie regułę formatowania warunkowego. W tym celu zaznacz dowolną komórkę zakresu z naszym formatowaniem i wejdź do Narzędzia główne/ Formatowanie warunkowe/ Zarządzaj regułami… i z listy wybierz naszą regułę. Zaznaczenie komórki jest o tyle istotne, że wtedy od razu zobaczymy tę regułę na liście reguł, gdyż Excel domyślnie wyświetla reguły dl bieżącego zaznaczenia. Po wybraniu naszej reguły na liście, kliknij przycisk Edytuj regułę (jak jest tylko jedna reguła na liście, to nawet nie musisz jej zaznaczać):

Otwieranie edycji reguły formatowania warunkowego

Otwieranie edycji reguły formatowania warunkowego

4. Otworzy się wtedy okienko edycji reguły, w której należy wybrać:

  1. Checkbox: Pokaż tylko ikonę (ukrywamy w ten sposób wartość komórki)
  2. W dwóch polach Typ wybrać opcję Liczba (aby ustalić liczbę powyżej i poniżej których ma działać reguła)
  3. Zamienić drugą ikonę (żółtą kreskę) na Brak ikony komórki (nie chcemy trzeciej ikony pośrodku)
  4. W pola z wartościami wpisać odpowiednio: 0,05 i -0,05.

Tak, jak na poniższym obrazku:

Edycja reguły formatowania warunkowego

Edycja reguły formatowania warunkowego

5. Po zatwierdzeniu wszystkich możliwych okienek, otrzymamy taki efekt:

Wynik

Wynik

Takie to prościutkie 🙂

A poniżej sposób na zrobienie tego w wersji wideo:

 

Poniżej plik do pobrania:
I plik z gotowcem do pobrania:MalinowyExcel Ikony formatowania warunkowego dw.xlsx

 

 

WYSZUKAJ.PIONOWO, PODAJ.POZYCJĘ i niewyświetlanie zer

$
0
0

Czyli przyporządkowanie ceny i kodu produktu, na podstawie jego kolekcji i modelu

Załóżmy, że sprzedajemy ubrania. Dzielimy je sobie na kolekcje, które mają różne modele. Wybieramy sobie kolekcję i model i na tej podstawie ma nam się wyświetlić indeks i cena danego ubrania. To jest zadanie na teraz, przy czym formatka wygląda tak:

Formatka

Formatka

Czyli wybieramy najpierw kolekcję z listy rozwijanej w komórce A2 (tak, wiem, że wygląda na to, że nic w niej nie ma, a to dlatego, że zastosowałam do niej takie formatowanie ;)), a następnie model w komórkach kolumny Model. Wpisujemy ilość, a kod produktu i cena same mają się pojawić.

Jak sugeruje tytuł tego posta, użyję do tego dwóch funkcji: WYSZUKAJ.PIONOWO i PODAJ.POZYCJĘ. Natomiast powiem Wam, że najfajniejszym trikiem będzie ukrycie zer (zwracanych przez formuły). Nie użyję do tego bowiem pustego ciągu tekstowego, czyli dwóch cudzysłowów obok siebie (“”), tylko formatowania niestandardowego… Warto więc doczytać do końca 🙂

Zrobienie list rozwijanych opisuję tutaj, więc przejdę dalej. Istotne są w naszym ćwiczeniu tabele z danymi: kodami/inddeksami i z cenami. Zauważcie, że nagłówkami kolumn są modele, a nagłówkami wierszy – kolekcje. Kolejność nie ma znaczenia, można zrobić odwrotnie, ale ważne jest, aby nazwy modeli i kolekcji były dokładnie takie same, jak na listach rozwijanych na formatce.

Jak już to jest, to możemy przejść do formuł.

Wyświetlanie kodu

Szukać będziemy kolekcji w tabelce z kodami. Będą to też nasze pierwsze dwa argumenty naszej kochanej WYSZUKAJ.PIONOWO. Szukać będziemy dokładnie, więc w ostatnim argumencie wpiszemy zero (0). Problem pojawia się jedynie przy trzecim argumencie, ponieważ nie wiemy, którą kolumnę wyświetlić.

Tutaj z pomocą przyjdzie nam właśnie funkcja PODAJ.POZYCJĘ, której każemy znaleźć nasz model w wierszu nagłówkowym tabeli. Funkcja ta wyświetli jedynie numer komórki, w której znajduje się nasz model, a będzie to niejednoczenie numer kolumny, którego potrzebuje od nas WYSZUKAJ.PIONOWO. Tadam!

Formułą jest następująca (C4):

=JEŻELI.BŁĄD(WYSZUKAJ.PIONOWO($A$2;$A$16:$D$19;PODAJ.POZYCJĘ($A4;$A$15:$D$15;0);0);0)

Wszystko wrzuciłam jeszcze w funkcję JEŻELI.BŁĄD, jeśli jakiś błąd się pojawi. A takiż może się pojawić, gdy user nie wybierze jeszcze modelu. W przypadku błędu chcę, aby funkcja wyświetliła zero. I tak wiem, że będzie to głupio wyglądało, natomiast poradzę sobie z tym za chwilę :).

Wyświetlanie ceny

Praktycznie identyczna formułkę zastosujemy do wyświetlenia ceny, z tą tylko różnicą, że każemy przeszukiwać tabelkę z cenami, a nie kodami. Oto ona (D4):

=JEŻELI.BŁĄD(INDEKS($B$23:$D$26;PODAJ.POZYCJĘ($A$2;$A$23:$A$26;0);PODAJ.POZYCJĘ(A4;$B$22:$D$22;0));0)

Wartość

Wartość sprzedaży jest już prosta, czyli (E4):

=B4*D4

Choćby dlatego wolę wyświetlać zero w przypadku błędu WYSZUKAJ.PIONOWO: formuły w stylu tej liczącej wartość ładnie się policzą. Gdybym kazała wyświetlać pusty tekst (“”) w przypadku błędu – formuła licząca cenę wyświetliłaby błąd (#ARG!) i tak w koło Macieju… A Excel umie pomnożyć jakąś liczbę razy zero, wiec jeden problem mniej :).

Efekt tego jest na razie taki (wpisałam kilka modeli):

Po wpisaniu formuł

Po wpisaniu formuł…

Widać brzydkie zera, ale przynajmniej wszystko się liczy. To pozbądźmy się tych zer…

Alternatywna formuła z INDEKS i PODAJ.POZYCJĘ

To samo można też zrobić wymienionymi wyżej funkcjami. Formuła dla ceny wyglądałaby tak:

=JEŻELI.BŁĄD(INDEKS($B$23:$D$26;PODAJ.POZYCJĘ($A$2;$A$23:$A$26;0);PODAJ.POZYCJĘ(A4;$B$22:$D$22;0));0)

Jak ukryć zera?

Należy do tego użyć formatowania niestandardowego.

1. Czyli zaznaczmy wszystkie komórki, w których chcemy ukryć zera. Ja na razie zaznaczę ceny i wartości (D4:E12), ponieważ przy okazji dorzucę separator tysięcy (nie potrzebuję miejsc dziesiętnych, ale oczywiście można byłoby je też tutaj dorzucić).

2. Następnie wchodzimy do formatowania komórki (skrót klawiszowy Ctrl +1)

3. Z zakładki Liczby wybieramy kategorię Niestandardowe. A w nim wpisujemy następujący typ formatowania:

# ##0;-# ##0;

W okienku wygląda to tak:

Formatowanie niestandardowe

Formatowanie niestandardowe

Zapis ten oznacza, że liczby dodatnie mają być wyświetlone z separatorem tysięcy, ujemne też, ale dodatkowo ze znakiem minus, a zera jako nic. Czyli zera niewyświetlane.

Dla kolumny z kodami z kolei, również w formatowaniu niestandardowym, skorzystam z takiego formatu:

Standardowy;-Standardowy;

To s kolei oznacza, że dodatnie i ujemne mają zostać wyświetlone w formacie ogólnym (nie chcę w żaden sposób ich formatować), a zera, jak poprzednio, nie będą wyświetlane.

W takim zapisie istotna jest kolejność: najpierw definiujemy jak mają wyglądać liczby dodatnie, potem ujemne, potem zero, a na końcu tekst. Ale tekstu akurat teraz nie wykorzystuję.

Wszystko razem wygląda tak:

Wynik

Wynik

I tyle :).

I wersja wideo tego wpisu (pokazuję na nim alternatywę z funkcjami INDEKS i PODAJ.POZYCJĘ):

 

 

 

Viewing all 291 articles
Browse latest View live