Excel Forum - Porady, Pomoc,  Excel Help, Excel FAQ Strona Główna
 FAQ  RegulaminRegulamin  Szukaj   Użytkownicy   Grupy   Rejestracja   Profil   Twoje wiadomości   Zaloguj 


Poprzedni temat «» Następny temat
ID tematu: 70561 Skopiuj do schowka Wywołanie makra zapisanego w komórce lub stringu
Autor Wiadomość
dzikzlasu
Stały bywalec Excelforum


Pomógł: 2 razy
Posty: 263
Wysłany: 01-04-2021, 12:18   Wywołanie makra zapisanego w komórce lub stringu

Witam.

mam zmienną String która przechowuje text
np
MsgBox "Jest GIT"

(z góry zaznaczam że nie chodzi mi dokładnie o MsgBox może to być Range(......) lub jakikolwiek kod VAB

Czy jest możliwość wykonać to makro które jest przechowywane w zmiennej.

I tu zależy mi o jak najprostszej metodzie gdzie nie trzeba włączać jakiś referencji czy programistycznego dostępu do pliku.


Wiem że poprzez VBA mogę utworzyć nowy moduł i tam wkleić tekst ze zmiennej a później to odpalić, ale do tego potrzebuje chyba właśnie tego programistycznego dostępu do pliku.
ID posta: 403065 Skopiuj do schowka
 
 
Marecki 
Excel Expert



Wersja: Win Office 2019
Pomógł: 2521 razy
Posty: 8407
Wysłany: 01-04-2021, 12:37   

Kod:
Sub Testowanie()
Dim zmienna_A As String
Dim zmienna_B As String

    Range("A1").Value = "Test1"
    Range("A2").Value = "Test2"

    zmienna_A = Range("A1").Value
    zmienna_B = Range("A2").Value


    Application.Run zmienna_A
    Application.Run zmienna_B
End Sub


Sub Test1()
    MsgBox "Wywołałeś makro Test1"
End Sub

Sub Test2()
    MsgBox "Wywołałeś makro Test2"
End Sub


_________________
Hardware - ta część komputera, którą można kopnąć kiedy software przestanie funkcjonować.

Szkolenia z Excela , FB
Office 2019 Professional Plus , Windows 10 x64
Pozdrawiam, były mkkk23 teraz Marecki.
  
ID posta: 403069 Skopiuj do schowka
 
 
Maciej Gonet 
Excel Expert


Wersja: Win Office 2016
Pomógł: 2112 razy
Posty: 6618
Wysłany: 01-04-2021, 14:17   

W zmiennej VBA może być nazwa makra (lub funkcji), ale nie jej treść.
Ewentualnie jeśli chciałbyś mieć treść makra w arkuszu, to można powrócić do starego systemu makr XLM (z wersji 4.0). Wtedy treść makra zapisujesz w specjalnym arkuszu makr. Ale to już nie jest VBA, tylko specjalny język makr opracowany do tego celu.
Kod:
Sub Test()
   Dim nazwa_makra As String
   nazwa_makra = "MojeMakro"
   Application.Run nazwa_makra
   Application.Run Sheets("Makro1").Range("A1")
End Sub

Sub MojeMakro()
   MsgBox "Wywołany przez nazwę"
End Sub


Kod:
=OSTRZEŻENIE("Jestem w arkuszu makr")
=POWRÓT()


Wywołanie.xlsm
Pobierz Plik ściągnięto 5 raz(y) 15.42 KB

ID posta: 403071 Skopiuj do schowka
 
 
Marecki 
Excel Expert



Wersja: Win Office 2019
Pomógł: 2521 razy
Posty: 8407
Wysłany: 01-04-2021, 14:24   

Aaaa, to ja źle zrozumiałem. :oops:

dzikzlasu, a do czego to potrzebujesz ?
Może jest jakieś inne rozwiązanie ?
_________________
Hardware - ta część komputera, którą można kopnąć kiedy software przestanie funkcjonować.

Szkolenia z Excela , FB
Office 2019 Professional Plus , Windows 10 x64
Pozdrawiam, były mkkk23 teraz Marecki.
  
ID posta: 403072 Skopiuj do schowka
 
 
Rafał B.
Stały bywalec Excelforum



Wersja: Win Office 2016
Pomógł: 39 razy
Posty: 281
Wysłany: 01-04-2021, 19:02   

dzikzlasu napisał/a:
Witam.
Wiem że poprzez VBA mogę utworzyć nowy moduł i tam wkleić tekst ze zmiennej a później to odpalić,
Dokładnie tak ja piszesz, to prawdopodobnie "najprostsza" opcja. Włączyć zaufanie dostępu do modelu obiektowego VBA możesz grzebiąc w rejestrze (bo jeśli dobrze rozumiem, to chciałbyś przestrzec użytkownika przed zmianą ustawień Excela samodzielnie). Chyba zależy to od Excela, u mnie wystarczy:
Kod:
Public Sub TurnOnTrustAccess()
   
    Dim WSO As Object
    Set WSO = CreateObject("WScript.Shell")

    Dim regKey As String
        regKey = "HKEY_CURRENT_USER\Software\Microsoft\Office\" & _
                  Application.Version & "\Excel\Security\AccessVBOM"
   
    WSO.RegWrite regKey, "1", "REG_DWORD"
    End Sub
    '---------------------------------------------------------------------*

Z tego, co piszesz już później wiesz co robić; kod ładujesz do zmiennej-stringa i tworzysz moduł programowo. Tylko daj też odczyt rejestru w pętli Do while, albo zwłokę czasową po tym kodzie, żeby Excel mógł "zatrybić".
_________________
Jest niemal niemożliwe nauczenie dobrego programowania uczniów, którzy byli narażeni na kontakt z BASIC: jako potencjalni programiści są okaleczeni, bez nadziei na poprawę. (Edsger Dijkstra, pionier informatyki).
Po części dotyczy również VBA.
  
ID posta: 403076 Skopiuj do schowka
 
 
Artik 



Wersja: Win Office 365
Pomógł: 3133 razy
Posty: 10378
Wysłany: 02-04-2021, 09:38   

O ile mnie pamięć nie myli, to po grzebnięciu w Rejestrze, Excela trzeba ponownie odpalić. Ta sama instancja ma stan sprzed modyfikacji Rejestru (odczyt tego ustawienia odbywa się w trakcie otwierania Excela, nie pliku!). Tak więc rozwiązanie z programową zmianą zabezpieczeń nie bardzo się nada do tego co kombinujesz (wiem trochę więcej niż napisano w tym wątku).
Masz cały czas pod górkę. ;-)

