< návrat zpět

MS Excel


Téma: VBA - pokračování po DoEvents rss

Zaslal/a 17.11.2014 22:39

Tlačítkem spouštím makro - nekonečný cyklus Do..Loop, který načítá neustále hodnoty z technologické karty. Potřebuji stiskem klávesy cyklus přerušit a pokračovat za Loop. Dal jsem tam DoEvents, ale to ukončí celé makro, dál už nepokračuje a ještě k tomu skočí zpět do EXCELU do editace buňky(tzn. nabídky v liště šedivé) a čeká na zápis do buňky.
Jde to přerušit nějak jinak?
Nebo aspoň, aby se to vrátilo "normálně" do EXCELU bez nutnosti potvrdit?
---
Do
DoEvents
If Keypressed then Exit Do
Call XXX
Loop
MsgBox(.....sem už to nikdy nedojde)
End Sub

Zaslat odpověď >

Strana:  « předchozí  1 2 3   další »
icon #022384
avatar
Ospravdelňujem sa, že sa do toho pletiem, ale nebola náhodou marjankajova reakcia na tvoje vyjadrenie: to není žádná proměnná, ale klíčové slovo pro událost VBA ? Kľúčové slovo (resp. rezervované slovo) je terminus technicus, nemôže im byť niečo, čo ním proste nie je, páč, ako už zmienili viacerí predo mnou, žiadny keypressed proste VBA nepozná, pokiaľ to teda nie je nejaký názov premennej apod., a to je jasné z kontextu, že tento prípad to nie je. Tak sa nediv, že sa niekto pozastaví nad tým, keď sa vyjadruješ ledabylo.citovat
icon #022386
eLCHa

mike55 napsal/a:

Co na to říct ? Omlouvám se stokrát za NEVHODNÉ, NEEXISTUJÍCÍ slovo keypressed. Sypu si popel na hlavu, jsem totální číňan, motám všechno dohromady. STAČÍ?
Chtěl jsem POUZE poradit, jak vyskočit z cyklu stiskem libovolné klávesy a ne tady vést nekonečnou, nesmyslnou debatu o slovu keypressed.

Já Vám rozumím od začátku. Chcete nahradit slovo keypressed něčím funkčním. Jenže VBA v tomto kontextu nic takového neobsahuje. Já chci ale vysvětlit to keypressed z toho úryvku, který jste sem dal - protože píšete že se kód zastaví, takže nějaký kód máte. Něco jste už zkoušel. Chtěl jste POUZE poradit, tak pokud jste si nevšiml, o nic jiného se celou dobu nesnažím. Dnes jsem na Vašem dotazu strávil cca 4 hodiny. Samozřejmě je to proto, že mně to zajímá, kdyby ne, tak jsem skončil svojí první odpovědí. Nicméně od začátku vím, že pokud nějaké řešení vymyslím (a věřte mi, že na netu jsem podobných dotazů jako je Váš už našel spoustu a nikdy žádné řešení nebylo - pouze sledování stavu CAPS, SHIFT apod.), hned Vám napíšu, že to není správná cesta. To je prostě můj názor. Řešení jsem nakonec vymyslel - má pravděpodobně ještě mouchy, kdyby to bylo moje a chtěl bych to tak, tak to dotáhnu až do konce...
Musíte si uvědomit, že excel není standardní prostředí pro programovací jazyk a tak, pokud něco znáte z jiného jazyka, tady se to dělá jinak.citovat
#022388
avatar
Dobře, prosím o pochopení, že tady odpovídám na dva názory. Takže konkrétně: s uživatelem marjankaj vedu debatu o "keypressed", z mého pohledu o ničem-uznal jsem, že to slovo je blbost a doufám, že tím to končí.
S uživatelem eLCHa vedu konkrétní debatu o mém problému, za což mu děkuji. Pokud se kódu týká, je to opravdu jen :
-------
Do
DoEvents
Call XXX - procedura pro načtení dat z karty
Loop
MsgBox(.....sem už to nikdy nedojde)
End Sub
---------
Na stisknutí klávesy- třeba mezera - se cyklus opravdu ukončí, ale bohužel s tím celé makro, takže na ten MsgBox prostě nedojde. to je celý problém - ukončit korektně cyklus stiskem klávesycitovat
#022389
avatar
Pro eLCHa : zkoušel jsem ten kód, ale laicky si stále myslím, že DoEvents prostě zareaguje na událost - stisknutí třeba mezerníku - a ukončí makro. Ten Váš kód proběhne, pokud se to nedostane do té části, kde je DoEvents (v závislosti na bEnd), tj. doběhne ten dlouhý cyklus.
Odborně Definice DoEvents od Microsoftu
"Funkce DoEvents vzdá spuštění makra tak, aby operační systém mohl zpracovávat další události. Funkce DoEvents předá řízení aplikací v operačním systému".
http://support.microsoft.com/kb/118468/cscitovat
#022390
avatar
No hlavní problém je, že stiskem některých kláves se dostaneš do editačního módu a tím pádem procedura skončí. Lze to ale řešit buď příkazovým tlačítkem, nebo změnou "selection". Oba způsoby máš v příloze.
Příloha: zip22390_stop_cykl.zip (18kB, staženo 17x)
citovat
#022392
avatar
A predsa až také nezmyselné to slovo KEYPRESSED nie je.
Síce to nefunguje na hociktorú klávesu, ale ENTER alebo smerové šípky zaberajú.


Sub Pokus()
Dim keypressed As Boolean
Cells(3, 3).Select
Do
DoEvents
keypressed = ActiveCell.Address(, , xlR1C1) <> "R3C3"
If keypressed Then Exit Do
Loop
MsgBox "konec"
End Sub


