moelle
Goto Top

ACCESS 2003 Zahl (Julianisches Datum umwandeln in Datum dd.mm.jjjj

Hallo

ich muss für o. in einer Access Abfrage ein Julianische Datum in ein Datum tt.mm.jjjj umwandeln.
Aus einer ODBC Verknüpfung erhalte ich nur ein Julianische Datum das in meiner Abfrage umgewandelt werden muss

Abfrage: Feld: DATUMAUSLIEF = 2454792
jetzt generiere ich ein neues Feld in der Abfrage LIEFDAT

Um ein ein Julianisch Datum in Excel umzuwandeln gehe wende ich folgende Formel an:

2454792-2415019=39773 jetzt Zellen formatieren Datum tt.mm.jjjj und schon erhalte ich 21.11.2008

Wie muss ich so eine Funktion in einer ACCESS Abfrage anwenden.

Mein Versuch: Abfrage Feld: ((LIEFDAT:[DATUMAUSLIEF]-2415019;'tt\.mm\.jjjj')
erhalte ich immer den Ausdruck syntaktisch falsch

Bitte um RAt?

Content-Key: 103151

Url: https://administrator.de/contentid/103151

Printed on: April 19, 2024 at 12:04 o'clock

Member: Biber
Biber Dec 02, 2008 at 18:01:27 (UTC)
Goto Top
Moin Moelle,

ich weiss ja nicht, ob der Schlenker über Excel in diesem Fall nötig ist.
Diese Redmonder wohnen in einem Land, in dem alles, was vor mehr als 200 Jahren war als "prähistorisch" gilt.
Und das Julianische Datum basiert immerhin auf dem 1. Januar 4713 v. Chr. als dem Tag Null (bzw.1).

Diese Excel-Krücke passt also nur unter den stillschweigend unterstellten Voraussetzungen, dass Du, genau wie die Excel-Formel das angeht,
  • das Datum erstmal tippfehlerfrei um die "Konstante" 2415019 reduzierst
  • und damit die Anzahl vergangener Tage seit dem 1. Jänner 1900 erhältst (das ist dieser Wert 39773)
  • den Du in Excel brauchst, weil Excel, wie es für ein Tabellenkalkutionstool naheliegend ist, dafür sorgt, dass alle AnwenderInnen nur Datumswerte nach 1900 verarbeiten können. (Bei allem, was früher ist, spinnen die meisten Datumsfunktionen bei Excel)

Wenn wir das also mit Access nachkaspern, dann sollte in etwa diese Syntax passen:

SELECT DatumAuslief as JulDatwert,  
DateAdd("d",#1/1/1900#, DatumAuslief - 2415019 ) AS AusliefDatum  
FROM LIEFDAT
[ungetestet, aber es sollte der Originalwert als "JulDatWert und daneben das "richtige" Datum als AusliefDatum angezeigt werden]

Erläuterung.
dateAdd( "d" , ....) ---> Erzeugt einen Datumswert im (System-)Standarddatumsformat.
wenn Du als in Deinem Accesskrams bisher immer das Datum als "tt.mm.jjjj" angezeigt bekommst, dann auch jetzt.
Die DateAdd()-Funktion addiert "Tage" (1, Parameter "d") zu dem Startdatum 1.1.1900 8 für Access: #01/01/1900#...
... und zwar den Wert (DeinJulDatum abzgl. 2415019)

Und nein, das ist sicherlich KEINE Formel, die ich für kompatibel mit anderen DateDiff()/DateAdd()-Implementierungen halte und ja, ich weiß, dass Umrechnungen vom Julianischen ins bei uns übliche Datum normalerweise mit 30zeiligen Funktionen berechnet werden.

Aber für die zu erwartenden "Lieferdatum"swerte in Deinen Daten sollte es bis zur Rente oder bis zur nächsten Access-Version passen.

Grüße
Biber
[Edit] Habe eben mal überprüft, ob mein Geschwafel meine Lösungsvorschläge mit der Realität kompatibel sind.
Wie immer... teils, teils.

Die Berechnung oben im SELECT-Statement passt (prinzipiell), ABER *Pest über diese Redmonder*...

  • Wenn diese "Konstante" zur Rückrechnung auf "Tage seit 1.1.1900" warum-auch-immer 2415019 (in Excel ) ist
  • So braucht Access an dieser Stelle eben eine andere Konstante: Zwei Tage mehr... 2415021

Nein, ich will es nicht kommentieren.
Das Statement, zumindest auf mieinem XP Pro-Rechner mit Access 2003, rechnet richtig(er) mit:
SELECT DatumAuslief as JulDatwert,  
DateAdd("d",#1/1/1900#, DatumAuslief - 2415021 ) AS AusliefDatum  
FROM LIEFDAT

[/Edit]
Member: Biber
Biber Dec 02, 2008 at 18:54:13 (UTC)
Goto Top
Nachtrag.

Mein Fehler.

Excel rechnet "Tage seit dem 1.1.1900". wie es halt ein Excel so tut...

Der "Julianische Datum" ist eine reine Tageszählung und rechnet wie oben geschrieben Tage seit 1.1.4000-und-irgendwas-vor-Gottschalk.

Access und alle Access/VBA/VB-Datumsfunktionen wiederum haben als Bezugsdatum nicht den 1.Januar 1900.

Sondern rechnen mit Bezugsdatum "30. Dezember 1899".
Zu Ehren von Uschi Glas, die an diesem Tag konfirmiert wurde.

Also stimmt die so genannte Moelle-Konstante (2415019)

und mein vorläufig finales Access-Statement heißt nun:

SELECT DatumAuslief as JulDatwert,  
DateAdd("d",#30/12/1899#, DatumAuslief - 2415019 ) AS AusliefDatum  
FROM LIEFDAT

Grüße
Biber
Member: Moelle
Moelle Dec 03, 2008 at 06:27:07 (UTC)
Goto Top
Danke Biber,

weiß zwar noch nicht so genau wie ich es in meiner Access Abfrage anwenden soll (bin kein SQL Experte)aber werde es mal versuchen.

Meine SQL Abfrage sieht momentan so aus:

SELECT d00_AUFTRAGSKOPF.TOURGEBIETID, d00_AUFTRAGSKOPF.NUMMERAUFT, d00_AUFTRAGSKOPF.NUMMERAUFTFO, d00_AUFTRAGSKOPF.KUNDENNUMMER, d00_KUNDEN.NAME1, d00_KUNDEN.NAME2, d00_KUNDEN.STRASSE, d00_KUNDEN.PLZ, d00_KUNDEN.ORT, d00_AUFTRAGSKOPF.DATUMAUSLIEF, d00_AUFTPOSITIONEN.NUMMERAUFTRAGPOS, d00_AUFTPOSITIONEN.ARTIKELNUMMER, d00_AUFTPOSITIONEN.BEZEICHNUNG1, d00_AUFTPOSITIONEN.BEZEICHNUNG2, d00_AUFTPOSITIONEN.BEZEICHNUNG3, d00_AUFTPOSITIONEN.MENGEGELIEF INTO Ladeliste_tst
FROM (d00_AUFTRAGSKOPF INNER JOIN d00_KUNDEN ON d00_AUFTRAGSKOPF.KUNDENNUMMER = d00_KUNDEN.KUNDENNUMMER) INNER JOIN d00_AUFTPOSITIONEN ON d00_KUNDEN.KUNDENNUMMER = d00_AUFTPOSITIONEN.KUNDENNUMMER
WHERE (((d00_AUFTRAGSKOPF.NUMMERAUFT)="766782"));

Ich weiß leider nicht wo ich jetzt diesen Teil einbauen muss "Select DatumAuslief as JulDatwert...."
Member: Biber
Biber Dec 03, 2008 at 08:33:57 (UTC)
Goto Top
Moin Moelle,

Du bist ja auch schon länger dabei und weißt, wie schwer es mir fällt, mich auf die Beantwortung der eigentlichen Frage zu beschränken.

Aber ich fange zumindest erstmal mit der eigentlichen Frage an.
SELECT 
ak.TOURGEBIETID, 
ak.NUMMERAUFT, 
ak.NUMMERAUFTFO, 
ak.KUNDENNUMMER, 
ku.NAME1, ku.NAME2, 
ku.STRASSE, ku.PLZ, ku.ORT, 
DateAdd("d",#30/12/1899#, ak.DATUMAUSLIEF -2415019) AS DATUMAuslief,   
apos.NUMMERAUFTRAGPOS, 
apos.ARTIKELNUMMER, apos.BEZEICHNUNG1, 
apos.BEZEICHNUNG2, apos.BEZEICHNUNG3, 
apos.MENGEGELIEF 
INTO Ladeliste_tst
FROM (
d00_AUFTRAGSKOPF ak 
INNER JOIN d00_KUNDEN ku
ON ak.KUNDENNUMMER = ku.KUNDENNUMMER) 
INNER JOIN d00_AUFTPOSITIONEN apos
ON ku.KUNDENNUMMER = apos.KUNDENNUMMER
WHERE (((ak.NUMMERAUFT)="766782"));  
Das hier wäre, ein bisschen lesbar gemacht, Dein Statement Eins-zu-Eins nur mit dem Unterschied, dass das Feld DATUMAUSLIEF nicht mehr als Long/als Zahlenwert, sondern als Datumswert kommt.

Ich empfehle dringend, das Statement erstmal nur zur Anzeige zu verwenden
OHNE das "INTO ladeliste_tst!
Also die Worte "into ladeliste_tst" wegzulassen.

SELECT 
ak.TOURGEBIETID, 
ak.NUMMERAUFT, 
ak.NUMMERAUFTFO, 
ak.KUNDENNUMMER, 
ku.NAME1, ku.NAME2, 
ku.STRASSE, ku.PLZ, ku.ORT, 
DateAdd("d",#30/12/1899#, ak.DATUMAUSLIEF -2415019) AS DATUMAuslief,   
apos.NUMMERAUFTRAGPOS, 
apos.ARTIKELNUMMER, apos.BEZEICHNUNG1, 
apos.BEZEICHNUNG2, apos.BEZEICHNUNG3, 
apos.MENGEGELIEF 
FROM 
d00_AUFTRAGSKOPF ak, 
d00_KUNDEN ku,
d00_AUFTPOSITIONEN apos
WHERE ak.KUNDENNUMMER = ku.KUNDENNUMMER
And ku.KUNDENNUMMER = apos.KUNDENNUMMER
AND ak.NUMMERAUFT="766782";  
So würde ich das Statement schreiben, damit ich sehe, was da abgeht.
...weil ich dann in dieser Variante sehen würde, dass es eigentlich nienich sein kein, dass in Deinem Modell die Auftragskopf und Auftragspositionen nur über die Kundennummer verknüpft sind - das sieht mir nach Bullshit aus.

Eine Verknüpfung von Auftragskopf zu Kunde über Kundennummer ist ja i.O.,
aber Auftragskopf und Auftragspos müssen eigentlich über eine "Auftragsnummer", in Deinem Fall wahrscheinlich NUMMERAUFT verbunden sein.

Eigentlich müsste also dieses etwas richtiger sein:
SELECT 
ak.TOURGEBIETID, 
ak.NUMMERAUFT, 
ak.NUMMERAUFTFO, 
ak.KUNDENNUMMER, 
ku.NAME1, ku.NAME2, 
ku.STRASSE, ku.PLZ, ku.ORT, 
DateAdd("d",#30/12/1899#, ak.DATUMAUSLIEF -2415019) AS DATUMAuslief,   
apos.NUMMERAUFTRAGPOS, 
apos.ARTIKELNUMMER, apos.BEZEICHNUNG1, 
apos.BEZEICHNUNG2, apos.BEZEICHNUNG3, 
apos.MENGEGELIEF 
FROM 
d00_AUFTRAGSKOPF ak, 
d00_KUNDEN ku,
d00_AUFTPOSITIONEN apos
WHERE ak.KUNDENNUMMER = ku.KUNDENNUMMER
And ak.NUMMERAUFT = apos.NUMMERAUFT
AND ak.NUMMERAUFT="766782";  

Grüße
Biber
Member: Moelle
Moelle Dec 03, 2008 at 14:33:47 (UTC)
Goto Top
Hallo Biber,

du hast es geschafft die Abfrage funktioniert so.

Allerdings soll diese jetzt nicht über Access erstellt werden sondern unter Excel via ODBC (Neue Abfrage erstellen). Leider muss dort die SQL-Anweisung anders aussehen

Zur Zeit
SELECT AUFTRAGSKOPF.TOURGEBIETID, AUFTRAGSKOPF.NUMMERAUFT, AUFTRAGSKOPF.NUMMERAUFTFO, AUFTRAGSKOPF.KUNDENNUMMER, KUNDEN.NAME1, KUNDEN.NAME2, KUNDEN.STRASSE, KUNDEN.PLZ, KUNDEN.ORT, DateAdd("d",#30/12/1899#, AUFTRAGSKOPF.DATUMAUSLIEF -2415019) AS DATUMAusliefAUFTPOSITIONEN.NUMMERAUFTFO, AUFTPOSITIONEN.ARTIKELNUMMER, AUFTPOSITIONEN.BEZEICHNUNG1, AUFTPOSITIONEN.BEZEICHNUNG2, AUFTPOSITIONEN.BEZEICHNUNG3, AUFTPOSITIONEN.MENGEGELIEF
FROM diacom.AUFTPOSITIONEN AUFTPOSITIONEN, diacom.AUFTRAGSKOPF AUFTRAGSKOPF, diacom.KUNDEN KUNDEN
WHERE AUFTPOSITIONEN.NUMMERAUFTFO = AUFTRAGSKOPF.NUMMERAUFTFO AND AUFTPOSITIONEN.NUMMERAUFT = AUFTRAGSKOPF.NUMMERAUFT AND AUFTPOSITIONEN.KUNDENNUMMER = KUNDEN.KUNDENNUMMER AND AUFTRAGSKOPF.KUNDENNUMMER = KUNDEN.KUNDENNUMMER AND ((AUFTRAGSKOPF.NUMMERAUFT='766782'))

Dann folgt aber die Fehlermeldung Inkorrekter Spaltenausdruck ab DateAdd bis ...-2415019)

Ich denke das ist nicht möglich über Excel oder????
Member: Biber
Biber Dec 03, 2008 at 15:15:39 (UTC)
Goto Top
Jessas, Moelle,

wenn ich nicht so unerschütterlich in mir ruhen würde, dann würde ich jetzt bestimmt diese ver###te ###abfrage nehmen und sie dreimal quer durch das ### ###, aber wirklich...

21, 22, 23....<durchatme>

Es ist schon immer wieder interessant, was so an kleinen unerheblichen Details nachtröpfelt...


Also, über ODBC-Aufruf an von Excel an ACCESS geht es bestimmt auch - aber...

  • wenn es partout in den ODBC-Aufruf soll, dann mach bitte einen neuen Beitrag daraus mit irgendetwas wie "Syntaxunterschiede Access-SQL und Access-Aufruf über ODBC?". Das findet sonst keiner außer aus beiden hier unter dieser Überschrift
  • ich würde allerdings dann eher diese Abfrage und diese funktionierende Syntax lieber dazu verwenden, im Access einen VIEW/eine "Abfrage" bereit zu stellen, die von vornherein diesen Wert liefert.
via ODBC kannst Du doch auch auf Access-Abfrage statt auf Access-Tabellen gehen, oder irre ich da?

Grüße
Biber
Member: Moelle
Moelle Dec 03, 2008 at 15:29:31 (UTC)
Goto Top
Die Access Abfrage ist aus ODBC Verknüpfungen entstanden. Leider ist das Problem das der Kollege kein Access besitzt sondern nur Excel installiert hat. Daher hat er nur den Zugriff via Excel auf ODBC. Ich kann natürlich gerne einen neuen Beitrag unter Excel erstellen aber meinst du das ausser mir irgendeiner solche Probleme mit Julianischen Daten hat. Du bist eine sehr große Hilfe gewesen freue mich schon ein deine Antwort in meinen neuen Beitrag.

Du bist ja im Thema... face-smile
Member: Guenni
Guenni Dec 07, 2008 at 12:46:59 (UTC)
Goto Top
Hi Moelle,

zu deiner Frage . . .
Mein Versuch: Abfrage Feld: ((LIEFDAT:[DATUMAUSLIEF]-2415019;'tt\.mm\.jjjj')
erhalte ich immer den Ausdruck syntaktisch falsch
Der Ausdruck wird mit der Funktion Format ausgewertet.

LIEFDAT: Format([DATUMAUSLIEF]-2415019;'tt\.mm\.jjjj')
liefert, wie in Excel, das Datum 21.11.2008.

Knacknuss@Biber(Damit der Sonntag nicht so langweilig wird face-smile ):

Zum Berechnen des Datums aus einem Julianischem Datum habe ich folg.
Seite gefunden: http://www.omega.it/u/um/umrechnung_zwischen_julianischem_1.html
Diese Beschreibung habe ich in Excel in eine Funktion umgesetzt:

Function jul2greg(JulDat)
JD = JulDat
JD0 = 1721426
N400 = Int((JD - JD0) / 146097)
R400 = Int((JD - JD0) Mod 146097)
N100 = Int(R400 / 36524)
R100 = Int(R400 Mod 36524)
If N100 = 4 Then
 N100 = 3
 R100 = 36524
End If
N4 = Int(R100 / 1461)
R4 = Int(R100 Mod 1461)
N1 = Int(R4 / 365)
LT = Int(R4 Mod 365)
If N1 = 4 Then
 N1 = 3
 LT = 365
End If
LJ = Int(400 * N400 + 100 * N100 + 4 * N4 + N1)
J = Int(LJ + 1)
M = Int((LT + 1) / 30 + 1)
SK = 0
MK = (-1)
If M > 12 Then
 M = 12
 SK = 1
 MK = 3
End If
T = Int((LT - 30 * (M - 1) - (SK + MK)))
jul2greg = T & "." & M & "." & J  
End Function

Diese Funktion, vorausgesetzt ich habe die Beschreibung richtig umgesetzt, liefert mir in Excel
aus dem Moelle'schem Jul.-Datum 2454792 nicht den 21.11.2008, sondern den 26.11.2008.
Die Beispielzahlen allerdings aus der Beschreibung . . .
2451545 = 1.1.2000 bzw.
2305813 = 31.12.1600
. . . werden korrekt, wie in der Beschreibung, von der Funktion wiedergegeben.
Gruß
Günni
Member: Biber
Biber Dec 07, 2008 at 22:31:33 (UTC)
Goto Top
Moin Günni,

danke für die Ergänzung und die Advents-Knobelaufgabe.

Der Fehler bzw. Effekt mit dem errechneten 26.11.2008 statt dem erwarteten 21.11.2008 liegt bei Dir bzw. im Kleingedruckten der Umrechnungsformel auf der (Unter-)Seite Berechnung des laufenden Tages.

Dort werden die Korrektur-"Konstanten" SK und MK (Schaltjahrkonstante und Monatskonstante) erläutert.

Die SK ist im Jahr 2000, wenn Monat <2: = 0
Die SK ist im Jahr 2008, Monat > 2: = 1

Die MK ist gemäß Tabelle:
   1 -1 Januar 
   2  0 Februar 
   3 -2 März 
   4 -1 April 
   5 -1 Mai 
   6  0 Juni 
   7  0 Juli 
   8 +1 August 
   9 +2 September
  10 +2 Oktober
  11 +3 November
  12 +3 Dezember
---> Für Monat 1 (am 1.1.2000)--> -1
---> Für Monat 11 (am 26.11.2008) -->+3

abzuziehen am 1.1.2000 also (SK+MK) = (0+(-1)) =-1--> minus minus 1 = +1

abzuziehen am 26.11.2008 (SK+MK)=(1+3) = 4

Diese Korrekturen hast Du hier vergessen:
...
SK = 0
MK = (-1)
If M > 12 Then
 M = 12
 SK = 1
 MK = 3
End If

Und da Du also nicht 4 Tage abziehst, sondern (mit der gleichen Korrekturrechnung wie am 1.1.2008) 1 Tag dazuzählst, hast Du im Ergebnis 5 Tage zuviel (26.11.2008 statt 21.11.2008).

Aber sei es drum - die Rückrechnung würde ja auch sowohl mit dem "Format(....,"tt.mm.jjjj)" klappen wie auch mit dem Umweg über "DateAdd(...über 30.12.1899...)".

Somit hätten wir genug Ansätze für eine funktionierende Umrechnung.
Jetzt fehlt uns noch eine, die wir OHNE Format() und ohne DateAdd() und ohne Excel-VBA hinbekommen bei einer ODBC-Abfrage--> siehe Moelle's Folgebeitrag.

Grüße
Biber