Edit: Post bardziej skierowany do dzika, jak do Rafała.

Artik
_________________
Persistence is a virtue in the world of programming.
  
ID posta: 403094 Skopiuj do schowka
 
 
Rafał B.
Stały bywalec Excelforum



Wersja: Win Office 2016
Pomógł: 39 razy
Posty: 281
Wysłany: 02-04-2021, 10:33   

No to nic straconego- za pomocą VBA piszemy prosty skrypt VBS w tym celu i modlimy się o brak alertu/blokady w antywirusie. Zapewne modyfikacją harmonogramu zadań też jest to możliwe. A jak nie pójdzie, to sendkeysem go :mrgreen:

Ale tak na serio chyba najprościej, to po sprawdzeniu czy mamy odblokowany dostęp (i stwierdzeniu jego braku) wyświetlać w pętli informację o tej konieczności użytkownikowi:
Kod:
Application.CommandBars.ExecuteMso("MacroSecurity")

Kaper ma w stopce:
Cytat:
Jeśli dane będą torturowane dość długo, przyznają się do wszystkiego

a ja bym trawestując powiedział:
Cytat:
Jeśli użytkownik będzie torturowany dość długo msgBoxem, zawsze kliknie OK
Application.EnableCancelKey = xlDisabled :mrgreen: No chyba, że każdorazowo musimy "posprzątać, czyli wyłączyć to ustawienie przy zamykaniu. Odpada też, gdy piszemy wirusa, no chyba że z jakąś sztuczką socjotechniczną... :devil : Ktoś ma tutaj


