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ść
apollo
ExcelSpec


Pomógł: 1317 razy
Posty: 4544
Wysłany: 02-04-2021, 21:27   

Marecki napisał/a:

Lipa, też nie zmienia stanu. Czar prysł :-(

Nie rozumiem. Kod
Kod:

Private Sub SetTrustAccess()
Dim shellObj As Object
    Set shellObj = CreateObject("WScript.Shell")
    shellObj.Run "D:\on.vbs"
    Set shellObj = Nothing
End Sub

ustawi AccessVBOM na 1.

Treść "d:\on.vbs" można generować w locie kodem.

Odpalić Excel z kodem -> sprawdzić, że AccessVBOM = 0 -> uruchomić kod, który generuje VBS i zapisze na dysku -> następnie odpali VBS (SetTrustAccess) -> skasuje VBS na dysku -> nie zamknąć Excel, sprawdzić, że AccessVBOM = 1.
ID posta: 403116 Skopiuj do schowka
 
 
Rafał B.
Stały bywalec Excelforum



Wersja: Win Office 2016
Pomógł: 40 razy
Posty: 283
Wysłany: 03-04-2021, 00:41   

apollo napisał/a:
Nie rozumiem.
Wtedy jeszcze nie wiedzieliśmy (tj. uczestniczący w wątku), że przy modyfikacji rejestru tym sposobem Excel powinien być wyłączony. Samo rozwiązanie z tą wiedzą jest już oczywiste. Ale jak Kolega zna sposób na napisanie kodu bez zapisywania pliku skryptu na dysku, to poprosiłbym o jego przytoczenie. Widziałem, że w Shell można chyba konkatenować linijki podwójnym ampersandem, ale nie wiem czy to dobry trop.
_________________
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: 403118 Skopiuj do schowka
 
 
Artik 



Wersja: Win Office 365
Pomógł: 3139 razy
Posty: 10389
Wysłany: 03-04-2021, 01:25   

Rafał B., skoro programistyczny dostęp do projektu jest problematyczny, to w Twoim przypadku może postępować inaczej. Dostarczać nowy plik, a makrem "tylko" przenosić dane ze starego do nowego.

A w ogóle, to wiesz, że popełniłeś podstawowy błąd? Gdzie rozdział danych od kodu?!
Ale kto zawsze rozdzielał dane od kodu niech pierwszy rzuci kamieniem. :mrgreen:

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



Wersja: Win Office 2016
Pomógł: 40 razy
Posty: 283
Wysłany: 03-04-2021, 02:22   

@Artik
Nie bardzo rozumiem, czy to wiadomość do mnie, bo u mnie problemu z dostępem programistycznym nie ma, mój klient zgodził się zaznaczyć. :-) A co do drugiej kwestii, to dalej uczę się pisania kodu z regułami SOLID, cały czas popełniam w tym błędy. Część z nich dostrzegam, część mi umyka, dlatego prosiłbym tutaj lub na priv o konkret, nie niestety nie wiem o co biega, a chcę się w tym temacie cały czas doskonalić, żeby "spaghetti-code" nie pisać. A większość ma z tym problem, szczególnie w świecie VBA. Nawet całkiem niedawno jeden z powszechnie szanowanych (również przeze mnie) modów sugerował mi tutaj- zapewne nieświadomie- złamanie zasady Single Resposibility Principle ... ;-)
_________________
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: 403121 Skopiuj do schowka
 
 
apollo
ExcelSpec


Pomógł: 1317 razy
Posty: 4544
Wysłany: 03-04-2021, 02:26   

Rafał B. napisał/a:
Ale jak Kolega zna sposób na napisanie kodu bez zapisywania pliku skryptu na dysku, to poprosiłbym o jego przytoczenie.

Bez żadnego pliku VBS, kod w np. Module1
Kod:

