Kategorie szkoleń | Egzaminy | Kontakt
  • 4
  • 0
  • 1

Od pewnego czasu szukam prostego i przejrzystego sposobu przypisania makra do przycisku Activex Command button przy użyciu procedury VBA.

To zadanie jest drobną cząstką szerszego. Poszatkowałem problem na części i z większością się uporałem. Zagadnienie w skrócie jest następujące:

Po edycji arkusza głównego generuję automatycznie (z częścią danych z arkusza głównego) arkusz dla kolejnego miesiąca na podstawie szablonu zawartego w (ukrytym) arkuszu pomocniczym. W każdym nowym arkuszu jest tabela (ListObject o nazwie zawierającej rok i dwuznakowy przyrostek będący nr miesiąca).

Procedura tworząca nowy arkusz z danymi z arkusza głównego zawiera również makro tworzące (lub kopiujące z szablonu) przycisk CommandButton1, którego zadaniem ma być wywołanie formularza UserForm1 z szeregiem dodatkowych funkcji (edycja, podsumowanie, statystyka, wydruk).

Dla uproszczenia używam tutaj standardowych, domyślnych nazw obiektów: CommandButton1, UserForm1, itp.

Przyciskowi CommandButton1, chciałbym przypisać trywialną procedurę:

Private Sub CommandButton1_Click()
    UserForm1.Show
End Sub

Wcześniej używałem kontrolki formularza (Przycisk – formant formularza) – kopiowanej z szablonu. W tym przypadku, przypisane kopiowanemu przyciskowi makro wywołujące UserForm1 jest również kopiowane do nowego arkusza miesięcznego i problem byłby rozwiązany, gdyby nie następujące niedogodności:

  1. Formant formularza nie zachowuje pierwotnego rozmiaru, puchnie, tyje i wygląda obrzydliwie każdorazowo po skopiowaniu i nie pomagają znane mi triki, by utrzymać rozmiar w ryzach.
  2. Formant Activex posiada znacznie więcej możliwych do edycji właściwości, które wpływają na wygląd arkusza.

Jak zatem programowo przypisać makro (wyżej pokazane) do istniejącego przycisku najprostszą, przejrzystą metodą. Z pewnością jest to możliwe, ale znalezione dotąd w Internecie propozycje zupełnie nie działają, generują błędy, które niewiele wyjaśniają.

Krzysztof-Mizera
  • Zapytał
  • @ Krzysztof-Mizera | 01.03.2019
    • 3
    • 0
    • 2

Odpowiedzi (4)

  • 0

W module takie dwie funkcje:

Pierwsza tworzy przycisk i przypisuje mu funkcję.

Function xxx()

 Dim btn As Button
  Application.ScreenUpdating = False

  Dim t As Range

    Set btn = ActiveSheet.Buttons.Add(Cells(3, 3).Left, Cells(3, 3).Top, Cells(3, 3).Width, Cells(3, 3).Height)
    With btn
      .OnAction = "btnS"
      .Caption = "TEST Button"
      .Name = "Btn TEST"
    End With

  Application.ScreenUpdating = True

End Function

A druga, to ta, która stworzony przycisk odpala. :)

Function btnS()

MsgBox "To działa!"

End Function



Tomasz_Kasprzycki
  • Odpowiedział
  • @ Tomasz_Kasprzycki | 01.03.2019
    • 2
    • 4
    • 8
  • 1

Dziękuję za zainteresowanie.

Ciekawe rozwiązanie, stosowałem dotąd procedurę Sub, więc włączę Function do swojej kolekcji.

Moje pytanie dotyczyło jednak innego typu formantu (kontrolki) – nie form control (formant/kontrolka formularza) czyli Button (przycisk), lecz activeX control (formant/kontrolka Activex, której używać można zarówno na arkuszu podobnie jak formant formularza, ale przede wszystkim na formularzu UserForm), czyli CommandButton. Ciekawe jest to, że wbrew nazewnictwu, kontrolki formularza nie można używać na formularzu UserForm.

Przyciski Button czyli formanty formularza rzeczywiście tworzyć można dość łatwo. Można je też bez problemów kopiować z jednego do drugiego arkusza wraz z przypisaną mu procedurą i nie musimy się martwić czy będzie działać. Jednakże, jeśli spojrzymy na ich właściwości, Button (przycisk) jest bardzo ubogi w porównaniu z kontrolką ActiveX. Mój problem jest banalny i gdyby najważniejszą własnością kontrolki miała być jej skuteczność nie byłbym zainteresowany zmianą na ActiveX. Ale nie jest. Moja zabawa z formantami ma walor edukacyjny, a nie komercyjny (jestem emerytem) i ze względu estetykę aplikacji mój buton musi mieć tło RGB(110, 140, 170). Formant formularza nie udostępnia właściwości zmiany tła (background, backcolor lub inaczej), natomiast ActiveX owszem, tak. Natomiast, ActiveX nie posiada (bardzo przydatnej) właściwości OnAction, dzięki której mógłbym przypisać procedurę do CommandButton.

Rozwiązałem problem w sposób, który mnie średnio satysfakcjonuje, bo to kompromis. Użyłem obiektu Shape malując prostokątny kształt w zastępstwie przycisku – posiada on obie wymagane właściwości: OnActionBackColor.

W każdym razie będę poszukiwał rozwiązania opisanego w nagłówku pytania.

Pozdrawiam.
Krzysztof.

Krzysztof-Mizera
  • Odpowiedział
  • @ Krzysztof-Mizera | 05.03.2019
    • 3
    • 0
    • 2
  • 0

Odpowiedź na fragment własnego pytania. Czyli ... zadawanie pytań też zmusza do myślenia.

Problem z paskudnym rozjeżdżaniem się rozmiaru przycisku po skopiowaniu do nowego arkusza (który opisałem w treści pytania), rozwiązałem, dopisując do aplikacji fragment kodu ustalającego ponownie rozmiar .Width i .Height. Banalne, prawda?

Krzysztof-Mizera
  • Odpowiedział
  • @ Krzysztof-Mizera | 05.03.2019
    • 3
    • 0
    • 2
  • 1

A spróbuj tego:

Kod = "Private Sub CommandButton1_Click()" & vbNewLine
Kod = Kod & "UserForm1.Show" & vbNewLine
Kod = Kod & "End Sub"

With ActiveWorkbook.VBProject.VBComponents(Worksheets("Arkusz...").CodeName).CodeModule
    .InsertLines .CountOfLines + 1, Kod
End With

Może to coś da. :)

Tylko ustawienia zabezpieczeń muszą być niskie i dopuszczać możliwość dodawania kodem kodu. ;)

Tomasz_Kasprzycki
  • Odpowiedział
  • @ Tomasz_Kasprzycki | 05.03.2019
    • 2
    • 4
    • 8