Frage

Ich habe eine sehr merkwürdige Situation hier konfrontiert. Ich bin Zugriff auf Datenbank (MDB) durch JET. Ich benutze DBGrid und DBNavigator um den Benutzerzugriff es zu erlauben. Datensatz wird erstellt TADOQuery Komponente, mit der folgenden Abfrage:

SELECT *, (DateDiff ('y',[Birth Date], Now())) AS [Age] FROM TableName

Es funktioniert gut. Aber immer, wenn ich Refresh-Taste auf DBNavigator das Ergebnis dieses berechneten Feldes drücken wird falsch. Wenn zum Beispiel normalerweise habe ich 7 auf Alte Spalte angezeigt, nachdem ich drücke Refresh es 40.149 wird, 7 Veränderungen zu 40149, 6 Änderungen 40150, 40156 usw. bis 0 Um ein korrektes Ergebnis sehen muß ich Abfrage erneut zu öffnen wieder.

Jeder kann helfen?

War es hilfreich?

Lösung

Versuchen Sie, die folgende, die das Alter in Tagen zurückkehren wird.

SELECT *, CINT(Now()-[Birth Date]) as AGE FROM TableName

Für Alter in Jahren verwenden:

SELECT *, INT((Now()-[Birth Date]) / 365.242199) as AGEYRS from TableName

(beachten Sie, CINT Runden, INT nicht)

Der Grund, dass dies funktioniert, ist, dass der Zugang speichert das Datum / Zeit in einem ähnlichen Verfahren wie Delphi, als Schwimmer, wo der ganzzahlige Teil ist die Anzahl der Tage seit einem bestimmten Tag und der Bruchteil als Bruchteil des Tages (0,25 = 06.00, 0.50 = Mittag, etc). Wenn Sie also die Unterschiede zwischen zwei Tagen wissen wollen, nehmen Sie nur die Unterschiede zwischen den Tageszahlen ... für mehrere Jahre, teilen Sie dies durch die Anzahl der Tage in einem Jahr.

Bearbeiten

Eine andere Möglichkeit wäre hier ein berechnetes Feld in Delphi zu erstellen und die Logik dort auszuführen. In Ihrem onCalculated Fall würde Code, den Sie so etwas wie die folgenden:

procedure TForm1.ds1CalcFields(DataSet: TDataSet);
begin
  DataSet.FieldByName('CALCDATE').AsInteger := 
    Trunc((Date - DataSet.FieldByName('BIRTH DATE').AsDateTime) / 365.242199);
end;

Bearbeiten

Und noch ein drittes Verfahren. Anstatt erlauben die Refresh zu arbeiten, wie es gegenwärtig der Fall ist, außer Kraft setzen, das Verhalten und erzwingen eine enge / wieder öffnen des Datensatzes durch die onClick des Navigators mit:

procedure TForm1.dbnvgr1Click(Sender: TObject; Button: TNavigateBtn);
begin
  if Button = nbRefresh then
    begin
      ds1.Close;
      ds1.Open;
    end;
end;

Andere Tipps

Versuchen Sie dieses Intervall Parameter statt:

SELECT *, (DateDiff ('yyyy',[Birth Date], Now())) AS [Age] FROM TableName

Hier ist, was "Intervalle" steht für:

yyyy    Year
q   Quarter
m   Month
y   Day of Year
d   Day
w   Weekday
ww  Week
h   Hour
n   Minute
s   Second

Ich habe einen Test mit dem vorherigen Kommentar, und ich habe auch den gleichen Fehler.

Ich denke, es ist ein Fehler irgendwo im Navigator oder in Jet.

Wenn Sie auf der nav getroffen aktualisieren. die 40149 gezeigt ist das Datum Darstellung als Doppel ohne die berechneten Sachen. Es scheint nur die erste Spalte zu verwenden gefunden und angezeigt werden.

Wenn Sie versuchen, es in einen String zu werfen, die angezeigten Daten nach wie vor ein Datetime.

Select *, ' ' & DateDiff(.......) as [Age] From table1;

Wenn ich eine Spalte vom Typ String oder Zahl zuerst in dem berechneten Feld verwenden, wird das Ergebnis angezeigt, wie es sollte. Sie können versuchen:

SELECT *,  mid(id & (DateDiff ('y',[madate], Now())), len(id) + 1) AS [Age] FROM Table1

Oder:

SELECT *,  (id-id) + (DateDiff ('y',[madate], Now()))  AS [Age] FROM Table1

Das ist ziemlich hässlich, aber es funktioniert der Trick ..

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top