16. august 2007 - 10:19Der er
32 kommentarer og 1 løsning
Dato i userform
Hejsa
Jeg har en userform hvor brugerne skal taste en dato. Men hvordan laver jeg en textbox e.l. hvor de kan taste denne dato og det skal selvfølgelig være et godkendt format (eks. 15-08-2007) Og de måske i stedet kan vælge datoen i en popup kalender. Så de kan gøre det på to måder.
Jeg går ud fra, at du tænker på valideringen af det, som brugeren indtaster. I så fald kan du bruge følgende kode på Exit-eventet i din tekstboks:
******** Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean) If Not IsDate(Me.TextBox1) Then MsgBox "Dette er ikke et godkendt format for dato. Indtast venligst som dd-mm-åååå.", vbExclamation, "Dato" Cancel = True End If End Sub *******
Mht. en kalenderkontrol (datepicker), så tror jeg ikke, at det er en standard-kontrol. Du skal derfor finde en og installere/registrere den, hvis den skal bruges. Den skal også være tilgængelig hos brugerne (og skal dermed også registreres der).
Hvad har du kaldt din tekstboks? Fjern lige den kode, som du har copy/pastet. Klik på din tekstboks i kodevinduet, klik på F7. Vælg Exit-eventet i rullelisten med events for kontrollen. Indsæt nu den kode, som jeg har lavet, men kun fra If-sætningens start og til if-sætningens slut.
Du kan godt få dags dato til at stå der som standard. På formens Initialize-event skriver du følgende:
me.Textbox1 = Format(Date, "dd-mm-yyyy")
Husk lige at angive det rigtige navn for din tekstbox og ikke kun Textbox1, hvis det ikke er det, den hedder. Jeg kigger lige på det med ugenummeret, men det bør i så fald stå i en tekstboks for sig selv (som skal være låst, da brugerne IKKE skal kunne rette heri - den bør være afhængig af datoen i dato-tekstboksen, og skal derfor ændres i forhold hertil).
******* If Not IsDate(Me.TextBox1) Then MsgBox "Dette er ikke et godkendt format for dato. Indtast venligst som dd-mm-åååå.", vbExclamation, "Dato" Cancel = True Else Me.TextBox2 = Format(Me.TextBox1, "ww", vbMonday, vbFirstFourDays) End If ******** Husk at rette navnene på tekstboksene, så de stemmer med din kode.
Du skal også tage linjen med Me.Textbox2 og inkludere i Initialize-eventet på din form. Ellers får du ikke ugenummeret med ved loading af formen. Husk, at den skal stå EFTER, at koden har skrevet datoen i dato-tekstboksen.
Private Sub f_dato_Exit(ByVal Cancel As MSForms.ReturnBoolean) If Not IsDate(Me.f_dato) Then MsgBox "Dette er ikke et godkendt format for dato. Indtast venligst som dd-mm-åååå.", vbExclamation, "Dato" Cancel = True End If End Sub
Er det ikke rigtigt forstået at fejlmeddelelsen skulle fremkomme når man forlader tekstboksen enten med tab eller enter ?
Private Sub f_dato_Exit(ByVal Cancel As MSForms.ReturnBoolean) If Not IsDate(DateValue(Me.f_dato)) Then MsgBox "Dette er ikke et godkendt format for dato. Indtast venligst som dd-mm-åååå.", vbExclamation, "Dato" Cancel = True End If End Sub
Jo, det er helt korrekt forstået, at du skal få en fejlmeddelelse, når du forlader tekstboksen, hvis indholdet i den ikke er et godkendt datoformat.
Nu har du vel ikke placeret tekstboksen i en frame, vel? For der bliver vba lidt rundtosset, hvilket betyder, at den først afvikler Exit-eventet på et senere tidspunkt. Jeg har selv været ved at blive vanvittig af denne lille "sjove" ting.
Har du prøvet at sætte et breakpoint i exit-eventet for at se, hvornår/hvordan den bliver afviklet og hvad der evt. går galt?
denne er nu testet og den virker, det er koden du selv viser kl. 13:38:54
Den virker uanset om du bruger tab,enter eller mus.
Private Sub f_dato_Exit(ByVal Cancel As MSForms.ReturnBoolean) If Not IsDate(Me.f_dato) Then MsgBox "Dette er ikke et godkendt format for dato. Indtast venligst som dd-mm-åååå.", vbExclamation, "Dato" Cancel = True End If End Sub
Du skal placere koden i Initialize-eventet på din form.
Klik på din form i kodevinduet. Klik på F7. Der skal nu stå UserForm i rullelisten til venstre "oven over" din kode. Klik på rullelisten i højre side. Vælg Initialize. Du har nu Initialize-eventet for din form (et event, der bliver fyret i luften, når du kalder din form første gang). Placer både linjen med dato og den med ugenummer deri.
Mht. formater, så behøver du ikke at angive hvilke formater der skal accepteres. vba genkender flere forskellige datoformater, f.eks.:
10-08-2007 10. august 2007
Og da koden er lavet på en måde, så brugeren bliver bedt om at indtaste det som dd-mm-åååå, hvis ikke datoformatet er korrekt i første ombæring, skulle det ikke være nødvendigt at gøre mere (med mindre selvfølgelig at du har behov for, at datoen kommer "ud" et andet sted på en bestemt måde).
Det virker egentlig fint, men når jeg placerer følgende kode skriver den "kun" ugenr. og ikke dato som udgangspunkt i tekstboxene.
Der måtte gerne stå noget i begge dele. Ugenr. skal selvfølgelig ikke kunne rettes i.
Yderligere... kan man få ugenr. til at tilrette sig efter hvad dato man taster. Kan den selv finde ud af det ?
Koden:
Private Sub f_dato_Exit(ByVal Cancel As MSForms.ReturnBoolean) If Not IsDate(Me.f_dato) Then MsgBox "Dette er ikke et godkendt format for dato. Indtast venligst som dd-mm-åå.", vbExclamation, "Dato" Cancel = True
End If End Sub
Private Sub UserForm_Initialize() Me.f_dato = Format(Date, "dd-mm-yy") Me.f_ugenr = Format(Me.f_dato, "ww", vbMonday, vbFirstFourDays) End Sub
Hvis vi tager starten af din kode (Initialize-eventet), så placerer den faktisk dags dato i tekstboksen med dato. Derefter placeres ugenummeret i ugenummer-tekstboksen (og som koden er lavet, ville den slet ikke placere ugenummeret, hvis ikke der stod en dato i dato-boksen).
Hvis du vil have ugenummeret til at ændre sig i takt med, at man ændrer dato i formen, skal du lige se på min kommentar 16/08-2007 11:44:03. Der har jeg faktisk lavet koden til det.
I øvrigt synes jeg, at du skal ændre dit format på datoen, når du starter formen. Hvis du beder brugerne om at indtaste dato i formatet dd-mm-yyyy, så bør du vel også "fodre" formen på samme måde.
Jeg tænkte på, om du evt. har noget "skrammel", der ligger og roder på din form. Som jeg skrev 08:57:37, så bliver tekstboksen med ugenummer IKKE udfyldt, hvis ikke der står noget i dato-boksen.
Jeg ved jeg udnytter dig grodt nu men jeg har lige opdaget et lidt større problem.
Informationerne indtastet i min userform bliver gemt på en linie i regnearket.
Jeg har to scroll pile i min userform. Når man kører op og ned viser den linierne en for en i regnearket (altså informationerne vises i de pågældende felter i userformen).
Når den viser informationerne om tidligere linier tastet vedr. dato så laver den seperatoren med "/" og datoen skrives mm/dd/åå.
Det er noget bøvl når brugeren får at vide han skal indtaste i formattet (dd-mm-åå).
Steppe igennem kode: Sæt et breakpoint (gøres ved at stille sig på linjen, hvor koden skal stoppes og trykke på F9 - F9 igen for at fjerne breakpointet eller brug Debug-menuen). Fyr formen i luften. Den kode vil nu stoppe ved breakpointet. Brug F8 til at steppe (din kode bliver nu afviklet linje for linje for hver gang du bruger F8 - kan man bare ikke leve uden, specielt ikke når man skal fejlsøge).
Informationer fra arket: Som jeg læser din oplysning, så indlæser du informationerne fra regnearket i formen. Hvis det er rigtigt, kan du jo formatere det, der bliver smidt ind i "informations-formen". Du har faktisk koden til det længere oppe (du skal bruge Format-funktionen, lige som når du fyrer formen i luften).
Hvordan står datoerne i øvrigt i Excel-arket? Står de, som de er tastet eller som de bliver vist i formen?
Sætter breakpoint ved: Private Sub f_dato_Exit(ByVal Cancel As MSForms.ReturnBoolean) og Me.f_dato = Format(Date, "dd-mm-yy")
Trykker F8 og den flytter sig linie for linie igennem begge makroer. Dernæst hopper den til denne makro:
Private Sub f_medarbnr_Enter() Me.f_medarbnr = ""
End Sub
Jeg trykker F8 og den hopper til at aktiverer min userform. Her står datoen som den skal. Ingen fejlmeddelelser e.l. i mellemtiden.
Men det gør den ikke når jeg bare aktiverer userformen.
Med hensyn til dato:
Datoerne står i excel arket som tastet i formen. Cellerne er formatteret således. Den viser dem bare ikke sådan når jeg viser dataene i userformen når jeg efterfølgende scroller gennemg linierne.
Hvilken kode skal jeg smide ind ?
Du får lige hele min kode, håber det er OK
Const grøn = &HC0FFC0 Const gul = &H80FFFF Const DataSti = "C:\Rødvig\Data.xls" 'tilpasses Dim dataarkXLS As Object, kXLS As Object, passFlag As Boolean Dim rækIArk, aktuelleRæk
Private Sub CommandButton1_Click() Dim a, r, tal, last, t Sheets("Data").Activate
last = Cells(65500, 1).End(xlUp).Row a = InputBox("Indtast medarbejdernr. ") If a = "" Then Exit Sub e = InputBox("Indtast ugenr. ") If e = "" Then Exit Sub For t = 11 To last If Cells(t, 1) = CDec(a) And Cells(t, 5) = CDec(e) Then tal = tal + Cells(t, 6) Next If tal = 0 Then MsgBox ("Medarbejdernr. ") & a & (" har ingen timer i uge ") & e: Exit Sub MsgBox ("Medarbejdernr. ") & a & (" har ") & tal & (" time(r) i uge ") & e End Sub
Private Sub f_afslut_Click() ClearFelter Unload UserForm ActiveWorkbook.Close True End Sub Private Sub f_clear_Click() ClearFelter aktuelleRæk = rækIArk visAktuelleRække End Sub Private Sub f_gem_Click() Rem test om alle felter er udfyldt If Me.f_medarbnr.Value <> "" And _ Me.f_timer.Value <> "" And _ Me.f_projekt.Value <> "" And _ Me.f_dato.Value <> "" And _ Me.f_arbejde.Value <> "" Then If Me.f_gem.BackColor = grøn Then OpdaterIArk rækIArk Else OpdaterIArk aktuelleRæk End If Else MsgBox ("Medarbejdernr., timer, projekt, dato og udført arbejde skal udfyldes") Me.f_arbejde.SetFocus End If End Sub
Private Sub f_visAktuelleRække_Exit(ByVal Cancel As MSForms.ReturnBoolean) If IsNumeric(Me.f_visAktuelleRække.Value) = True And _ Val(Me.f_visAktuelleRække.Value) > 1 And _ Val(Me.f_visAktuelleRække.Value) <= rækIArk Then aktuelleRæk = Val(Me.f_visAktuelleRække) visAktuelleRække End If End Sub
Private Sub SpinButton1_SpinUp() If aktuelleRæk - 1 >= 11 Then aktuelleRæk = aktuelleRæk - 1 End If visAktuelleRække End Sub Private Sub SpinButton1_SpinDown() If aktuelleRæk + 1 <= rækIArk Then aktuelleRæk = aktuelleRæk + 1 End If visAktuelleRække End Sub Private Sub visAktuelleRække()
Me.f_visAktuelleRække.Value = aktuelleRæk If aktuelleRæk = rækIArk Then Me.f_visAktuelleRække.BackColor = grøn Me.f_gem.Caption = "Gem" Me.f_gem.Accelerator = "G" Me.f_gem.BackColor = grøn Else Me.f_visAktuelleRække.BackColor = gul Me.f_gem.Caption = "Ret/slet" Me.f_gem.Accelerator = "K" Me.f_gem.BackColor = gul Me.f_sletRækkedata = False End If
ClearFelter Me.f_medarbnr.SetFocus End Sub Private Sub ClearFelter() Me.f_medarbnr.Value = "" Me.f_medarbnavn = "" Me.f_projekt.Value = "" Me.f_dato.Value = "" Me.f_timer.Value = "" Me.f_arbejde.Value = "" Me.f_medarbnr.SetFocus End Sub Private Sub OpdaterIArk(række) If Me.f_sletRækkedata = False Then
rækIArk = findFørsteLedigeRække aktuelleRæk = rækIArk visAktuelleRække Cells(rækIArk, 1).Select ClearFelter End Sub Private Function findFørsteLedigeRække() Dim r For r = 11 To 65000 If Cells(r, 2) = "" Then findFørsteLedigeRække = r Exit Function End If Next r End Function
Private Sub f_medarbnr_Enter() Me.f_medarbnr = ""
End Sub Private Sub f_medarbnr_Exit(ByVal Cancel As MSForms.ReturnBoolean) If passFlag = False Then passFlag = True If Me.f_medarbnr <> "" And IsNumeric(Me.f_medarbnr) = True Then Me.f_medarbnavn = søgKunde(Val(Me.f_medarbnr))
If Me.f_medarbnavn <> "" Then Me.f_medarbnr.SetFocus End If
kXLS.Quit Set kXLS = Nothing End If passFlag = False End If End Sub
Private Function søgKunde(kNr) Set kXLS = CreateObject("Excel.application") With kXLS .Workbooks.Open DataSti, False, True .Sheets(2).Activate Max = .ActiveCell.SpecialCells(xlLastCell).Row For r = 1 To Max If .Cells(r, 1) = kNr Then søgKunde = .Cells(r, 2) Exit Function End If Next r End With søgKunde = "" MsgBox ("Det indtastede medarbnr. kunne ikke findes") End Function
Private Sub indlæsprojekt() On Error GoTo fejlprojektSti
Set dataarkXLS = CreateObject("Excel.application") With dataarkXLS .Workbooks.Open DataSti, False, True .Sheets(3).Activate Max = .ActiveCell.SpecialCells(xlLastCell).Row For r = 11 To Max Me.f_projekt.AddItem .Cells(r, 1) Next r End With
dataarkXLS.Quit Set dataarkXLS = Nothing Exit Sub
fejlprojektSti: MsgBox ("Fejl i sti t/Data.xls") End Sub
Private Sub f_dato_Exit(ByVal Cancel As MSForms.ReturnBoolean) If Not IsDate(Me.f_dato) Then MsgBox "Dette er ikke et godkendt format for dato. Indtast venligst som dd-mm-åå.", vbExclamation, "Dato" Cancel = True Else Me.f_ugenr = Format(Me.f_dato, "ww", vbMonday, vbFirstFourDays)
End If
End Sub
Private Sub UserForm_Initialize() Me.f_dato = Format(Date, "dd-mm-yy") Me.f_ugenr = Format(Me.f_dato, "ww", vbMonday, vbFirstFourDays) End Sub
Du skal ikke sætte breakpoint i Exit-eventet, men i Initialize-eventet. Det er jo her, du siger, at datoen ikke bliver vist.
Mit temperament duer ikke rigtig til gennemgang af en masse linjer kode, men når du hiver datoen fra dit Excel-ark ind igen for at vise det til brugeren, skal du formatere det på samme måde, som du gør i Me.f_dato = Format(Date, "dd-mm-yy").
Du må gerne sende din fil til mig (lemontree snabelting jubii dot dk), så jeg kan kigge på det med datoen, når din form bliver fyret i luften.
Du har en procedure (ClearFelter) på Activate-eventet på din form, som clearer dine tekstbokse og dermed også datoen. Activate kommer efter Initialize-eventet. Hvad er årsagen til, at du clearer tekstboksene? Du unloader vel din form på et eller andet tidspunkt?
Det er ren fejlsøgning. Du er nødt til at finde det sted, som gør, at tekstboksen bliver clearet efterfølgende. Søg eft. i koden efter navnet på din kontrol.
Har jeg ret, når jeg antager, at det ikke er dig, der har lavet koden oprindelig?
Der er helt klart noget "snask" et eller andet sted. Jeg har lige forsøgt følgende:
Remmet ClearFelter ud. Fyret dialogboksen i luften. Ingen dato. Gik derefter i kodevinduet og skrev noget tekst direkte i tekstboksen. Smed dialogboksen i luften igen. Nu kom datoen (så vi ikke det tidligere? 16/08-2007 16:46:06)
Som sagt - ren fejlsøgning. Step din kode igennem fra start til slut.
I proceduren visAktuelleRække kalder du også ClearFelter-proceduren. Den benyttes rigtig mange steder.
Flyt de 2 linjer kode med hhv. dato og ugenummer til dit activate-event (til sidst). Du skal dog være opmærksom på, at du så bør indføre et tjek på, om de er udfyldt i forvejen. For hvis du har andet kode (f.eks. andre dialogbokse), der gør, at activate-eventet fyres i luften igen, skal den jo ikke ændre datoen, hvis brugeren har udfyldt den med en anden. Og det vil den gøre, hvis ikke du tjekker på tekstboksens indhold først.
1. Ja du har ret, jeg har ikke lavet koden selv. Jeg klipper og klisterer og modtager gerne alt den hjælp jeg kan få herinde.
2. Jeg har testet koden lidt. a) Jeg har flyttet de linier du skriver (9:56:40) b) Hvis jeg åbner mit Excel ark og går i Funktioner - Makro osv. og starter min userform, så kommer datoen fint nok
c) Men da jeg har lavet en menu i Excel (xla-fil) som indeholder et punkt der kalder min makro i Excel arket er det der den går galt. Der viser den ikke datoen.
Koden til dette menupunkt er
Sub timesag() ActiveWorkbook.Sheets("Data").Select ActiveWorkbook.Sheets("Plan").Visible = False Load UserForm UserForm.Show ActiveWorkbook.Close True End Sub
Kan du udlede noget af det ?
P.S. Jeg har ikke en jordisk forståelse af denne fejlsøgning du nævner. Jeg forstår det simpelthen ikke.
Godt at høre, at du har fået det til at fungere. I øvrigt er det ikke noget galt med din procedure timesag, men du kan faktisk slette linjen Load UserForm. UserForm.Show klarer hele "tricket" ;-)
Fejlsøgning betyder, at man kigger sin kode igennem for at finde ud af, hvad der foregår og hvad der går galt undervejs. Men det kan være svært, når du ikke selv har lavet koden og bruger klippe/klistre uden måske at være helt sikker på, hvad der foregår.
Fejlsøgningen ville i dette tilfælde gå ud på at finde ud af, hvor datoen fra din tekstboks bliver fjernet (for tro mig - den bliver sat ind i Initialize-eventet, men fjernet igen på et senere tidspunkt). Jeg har ovenfor beskrevet lidt om, hvordan det kan gøres (breakpoint, steppe koden igennem linje for linje med F8).
Synes godt om
Ny brugerNybegynder
Din løsning...
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.