poniedziałek, 16 czerwca 2014

Blokada edycji zakładek w dokumencie MS Word

Poniższy problem został wywołany niedawno na forum StackOverflow.Com i można go opisać w następujących kilku słowach:

W jaki sposób zablokować dostęp do zakładek dokumentu jednocześnie umożliwiając edycję pozostałych elementów dokumentu?

Całkiem ciekawe rozwiązanie tego problemu opiera się na wykorzystaniu obiektów ContentControl (CC) i zdarzeń powiązanych z tym obiektami. Co ważne, rozwiązanie to dostępne jest począwszy od wersji 2007 aplikacji MS Word.

Krok 1. Każdą zakładkę w dokumencie musimy umieścić wewnątrz obiektu ContentControl. Jeżeli nie chcemy wykonywać tej operacji ręcznie wystarczy uruchomić proste makro:


Krok 2. Zakładamy, że naszym celem jest uniemożliwienie edycji bez blokowania obiektu ContentControl. W tym celu wykorzystamy zdarzenie powiązane z tego typu obiektami i wymusimy zmianę zaznaczenia w sytuacji gdy użytkownik kliknie wewnątrz obiektu CC:


Alternatywnie krok 1 można rozszerzyć o mechanizm blokowania edycji obiektu CC i jednocześnie zrezygnować z obsługi zdarzenia obiektów CC. W tym wypadku zamiast kroków 1 i 2 zastosujemy poniższy rozszerzony kod z kroku 1:


piątek, 6 czerwca 2014

Imitacja zdarzenia MouseOver (Hover) dla komórki Excela...

...czyli jak wywołać makro pod wpływem najechania wskaźnikiem myszy nad określoną komórkę Excela.

Znawcy VBA z pewnością od razu domyślają się, że nie chodzi o wykorzystanie zdarzenia gdyż do wersji Office 2013 w zasobie dostępnych zdarzeń nie znajdziemy takiego, które wywoła efekt MouseOver dla komórki Excela. Okazuje się jednak, że efekt ten możemy uzyskać połączywszy ze sobą dwa elementy:
  • własną funkcję użytkownika (UDF), wewnątrz której zdefiniujemy określoną akcję wywoływaną pod wpływem najechania myszą nad komórkę
  • formułę komórkową HIPERŁĄCZE (opcjonalnie połączoną z formułą JEŻELI).
Zanim zaprezentuję określony kod nakreślmy oczekiwany scenariusz:
  • komórka A1 zawierać będzie tekst: "Najedź myszą w celu uzyskania dodatkowych informacji"
  • komórka B1 zawierać będzie tekst: "Wyłącz dodatkowe informacje"
  • najechanie myszą na komórki A1 i B1 będzie odpowiednio odkrywać i ukrywać obiekt Shape zawierający dodatkowe informacje (kształt Shape w naszym przypadku nazywa się "ShapeTip1")
Krok 1. Zacznijmy od stworzenia funkcji UDF, której zadaniem będzie pobranie parametru decydującego o odkryciu/ukryciu kształtu:


Krok 2. W arkuszu tworzymy kształt i ustawiamy jego nazwę na ShapeTip1.

Krok 3. W komórce A1 dodajemy formułę HYPERLINK wg schematu:


Z niewiadomych przyczyn formuła HIPERŁĄCZE zwracać może błąd dla powyższej konstrukcji dlatego też warto od razu obudować ją w formułę JEŻELI(CZY.BŁ(...)) (wskazówka: formuła JEŻELI.BŁĄD() niekoniecznie sprawdza się w tej sytuacji co warto przetestować).
Ostatecznie więc do komórki B1 wpisujemy następującą formułę wyzwalającą ukrywanie:


Ostateczny układ arkusza mógłby wyglądać jak na poniższym zrzucie ekranu. Najechanie muszą na komórkę A1 odkrywa prostokąt z komunikatem. Ukrywanie prostokąta wyzwalane jest przez najechanie myszą na komórkę B1.


Wskazówki i uwagi końcowe:

  • warto zwrócić uwagę, że zatrzymanie myszy nad komórkami A1 i B1 powodują nieustanne wywoływanie utworzonej funkcji UDF co nie jest zbyt efektywne
  • niestety nie udało mi się stworzyć mechanizmu autoukrywania kształtu po opuszczeniu komórki A1 bez najechania na komórkę B1. Funkcja nie wyzwala zdarzeń ani polecenia Application.OnTime.
  • Inspiracją do stworzenia niniejszego wpisu były przykłady znalezione w sieci. Tu chciałbym jednak polecić Waszej uwadze doskonały arkusz oparty o podobne rozwiązanie, który prezentuje okresowy układ pierwiastków. Pod tym linkiem znajdziecie zarówno gotowy przykład pliku Excela jak również prosty filmik prezentujący działanie tego narzędzia.