Później dodanie referencji (bo zakładam, że standardowo VBA Extensibility library) już programowo, ale to zapewne wiesz, np.:
Kod:
Public Sub AddModule()

    ThisWorkbook.VBProject.References.AddFromGuid _
                    GUID:="{0002E157-0000-0000-C000-000000000046}", _
                    Major:=5, Minor:=3
                   
    Dim VBProj As Object 'VBIDE.VBProject
    Dim VBComp As Object 'VBIDE.VBComponent
   
  ' i tu już Twoje zabawy kodostringowe ;)
  ' ale zapewne zaczniemy od wstawienia modułu
    Set VBProj = ActiveWorkbook.VBProject
    Set VBComp = VBProj.VBComponents.Add(1) ' 1 = vbext_ct_StdModule
    VBComp.Name = "NewModule"
    End Sub
    '---------------------------------------------------------------------*



BTW @Artik, zamierzam u klienta podmieniać moduły nie zmuszając go do wyłączania pliku, na którym pracuje. Jest to kłopotliwe, bo często przez presję czasu jest konieczność wypuszczenia wersji nie do końca prawidłowo przetestowanej (oczywiście sam skoroszyt poza danymi nie ulega zazwyczaj zmianie). Więc albo dodaję funkcjonalność, albo wyłapię buga, lub coś przyspieszę i zamierzam w tym celu użyć własnie wspomnianej biblioteki. Żeby nie zamieszać za bardzo nie chcę monitorowania żadnego, ale po prostu umieszczam nowe moduły w określonej ścieżce, a klient przyciskiem je dodaje/nadpisuje w swoim skoroszycie. Czy może jednak zaproponujesz lepsze rozwiązanie?
_________________
Jest niemal niemożliwe nauczenie dobrego programowania uczniów, którzy byli narażeni na kontakt z BASIC: jako potencjalni programiści są okaleczeni, bez nadziei na poprawę. (Edsger Dijkstra, pionier informatyki).
Po części dotyczy również VBA.
Ostatnio zmieniony przez Rafał B. 02-04-2021, 10:55, w całości zmieniany 2 razy  
ID posta: 403097 Skopiuj do schowka
 
 
Artik 



Wersja: Win Office 365
Pomógł: 3133 razy
Posty: 10378
Wysłany: 02-04-2021, 10:53   

Rafał B. napisał/a:
No chyba, że każdorazowo musimy "posprzątać
Moim zdaniem należało by posprzątać, by użytkownika nie narażać w przyszłości.
Rafał B. napisał/a:
wyświetlać w pętli informację o tej konieczności użytkownikowi:
Proces ma przebiegać w ciszy, więc komunikaty odpadają.

BTW
Jak tam, Excel dalej czeka na zakończenie OLE?

Artik
_________________
Persistence is a virtue in the world of programming.
ID posta: 403099 Skopiuj do schowka
 
 
Rafał B.
Stały bywalec Excelforum



Wersja: Win Office 2016
Pomógł: 39 razy
Posty: 281
Wysłany: 02-04-2021, 10:58   

Pamiętam o Twojej odpowiedzi, ale z racji czasochłonności generowania tych pdfów jeszcze nie przymusiłem klienta do ponownego przetestowania (bo problem występuje tylko na jego maszynie). Na pewno dam znać! (PS pozwoliłem sobie zedytować powyższy post w "międzyczasie" z pytaniem na końcu) :-)

A co do bieżącego tematu, to jeszcze wczoraj byłem niemalże pewien, że czytałem wątek, w którym ktoś na SO nie dalej jak 2 lata temu znalazł sprytne i w miarę czyste obejście problemu, ale nie mogę sobie przypomnieć gdzie to zapisałem, bo takie sztuczki nie są mi potrzebne... Na pewno poszukam jeszcze raz w wolnej chwili.
_________________
Jest niemal niemożliwe nauczenie dobrego programowania uczniów, którzy byli narażeni na kontakt z BASIC: jako potencjalni programiści są okaleczeni, bez nadziei na poprawę. (Edsger Dijkstra, pionier informatyki).
Po części dotyczy również VBA.
  
