27. august 2007 - 13:09Der er
30 kommentarer og 1 løsning
En countdown
Hej eksperter.
Jeg søger en 20 sekunder countdown som skal køre i en msgbox (efter man har trykket ok i en form - til excel skal bruge dataen til andet senere). Den skal bare køre "20-19-18..-færdig"
- grunden er at den database, der hentes data fra, er ret så langsom, så der skal lige være 20 sek. delay inden processen fortsætter (eller står der bare N/A i alle celler).
I dette særtema om aspekter af AI ser vi på skiftet fra sprogmodeller til AI-agenter, og hvordan virksomheder kan navigere i spændet mellem teknologisk hastighed og behovet for menneskelig kontrol.
Du kan så vidt jeg vid ikke gøre det et et msgbox men du kan lave din egen msgbox af en form, hvor du starter en ontime event i det øjeblik at formen vises.
Dim CountDown As Date Sub Timer() CountDown = Now + TimeValue("00:00:01") Application.OnTime CountDown, "Reset" End Sub Sub Reset() Dim count As Range Set count = [A1] ' A1 indeholder antal sekunder, samt er cellen der tæller ned. count.Value = count.Value - 1 If count <= 0 Then MsgBox "Countdown complete." Exit Sub End If Call Timer End Sub
Men jeg kan ikke finde ud af, at få tælleren ind i en msgbox (uden at man skal klikke ok hver gang).
Er det sådan at du vil have den til at tælle ned til fra 10 til 0, og så gøre noget - derefter tælle ned fra 10 til 1, gøre noget - uden at du skal trykke på ok?
Når man har lavet sine valg i UserForm, og klikker "ok", skal der gerne springe en msgbox frem, som tæller ned fra 20 - når den er færdig, skulle al data gerne være indlæst, og man kan se sit output.
Dim CountDown As Date Sub Timer() CountDown = Now + TimeValue("00:00:01") Application.OnTime CountDown, "Reset" End Sub
Sub Reset() Dim count As Range Set count = [A1] ' A1 indeholder antal sekunder, samt er cellen der tæller ned. count.Value = count.Value - 1
If count <= 0 Then MsgBox "Countdown complete." Exit Sub Else Application.StatusBar = "Færdig om " & count.Value & " sekunder" End If Call Timer End Sub
Public Sub Delay() Dim i As Integer Dim Ventetid As Integer
FRM_Statusbar.Show
DoEvents Ventetid = 20
For i = 0 To Ventetid Application.OnTime Now + TimeValue("00:00:01") FRM_Statusbar.Txtbox_status.Width = (230 / (Ventetid)) * i FRM_Statusbar.Repaint Next i
FRM_Statusbar.Hide
End Sub
Men intet virker (hvis ikke koden giver mening, så se evt. linket, det er en userform med en farvet textbox, der opdateres). Den ville se supersprød ud, og derfor kunne det være fedt, hvis en af jer, lige kunne rette lidt i koden, så den virker :D
Jeg har selv engang brugt en lignende løsning. Du kan dog bruge en progressbar der kommer med Windows:
* Åbn værktøjslinien "Kontrolelementer" * Klik på "Hammer & skruenøgle" der hedder "Flere kontrolelementer" * Find Microsoft Progressbar Control, Version 6
Der er dog noget med at den kun virker på den computer den er lavet i, medmindre den er tilføjet på andre computere hvor arket skal bruges.
Med hensyn til løsningen du arbejder på:
lav den med 2 labels: 1 der er hvid, og en der er blå. Den blå skal have lidt mindre dimensioner i højde end den hvide. På den måde får du en "professionel" progressbar.
Og du bør overveje at sætte progressbaren til at køre med kodens afvikling, fremfor på tid. Derudover skal din form måske være sat til ShowModal = false
Hvis din kode til at hente data, ikke kører i et loop, får du aldrig opdaterer tiden. Fordi du skal bruge komandoen "DoEvents", til at fortælle excel at den skal lave andet indimellem sine loops.
Sub Main() Dim i As Long, Ventetid As Long Dim PctDone As Single
If TypeName(ActiveSheet) <> "Worksheet" Then Exit Sub Ventetid = 10 For i = 1 To Ventetid PctDone = i / Ventetid With ProgressBar .FrameProgress.Caption = Format(PctDone, "0%") .LabelProgress.Width = PctDone * (.FrameProgress.Width - 15) End With ' The DoEvents statement is responsible for the form updating DoEvents ' Call Timer Next i MsgBox "Færdig" Unload ProgressBar End Sub
Sub Timer() Dim CountDown As Date CountDown = Now + TimeValue("00:00:01") Application.OnTime CountDown End Sub
Hvordan kan jeg få timeren ind i min lykke, så jeg kan styre "tiden", for det er lidt ufedt, at lade den køre fra 1-100.000 bare for at den skal stå i 30-40 sek.
Lavede en såkaldt "cowboyder", så nu virker det - men jeg er stadig åben overfor forslag til forbedringer :)
Sub Main() Dim i As Long, Ventetid As Long Dim PctDone As Single
If TypeName(ActiveSheet) <> "Worksheet" Then Exit Sub Ventetid = 20 For i = 1 To Ventetid PctDone = i / Ventetid With ProgressBar .FrameProgress.Caption = Format(PctDone, "0%") .LabelProgress.Width = PctDone * (.FrameProgress.Width - 15) End With DoEvents Call Timer Next i MsgBox "Done receiving data" Unload ProgressBar End Sub
Sub Timer() 'Cowboyder finte loades Dim CountDown As Date CountDown = Now + TimeValue("00:00:01") Do While Now < CountDown Loop End Sub
Den skal som sådan bare stå og køre i 20 sek, mens de indhentede celler i baggrunden står og modtager data fra datakilden (som er den langsomme). Her kan man ikke blot gå videre i processen, da de data med det samme skal laves fra formel til value, og derfor strengt nødvendigt behøver at være 100% indlæst.
(har dog endnu ikke testet, om excel henter data, når den står og kører andre processer...)
Ok, efter at have kæmpet med det #"¤"#¤"% i mange timer må jeg nu give lidt op, jeg kan simpelthen ikke hente værdierne i cellerne før makroen er kørt helt færdig. Det er helt ligegyldigt, hvor meget jeg lader den vente (køre do while løkker).
Dog kan jeg bede den om at lave Application.OnTime, men da den første af disse skal køre midt i mit program, bliver det et helvede. Så skal man nemlig pludselig køre alle subs senere, hvilket betyder, at man ikke kan hente variable ind i dem - jeg ved i hvert fald ikke hvordan, og nu er jeg blevet træt og sur!
Har testet med skærmupdate og calculation, det hjælper ikke meget...
I baggrunden henter excel data fra Bloomberg (en database over priser på obligations og valutamarkedet mm.). De er et stykke tid om at blive loadet, det vil sige, at den starter med at skrive "#N/A" i alle celler og efter 10 sek, så kommer værdierne ind i cellerne. De celler hedder jo så noget i stil med ="BLP <nøgletal> <index>", derfor skal jeg lige have kopieret værdierne over i et nyt ark, inden jeg kan begynde at arbejde på dem.
Det jeg har lavet er altså, et program der ved kørsel beder om at få alle værdier opdateret, vente 10 sek, kopiere cellerne over i nyt ark (pastespeciel values only), og derfra lave det relevante arbejde på dem.
Men cellerne henter først værdier ind i det sekund, at ingen makroer kører, sætter jeg delay til et sekund, går der 9 sekunder før data kommer (efter makro stop), sætter jeg delay til 20 sekunder, kommer data'en milisekundet efter makroen stopper - men ikke før.
Mit dilemma er altså, at jeg ser det nødvendigt, at lave to makroer, en der henter relevant data, og så en der gør resten, ville ellers gerne have det automatiseret til at blive en enkelt makro - "åben ark, opdater, luk". Men det er nok umuligt :S
Ja, det kan hverken lade sig gøre med en Msgbox, Statusbar, eller på anden vis. Når der kører noget VBA kode, er arket i princippet spærret. Jeg forstår dog ikke lige hvorfor det taget 20 sekunder før den har beregnet alle cellerne! Hvor mange data drjer det sig om?
Heh, den er lidt speciel hvad det angår, for den retter kun den enkelte celle, når jeg retter en enkelt celle. Men det drejer som 1295*7 celler ~ 10.000, vil dog nok skære lidt ned på antallet, da nogen af dem er statiske, og derfor ikke behøves at blive opdateret.
Men at lave 10.000 opslag i Bloomberg tager lidt tid for Bloomberg at behandle - har prøvet løsningen med at slå ScreenUpdating og Calculation fra, men det hjælper lige lidt, når data først kommer frem når makroen er færdig med at læse.
Men i dag er en ny dag, så nu vil jeg prøve at gribe problemet an på en ny måde - har desuden fundet ud af, at jeg skal gemme de data i 200 dage tror jeg.. hvor til den skal lave opslag og sammenligninger på dato'er, lidt et helvede..
Nu ved jeg jo ikke hvordan du henter data, men hvis du skriver 10.000 gange i et ark, vil arket stadig prøve at beregne for hver gang der indsættes en værdi. Dette gælder selvfølgelig ikke hvis dataene bliver indsat i et hug. Men tilsyneladende tager din hentning længere tid, en beregningen, siden du intet vinder i tid.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.