Seite 1 von 2
Datum berechnen
Verfasst: Mo, 19.11.2012 14:20
von gnaps
Hallo Forum,
ich erstelle gerade eine Datenbank für Bankbürgschaften,
hier habe ich ein Datumsfeld für: Datum-Austellung
und ein Feld mit den Laufzeit in Jahren: Laufzeit
jetzt habe ich noch ein Datumsfeld für die Rückforderung: Datum Rueckforderung
dieses Feld ist schreibgeschützt und kann nicht geändert werden, da hier das Datum
immer aus Datum-Austellung + Laufzeit generiert werden soll.
Wie stelle ich so etwas an.
Ich komme von Lotus Approach, hier war die Funktion ganz einfach zu realisieren.
Dank im vorraus.
Gruß
gnaps
Re: Datum berechnen
Verfasst: Mo, 19.11.2012 15:25
von juetho
Hallo und willkommen im Forum,
welche Lösung am besten passt, hängt vom DBMS ab. Es gibt die verschiedensten Funktionen, durch die aus dem Datum "Ausstellung" das Datum "Laufzeit" errechnet werden kann. Ob das beim Abrufen der Daten im SELECT gemacht werden sollte oder beim Speichern in der Tabelle, hängt zusätzlich davon ab, in welchem Zusammenhang die Daten eingegeben und ausgewertet werden. Vor einer genaueren Antwort müsstest du also mehr Informationen geben: DBMS, Treiber, Benutzeroberfläche; dazu vorsichtshalber OO-Programm und Version sowie Betriebssystem. Jürgen
Re: Datum berechnen
Verfasst: Mo, 19.11.2012 16:36
von gnaps
Hallo Juetho,
Danke für die schnelle Antwort.
Die Berechnung sollte über ein Makro gehen, wenn ich das Laufzeit-Eingabefeld verlasse.
Hier habe ich schon einen Code
Code: Alles auswählen
Sub Main
End Sub
Sub AddDate ' wird beim Ereignis "Focusverlust" von Datum oder Tage aufgerufen
Dim oFeld As Object, oJahr As Object
Dim dDate As Date
oFeld = thisComponent.drawpage.forms.getByName("MainForm").getByName("UebernahmeDatum") ' hole das Object Datum
oJahr = thisComponent.drawpage.forms.getByName("MainForm").getByName("Laufzeit") ' hole die Jahre
dDate = CDate(datevalue(oFeld.text))+1826 ' addiere Tage auf Datum
thisComponent.drawpage.forms.getByName("MainForm").getByName("RuecknahmeDatum").date = setDate(dDate)
End Sub
Function setDate(dDate) ' bereite das Datum auf, damit es das Ergebnis im richtigen Format füllt
y = year(dDate)
m = month(dDate)
d = day(dDate)
x = y*10000+m*100+d
setDate = x ' hier wird das Datum zurückgegeben
End Function
jedoch habe ich ein Problem bei
dDate = CDate(datevalue(oFeld.text))+1826
er rechnet jetzt richtig jedoch nicht mit der eingabe in der Laufzeit sondern direkt mit 5x365=1826.
Wie ändere ich den Code richtig ab.
Richtg wäre ja:
Hier bekomme ich eine Fehlermeldung.
Ich arbeite mot OO 3.4.1. unter Windows 7 und Windows 8
Gruß
gnaps
Re: Datum berechnen
Verfasst: Mo, 19.11.2012 16:50
von RobertG
Hallo gnaps,
dDate = CDate(datevalue(oFeld.text))+1826 ' addiere Tage auf Datum
kann so nicht funktionieren. Du musst die Funktion DateAdd verwenden.
dDate = DateAdd("d",+1826,CDate(datevalue(oFeld.text)))
führt vermutlich zum richtigen Datum.
Jetzt kann es nur noch sein, dass das Datum nicht SQL-Konform ist. Das wirst Du herausbekommen, wenn Du das Datumsfeld für das Rücknahmedatum bestücken willst.
Gruß
Robert
Re: Datum berechnen
Verfasst: Mo, 19.11.2012 17:00
von gnaps
Hallo RobertG,
der Code
geht,
jedoch wollte ich ja mit der Angabe im Laufzeit-Eingabefeld * 365 rechnen, da die Laufzeit unterschiedlich ist.
Hier bekomme ich den Fehler.
Gruß
gnaps
Re: Datum berechnen
Verfasst: Mo, 19.11.2012 17:03
von juetho
gnaps hat geschrieben:Die Berechnung sollte über ein Makro gehen, wenn ich das Laufzeit-Eingabefeld verlasse.
Das ist eine der Möglichkeiten. (Ich würde persönlich die Berechnung in der Datenbank vorziehen; aber wenn die Laufzeit im Formular als Jahreszahl eingegeben wird, ist das auch ein sinnvolles Verfahren.)
Dein Hauptproblem ist folgende Festlegung:
Hier habe ich schon einen Code
Date ist der Datentyp, den StarBasic verwendet. Der Formular-Designer benutzt einen anderen Datentyp; und die Funktionen müssen die Werte richtig zuordnen. Ein Lösungsweg geht so:
Code: Alles auswählen
dim dDate as new com.sun.star.util.Date ' beachte den speziellen Datentyp und das "new"
dDate = oForm.getDate(5) ' hole den Wert als Datum aus dem Formular, nicht aus dem Feld
dDate.year = dDate.year + oForm.getInt(6) ' hole den Wert als Integer und addiere die Jahre
oForm.updateDate(7, dDate) ' übertrage diesen Wert in das Formular
In den meisten Fällen ist per Makro das Lesen und Schreiben von Werten in Formularfelder besser, praktischer und sicherer über die Spalten des aktuellen Datensatzes im Formular. Vor allem beim Speichern direkt in die Formularfelder muss man sehr genau aufpassen (und "Klimmzüge" machen), um die Werte richtig zu konvertieren und zum richtigen Zeitpunkt (!) einzutragen.
Richtg wäre ja:
Hier bekomme ich eine Fehlermeldung.
Grundsätzlich: Wir wollen solche Fehlermeldungen nicht erraten, sondern sie ist möglichst konkret anzugeben!!! Aber es ist ja klar: oJahr ist das Feld und nicht die Zahl.
Nebenbei: In den meisten Fällen kann auf getByName verzichtet werden, vor allem bei so schönen Bezeichnern (ohne Umlaute, ohne Sonderzeichen),
Das ist kein Fehler, erleichtert aber das Schreiben von Code und macht ihn leichter lesbar.
Code: Alles auswählen
oForm = thisComponent.drawpage.forms.MainForm
oFeld = oForm.UebernahmeDatum
Gruß Jürgen
PS. Ich sehe gerade, dass Robert inzwischen geantwortet, während ich meinen Text geschrieben habe. Seine Hinweise sind immer richtig und wichtig; er hat auch mir viel beigebracht. Mein obiger Vorschlag basiert vor allem auf seiner Hilfe.
Re: Datum berechnen
Verfasst: Mo, 19.11.2012 17:27
von RobertG
Hallo gnaps,
oJahr = thisComponent.drawpage.forms.getByName("MainForm").getByName("Laufzeit") ' hole die Jahre
Das ist ein Objekt, kein Wert. Willst Du den Wert aus dem Feld auslesen, so hilft z.B.
oJahr.getCurrentValue()
Gruß
Robert
Re: Datum berechnen
Verfasst: Mo, 19.11.2012 17:32
von F3K Total
NA, Superklasse gnaps!!!
Du beschäftigst also mehrere Foren gleichzeitig?
http://www.openoffice-forum.de/viewtopic.php?f=9&t=3791
CROSSPOSTING ist unhöflich!
Re: Datum berechnen
Verfasst: Fr, 23.11.2012 17:28
von gnaps
Hallo Forum,
zuerst einmal sorry für den Doppelpost, wird nicht mehr vorkommen.
Ich wollte nur schnellstmöglich eine Lösung.
Leider sitze ich immer noch über diesem Problem und komme nicht weiter.
Kann mir jemand sagen wie ich den Code
Code: Alles auswählen
Sub Main
End Sub
Sub AddDate ' wird beim Ereignis "Focusverlust" von Datum oder Tage aufgerufen
Dim oFeld As Object, oJahr As Object
Dim dDate As Date
oFeld = thisComponent.drawpage.forms.getByName("MainForm").getByName("UebernahmeDatum") ' hole das Object Datum
oJahr = thisComponent.drawpage.forms.getByName("MainForm").getByName("Laufzeit") ' hole die Jahre
dDate = CDate(datevalue(oFeld.text))+1826 ' addiere Tage auf Datum
thisComponent.drawpage.forms.getByName("MainForm").getByName("RuecknahmeDatum").date = setDate(dDate)
End Sub
Function setDate(dDate) ' bereite das Datum auf, damit es das Ergebnis im richtigen Format füllt
y = year(dDate)
m = month(dDate)
d = day(dDate)
x = y*10000+m*100+d
setDate = x ' hier wird das Datum zurückgegeben
End Function
wie RobertG oben geschrieben hat soll ich
das hier benutzen, ich bin Frischling in BASE und dessen Mocrosprache und kann das nicht richtig zuordnen.
Lesen, Lesen, Lesen habe ich alles schon gemacht und kommen nicht weiter.
Ich hoffe es hat jemand von Euch noch Lust mir die Lösung zu zeigen.
gruß
gnaps
Re: Datum berechnen
Verfasst: Fr, 23.11.2012 17:50
von juetho
Zuerst solltest du hier den Basic-Kommentar ändern. Deine Formulierung führt (auch dich) in die Irre:
gnaps hat geschrieben:Code: Alles auswählen
oJahr = thisComponent.drawpage.forms.getByName("MainForm").getByName("Laufzeit") ' hole die Jahre
Das sollte so lauten:
Code: Alles auswählen
oJahr = thisComponent.drawpage.forms.MainForm.Laufzeit ' hole das Objekt für die Jahre
Dann ist sofort klar, dass als nächstes der Feldinhalt benötigt wird; hierher gehört also Roberts Code-Zeile (und dazu nach oben die DIM-Anweisung):
Für das Rücknahmedatum passt (wie von Robert vorgeschlagen) DateAdd, aber bezogen auf die Laufzeit von Jahren:
Code: Alles auswählen
dDate = DateAdd("yyyy", iJahr, CDate(datevalue(oFeld.text)))
Statt deiner setDate-Funktion schlage ich vor, zuerst die Standardfunktion CDateToIso probieren:
Code: Alles auswählen
thisComponent.drawpage.forms.MainForm.RuecknahmeDatum.date = CDateToIso(dDate)
Ohne Gewähr! (Ich würde, wie gesagt, über oForm-Werte gehen.) Jürgen
Re: Datum berechnen
Verfasst: Sa, 24.11.2012 08:00
von gnaps
Hallo juetho,
ich habe das ganze nun angepasst und das Datum wird jetzt richtig berechnet und im Formular angezeigt.
Jetzt kommt ein weiteres Problem.
Gehe ich zum nächsten Datensatz und dann wieder zurück, ist das berechnete Datum nicht mehr da.
Warum ist das so. Ich schreibe doch den Wert zurück.
Code: Alles auswählen
thisComponent.drawpage.forms.MainForm.RueckforderungDatum.date = CDateToIso(dDate) 'schreibe das Datum zurück
Hier der komplette Code.
Code: Alles auswählen
Sub Main
End Sub
Sub AddDate ' wird beim Ereignis "Focusverlust" von ÜbernahemDatum oder Laufzeit aufgerufen
Dim oFeld As Object
Dim oJahr As Object
Dim dDate As Date
Dim iJahr as Integer
oFeld = thisComponent.drawpage.forms.getByName("MainForm").getByName("UebernahmeDatum") ' hole das Object Datum
oJahr = thisComponent.drawpage.forms.MainForm.Laufzeit ' hole das Objekt für die Jahre
iJahr = oJahr.getCurrentValue() 'hole die Jahre aus dem Objekt
dDate = DateAdd("yyyy", iJahr, CDate(datevalue(oFeld.text))) 'berechne die Jahre
thisComponent.drawpage.forms.MainForm.RueckforderungDatum.date = CDateToIso(dDate) 'schreibe das Datum zurück
End Sub
Gruß
gnaps
Re: Datum berechnen
Verfasst: Sa, 24.11.2012 10:04
von juetho
gnaps hat geschrieben:Jetzt kommt ein weiteres Problem.
Gehe ich zum nächsten Datensatz und dann wieder zurück, ist das berechnete Datum nicht mehr da.
Warum ist das so. Ich schreibe doch den Wert zurück.
Code: Alles auswählen
thisComponent.drawpage.forms.MainForm.RueckforderungDatum.date = CDateToIso(dDate) 'schreibe das Datum zurück
Das ist ein Irrtum: Du schreibst den Wert erst einmal nur in das Feld, also in die Benutzeroberfläche. Damit landet er noch nicht im Zwischenspeicher mit der Tabelle und erst recht nicht in der Datenbank. Wenn der Wert im Zwischenspeicher landen würde, würde er durch den Wechsel des aktuellen Datensatzes automatisch in die Datenbank übertragen und stünde beim nächsten Aufruf wieder zur Verfügung. Du musst also zunächst folgenden Hinweis (Handbuch S. 234 f.) übernehmen:
Zuerst wird der Inhalt der Listenfelder an das darunterliegende Formular mit 'commit()' weitergegeben.
Das müsste mit folgendem Befehl erreicht werden (nicht getestet, ich arbeite anders):
Code: Alles auswählen
thisComponent.drawpage.forms.MainForm.RueckforderungDatum.commit()
Eine Alternative ist mein Vorschlag, grundsätzlich über oForm auf die Daten zugreifen, also mit getDate und updateDate (siehe oben). Damit werden die Werte im Zwischenspeicher bearbeitet (und an die Benutzeroberfläche weitergegeben).
Ich wundere mich sowieso, dass Robert nicht auch vorzugsweise diesen Weg angibt. Er gehört schließlich zu den Nutzern mit den umfassendsten Kenntnissen über die Arbeitsweisen von Base und weiß am besten, was sinnvoll ist.
Jürgen
Re: Datum berechnen
Verfasst: Sa, 24.11.2012 18:00
von RobertG
Hallo Jürgen,
ich habe mich in diesem Thread ja sowieso etwas rausgehalten. In Base arbeite ich bei so einem Problem zuerst einmal mit Abfragen. Und die würden in diesem falle völlig ausreichen, da es um Jahre geht und also nur zu der Jahreszahl eine Addition erfolgen müsste. Ich würde das Datum nie speichern.
Die Lösung hat FK3 hier gepostet:
http://www.openoffice-forum.de/viewtopi ... 3791#p8916
Speichern geht für mich immer über den Weg
oFeld.BoundField.UpdateDate()
Die Ansicht eines Wertes und die Übergabe des Wertes an die darunterliegende Tabelle sind eben zwei Schritte, die hiermit gleichzeitig gemacht werden.
Gruß
Robert
Re: Datum berechnen
Verfasst: Mo, 26.11.2012 11:59
von gnaps
Hallo Leute,
so ich bin jetzt mal weg vom Macro und wollte diesen Code von F3K_Total über "Abfrage in SQL-Ansicht erstellen ..."
Code: Alles auswählen
SELECT "ID", "Datum_Ausstellung", "Laufzeit", CONVERT ( YEAR( "Datum_Ausstellung" ) + "Laufzeit" || '-' || CASE WHEN ( MONTH( "Datum_Ausstellung" ) < 10 ) THEN '0' || MONTH( "Datum_Ausstellung" ) ELSE '' || MONTH( "Datum_Ausstellung" ) END || '-' || CASE WHEN ( DAY( "Datum_Ausstellung" ) < 10 ) THEN '0' || DAY( "Datum_Ausstellung" ) ELSE '' || DAY( "Datum_Ausstellung" ) END , DATE ) AS "Datum Rueckforderung" FROM "Laufzeiten"
nutzen. Ich bin Anfänger auf SQL und bekomme jetzt die Meldung bei Nutzung der Abfrage:
Die Dateninhalte konnten nicht geladen werden.
Table not found in statmend [SELECT "ID" .....
Warum das was mach jetzt wieder falsch ?
Gruß
gnaps
Re: Datum berechnen
Verfasst: Mo, 26.11.2012 12:20
von juetho
gnaps hat geschrieben:... und bekomme jetzt die Meldung bei Nutzung der Abfrage:
Die Dateninhalte konnten nicht geladen werden.
Table not found in statmend [SELECT "ID" .....
Das ist das Problem, wenn Code einfach kopiert und nicht verstanden wird. (Das kennt man schon aus der Schule: einfach abschreiben trägt nicht zum Verständnis bei.) Hinzu kommen die störenden Gänsefüßchen und die fehlende Formatierung des Codes. Man muss deshalb erst genau suchen, bis man den Namen der Tabelle/n findet:
Deine Tabelle hat offensichtlich einen anderen Namen. Bei der Gelegenheit solltest du auch die Namen der Spalten kontrollieren. Jürgen