Avatar billede ds-zim Nybegynder
18. oktober 2000 - 13:44 Der er 37 kommentarer og
1 løsning

Typeuoverenstemmelse i datatype

Jeg er strandet med et forhenværende faktureringssystem, der lagrer den forbrugte tid
i formatet \'Dato & Klokkeslet\' .. Når jeg åbner tabellen, står data da også nok så fint
i formatet \'HH:MM:SS\'. Så langt, så godt ! Når jeg så eksporterer til .txtfil,
for derefter at importere til .mdb, vælger jeg at bestemme feltets datatype skal være tekst. Nu står mine data med formatet \'DD-MM-YY HH:MM:SS\', hvor \'DD-MM-YY\'=30-12-1899 !!!
Har dette nogen betydning ???

Problemet udmunder sig i, at jeg har bikset et nyt faktureringsystem sammen og der er
flere felter med forskellige datatyper :( Nu har jeg så fået at vide, at de \"gamle\" data
gerne skulle kunne importeres i den nye tabel *GRR* ... Jeg er ret vild efter at få nogen løsningsforslag, da det trods alt
basicly er indtjeningsgrundlaget for firmaet jeg piller ved her.

Cheers, Zim
Avatar billede ds-zim Nybegynder
18. oktober 2000 - 13:54 #1
BTW, så har jeg også prøvet at importere feltet som tal(det selvsamme format jeg ønsker det skal
ende med), men det resulterer bare i enten 0- eller 1taller
Avatar billede ds-zim Nybegynder
18. oktober 2000 - 13:57 #2
Kort forklaret, så går spørgsmålet på;

Hvordan får jeg konverteret et felt af typen klokkeslet til en talværdi ? (for at kunne opsummere)
Avatar billede moses Praktikant
18. oktober 2000 - 15:06 #3
Du kan sådan set sætte det op, som du vil:

CStr laver det om til en tekststreng.
Format definerer formatet, som du har angivet bagefter.
Ud over det du ser her, kan du også benytte:
YYYY: årstal med 4 cifre
MM: månedstal med 2 cifre
DD: dagen med 2 cifre

CStr(format(#1965-05-23 13:23:45#,\"HH:MM:SS\"))

Jeg har her benyttet kolon imellem tidstallene og du kan benytte \"/\" imellem datoer.
Avatar billede ds-zim Nybegynder
18. oktober 2000 - 15:15 #4
Hva betyder fejlen \'Expected : Identifier\' ? VBA kan åbenbart ikke genkende CStr ..
Avatar billede ds-zim Nybegynder
18. oktober 2000 - 15:19 #5
Omfanget af den \"gamle\" tabel er det egentlige grundlag for mit problem ..
Der er næsten 20K poster, der alle indeholder et \'ForbrugtTid\'-felt
Kan du, evt. mod flere point, give mig et forslag til en funktion/rutine, der læser felter fra
\"den gamle\" og skriver dem til en ny tabel ?
(I et andet format)
Avatar billede moses Praktikant
18. oktober 2000 - 15:24 #6
Lav en kopi af din tabel.
Lav en update query, der opdaterer tidsfeltet til formlen herover.

Det skal virke - CStr er en basal funktion i VBA (Der er sat flueben ved Tools / References: Visual Basic for Applications).

Så skiftes den gamle værdi ud med den nyformatterede værdi.
Avatar billede ds-zim Nybegynder
18. oktober 2000 - 15:42 #7
Jeg er bange for at jeg har formuleret mig tvetydigt :(
Jeg ønsker at opnå mulighed for at kunne opsummere \'ForbrugtTid\', og når jeg kører en Sum
([ForbrugtTid]), får jeg et decimaltal, med 10+ cifre, altså langt fra hvad jeg forventede.

PS. Du mente oprigtigt, at jeg i min update query, skulle indsætte CStr(format(#1965-05-23 13:23:45#,\"HH:MM:SS\"))
i feltet \'Opdater til\' ? right ?!? umm, alle indstanser er blevet til 13:23:45 !

Avatar billede moses Praktikant
18. oktober 2000 - 16:02 #8
Det var derfor jeg sagde, at du skulle starte med at lave en kopi !?!?!
Rigtige mænd laver ikke koiper - de græder meget !!

NEJ - Jeg mente ikke direkte mit eksempel - sorry

Hvis feltet hedder [Tid], så skal du i feltet \"Opdateres til\" skrive:

CStr(format([Tid],\"HH:MM:SS\"))

Det var dengang - nu har jeg jo så i mellemtiden fundet ud af, at du vil lægge det hele sammen.

Da skal du lige passe på, for der er en regnefejl i tidssammenlægningen i Access2000 (er på eksperten et eller andet sted.)

Det smarteste er, at konvertere det hele til sekunder, som Long Integer og så lægge hele molevitten sammen.

\"Opdater til\" skal så bare indeholde:

=Hour([Tid])*3600 + Minute([Tid])*60 + Second([Tid])

Derefter har du din tabel med Tid angivet i rene sekunder.

Dernæst kan du lave en almindelig Select query med sammenlægning af alle de ønskede records.

Når du skal vise resultatet, laver du bare denne omvendte funktion.
Avatar billede lens Nybegynder
18. oktober 2000 - 16:13 #9
Du kan da bare kopiere den pågældende kolonne fra Access over i Word eller en anden editor - fjerne alle mærkelige tegn såsom - og :, og så kopiere den over i din nye felt af kolonnetal. Du skal så lige huske at det står i timer, minutter og sekunder nå du skal regne det sammen. Her kan du eventuelt opsplitte kolonnen i tre eller flere nye så du har en til henholdsvis timer, minutter osv....
Avatar billede lens Nybegynder
18. oktober 2000 - 16:15 #10
Undskyld, på midterste linie skulle der stå:
over i din nye kolonne af typen tal.  ;-)
Avatar billede ds-zim Nybegynder
20. oktober 2000 - 11:50 #11
-> lens
Gider ikke behandle samtlige 20K poster ... jvf. [ Kommentar fra ds-zim 18/10 2000 15:19:59 ]
Avatar billede ds-zim Nybegynder
20. oktober 2000 - 11:52 #12
-> Moses

Jeg mener ikke at kunne overkomme din hypotese omkring hvordan, jeg smartest løser opgaven ..
Jeg har prøvet forskellige metoder til at konvertere tabellen/feltet, og lige meget hjælper det.
Jeg ville blive meget glad, hvis du kunne uddybe hvordan du vil have mig til at konvertere tabellen!
Avatar billede ds-zim Nybegynder
20. oktober 2000 - 11:54 #13
-> Er så småt ved at have en funktion klar til at løse problemet .. roder med nogen småting jeg måske
får brug for hjælp til .. mere om dette senere
Avatar billede ds-zim Nybegynder
20. oktober 2000 - 12:03 #14
Her er tabellerne\'s felter med tilhørende datatyper ;

** Log-Tabel **

ID ~ Autonummerering
Kundenummer ~ Tekst(15)
Policenummer ~ Tekst(50)
Dato ~ Dato & Klokkeslet(Kort)
Medarbejder ~ Tekst(50)
Tekst ~ Tekst(255)
ForbrugtTid ~ Dato & Klokkeslet(Standard)

** Aktiviteter-Tabel **

AktivitetsID ~ Autonummerering
Kundenummer ~ Tekst(50)
PoliceID ~ Tal(Long)
Udført ~ Tal(Integer)
Aktivitetskode ~ Tal(Integer)
Arbejdsbeskrivelse ~ Notat(Engelsk navn er ?!?)
Status ~ Tal(Integer)
På Rykkerliste ~ Ja/Nej(Boolean)
Rykkerdato ~ Dato & Klokkeslet(Kort datoformat)
Arbejdsdato ~ Dato & Klokkeslet(Kort datoformat)
Deadline ~ Dato & Klokkeslet(Kort datoformat)
TidFra ~ Dato & Klokkeslet(Langt klokkeslætsformat)
TilTil ~ Dato & Klokkeslet(Langt klokkeslætsformat)
ForbrugtTid ~ Tal(Long)
TilFakturering ~ Ja/Nej(Boolean)
IntFakturering ~ Ja/Nej(Boolean)
FaktDato ~ Dato & Klokkeslet(Kort datoformat)
Begrundelse ~ Notat(Engelsk navn er ?!?)
Udskrevet ~ Dato & Klokkeslet(Kort datoformat)
Avatar billede moses Praktikant
20. oktober 2000 - 12:08 #15
- Lav en kopi (jvf. tidligere katastrofe)
- Lav en Update Query med følgende indhold:
  Opdater feltet [Tid] til følgende formel:
    =Hour([Tid])*3600 + Minute([Tid])*60 + Second([Tid])
- Når du har udført denne konvertering, laver du en ny query, som sorterer de records fra, som du nu vil have summeret og så summerer den feltet [Tid].
- Det tal [SumOfTid] du får ud af det, er en masse sekunder, så derfor skal du lige konvertere det med følgende formel:

Dim TmpTid as Date
Dim TmpSum as Long
Dim TmpHours, TmpMinutes, TmpSeconds as Integer
TmpHours = TmpSum \\ 3600
TmpSum = TmpSum - TmpHours * 3600
TmpMinutes = TmpSum \\ 60
TmpSum = TmpSum - TmpHour * 60
TmpSeconds = TmpSum
TmpTid = TimeSerial(TmpHours, TmpMinutes, TmpSeconds)
Avatar billede moses Praktikant
20. oktober 2000 - 12:09 #16
TmpSum sættes selvfølgelig lige til SumOfTid fra Query\'en
Avatar billede ds-zim Nybegynder
20. oktober 2000 - 12:22 #17
Bare rolig, jeg er ikke en rigtig mand :) Jeg laver nemli\' kopier :)
Avatar billede ds-zim Nybegynder
20. oktober 2000 - 12:40 #18
Tjae .. Jeg havde lidt håbet på at jeg kunne bikse en funktion sammen som ville klare skærende ..

Her er et udkast;

Sub DataOverførsel()

  Dim dbs As Database
  Dim rst As Recordset
  Dim Kunde As String
  Dim Police As String
  Dim ADato As Date
  Dim DoneBy As String
  Dim DidWhat As String
  Dim TimeSpend As Date
  Dim NewKunde As String
  Dim NewPolice As String
  Dim NewADato As Date
  Dim NewDoneBy As String
  Dim NewDidWhat As String
  Dim NewTimeSpend As Long
 
  Set dbs = CurrentDb
  Set rst = dbs.OpenRecordset(\"Log\", dbOpenDynaset)
   
\' While X=1 to Y DO (*)

    With rst
      .MoveFirst \'(*)
      .GetRows (1) \'(*)
      Kunde = !Kundenummer
      Police = !Policenummer
      ADato = !Dato
      DoneBy = !Medarbejder \'(**)
      DidWhat = !Tekst
\'      TimeSpend = !ForbrugtTid \' Ved en NULL-værdi fås fejlen \'Invalid Use of Null\'
      .Close
    End With
   
  NewKunde = Kunde
  NewPolice = Police
  NewADato = ADato
  NewDoneBy = DoneBy \'(**)
  NewDidWhat = DidWhat
  NewTimeSpend = (Hour([TimeSpend]) * 3600) + (Minute([TimeSpend]) * 60) + Second([TimeSpend])

  Set dbs = CurrentDb
  Set rst = dbs.OpenRecordset(\"Aktiviteter\", dbOpenDynaset)
   
    With rst
      .AddNew
      !Kundenummer = NewKunde
      !PoliceID = NewPolice
\'      !Udført = NewDoneBy (**)
      !Arbejdsbeskrivelse = NewDidWhat
      !Arbejdsdato = NewADato
      !ForbrugtTid = NewTimeSpend
      .Update
      .Close
    End With
   
  Set dbs = Nothing
 
\' End While

End Sub

\' (*) : Som du nok kan C, har jeg ingen idé om hvordan jeg får behandlet samtlige 20K poster .. PIV
\' (**) : Jeg har valgt at lagre en pointer til en ansattabel istedet.. R lidt i tvivl om hvordan jeg
\'        ud fra en given tekststreng, korrekt får angivet medarbejderværdien ..
\'        FX: If Doneby = \"?Verny?\" then NewDoneBy = 1
Avatar billede ds-zim Nybegynder
20. oktober 2000 - 12:48 #19
Hov ! Jeg vil have \"de gamle\" data (i datoformat) konverteret til \"de nye\" data (i sekunder)
Avatar billede ds-zim Nybegynder
20. oktober 2000 - 12:48 #20
DVS,i den nye tabel vil jeg gerne gemme dem i antal sekunder !
Avatar billede moses Praktikant
20. oktober 2000 - 12:52 #21
(*)
While not rst.EOF

(**)
Forstår jeg ikke helt !?!?
Avatar billede ds-zim Nybegynder
20. oktober 2000 - 13:01 #22
Feltet DoneBy er et tekstfelt og kan indeholde alt fra en NULL værdi til små grønne mænd :(
Det kan også indeholde et reélt medarbejdernavn og så skal posten gerne linkes til vor \'Ansatte\'-
tabel ( Linket foretages ved at indsætte den aktuelle medarbejders ID i \'Ansatte\'-tabellen,
FX står \'Verny\' først ~ Verny = 1
Avatar billede ds-zim Nybegynder
20. oktober 2000 - 13:02 #23
Frokost is up, bb in 30 mins :)
Avatar billede moses Praktikant
20. oktober 2000 - 13:42 #24
Det er noget med:

if isnull(NewDoneBy) then
  !Udført = \"N/A\"  \' eller hvad du nu vil
else
  !Udført = NewDoneBy
end if
Avatar billede moses Praktikant
20. oktober 2000 - 13:43 #25
Med hensyn til det med at slå op i ansat tabel - det må du lige selv finde ud af.
Avatar billede ds-zim Nybegynder
20. oktober 2000 - 13:46 #26
Hva\' gør jeg ved !ForbrugtTid = Null ?

With rst
      .MoveFirst \'(*)
      .GetRows (1) \'(*)
      Kunde = !Kundenummer
      Police = !Policenummer
      ADato = !Dato
      DoneBy = !Medarbejder \'(**)
      DidWhat = !Tekst
\'      TimeSpend = !ForbrugtTid \' Ved en NULL-værdi fås fejlen \'Invalid Use of Null\'
      .Close
    End With
Avatar billede ds-zim Nybegynder
20. oktober 2000 - 13:57 #27
For at kunne bestemme medarbejderen ud fra en tekststreng, er jeg nødt til at søge strengen igennem efter specifikke ord, fx;

Dim Søgekriterier as String
Dim TekstStreng as String
Dim TempTekst as String

Søgekriterier = \"Verny\",\"Vibeke\",\"Bjarne\"

If TekstStreng = \"BLEHVERNYBLEH\" then
TempTekst = Verny
Endif

If TempTekst = \"Verny\" then
  MedarbejderID = 1
Endif

If TempTekst = \"Vibeke\" then
  MedarbejderID = 2
Endif

If TempTekst = \"Bjarne\" then
  MedarbejderID = 3
Endif

U dig it ?
Avatar billede moses Praktikant
20. oktober 2000 - 13:59 #28
Mht. NULL værdien, så kan du bare checke det:

isnull(!ForbrugtTid) then
  TimeSpend = 0
else
  TimeSpend = !ForbrugtTid
end if
Avatar billede moses Praktikant
20. oktober 2000 - 14:03 #29
For ligesom at runde denne her af, så vil jeg nok mene, at du står overfor et problem med datadisciplin.

Efter oprydning i DoneBy feltet, bør du lave en 1-mange relation fra ansatID feltet ovre i ansat tabellen til det der mærkelige DoneBy felt.
På den måde tvinger du brugeren til at vælge en ansat.
Avatar billede ds-zim Nybegynder
20. oktober 2000 - 14:09 #30
Jeg kan umiddelbart ikke C andre fejl i flg. kode, end at jeg ikke kommer til at få den første post
med i den nye tabel. Har du nogen kommentarer ?

Sub DataOverførsel()

  Dim dbs As Database
  Dim rst As Recordset
  Dim Kunde As String
  Dim Police As String
  Dim ADato As Date
  Dim DoneBy As String
  Dim DidWhat As String
  Dim TimeSpend As Date
  Dim NewKunde As String
  Dim NewPolice As String
  Dim NewADato As Date
  Dim NewDoneBy As String
  Dim NewDidWhat As String
  Dim NewTimeSpend As Long
 
  Set dbs = CurrentDb
  Set rst = dbs.OpenRecordset(\"Log\", dbOpenDynaset)
   
  With rst
    .MoveFirst
  End With
 
  While Not rst.EOF

    With rst
      .MoveNext  \'(*)
      .GetRows (1) \'(*)
      Kunde = !Kundenummer
      Police = !Policenummer
      ADato = !Dato
      DoneBy = !Medarbejder \'(**)
      DidWhat = !Tekst
      If ForbrugtTid = Null Then
        TimeSpend = 0
      Else
        TimeSpend = !ForbrugtTid
      End If
      .Close
    End With
   
  NewKunde = Kunde
  NewPolice = Police
  NewADato = ADato
  NewDoneBy = DoneBy \'(**)
  NewDidWhat = DidWhat
  NewTimeSpend = (Hour([TimeSpend]) * 3600) + (Minute([TimeSpend]) * 60) + Second([TimeSpend])

  Set dbs = CurrentDb
  Set rst = dbs.OpenRecordset(\"Aktiviteter\", dbOpenDynaset)
   
    With rst
      .AddNew
      !Kundenummer = NewKunde
      !PoliceID = NewPolice
\'      !Udført = NewDoneBy (**)
      !Arbejdsbeskrivelse = NewDidWhat
      !Arbejdsdato = NewADato
      !ForbrugtTid = NewTimeSpend
      .Update
      .Close
    End With
   
  Set dbs = Nothing
 
Wend

End Sub
Avatar billede moses Praktikant
20. oktober 2000 - 14:21 #31
Prøv lige selv at kigge på det.
Du har rodet tingene sammen !!!

rst.EOF skal netop sørge for, at du kører indtil der ikke er flere records, så din Wend må ikke først komme i bunden, hvor du iøvrigt for længe siden har lukket din rst og åbnet en ny.

Desuden skal du ikke starte din while rst.EOF med at en .move - den skal først komme lige før Wend, hvorefter While lige checker for, om du rammer bunden - inden du fortsætter med at læse ind.

Avatar billede ds-zim Nybegynder
20. oktober 2000 - 14:34 #32
Piv :(

Jamen, hvis jeg skal læse poster while not rst.EOF, burde jeg så ikke gemme disse data i et array ?
Avatar billede moses Praktikant
20. oktober 2000 - 14:47 #33
Sådan:

Sub DataOverførsel()

  Dim dbs As Database
  Dim rst As Recordset
  Dim Kunde As String
  Dim Police As String
  Dim ADato As Date
  Dim DoneBy As String
  Dim DidWhat As String
  Dim TimeSpend As Date
  Dim NewKunde As String
  Dim NewPolice As String
  Dim NewADato As Date
  Dim NewDoneBy As String
  Dim NewDidWhat As String
  Dim NewTimeSpend As Long
  Dim NewTimeSpendSum As Long 

  NewTimeSpendSum = 0

  Set dbs = CurrentDb
  Set rst = dbs.OpenRecordset(\"Log\", dbOpenDynaset)
   
  Set rst2 = dbs.OpenRecordset(\"Aktiviteter\", dbOpenDynaset)

  rst.MoveFirst
  While Not rst.EOF

    With rst
      Kunde = !Kundenummer
      Police = !Policenummer
      ADato = !Dato
      DoneBy = !Medarbejder \'(**)
      DidWhat = !Tekst
      If ForbrugtTid = Null Then
        TimeSpend = 0
      Else
        TimeSpend = !ForbrugtTid
      End If
    End With
   
  NewKunde = Kunde
  NewPolice = Police
  NewADato = ADato
  NewDoneBy = DoneBy \'(**)
  NewDidWhat = DidWhat
  NewTimeSpend = (Hour([TimeSpend]) * 3600) + (Minute([TimeSpend]) * 60) + Second([TimeSpend])
  NewTimeSpendSum = NewTimeSpendSum + NewTimeSpend
   
    With rst2
      .AddNew
      !Kundenummer = NewKunde
      !PoliceID = NewPolice
      !Udført = NewDoneBy
      !Arbejdsbeskrivelse = NewDidWhat
      !Arbejdsdato = NewADato
      !ForbrugtTid = NewTimeSpend
      .Update
    End With
 
  rst.MoveNext
Wend

rst.Close
rst2.close

End Sub
Avatar billede ds-zim Nybegynder
20. oktober 2000 - 15:32 #34
JAAAH SGU\' !!!! Way to GO, Moses !!!! Med enkelte modificeringer var der HOMERUN !!! :D
Jeg beklager, at jeg er løbet tør for point, men jeg er sikker på du forstår hvorfor ;)

Her har du den endelige kode, just in case u care;

Sub DataOverførsel()

  Dim dbs As Database
  Dim rst As Recordset
  Dim rst2 As Recordset
  Dim Kunde As String
  Dim Police As String
  Dim ADato As Date
  Dim DoneBy As String
  Dim DidWhat As String
  Dim TimeSpend As Date
  Dim NewKunde As String
  Dim NewPolice As String
  Dim NewADato As Date
  Dim NewDoneBy As String
  Dim NewDidWhat As String
  Dim NewTimeSpend As Long
  Dim NewTimeSpendSum As Long

  NewTimeSpendSum = 0

  Set dbs = CurrentDb
  Set rst = dbs.OpenRecordset(\"Log\", dbOpenDynaset)
   
  Set rst2 = dbs.OpenRecordset(\"Aktiviteter\", dbOpenDynaset)

  rst.MoveFirst
  While Not rst.EOF

    With rst
      If IsNull(!Kundenummer) Then
        Kunde = 0
      Else
        Kunde = !Kundenummer
      End If
      If IsNull(!Policenummer) Then
        Police = 0
      Else
        Police = !Policenummer
      End If
      If IsNull(!Dato) Then
        ADato = 0
      Else
        ADato = !Dato
      End If
      If IsNull(!Medarbejder) Then
        DoneBy = 0
      Else
        DoneBy = !Medarbejder
      End If
      If IsNull(!Tekst) Then
        DidWhat = \"N/A\"
      Else
        DidWhat = !Tekst
      End If
      If IsNull(!ForbrugtTid) Then
        TimeSpend = 0
      Else
        TimeSpend = !ForbrugtTid
      End If
    End With
   
  NewKunde = Kunde
  NewPolice = Police
  NewADato = ADato
  NewDoneBy = DoneBy \'(**)
  NewDidWhat = DidWhat
  NewTimeSpend = (Hour([TimeSpend]) * 3600) + (Minute([TimeSpend]) * 60) + Second([TimeSpend])
  NewTimeSpendSum = NewTimeSpendSum + NewTimeSpend
   
    With rst2
      .AddNew
      !Kundenummer = NewKunde
\'      !PoliceID = NewPolice
\'      !Udført = NewDoneBy
      !Arbejdsbeskrivelse = NewDidWhat
      !Arbejdsdato = NewADato
      !ForbrugtTid = NewTimeSpend
      .Update
    End With
 
  rst.MoveNext
Wend

rst.Close
rst2.Close

End Sub
Avatar billede ds-zim Nybegynder
20. oktober 2000 - 15:35 #35
Mange tak for tålmodigheden iøvrigt !! Blev en smule ivrig, da klaveret pludselig spillede ;)
Håber du får en kanon weekend!
Cheers, Zim
Avatar billede moses Praktikant
23. oktober 2000 - 08:06 #36
Tak for det og i lige måde.

Kender problemet med pointene. Sådan har vi andre det med økonomien !! ;-)
Avatar billede ds-zim Nybegynder
23. oktober 2000 - 13:00 #37
Jeg går ud fra at din kommentar ang. regnefejl i access angår spørgsmålet http://www.eksperten.dk/spm/26335
Jeg synes ikke at der er nogen egentlig konklusion på spm.. Skal jeg gå ud fra at der
regnes rigtigt ?

Zim
Avatar billede moses Praktikant
23. oktober 2000 - 13:09 #38
Ja - det var lige præcist det spørgsmål.

Det undrer også mig, hvorfor ingen svarer på min kommentar/mit spørgsmål.
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Dyk ned i databasernes verden på et af vores praksisnære Access-kurser

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester