Sida 1 av 1
EXCEL macron
Postat: 23 september 2006, 19:47:11
av Chribbe76
Hej!
Jag har just upptäckt hur flexibelt Excel är.
Excel macron är uppbyggda av visual basic så man kan göra väldigt avancerade grejer.
Min fråga är: Kan man få en snutt med VB-kod att execveras kontinuerligt(med ett tids intervall)?
Det jag har gjort hittils är att VB-koden bara execveras när man pillar i dokumentet.
Så här ser det ut:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'Här ligger koden
End Sub
Postat: 23 september 2006, 22:14:52
av pheer
Vilke funktion är du ute efter? Kanske duger sheet change eventet? Enklast placerar du följande kod i open-eventet för workbook:
Kod: Markera allt
do
DoSomeThings()
sleep(sleepTime)
loop while something
Deklarationen för sleep hittar du i api text viewer.
*ändrad*
Postat: 23 september 2006, 23:46:37
av Chribbe76
Jag är ute efter exakt vad du visar och det blev nästan rätt.
Problemet med följade kod i Workbook Open är att resten av programmet inte får någon cpu-kraft, jag får timglas och kan inte göra något alls men denna funktion gör vad den ska.
(Jag är inte så bra på visual basic så jag har säkert gjort något pinsamt fel)
Kod: Markera allt
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Sub Workbook_Open()
Do
Worksheets("Blad1").Cells(21, 2) = Worksheets("Blad1").Cells(21, 2) + 1 'Cellen ökar med 1
Sleep (300)
Loop
End Sub
Postat: 24 september 2006, 00:08:06
av pheer
Släng in DoEvents i loopen, det gör susen. Den lämnar kontroll till windows så att meddelanden kan hanteras.
Postat: 24 september 2006, 00:20:47
av ANEE
Nu var det längesen jag kodade nått i VBA, men testa att lägga in
"DoEvents" i loopen, borde göra susen.
EDIT: Jädrans....pheer hann före

Postat: 24 september 2006, 00:36:22
av Chribbe76
Jippi det funkar!
Tanken med tisdfördröjningen var egentligen att ge cpu-kraft till resten och som det är nu gör den bara så allt laggar så jag skippar fördröjningen.
Bara ett problem till.
Om jag skriver något i en cell så stannar snurran.
Det finns troligtvis någon enkel lösning på det, får klura på det imorgon.
Postat: 24 september 2006, 13:41:40
av Chribbe76
Det fungerar nu, jag placerade min eviga loop i slutet av:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Den triggas varje gång man flyttar markören.
Det känns lite fel att göra så men inget annat har fungerat.
Jag har gjort ett test som visar kedje-reaktionen Markörflyttning --> VB ändrar en cell --> En formel i en cell läser av värdet och räknar lite --> VB läser av resultatet och dribblar med diverse texter i bladet. Och allt upprepas kontinuerligt.
När man startar excel kör inte den eviga loopen (det är väl ok) och den stannar när man skriver något i en cell (mycket bra) och startar igen när man trycker enter.
Riktigt dålig film men jag visar den iaf:
http://ake.myftp.org/forum/Excel_Macro.MOV
Det jag planerar är att detta(nja.. något helt annat) ska användas i en CNC-maskin på jobbet så det är viktigt att det inte innehåller några "tveksamma lösningar".
Det som kan vara tveksamt i detta fall är den eviga loopen i slutet av Worksheet_SelectionChange som exekveras varje gång man flyttar markören.
Vad tycker expert-panelen om den lösningen, duger det i en CNC-maskin?
Kod: Markera allt
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
' Här lägger jag det som ska hända varje gång man flyttar markören
Worksheets("Blad1").Cells(20, 2) = Worksheets("Blad1").Cells(20, 2) + 1
Do
If (Timer > R1 + 0.5) Or (R1 > Timer) Then
R1 = Timer
'Denna kod körs 2 gånger/sekund kontinuerligt
Counter2 = Counter2 + 1
If Counter2 > 5 Then Counter2 = 0
If Counter2 = 0 Then Worksheets("Blad1").Cells(22, 5) = ">> "
If Counter2 = 1 Then Worksheets("Blad1").Cells(22, 5) = " >> "
If Counter2 = 2 Then Worksheets("Blad1").Cells(22, 5) = " >> "
If Counter2 = 3 Then Worksheets("Blad1").Cells(22, 5) = " >> "
If Counter2 = 4 Then Worksheets("Blad1").Cells(22, 5) = " >> "
If Counter2 = 5 Then Worksheets("Blad1").Cells(22, 5) = " >>"
Worksheets("Blad1").Cells(21, 2) = Worksheets("Blad1").Cells(21, 2) + 1
End If
DoEvents
Loop
[EDIT] Jag har ändrat så att programmet använder den inbyggda sekundräknaren för att bestämma när något ska hända så nu blir det inte cpu-beroende.
Postat: 24 september 2006, 17:46:59
av pheer
Om du vill ha bättre upplösning föreslår jag att du använder någon av följande:
GetTickCount() - 10-50ms upplösning
timeGetTime()+timeBeginPeriod() - 1 ms upplösning
QueryPerformanceFrequency()+QueryPerformanceCounter() - upplösningen är hårdvaruberoende men betydligt lägre än 1ms
Postat: 24 september 2006, 19:02:23
av Chribbe76
Till detta behövs inte bättre upplösning än vad Timer ger, den verkar ha en upplösning på 1/60 sekunder.
Det som den eviga loopen kommer göra är att hämta och skicka data till styrsystemet och det räcker egentligen med en gång per sekund.
Tack för hjälpen!
Kommentarer eller tips angående metoden är välkommna.