ID posta: 403100 Skopiuj do schowka
 
 
Artik 



Wersja: Win Office 365
Pomógł: 3133 razy
Posty: 10378
Wysłany: 02-04-2021, 11:56   

Rafał B. napisał/a:
zamierzam u klienta podmieniać moduły nie zmuszając go do wyłączania pliku, na którym pracuje.
Opisany schemat działania wydaje się OK. Użytkownik wie, że jest aktualizacja (jakaś flaga do sprawdzenia przy otwarciu pliku) i dalsze działania są jawne, realizowane za zgodą użytkownika. Ponieważ inaczej trzeba postępować przy podmianie modułu standardowego, a inaczej modułu klasy powiązanej z obiektem ThisWorkbook lub Sheet trzeba się zdecydować na jedno z rozwiązań:
1. Albo we wszystkich modułach (standardowych i klas) podmieniamy sam kod (bez importu modułu), albo
2. Moduły standardowe importujemy, a w modułach klas - podmieniamy kod.

Należy pamiętać, że po zakończeniu podmiany wszystkie zmienne globalne ulegają wyczyszczeniu. Jeżeli chcesz uruchomić jakąś procedurę zawartą w projekcie, to nie możesz jej wołać z makra, które modyfikowało projekt. To znaczy możesz, ale w nowym wątku:
Kod:
Sub AAA()
    ...
    ' Tutaj kod ingerujący w strukturę projektu
    ...
    'Wywołanie procedury
    Application.OnTime Now(), "BBB"
End Sub
Wrzuć do wyszukiwarki forumowej hasło rekompilacj*. Omawiałem zagrożenia parokrotnie.

Rafał B. napisał/a:
A co do bieżącego tematu, to jeszcze wczoraj byłem niemalże pewien, że czytałem wątek, w którym ktoś na SO nie dalej jak 2 lata temu znalazł sprytne i w miarę czyste obejście problemu, ale nie mogę sobie przypomnieć gdzie to zapisałem, bo takie sztuczki nie są mi potrzebne... Na pewno poszukam jeszcze raz w wolnej chwili.
Poszukaj w wolnej chwili, bo chętnie poczytam, mimo że na ogół nie mam tego typu potrzeb.

Artik
_________________
Persistence is a virtue in the world of programming.
  
ID posta: 403104 Skopiuj do schowka
 
 
Marecki 
Excel Expert



Wersja: Win Office 2019
Pomógł: 2521 razy
Posty: 8407
Wysłany: 02-04-2021, 12:20   

Rafał B., testowałeś te rozwiązanie, chodzi o procedurę TurnOnTrustAccess ?
Generalnie działa, bo zaznacza dostęp programistyczny, aaaale jak plik zapiszemy i zamkniemy kodem, to i tak nie zapisuje się stan dostępu.

Testuje to tak:
1. Otwieram nowy plik , wyłączam dostęp programistyczny, wklejam makro:
Kod:
Public Sub TurnOnTrustAccess()
Dim regKey As String
Dim NrRegKey As Byte
Dim WSO As Object

    Application.CommandBars.ExecuteMso ("MacroSecurity")
    Set WSO = CreateObject("WScript.Shell")

    regKey = "HKEY_CURRENT_USER\Software\Microsoft\Office\" & Application.Version & "\Excel\Security\AccessVBOM"
    NrRegKey = WSO.RegRead(regKey)

    If NrRegKey = 1 Then
        ThisWorkbook.VBProject.VBComponents("Module1").Export (ThisWorkbook.Path & "\Module.bas")
    Else
        WSO.RegWrite regKey, "1", "REG_DWORD"
    End If

    ThisWorkbook.Close True

End Sub

nie uruchamiam kodu, ręcznie zapisuje plik i zamykam.

