I makroen hvor vi importerede CSV-filen ved at indlæse linje for linje, anvendte vi the_cell.Value = [datoværdi]. Lad os kige lidt mere på, hvordan datoer håndteres i LibreOffice i makroer.
Vi skal se dato-format problemet i to perspektiver:
1) Datoformatet i variable i makroen
2) Datoen, når den indsættes i eller læses fra en celle.
Det er vigtigt at skelne tydeligt mellem de to perspektiver, da resultatet ellers kan vise sig overraskende (forkert).
Denne artikel omhandler andet punkt, nemlig håndtering af datoer i regnearkets celler.
I eksemplet importerede vi datoen fra en CSV-fil, og derfor var udgangspuntket en tekststreng, som vi så behandlerede således:
t= split(s, "-", 3)
s=DateSerial(t(2), t(1), t(0))
Og vi indsatte så resultatet i cellen sådan:
my_cell.String=s
Det betyder at resultatet er en tekststreng (.String).
Vi burde have gjort det anderledes, nemlig med
my_cell.Value=s
Problemet er dog at resultatet vises i regnearket som datoværdier, f.eks. 42659
Det håndterer vi ved at formatere cellen således:
my_cell.Value=s
my_cell.NumberFormat=36
Tallet .NumberFormat=36 viser datoen som 09-10-2016, hvilket er præcist som ønsket. Tallet 36 fandt jeg frem til ved at formatere en celle manuelt, og så aflæse tallet
Print my_cell.NumberFormat
Her er en makro som demonstrerer det meste:
REM ***** BASIC *****
Sub Main
Dim my_date As Date
my_doc = ThisComponent
my_sheets = my_doc.Sheets
antal=my_sheets.count
If NOT my_sheets.hasbyName("Dato") Then
my_sheets.insertNewByName("Dato", antal)
End If
the_sheet = my_sheets.getByName("Dato")
the_sheet.TabColor= RGB(0, 0, 100)
rem --------------------
my_date = DateValue("20 Jan 2016")
my_cell = the_sheet.getCellbyPosition(1,1)
my_cell.Value = my_date
my_cell.NumberFormat=36
Print my_cell.Value
Print CDate(my_cell.Value)
Print IsDate(my_cell.Value)
End Sub
Her kan du læse artikler fra LibreOffice i Danmarks månedlige nyhedsbrev. Du kan tilmelde dig nyhedsbrevet ved at sende en mail til nyhedsbrev+subscribe@da.libreoffice.org
Viser opslag med etiketten dato. Vis alle opslag
Viser opslag med etiketten dato. Vis alle opslag
fredag den 21. oktober 2016
Datoer i Calc med makroer
Lidt om datoer (i makro)
I makroen hvor vi importerede CSV-filen ved at indlæse linje for linje, anvendte vi the_cell.Value = [datoværdi]. Lad os kigge lidt mere på, hvordan datoer håndteres i LibreOffice i makroer.
Vi skal se dato-format problemet i to perspektiver:
1) Datoformatet i variable i makroen
2) Datoen, når den indsættes i eller læses fra en celle.
Det er vigtigt at skelne tydeligt mellem de to perspektiver, da resultatet ellers kan vise sig overraskende (forkert).
Denne artikel omhandler første punkt, nemlig håndtering og bearbejdning af datoer med makroer. Datofunktionerne er ikke afhængige af Calc, men fungerer også med datoer i f.eks. Writer.
I makroen, når vi arbejder med datoer i variable, kan vi tænk på datoer som to forskellige typer tekst: En lokaliseret (dansk, engelsk, ...) version og en international version (ISO 8601 date format). I bund og grund fungerer begge typer fuldstændig uden problemer, men lokaliseret dato er standard, og ISO 8601 (YYYY-MM-DD) er kun relevant, når vi vælger det eksplicit.
Ikke desto mindre regner LibreOffice med en intern dato-værdi, hvor 0 svarer til 29/12/1899: -1
30/12/1899: 0
31/12/1899: 1
01/01/1900: 2
01/02/1900: 3
01/01/2001: 36892
Datokonvertering:
Når vi så har en dato(værdi), kan vi udlede nogle interessante informationer:
Sub test
my_date=DateValue("19 Januar 1965")
Print isDate(my_date) 'True
Print my_date '19/01/1965
Print year(my_date) '1965
End sub
Funktionen DatePart gør noget lignende, nemlig udleder en konkret information
Print DatePart("yyyy",my_date) 'Årstal
Print DatePart("q",my_date) 'Kvartal
Print DatePart("m",my_date) 'Måned
Print DatePart("y",my_date) 'dag i året
Print DatePart("w",my_date) 'Ugedag
Print DatePart("d",my_date) 'Dag
DatePart splitter altså en dato ad i enkeltdele, og vi har en tilsvarende funktion til at samle delene i en dato igen:
Print DateSerial(1965, 1, 19) '19/01/1965
Vær opmærksom på at DateSerial har en fejl, som betyder at datoen før år 100 konverteres forkert, idet der lægges 1900 til årstallet:
Print DateSerial(90, 1, 19) '19/01/1990
Vi kan manipulere datoen med funktionen DateAdd sådan:
DateAdd("d", 3, my_date) 'Læg tre dage til datoen
DateAdd("m", 3, my_date) 'Læg 3 måneder til datoen
DateAdd("yyyy", -3, my_date) 'Træk 3 år fra datoen
DateDiff anvender tilsvarende tekstparameter til at formatere svaret fra en subtraktion:
my_date=DateValue("19 Januar 1965")
Print DateDiff("yyyy", my_date, Date) 'Jeg er 51 år
Print DateDiff("d", my_date, Date) 'Mere præcist 18903 dage
Vi skal se dato-format problemet i to perspektiver:
1) Datoformatet i variable i makroen
2) Datoen, når den indsættes i eller læses fra en celle.
Det er vigtigt at skelne tydeligt mellem de to perspektiver, da resultatet ellers kan vise sig overraskende (forkert).
Denne artikel omhandler første punkt, nemlig håndtering og bearbejdning af datoer med makroer. Datofunktionerne er ikke afhængige af Calc, men fungerer også med datoer i f.eks. Writer.
I makroen, når vi arbejder med datoer i variable, kan vi tænk på datoer som to forskellige typer tekst: En lokaliseret (dansk, engelsk, ...) version og en international version (ISO 8601 date format). I bund og grund fungerer begge typer fuldstændig uden problemer, men lokaliseret dato er standard, og ISO 8601 (YYYY-MM-DD) er kun relevant, når vi vælger det eksplicit.
Ikke desto mindre regner LibreOffice med en intern dato-værdi, hvor 0 svarer til 29/12/1899: -1
30/12/1899: 0
31/12/1899: 1
01/01/1900: 2
01/02/1900: 3
01/01/2001: 36892
Datokonvertering:
- CDate: Konverter et tal (datoværdi) eller en tekst til en dato.
- DateValue: Konverterer en formateret tekst (i intervallet 1. december 1, 1582 til 31 December 9999) til en dato-værdi, som ikke har tidsinformationer. Datoen 1. december 1582 svarer ca. til det tidspunkt, hvor den gregorianske kalender blev indført. Se https://da.wikipedia.org/wiki/Gregorianske_kalender
- CDateFromIso: Konverterer til en dato fra en ISO 8601-dato.
- CDateToIso: Konverterer en dato til en ISO 8601-dato.
- IsDate: Er teksten korrekt formateret som dato? Brug IsDate til at afprøve om en tekst indeholder en korrekt formateret dato.
Når vi så har en dato(værdi), kan vi udlede nogle interessante informationer:
- Year(date): Returnerer årstallet af en dato som et heltal.
- Month(date): Returnerer månedsnummeret af en dato som et heltal.
- Day(date): Returnerer dagstallet af en dato som et heltal.
- WeekDay(date): Returnerer et heltal fra 1 til 7, som svarer til dage i ugen (søndag til lørdag).
Sub test
my_date=DateValue("19 Januar 1965")
Print isDate(my_date) 'True
Print my_date '19/01/1965
Print year(my_date) '1965
End sub
Funktionen DatePart gør noget lignende, nemlig udleder en konkret information
Print DatePart("yyyy",my_date) 'Årstal
Print DatePart("q",my_date) 'Kvartal
Print DatePart("m",my_date) 'Måned
Print DatePart("y",my_date) 'dag i året
Print DatePart("w",my_date) 'Ugedag
Print DatePart("d",my_date) 'Dag
DatePart splitter altså en dato ad i enkeltdele, og vi har en tilsvarende funktion til at samle delene i en dato igen:
Print DateSerial(1965, 1, 19) '19/01/1965
Vær opmærksom på at DateSerial har en fejl, som betyder at datoen før år 100 konverteres forkert, idet der lægges 1900 til årstallet:
Print DateSerial(90, 1, 19) '19/01/1990
Vi kan manipulere datoen med funktionen DateAdd sådan:
DateAdd("d", 3, my_date) 'Læg tre dage til datoen
DateAdd("m", 3, my_date) 'Læg 3 måneder til datoen
DateAdd("yyyy", -3, my_date) 'Træk 3 år fra datoen
DateDiff anvender tilsvarende tekstparameter til at formatere svaret fra en subtraktion:
my_date=DateValue("19 Januar 1965")
Print DateDiff("yyyy", my_date, Date) 'Jeg er 51 år
Print DateDiff("d", my_date, Date) 'Mere præcist 18903 dage
Abonner på:
Opslag (Atom)