Sub SetTrustAccess(ByVal value As Long)
Dim shellObj As Object
    If value < 0 Or value > 1 Then Exit Sub
    Set shellObj = CreateObject("WScript.Shell")

    shellObj.RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Office\" & Application.Version & "\Excel\Security\AccessVBOM", value, "REG_DWORD"
    Set shellObj = Nothing
End Sub

Sub test()
    SetTrustAccess 1
'    SetTrustAccess 0
End Sub
ID posta: 403122 Skopiuj do schowka
 
 
Rafał B.
Stały bywalec Excelforum



Wersja: Win Office 2016
Pomógł: 40 razy
Posty: 283
Wysłany: 03-04-2021, 02:34   

@Apollo Oczywiście ten kod nie działa,
Kod:
?ThisWorkbook.VBProject.VBComponents.Count

w Immediate daje dalej po jego odpaleniu Runtime Error 1004 i brak dostępu programistycznego mimo "fejkowego" zaznaczenia w oknie Trust. Ale przecież o tym pisaliśmy już w tym wątku kilkukrotnie; Excel musi być wyłączony. Nie jestem biegły w VBS, po prostu potrzebujemy skryptu, który działa zgodnie, a nie podobnie z opisem Kolegi, czyli (1) zmodyfikuje rejestr bez żadnej instancji Excela w tle. I (2) chcemy go odpalić z Excela. Prosty skrypt, który ma zrestartować Excela, w międzyczasie zrobić swoją robotę. Prosta sprawa, pytanie tylko czy bez tymczasowego pliku da radę, żeby ograniczyć ryzyko odezwania antywirusa.
_________________
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: 403123 Skopiuj do schowka
 
 
apollo
ExcelSpec


Pomógł: 1317 razy
Posty: 4544
Wysłany: 03-04-2021, 12:25   

Rafał B. napisał/a:
@Apollo Oczywiście ten kod nie działa,
Kod:
?ThisWorkbook.VBProject.VBComponents.Count

Przepraszam, moja wina, że nie czytałem wszystkich postów, dlatego nie zrozumiałem problemu. ;-)
ID posta: 403141 Skopiuj do schowka
 
 
Artik 



Wersja: Win Office 365
Pomógł: 3139 razy
Posty: 10389
Wysłany: 06-04-2021, 02:35   

Rafał B. napisał/a:
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).
Poszperałem nieco.
Ale zanim do sedna, to tylko wspomnę o konfiguracji, na której testowałem: Win10 64-bit, MSO 365 32-bit.
Zaczęło się od prostego kodu stąd:
Kod:
Sub AAA()
    Dim scr         As Object
    Set scr = CreateObject("ScriptControl")    'CreateObject("MSScriptControl.ScriptControl")

    'Dim scr As ScriptControl
    'Set scr = New ScriptControl


    scr.Language = "VBScript"
    scr.AddCode "Sub T: MsgBox ""Hello World"": End Sub"
    scr.Run "T"
End Sub
Obojętnie, czy to na późnym, czy wczesnym wiązaniu, to kicha. Nie był w stanie przełknąć języka (JScript łyknął).

Szukam dalej i trafiam na kod przedstawiony przez omegastripes. Skupiłem się tylko na pierwszym kodzie. Też nie do końca zatrybiło. Kompilacja warunkowa spowodowała, że właściwie wykonywał się kod cytowany wyżej. Dopiero jak usunąłem warunki to załapało:
Kod:
Sub Test()

    Dim oSC         As Object

    Set oSC = CreateObjectx86("MSScriptControl.ScriptControl")    ' create ActiveX via x86 mshta host
    Debug.Print TypeName(oSC)    ' ScriptControl
    ' do some stuff

    oSC.Language = "VBScript"
    oSC.AddCode "Sub T: MsgBox ""Hello World"": End Sub"
    oSC.Run "T"


    CreateObjectx86 , True    ' close mshta host window at the end

End Sub


