IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Bases de données Delphi Discussion :

calcul dans une table


Sujet :

Bases de données Delphi

  1. #1
    Membre à l'essai
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Octobre 2014
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2014
    Messages : 25
    Points : 17
    Points
    17
    Par défaut calcul dans une table
    Bonsoir

    Je veux faire se calcul :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure TForm1.Table1CalcFields(DataSet: TDataSet);
    begin
    table1.FieldByName('Total4').AsDateTime:=
    table1.FieldByName('Heurefin').AsDateTime
    -table1.FieldByName('Heuredeb').AsDateTime;
    end;
    le soucis est que dans mon DBgrid le résultat ne s'affiche pas.
    Par contre si je double Click sur le comp. table et que je fais 'ajouter nouveau champ' en renseignant le : nom le type et coche 'calculé' , là cela fonctionne ?

    sinon les 3 champs dans le code du dessus sont bien créer dans ma table

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 038
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 038
    Points : 40 943
    Points
    40 943
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    N'ayant pas indiqué le type de BDD, le fait que le champ ne soit pas un champ calculé me fait penser à une table Paradox , exact ?
    Quelle est la structure de la table (nom des champs et types)?
    Total4 ne peut être un champ de la table sauf s'il est de type calculé , mais dans ce cas nul besoin de l’événement onCalcField
    NOTE : d'un point de vue base de données total4 est un champ inutile car calculable

    si TOTAL4 ne fait pas partie des champs de la table , c'est bien cette méthode qu'il faut utiliser.
    Par contre si je double Click sur le comp. table et que je fais 'ajouter nouveau champ' en renseignant le : nom le type et coche 'calculé'

    le plus simple , au lieu de passer par une table , serait de passer par une query
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT * , Heurefin-heuredebut as total4 FROM NOMTABLE;
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  3. #3
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut
    Citation Envoyé par quattro Voir le message
    Bonsoir

    Je veux faire se calcul :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure TForm1.Table1CalcFields(DataSet: TDataSet);
    begin
    table1.FieldByName('Total4').AsDateTime:=
    table1.FieldByName('Heurefin').AsDateTime
    -table1.FieldByName('Heuredeb').AsDateTime;
    end;
    le soucis est que dans mon DBgrid le résultat ne s'affiche pas.
    Par contre si je double Click sur le comp. table et que je fais 'ajouter nouveau champ' en renseignant le : nom le type et coche 'calculé' , là cela fonctionne ?

    sinon les 3 champs dans le code du dessus sont bien créer dans ma table
    Le OnCalcFields n'est lancé que s'il y a des champs de type 'calculé', ceci doit expliquer cela
    Si le but c'est d'enregistrer le résultat d'un champs calculé dans un vrai champ de votre base il y a plusieurs moyens.

    Le premier voir si du coté de la base on ne peut pas le faire.

    En second le faire coté client. Plusieurs possibilités, dont une serait de créer un CalcField DifTemp et gérer dans le OnCalcField son calcul. Puis dans l'évènement BeforePost vous enregistrez le FieldCalc FifTemp dans votre colonne Total4.

    Et je rejoins l'avis de SergioMaster, la plupart du temps c'est une fausse bonne idée de vouloir enregistrer dans la base un champs calculé. (Je ne parle pas des champs calculés par la base données mais des champs 'normaux' qui contiendrait un résultat d'un calcul fait pas un programme extérieur. Comme dans votre cas.)

    Idem évitez d'utiliser les composant d'accès de type table qui reviennent à faire des select * from table...

    Et préférez définir vos fields cela vous facilitera les choses :

    Plutôt de que d'utliser QueryTable.FieldByName('Heurefin').asDataTime vous aurez :

    QueryTableHeurefin.asDateTime et surtout vous aurez accès aux évènements (On change, On validate...) et propriétés du fields plus facilement.

  4. #4
    Membre à l'essai
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Octobre 2014
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2014
    Messages : 25
    Points : 17
    Points
    17
    Par défaut
    bonsoir

    Pas familier du tout avec le SQL, je n'arrive pas a trouver la solution pour mon pb.
    J'ai déjà un comp. SQL1 qui gere la recherche de date, voici la chaine SQL renseigner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM t1.db WHERE dated BETWEEN :dated AND :fin
    moi je voudrais juste faire une soustration d'heure : H2-H1 et mettre resultat dans : total1.

    1 - puis-je réutiliser le même comp. SQL1 ou dois-je en prendre un autre?
    2 - dois je utiliser un autre composant (bouton,etc..) pour insérer le code permettant la soustraction?
    3 - a quoi ressemblerais ce code?

    sachant que j'utilise paradox et que les champ : H1,H2,total1 sont créer...
    Merci

  5. #5
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 038
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 038
    Points : 40 943
    Points
    40 943
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    Je plussoie ce qu'écrit barbibulle
    Citation Envoyé par barbibulle
    la plupart du temps c'est une fausse bonne idée de vouloir enregistrer dans la base un champs calculé. (Je ne parle pas des champs calculés par la base données mais des champs 'normaux' qui contiendrait un résultat d'un calcul fait pas un programme extérieur. Comme dans votre cas.)
    une réflexion au sujet des requêtes de selection : nommer tous les champs que l'on veut est toujours préférable à un *

    Si vous ne pouvez vraiment pas vous passer de ce champ , voilà quelques pistes
    Citation Envoyé par quattro Voir le message
    1 - puis-je réutiliser le même comp. SQL1 ou dois-je en prendre un autre?
    2 - dois je utiliser un autre composant (bouton,etc..) pour insérer le code permettant la soustraction?
    3 - a quoi ressemblerais ce code?
    1- cela dépend de comment vous l'utilisez , donc difficile de confirmer quoique ce soit à ce sujet

    2- idem , ce n'est pas obligé vous pourriez par exemple le faire (le calcul)dans un évènement BeforePost

    3- s'il s'agit de faire une mise à jour du champ total1 quelque chose du genre
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    update tb1.db set total1=H2-H1
    fera la mise à jour du champ total1 pour toute la table , en y ajoutant une clause where on pourra limiter cette mise à jour à l'ensemble voulu
    par exemple :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    UPDATE t1.db SET  total1=H2-H1 WHERE dated BETWEEN :dated AND :fin

    maintenant vous pourriez aussi utiliser un TUpdateSQL pour gérer cela directement avec votre composant table
    le texte ressemblerai à ça pour l'update
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    update "test.db"
    set
      H1 = :H1,
      H2 = :H2,
      Total1 =:H2-:H1
    where
      CLE = :OLD_CLE
    et à ceci pour l'insert
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    insert into "test.db"
      (H1, H2,Total1)
    values
      (:H1, :H2, :H2-:H1)
    utilisez le menu contextuel de l'updatesql pour générer les SQL puis modifiez les de façon à calculer le champ T1 comme indiqué.
    ! Attention la propriété UpdateMode a (pour cet exemple) été mise à upWhereKeyOnly , faites des essais avec les autres modes pour voir ce qui se passe au niveau de la clause Where du Update , c'est instructif

    Dernier point , si les enregistrements et tous les champs sont affichés dans une dbgrid , je ne suis pas sur qu'il ne faille pas mettre Autorefresh à true et/ou peut être travailler en cacheupdates (cela fait longtemps que je n'ai pas travaillé avec paradox et bde )
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  6. #6
    Membre à l'essai
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Octobre 2014
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2014
    Messages : 25
    Points : 17
    Points
    17
    Par défaut
    J'ai opté pour un comp. : TUpdateSQL
    par contre ou dois-je taper les deux lignes de codes ?
    Dans ses propriétés il me propose : DeleteSQL,InsertSQL,ModifySQL.
    Dans les évènement, rien..

  7. #7
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 038
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 038
    Points : 40 943
    Points
    40 943
    Billets dans le blog
    62
    Par défaut
    Citation Envoyé par quattro Voir le message
    J'ai opté pour un comp. : TUpdateSQL
    par contre ou dois-je taper les deux lignes de codes ?
    Dans ses propriétés il me propose : DeleteSQL,InsertSQL,ModifySQL.
    Dans les évènement, rien..
    vous auriez utilisé , comme suggéré , le menu contextuel de TUpdateSQL (première option : "Editeur Update SQL"), puis utilisé le bouton Generate SQL tout aurait été révélé
    bref, bien sur , c'est respectivement dans les propriétés DeleteSQL,insertSQL,ModifySQL que les sql que j'ai indiqué serait à mettre .
    Non TUpdateSQL n'a aucun événement en fait , c'est le Post , dans le cas d'un Insert ou d'un Update , ou le Delete qui font le travail .
    Considérez que les directives du TupdateSQL écrase le comportement "normal" de ces dernières instructions , pour le remplacer par le sql que vous lui avez fourni . De fait c'est plus ou moins ce qui se passe (d'où l'importance de changer le upWhereAll par un upWhereKey moins gourmand dès que la table a un index unique) . Faites des essais avec l'éditeur d'UPDateSQL , c'est édifiant
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  8. #8
    Membre à l'essai
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Octobre 2014
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2014
    Messages : 25
    Points : 17
    Points
    17
    Par défaut
    J'ai donc mis mon TupDateSQL1, j'ai ouvert l'editeur updateSQL, j'ai renseigné dans l'onglet "SQL" "modification" ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     update t1.db
    set
      Dated= :Dated,
      fin= :fin,
      Total1 =:fin-:Dated
    where
      CLE = :OLD_CLE
    ensuite j'ai renseigné "insertion" avec ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     insert into "t1.db"
      (dated, fin,Total1)
    values
      (:dated, :fin, :fin-:dated)
    - L’éditeur de colonne de mon DBgrid a bien tous les champs.
    - Mon comp. SQL1 a son cachesupdate a true et son autorefresh a false.
    - j'ai essayé de modifier le upDatemode au 3 valeurs proposé, toujours pas bon...

  9. #9
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 038
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 038
    Points : 40 943
    Points
    40 943
    Billets dans le blog
    62
    Par défaut
    bonjour,

    comme déjà dit cela fait longtemps que je n'ai pas touché paradox et le BDE .
    j'ai rapidement fait un programme et me suis aperçu que
    1- un champ time - un champ time ne donne pas un time ,j'ai donc changé le champ résultant en Numerique
    2- si , selon ma méthode , le insert fonctionne (t1 calculé) , le update semblait sourd (ceci étant j'ai bâclé ce test en 10mn)
    une fermeture/réouverture de la table (rafraichissement de l'ensemble de données) et tout était rentré dans l'ordre des choses !

    voici le source et dfm
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    56
    57
    58
    59
    60
     
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ExtCtrls, DBCtrls, Grids, DBGrids, DB, DBTables;
     
    type
      TForm1 = class(TForm)
        Database1: TDatabase;
        Table1: TTable;
        UpdateSQL1: TUpdateSQL;
        DataSource1: TDataSource;
        DBGrid1: TDBGrid;
        DBNavigator1: TDBNavigator;
        Button1: TButton;
        Table1CLE: TAutoIncField;
        Table1H1: TTimeField;
        Table1H2: TTimeField;
        Table1T1: TFloatField;
        Button2: TButton;
        Query1: TQuery;
        procedure Button1Click(Sender: TObject);
        procedure Table1AfterPost(DataSet: TDataSet);
        procedure Button2Click(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
    Table1.Active:=True;
    end;
     
    procedure TForm1.Table1AfterPost(DataSet: TDataSet);
    begin
    if table1.UpdatesPending then table1.CommitUpdates;
    table1.Active:=False;
    Table1.active:=true;
    end;
     
    procedure TForm1.Button2Click(Sender: TObject);
    begin
    Query1.ExecSQL;
    table1.Active:=False;
    Table1.active:=true;
    end;
     
    end.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
     
    // DFM ---------------------------------------------
    object Form1: TForm1
      Left = 198
      Top = 125
      Width = 393
      Height = 472
      Caption = 'Form1'
      Color = clBtnFace
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -11
      Font.Name = 'MS Sans Serif'
      Font.Style = []
      OldCreateOrder = False
      PixelsPerInch = 96
      TextHeight = 13
      object DBGrid1: TDBGrid
        Left = 40
        Top = 80
        Width = 289
        Height = 297
        DataSource = DataSource1
        TabOrder = 0
        TitleFont.Charset = DEFAULT_CHARSET
        TitleFont.Color = clWindowText
        TitleFont.Height = -11
        TitleFont.Name = 'MS Sans Serif'
        TitleFont.Style = []
        Columns = <
          item
            Expanded = False
            FieldName = 'CLE'
            Visible = True
          end
          item
            Expanded = False
            FieldName = 'H1'
            Visible = True
          end
          item
            Expanded = False
            FieldName = 'H2'
            Visible = True
          end
          item
            Expanded = False
            FieldName = 'T1'
            Visible = True
          end>
      end
      object DBNavigator1: TDBNavigator
        Left = 40
        Top = 392
        Width = 280
        Height = 25
        DataSource = DataSource1
        TabOrder = 1
      end
      object Button1: TButton
        Left = 32
        Top = 8
        Width = 75
        Height = 25
        Caption = 'Ouverture'
        TabOrder = 2
        OnClick = Button1Click
      end
      object Button2: TButton
        Left = 32
        Top = 48
        Width = 75
        Height = 25
        Caption = 'Update All'
        TabOrder = 3
        OnClick = Button2Click
      end
      object Database1: TDatabase
        AliasName = 'Travail'
        SessionName = 'Default'
        Left = 160
        Top = 8
      end
      object Table1: TTable
        CachedUpdates = True
        AfterPost = Table1AfterPost
        DatabaseName = 'Travail'
        TableName = 'test.DB'
        UpdateMode = upWhereKeyOnly
        UpdateObject = UpdateSQL1
        Left = 208
        Top = 8
        object Table1CLE: TAutoIncField
          FieldName = 'CLE'
          ReadOnly = True
        end
        object Table1H1: TTimeField
          FieldName = 'H1'
        end
        object Table1H2: TTimeField
          FieldName = 'H2'
        end
        object Table1T1: TFloatField
          FieldName = 'T1'
        end
      end
      object UpdateSQL1: TUpdateSQL
        ModifySQL.Strings = (
          'update "test.DB"'
          'set'
          '  H1 = :H1,'
          '  H2 = :H2,'
          '  T1 = :H2 - :H1'
          'where'
          '  CLE = :OLD_CLE')
        InsertSQL.Strings = (
          'insert into "test.DB"'
          '  (H1, H2, T1)'
          'values'
          '  (:H1, :H2, :H2 - :H1)')
        DeleteSQL.Strings = (
          'delete from "test.DB"'
          'where'
          '  CLE = :OLD_CLE')
        Left = 256
        Top = 8
      end
      object DataSource1: TDataSource
        DataSet = Table1
        Left = 320
        Top = 8
      end
      object Query1: TQuery
        DatabaseName = 'Travail'
        SQL.Strings = (
          'UPDATE TEST.DB SET T1=H2-H1')
        Left = 208
        Top = 56
      end
    end
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

Discussions similaires

  1. colonne calculée dans une table
    Par gicquairea dans le forum WinDev
    Réponses: 6
    Dernier message: 10/10/2007, 06h10
  2. champs calculé dans une table
    Par tomas dans le forum Modélisation
    Réponses: 1
    Dernier message: 17/09/2007, 11h18
  3. Champs calculés dans une table
    Par froutloops62 dans le forum Access
    Réponses: 7
    Dernier message: 22/05/2007, 23h50
  4. [Requête/SQL]ajouter un champ calculé dans une table
    Par zougna dans le forum Requêtes et SQL.
    Réponses: 8
    Dernier message: 17/04/2007, 19h09
  5. Créer un champ calculé dans une table
    Par tigevellou dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 21/04/2006, 15h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo