Question

J'ai fait face à une situation très étrange ici. Je base accède (MDB) par JET. J'utilise DBGrid et DBNavigator pour permettre l'accès des utilisateurs il. Jeu de données est créée en utilisant le composant TADOQuery, avec la requête suivante:

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

Il fonctionne très bien. Mais chaque fois que j'appuyez sur le bouton Actualiser sur DBNavigator le résultat de ce champ calculé devient mauvais. Par exemple, si normalement je 7 montré sur la colonne Âge, après que je presse Actualiser devient 40149, 7 changements à 40149, 6 changements à 40150, 0 à 40156, etc. Pour afficher le résultat correct, je dois rouvrir à nouveau la requête.

Tout le monde peut aider?

Était-ce utile?

La solution

Essayez ce qui suit, qui retournera l'âge en jours.

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

Pour l'âge dans les années utilisation:

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

(note, CINT tours, INT ne fonctionne pas)

La raison pour laquelle cela fonctionne est que l'accès stocke la date / heure dans une méthode similaire à Delphi, comme un flotteur où la partie entière est le nombre de jours écoulés depuis une date précise et la partie décimale que la partie fraction de ce jour-là (0,25 = 6 heures, 0,50 = midi, etc). Ainsi, si vous voulez connaître les différences entre deux jours, juste prendre les différences entre les numéros de jour ... pour le nombre d'années, il faut diviser par le nombre de jours dans une année.

EDIT

Une autre option serait ici de créer un champ calculé à Delphes et y effectuer la logique. Dans votre cas onCalculated vous code quelque chose comme ce qui suit:

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

EDIT

Et une troisième méthode. Plutôt que de permettre l'actualisation de travailler comme il le fait actuellement, remplacer le comportement et forcer une fermeture / réouverture de l'ensemble de données en utilisant le onClick du navigateur:

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

Autres conseils

Essayez ce paramètre intervalle à la place:

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

Voici ce que "intervalles" signifie:

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

J'ai fait un test avec votre commentaire précédent, et j'ai aussi la même erreur.

Je pense qu'il est un bug quelque part dans le navigateur ou jet.

Lorsque vous actualisez sur la navigation. le 40149 est la représentation montré date comme un double sans la substance calculée. Il semble utiliser uniquement la première colonne trouvée et pour l'afficher.

Si vous essayez de le jeter à une chaîne, les données affichées est encore datetime.

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

Quand j'utilise une colonne de type String ou numéro d'abord dans le champ calculé, le résultat est affiché comme il se doit. Vous pouvez essayer:

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

Ou:

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

Ceci est assez laid, mais il fait le tour ..

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top