Function CreateObjectx86(Optional sProgID, Optional bClose = False)

    Static oWnd     As Object
    Dim bRunning    As Boolean

    '#If Win64 Then
    bRunning = InStr(TypeName(oWnd), "HTMLWindow") > 0
    If bClose Then
        If bRunning Then oWnd.Close
        Exit Function
    End If

    If Not bRunning Then
        Set oWnd = CreateWindow()
        oWnd.execScript "Function CreateObjectx86(sProgID): Set CreateObjectx86 = CreateObject(sProgID): End Function", "VBScript"
    End If
    Set CreateObjectx86 = oWnd.CreateObjectx86(sProgID)
    '#Else
    '    Set CreateObjectx86 = CreateObject(sProgID)
    '#End If

End Function


Function CreateWindow()

    ' source http://forum.script-coding.com/viewtopic.php?pid=75356#p75356
    Dim sSignature, oShellWnd, oProc

    On Error Resume Next
    sSignature = Left(CreateObject("Scriptlet.TypeLib").GUID, 38)
    CreateObject("WScript.Shell").Run "%systemroot%\syswow64\mshta.exe about:""about:<head><script>moveTo(-32000,-32000);document.title='x86Host'</script><hta:application showintaskbar=no /><object id='shell' classid='clsid:8856F961-340A-11D0-A96B-00C04FD705A2'><param name=RegisterAsBrowser value=1></object><script>shell.putproperty('" & sSignature & "',document.parentWindow);</script></head>""", 0, False
   
    Do
        For Each oShellWnd In CreateObject("Shell.Application").Windows
            Set CreateWindow = oShellWnd.GetProperty(sSignature)
            If Err.Number = 0 Then Exit Function
            Err.Clear
        Next
    Loop

End Function
Nie analizowałem dalszych aktualizacji w wątku, a być może warto.

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


Pomógł: 2 razy
Posty: 263
Wysłany: 06-04-2021, 10:08   

Wow... ale Panowie się rozgadaliście :)
Dziękuje wszystkim za zainteresowanie i chęć rozwiązania problemu.

Ja potrzebuje tego rozwiązania do dynamicznej zmiany zachowania excela w razie nagłych potrzeb.

Czyli posiadam oryginalny pusty formularz z którego są tworzone setki kopii.
Jeżeli potrzeby firmy się zmienią to muszę masowo zmieniać makra we wszystkich plikach. A jeśli plik został wysłany mailem i będzie używany bez zmiany makra to zaczyna się problem.

Dlatego makro chce pobierać z sieci i w razie potrzeb zmieniać je. Czyli przy otworzeniu skoroszytu zaciągam właściwy kod.
Podczas pracy makra mam go w zmiennej - problem właśnie z odpaleniem kodu.
i jak by to dało rade zrobić to pozamiatane. nie musze zmieniać kodu w setkach innych skoroszytach.

*Edit - no i oczywiście chciałbym aby działało to bez żadnych komunikatów, dodatkowych plików itp.
  
ID posta: 403228 Skopiuj do schowka
 
 
Rafał B.
Stały bywalec Excelforum



Wersja: Win Office 2016
Pomógł: 40 razy
Posty: 283
Wysłany: 06-04-2021, 17:07   

Cytat:
no i oczywiście chciałbym aby działało to bez żadnych komunikatów

Rozumiem, ale ze swojej strony bym odradzał.

Gra moim zdaniem nie warta świeczki w tym przypadku- dziwne kombinacje (i czy niezawodne takie obejścia? Pięciu złotych bym na to nie postawił, że zadziała u wszystkich, tym bardziej gdy mówimy o kilkudziesięciu i więcej maszynach), żeby ulżyć użytkownikowi dosłownie dwu kliknięć myszy (sic! checkbox "Ufaj..." + OK) i to jednorazowo w automatycznie wyświetlonym okienku, żeby było jeszcze wygodniej. A makra też programowo Kolega im wszystkim włącza?

PS
Przy opisywanym problemie niezależnie od obranego rozwiązania należy oczywiście zadbać, żeby bez połączenia z siecią formularz był bezużyteczny (zagrożenie korzystania ze starej wersji schemy).

