Faussées après Refresh pressé sur DBNavigator Delphi
-
18-09-2019 - |
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?
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 ..