1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| procedure TDBGridKeyIncADOMainForm.DBGridKeyPress(Sender: TObject; var Key: Char);
var
DataSet: TDataSet;
Qte: TField;
begin
if (Key = '+') or (Key = '-') then
begin
// A voir si le caractère + iou - peuvent être dans une référence, donc prévoir de limiter selon la colonne active
//if DBGrid.SelectedField.FieldName = 'Qte' then
begin
DataSet := DBGrid.DataSource.DataSet;
Qte := DataSet.FieldByName('Qte');
// Dans le cas de cette modification sans avoir écrit le moindre caractère sur la ligne, le AutoEdit du TDataSource ne fait pas effet
if not (DataSet.State in [dsEdit, dsInsert]) then
DataSet.Edit();
Qte.AsInteger := Qte.AsInteger + 44 - Ord(Key);
ADOQueryCalcFields(DBGrid.DataSource.DataSet);
Key := #0;
// Comme la donnée n'est pas encore validée en base, la somme issue sera pas à jour donc il faut compenser
// Ici ne pas balayer le DataSet, cela va pourrir l'ergonomie de la saisie, sans compter les efforts bords techniques.
with TADOQuery.Create(nil) do
try
ConnectionString := Format('Provider=%s;Persist Security Info=False;Data Source=%s;Initial Catalog=%s;User ID=%s;Password=%s', ['SQLNCLI11.1', edServerName.Text, edDataBaseName.Text, edUser.Text, edPassword.Text]);
// On prend donc le total des autres lignes (ignore la ligne en cours)
SQL.Text := 'SELECT SUM(COALESCE(PU,0)*COALESCE(Qte,0)) AS F_TOTAL FROM [AAA_SLT_07] WHERE CMD = :pCmd AND ID <> :pID';
with Parameters do
begin
ParamByName('pCmd').DataType := ftInteger;
ParamByName('pCmd').Value := FSession;
ParamByName('pID').DataType := ftInteger;
ParamByName('pID').Value := FAutoInc;
end;
Open();
// Cumul des autres lignes + la ligen en cours qui n'est pas encore validé.
edTotal.Text := FloatToStr(FieldByName('F_TOTAL').AsFloat + DataSet.FieldByName('Total').AsFloat);
finally
Free();
end;
end;
end;
end;
procedure TDBGridKeyIncADOMainForm.ADOQueryAfterInsert(DataSet: TDataSet);
begin
// Idem, bricolage poourri parce que la base est simpliste, une colonne Identity est nécessaire
// Par curiosité faudrait que je regarde si l'on récupère l'Identity après un post, comme je le disais, tout INSERT\UPDATE\DELETe est explicitement en SQL jamais en direct sur le Query, souvent en lecture seule, unidirectionnel couplé à un tampon
FAutoInc := GetTickCount();
DataSet.FieldByName('ID').AsInteger := FAutoInc;
DataSet.FieldByName('CMD').AsInteger := FSession; // Je pense qu'il est indispensable d'avoir une Table Commande et une Foreign Key entre la Maitre\Detail, idem utiliser une FK avec la table PRODUIT
end; |