PPS
@Artik
bardzo ciekawe,muszę przeanalizować na spokojnie, dzięki! :)
_________________
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: 403250 Skopiuj do schowka
 
 
Artik 



Wersja: Win Office 365
Pomógł: 3139 razy
Posty: 10389
Wysłany: 09-04-2021, 11:55   

Marecki napisał/a:
Testuje to tak:
1. Otwieram nowy plik , wyłączam dostęp programistyczny, wklejam makro:
Kod:
Public Sub TurnOnTrustAccess()
...
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.
Rafał B. napisał/a:
Ciekawe czy SendKeysem pójdzie
No i chyba trzeba będzie się przeprosić z SendKeys-em. A przynajmniej znacząco ułatwi to kod.

Taka procedura testująca:
Kod:
Sub Test2()
    MsgBox "Programistyczny dostęp do projektu: " & IIf(TrustAccess, "Tak", "Nie")

    Application.SendKeys "{TAB 2} ~", True

    Application.CommandBars.ExecuteMso ("MacroSecurity")

    MsgBox "Programistyczny dostęp do projektu: " & IIf(TrustAccess, "Tak", "Nie")
End Sub


Private Function TrustAccess() As Boolean
    Dim vbProj      As Object

    On Error Resume Next
    Set vbProj = ThisWorkbook.VBProject
    On Error GoTo 0

    TrustAccess = (Not vbProj Is Nothing)

End Function
Dwa minusy tego rozwiązania:
1. Niepewny SendKeys i ingerencja w NumLock
2. Mignięcie okna.

W trakcie testów ani razu SendKeys nie zawiódł, ale to nie znaczy, że w przyszłości lub wykorzystany w nieco innym kodzie nie zawiedzie. Już dość dawno zauważyłem, że zamiast SendKeys-a warto używać Win API. API też nie jest 100% rozwiązaniem, jednak jest zdecydowanie pewniejsze od SendKeys-a. Dlatego zamienię kod na
Kod:
Sub Test2()
    MsgBox "Programistyczny dostęp do projektu: " & IIf(TrustAccess, "Tak", "Nie")

    VirtualKey_Send KEY_TAB
    VirtualKey_Send KEY_TAB
    VirtualKey_Send KEY_SPACE
    VirtualKey_Send KEY_RETURN

    Application.CommandBars.ExecuteMso ("MacroSecurity")

    MsgBox "Programistyczny dostęp do projektu: " & IIf(TrustAccess, "Tak", "Nie")
End Sub
plus moduł do obsługi API (w załączniku).
W kodzie produkcyjnym należało by po "zaznaczeniu" CheckBox-a sprawdzić, czy mamy już programistyczny dostęp. Jeżeli nie, to ponownie wywołać okno i "kliknąć" CheckBox-a. Czynność możemy wykonywać do skutku lub poddać się po iluś tam razach. "Do skutku" nie można, bo możemy wpaść w nieskończoną pętlę, więc kiedyś trzeba się poddać (lub zastosować inne rozwiązanie).

Drugi problem (mignięcie okna) też prawdopodobnie da się rozwiązać stosując jakieś "mocniejsze" zamrożenie ekranu. Tego już nie ćwiczyłem.


Rafał B. napisał/a:
Gra moim zdaniem nie warta świeczki (...) żeby ulżyć użytkownikowi dosłownie dwu kliknięć myszy
Akurat w kodzie, który dzikzlasu potrzebuje nie może być żadnych komunikatów. To ma być swego rodzaju rozwiązanie szpiegujące, którego działania użytkownik nie ma świadomości.
Jednak wyżej przedstawiony kod może wykluczyć klikanie przez użytkownika.

Artik

mod_SendKeys_API.bas
Pobierz Plik ściągnięto 4 raz(y) 16.03 KB

_________________
Persistence is a virtue in the world of programming.
  
ID posta: 403329 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