@kp57 Snáď ma nezabiješ, že som použil tvoj nápad. 1citovat
icon #022393
eLCHa
@mike55
zkoušel jsem ten kód, ale laicky si stále myslím, že DoEvents prostě zareaguje na událost - stisknutí třeba mezerníku - a ukončí makro
Ne, tak to není a v následujících příspěvcích se Vám (a nejen Vám) to pokusím objasnit

1) - upravil jsem si Váš kód taktoSub test()
Dim i As Long, iMax As Long
i = 0
iMax = 100000

Do
i = i + 1
DoEvents
If Keypressed Or i >= iMax Then
Exit Do
End If
Debug.Print i
Loop
MsgBox "(.....sem už to nikdy nedojde)"
End Sub
a k MsgBoxu jsem se dostal. Je to proto, že jsem mu zadal alternativní konec cyklu.
Pokud stisknete klávesu na listu bez spuštěného kódu, co se stane? Začne editace buňky.
Pokud spustíte jakýkoliv kód, to se nestane, dokud kód neskončí.
Dal jsem tam DoEvents, čímž jste umožnil systému zpracovat jiné události (stisk klávesy) a tak dál už nepokračuje a ještě k tomu skočí zpět do EXCELU do editace buňky. Už vidíte tu logiku? V tuto chvíli běh kódu neskončil - on běží dál, ale mezitím se Vám excel přepnul do editace buňky. Problém je v tom keypressed - máte ho nedefinované a tak je to proměnná typu Variant a hlavně - nikde mu nepřiřazujete žádnou hodnotu a přitom testujete, zda se rovná True.If Keypressed then Exit DoAle hodnota je Empty a tak se Vám ten kód nikdy nezastaví.citovat
icon #022394
eLCHa
2)Teď k mému kódu. Na první pohled to vypadá stejně. Pokud spustíte kód na listu a stisknete mezerník, objeví se hláška a po jejím odkliknutí se přepne do editace buňky. Ano, protože jsem stiskl mezerník a instrukce DoEvents toto umožnila.Zároveň jsem ale přidal požadavek, že pokud dojde ke stisku klávesy, spustí DoEvents proceduru fncKeyboardProc a pokud ta stisknutá klávesa bude mezerník, tak proměnné bEnd (mohl jsem ji nazvat keypressed) přiřadí hodnotu True. A tak dojde k ukončení cyklu - tzn. doplnil jsem ten Váš chybějící krok přiřazení hodnoty. Rozdíl poznáte podle toho, že už nejsounabídky v liště šedivé - u mně se to projevilo až po kliknutí kdekoliv na list. Tzn - kód už neběží.
Procedura fncKeyboardProc se spustí po stisku jakékoliv klávesy a k přerušení dojde pouze při stisku mezerníku (ten jsem si vybral, protože je největší ;) )citovat
icon #022395
eLCHa
3)

mike55 napsal/a:

"Funkce DoEvents vzdá spuštění makra tak, aby operační systém mohl zpracovávat další události. Funkce DoEvents předá řízení aplikací v operačním systému".
http://support.microsoft.com/kb/118468/cs

Toto jsem samozřejmě četl, ale trvalo mi dlouho, než jsem to skutečně pochopil.
Kód, který tu dal marjankaj (kp57 jsem nestudoval, ale bude to podobné) bude fungovat pro směrové šipky a na některých (většině) počítačích i pro klávesu ENTER - je to logické - DoEvents umožní systému zpracovat informaci o stisku směrové klávesy a tak posune kurzor - takové řešení mně samozřejmě taky napadlo a v podstatě to může být nejsnazší řešení pro Vás. Když už jsem se tím ale zabýval, chtěl jsem obecné řešení pro stisk jakékoliv klávesy, což se mi povedlo. Stačí jen dořešit zrušení stavu editace buňky a je možné si vybrat jakoukoliv klávesu či kombinaci kláves. Jsou tam ale ještě ale, které, jak už jsem psal dříve, kdybych to chtěl dotáhnout, tak to dotáhnu (Např. musí se zajistit, aby proběhlo UnhookWindowsHookEx hHook, jinak bude procedura fncKeyboardProc volána, i když samotný cyklus už dávno skončí.)

Osobně bych ale opravdu využil .NET, který má určitě objekt Klávesnice a v něm testuje, zda je stisknutá klávesa a která to je a tak ten kód bude jednodušší (VB6 je sice blíže VBA, ale editor je placený a když už bych se začal v něčem hrabat, tak v něčem modernějším - pro nás obyčejné laiky mi jako ideální přijde C#).citovat
#022413
avatar
Pokud by stačilo testovat jen jednu klávesu, tak je to celkem jednoduché:

Private Const VK_SPACE As Long = &H20

#If VBA7 Then
Private Declare PtrSafe Function GetKeyState Lib "user32" (ByVal vKey As Long) As Integer
#Else
Private Declare Function GetKeyState Lib "user32" (ByVal vKey As Long) As Integer
#End If

Sub Pokus()
Do Until GetKeyState(VK_SPACE) < 0
DoEvents
Loop
MsgBox "konec"
End Sub

Zastaví na stisk mezery.citovat

Strana:  « předchozí  1 2 3   další »

Uživatelské menu

Nejste přihlášen(a)
avatar\n

Menu

Formulář Faktura

Formulář Faktura IV

Oblíbený formulář Faktura byl vylepšen a rozšířen.
Více se dočtete zde.

Helios iNuvio

Používáte podnikový systém Helios iNuvio? Potřebujete pomoci se správou nebo vyvinout SQL proceduru? Více informací naleznete na stránce Helios iNuvio.

On-line nástroje