2. Otwieram zapisany wcześniej plik i uruchamiam procedurę TurnOnTrustAccess
3. Otwieram plik i widzę że nie mam dostępu programistycznego.

Dostęp taki będzie zapisany jak wy-klikam go"ręcznie" i "ręcznie" zapisze plik.
Też tak macie, bo jak tak to
Artik napisał/a:
po grzebnięciu w Rejestrze, Excela trzeba ponownie odpalić
się nie sprawdzi.
_________________
Hardware - ta część komputera, którą można kopnąć kiedy software przestanie funkcjonować.

Szkolenia z Excela , FB
Office 2019 Professional Plus , Windows 10 x64
Pozdrawiam, były mkkk23 teraz Marecki.
ID posta: 403105 Skopiuj do schowka
 
 
Rafał B.
Stały bywalec Excelforum



Wersja: Win Office 2016
Pomógł: 39 razy
Posty: 281
Wysłany: 02-04-2021, 12:40   

Artik napisał/a:
Ponieważ inaczej trzeba postępować przy podmianie modułu standardowego, a inaczej modułu klasy powiązanej z obiektem ThisWorkbook lub Sheet trzeba się zdecydować na jedno z rozwiązań:
1. Albo we wszystkich modułach (standardowych i klas) podmieniamy sam kod (bez importu modułu), albo
2. Moduły standardowe importujemy, a w modułach klas - podmieniamy kod.
W zasadzie niezalecane jest tam trzymanie większego kodu, więc zazwyczaj taka konstrukcja też powinna wystarczyć:
Kod:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
   
    onWorksheetSelectionChange Rng:=Target
    End Sub
    '--------------------------------------------------------------------*
I właściwy kod w zwykłym module. Grzebię w arkuszach tak rzadko, że nie przewiduję tak modyfikacji. Ale dzięki za ostrzeżenie! :-)

Artik napisał/a:
Należy pamiętać, że po zakończeniu podmiany wszystkie zmienne globalne ulegają wyczyszczeniu
Akurat nie korzystam ze zmiennych tego typu, wszystko co ważne zapisuję lub w skoroszycie lub czasem ustawienia przez SaveSetting. A ustawione obiekty trzymam w funkcjach:
Kod:
Public Function Table() As ListObject

    Static obj As ListObject
    If obj Is Nothing Then _
        Set obj = wsBaza.ListObjects("baza")
    Set Table = obj
    End Function
    '--------------------------------------------------------------------*

Teoretycznie ma to swoją wadę (nie zadziała konstrukcja set Table = Nothing, ale więcej korzyści, bo nigdy się globalnymi zmiennymi nie przejmuję, poza tym po co Nothing w takiej sytuacji).
_________________
Jest niemal niemożliwe nauczenie dobrego programowania uczniów, którzy byli narażeni na kontakt z BASIC: jako potencjalni programiści są okaleczeni, bez nadziei na poprawę. (Edsger Dijkstra, pionier informatyki).
Po części dotyczy również VBA.
  
ID posta: 403106 Skopiuj do schowka
 
 
Rafał B.
Stały bywalec Excelforum



Wersja: Win Office 2016
Pomógł: 39 razy
Posty: 281
Wysłany: 02-04-2021, 12:53   

@Marecki Faktycznie u mnie jednak tak samo się zachowuje. Nie mam teraz czasu, ale w wolnej chwili pokombinuję/poszukam (może da się z tym CommandBarem coś zrobić? Ale to by było pewnie za proste). Z jednej strony lipa, a z drugiej w miarę dobrze to Microsoft zabezpieczył. Ciekawe czy SendKeysem pójdzie, możecie Panowie spróbować z ciekawości :-) Więc odwołuję, że u mnie działa.

Przypadkowo post pod postem
_________________
Jest niemal niemożliwe nauczenie dobrego programowania uczniów, którzy byli narażeni na kontakt z BASIC: jako potencjalni programiści są okaleczeni, bez nadziei na poprawę. (Edsger Dijkstra, pionier informatyki).
Po części dotyczy również VBA.
  
ID posta: 403107 Skopiuj do schowka
 
 
Marecki 
Excel Expert



Wersja: Win Office 2019
Pomógł: 2521 razy
Posty: 8407
Wysłany: 02-04-2021, 13:45   

Jeszcze taki pomysł, aby włączyć lub wyłączyć dostęp przez plik vbs
Dla np. pliku "On.vbs"
Kod:
Dim WshShell, objExcel
Set objExcel = CreateObject("Excel.Application")
Set ObjShell = WScript.CreateObject("WScript.Shell")

ObjShell.RegWrite"HKEY_CURRENT_USER\Software\Microsoft\Office\" & objExcel.Version & "\Excel\Security\AccessVBOM", 1, "REG_DWORD"
objExcel.Quit

Odpalając ręcznie pliki zmienia się stan dostępu.
Sprawdzę jeszcze jak się zachowa odpalając plik ze skoroszytu.

Edit:

Lipa, też nie zmienia stanu. Czar prysł :-(
_________________
Hardware - ta część komputera, którą można kopnąć kiedy software przestanie funkcjonować.

Szkolenia z Excela , FB
Office 2019 Professional Plus , Windows 10 x64
Pozdrawiam, były mkkk23 teraz Marecki.
  
ID posta: 403109 Skopiuj do schowka
 
 
Rafał B.
Stały bywalec Excelforum



Wersja: Win Office 2016
Pomógł: 39 razy
Posty: 281
Wysłany: 02-04-2021, 14:37   

Haha, jednak wydaje się działać :) Tylko nie można zmieniać tego wpisu w rejestrze przy włączonym Excelu. Tutaj ta mała modyfikacja:
Kod:
Dim WshShell
Set objExcel = CreateObject("Excel.Application")
Set ObjShell = WScript.CreateObject("WScript.Shell")

Dim version
version = objExcel.Version
objExcel.Quit

ObjShell.RegWrite"HKEY_CURRENT_USER\Software\Microsoft\Office\" & version & "\Excel\Security\AccessVBOM", 1, "REG_DWORD"


Teraz spróbowałbym więc utworzyć ten skrypt VBS poprzez VBA, dać w nim jakiś Sleep (lub lepiej w pętli sprawdzenie czy już się zamknął) do czasu zamknięcia Excela, zmienić rejestr i odpalić również przez ten skrypt Excela od nowa. Fajnie jakby się udało to zrobić bez zapisu żadnego pliku na dysk (skrypt.vbs załadować do pamięci, nie wiem czy to możliwe).

PS. poza gałęzią w CURRENT_USER, trzeba sprawdzić jeszcze chyba MACHINE (u mnie nie ma, ale jak wczoraj czytałem, to niektórzy zgłaszali że mają- jeśli istnieje, to ma priorytet nad CURRENT_USER w kwestii naszego klucza).
_________________
Jest niemal niemożliwe nauczenie dobrego programowania uczniów, którzy byli narażeni na kontakt z BASIC: jako potencjalni programiści są okaleczeni, bez nadziei na poprawę. (Edsger Dijkstra, pionier informatyki).
Po części dotyczy również VBA.
  
ID posta: 403110 Skopiuj do schowka
 
 
Wyświetl posty z ostatnich:   
Odpowiedz do tematu
Nie możesz pisać nowych tematów
Nie możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach
Nie możesz załączać plików na tym forum
Możesz ściągać załączniki na tym forum
Dodaj temat do Ulubionych
Wersja do druku

Skocz do:  

Powered by phpBB modified by Przemo © 2003 phpBB Group
Theme xandgreen created by spleen& Programosy modified v0.3 by warna
Opieka techniczna www.marketingNET.pl

Archiwum

Strona używa plików cookies.

Kliknij tutaj, żeby dowiedzieć się jaki jest cel używania cookies oraz jak zmienić ustawienia cookie w przeglądarce.
Korzystając ze strony użytkownik wyraża zgodę na używanie plików cookies, zgodnie z bieżącymi ustawieniami przeglądarki.
Sprawdź, w jaki sposób przetwarzamy dane osobowe