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 :

Composant TDBF et le type Time


Sujet :

Bases de données Delphi

  1. #1
    Nouveau membre du Club
    Inscrit en
    Février 2006
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Février 2006
    Messages : 39
    Points : 39
    Points
    39
    Par défaut Composant TDBF et le type Time
    J'utilise le composant tDBF avec la fonction CopyFrom(DataSet:TDataSet;FileName:string;
    DateTimeAsString:Boolean;Level:Integer) pour générer les états.
    Le problème est : quand le dataset à copier contient un champs de type Time alors j'ai cette erreur : "VCL field type A not supported by DBF".
    Y-a-t-il un moyen pour remédier à ce problème et merci.

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Je fais quelques fois du DBase (fichier DBF) sous Appollo, il me semble que les Types Time et DateTime n'existent pas, c'est que le type DATE ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Nouveau membre du Club
    Inscrit en
    Février 2006
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Février 2006
    Messages : 39
    Points : 39
    Points
    39
    Par défaut
    j'ai trouvé ça sur la doc mais je ne sais comment ça fonctionne

    property OnCopyDateTimeAsString: TConvertFieldEvent read
    FOnCopyDateTimeAsString write FOnCopyDateTimeAsString;
    Write an OnCopyDateTimeAsString event to provide a custom formatting of DateTime ?elds
    into string Fields. See the CopyFrom procedure.

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Je ne connais pas ce composant mais cela me semble être ceci

    pour l'appel de ta méthode faut écrire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CopyFrom(DataSet, 'MaTable.DBF', True, 0);
    pour OnCopyDateTimeAsString, c'est un Evènement doit tu fois fournir le Gestionnaire

    tu affecte un Gestionaire de ce type au composant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    procedure TFormDBF.ComponentDBFCopyDateTimeAsString(DataSet: TDataSet; const FieldName: string; var StringValue: string);
    begin
      // tu dois avoir une valeur datetime à ce moment, avec un FormatDateTime tu dois pouvoir faire une chaine ...
    end;
    pour affecter le Gestionnaire, tu clicque sur le composant DBF, tu fais F11, tu vas dans l'onglet Evenement, tu double clique dans OnCopyDateTimeAsString, ça devrait te créer un code proche de celui ci dessus, ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Salut

    Tu as cet échec simplement parce que le type ftTime n'existe pas sous dBase, et ne peut être transcrit.

    2 solutions s'offre à toi:
    1. Tu modifies le code source du compo pour transcrire le champ Time en String
    2. Ou plus simple, tu castes ton champ Time en String dans ta requête source


    @+ Claudius

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    @Claudius
    Justement, la conversion ne serait pas prévu via l'implémentation d'un Gestionnaire pour OnCopyDateTimeAsString ???

    Sinon, selon les moteurs, le SQL est très très lent avec Dbase, il existe un script natif pour faire des filtres assez poussé sous Apollo ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Salut Shai

    Citation Envoyé par ShaiLeTroll Voir le message
    Justement, la conversion ne serait pas prévu via l'implémentation d'un Gestionnaire pour OnCopyDateTimeAsString ???
    Ben non le problème est en amont lorsque le compo créé la structure de la table dBase cible. Paf échec lorsqu'il tombe sur champ ftTime qu'il ne sait pas transcrire.

    Peut-être en définissant des champs persistants sur la table cible ? Il faut que je teste.

    @+ Claudius

  8. #8
    Nouveau membre du Club
    Inscrit en
    Février 2006
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Février 2006
    Messages : 39
    Points : 39
    Points
    39
    Par défaut
    Merci à vous deux, j'ai essayé la solution que ShaiLeTroll a proposé c.à.d:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CopyFrom(DataSet, 'MaTable.DBF', True, 0);
     
    procedure TFormDBF.Dbf_PRNCopyDateTimeAsString(Dbf: TDbf; DstField,
      SrcField: TField);
    begin
      DstField.AsString := FormatDateTime('hh:mm', SrcField.AsDateTime);
    end;
    Mais toujours le même problème. Il reste à tester la solution de Cl@udius.

  9. #9
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Salut

    Citation Envoyé par edisson81 Voir le message
    Il reste à tester la solution de Cl@udius.
    Champs persistants ou pas: même problème.

    De quelle version du compo disposes-tu ?
    Perso j'ai la version 6.9.0 que je viens de modifier pour qu'il gère les champs ftTime

    @+ Claudius

  10. #10
    Nouveau membre du Club
    Inscrit en
    Février 2006
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Février 2006
    Messages : 39
    Points : 39
    Points
    39
    Par défaut
    Je dispose de la version 6.48. Peux tu m'envoyer la 6.9?
    et merci.

  11. #11
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Re,

    En fait je dispose de la 6.9.1 que tu peux télécharger ici
    C'est la dernière en date.

    Ensuite je te prépare les modifs à effectuer...

    [edit]
    Et voici.

    Unit dbf.pas

    Modification de l'implémentation de la procedure TDbf.CopyFrom (1 ajout, 1 modif)

    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
     
    procedure TDbf.CopyFrom(DataSet: TDataSet; FileName: string; DateTimeAsString: Boolean; Level: Integer);
    var
      lPhysFieldDefs, lFieldDefs: TDbfFieldDefs;
      lSrcField, lDestField: TField;
      I: integer;
    begin
      FInCopyFrom := true;
      lFieldDefs := TDbfFieldDefs.Create(nil);
      lPhysFieldDefs := TDbfFieldDefs.Create(nil);
      try
        if Active then
          Close;
        FilePath := ExtractFilePath(FileName);
        TableName := ExtractFileName(FileName);
        FCopyDateTimeAsString := DateTimeAsString;
        TableLevel := Level;
        if not DataSet.Active then
          DataSet.Open;
        DataSet.FieldDefs.Update;
        // first get a list of physical field defintions
        // we need it for numeric precision in case source is tdbf
        if DataSet is TDbf then
        begin
          lPhysFieldDefs.Assign(TDbf(DataSet).DbfFieldDefs);
          IndexDefs.Assign(TDbf(DataSet).IndexDefs);
        end else begin
    {$ifdef SUPPORT_FIELDDEF_TPERSISTENT}
          lPhysFieldDefs.Assign(DataSet.FieldDefs);
    {$endif}      
          IndexDefs.Clear;
        end;
        // convert list of tfields into a list of tdbffielddefs
        // so that our tfields will correspond to the source tfields
        for I := 0 to Pred(DataSet.FieldCount) do
        begin
          lSrcField := DataSet.Fields[I];
          with lFieldDefs.AddFieldDef do
          begin
            if Length(lSrcField.Name) > 0 then
              FieldName := lSrcField.Name
            else
              FieldName := lSrcField.FieldName;
            FieldType := lSrcField.DataType;
            Required := lSrcField.Required;
            if (1 <= lSrcField.FieldNo)
                and (lSrcField.FieldNo <= lPhysFieldDefs.Count) then
            begin
              // Ajout -------------------------------------------------------------
              if DataSet.Fields[I].DataType = ftTime then
                Size := 8   // 'hh:mm:ss'
              else
              // Fin Ajout -------------------------------------------------------------
                Size := lPhysFieldDefs.Items[lSrcField.FieldNo-1].Size;
              Precision := lPhysFieldDefs.Items[lSrcField.FieldNo-1].Precision;
            end;
          end;
        end;
     
        CreateTableEx(lFieldDefs);
        Open;
        DataSet.First;
    {$ifdef USE_CACHE}
        FDbfFile.BufferAhead := true;
        if DataSet is TDbf then
          TDbf(DataSet).DbfFile.BufferAhead := true;
    {$endif}      
        while not DataSet.EOF do
        begin
          Append;
          for I := 0 to Pred(FieldCount) do
          begin
            lSrcField := DataSet.Fields[I];
            lDestField := Fields[I];
            if not lSrcField.IsNull then
            begin
              // Modif -------------------------------------------------------------
    //        if lSrcField.DataType = ftDateTime then
              if lSrcField.DataType in [ftDateTime, ftDate] then
              // Fin Modif ---------------------------------------------------------
              begin
                if FCopyDateTimeAsString then
                begin
                  lDestField.AsString := lSrcField.AsString;
                  if Assigned(FOnCopyDateTimeAsString) then
                    FOnCopyDateTimeAsString(Self, lDestField, lSrcField)
                end else
                  lDestField.AsDateTime := lSrcField.AsDateTime;
              end else
                lDestField.Assign(lSrcField);
            end;
          end;
          Post;
          DataSet.Next;
        end;
        Close;
      finally
    {$ifdef USE_CACHE}
        if (DataSet is TDbf) and (TDbf(DataSet).DbfFile <> nil) then
          TDbf(DataSet).DbfFile.BufferAhead := false;
    {$endif}      
        FInCopyFrom := false;
        lFieldDefs.Free;
        lPhysFieldDefs.Free;
      end;
    end;

    unit dbf_fields.pas

    Modication de la procédure TDbfFieldDef.VCLToNative (1 Ajout)

    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
     
    procedure TDbfFieldDef.VCLToNative;
    begin
      FNativeFieldType := #0;
      case FFieldType of
        ftAutoInc  : FNativeFieldType  := '+';
        // Ajout -------------------------------------------------------------------
        ftTime     : FNativeFieldType  := 'C';
        // Fin Ajout ---------------------------------------------------------------
        ftDateTime :
        [...]
      end;
      if FNativeFieldType = #0 then
        raise EDbfError.CreateFmt(STRING_INVALID_VCL_FIELD_TYPE, [GetDisplayName, Ord(FFieldType)]);
    end;
    Voilà !

    Le champs de type ftTime sont automatiquement transformés en champs de type ftString de longueur 8.

    Et ceci fonctionne indépendemment de l'option DateTimeAsString (True ou False).

    @+ Claudius

  12. #12
    Nouveau membre du Club
    Inscrit en
    Février 2006
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Février 2006
    Messages : 39
    Points : 39
    Points
    39
    Par défaut
    ça marche sans erreur, mais au lieu d'avoir 15:00:00 j'ai 30/12/18 et ce dans toutes les colones

  13. #13
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Quand tu dis dans toutes les colonnes, tu veux sûrement dire pour tous les enregistrements de ma colonne du type ftTime. Oui?


    Appelle la fonction CopyFrom de cette façon, pour voir:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
      DBF1.CopyFrom(DataSetSource, 'c:\temp\CopyTest.dbf', False, 4);
    @+

  14. #14
    Nouveau membre du Club
    Inscrit en
    Février 2006
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Février 2006
    Messages : 39
    Points : 39
    Points
    39
    Par défaut
    c'est bon ça marche mnt, j'ai ajouter le ftTime dans le test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
      [...]
    //Modif -------------------------------------------------------------
    //        if lSrcField.DataType = ftDateTime then
              if lSrcField.DataType in [ftDateTime, ftDate, ftTime] then
    // Fin Modif ---------------------------------------------------------
       [...]

  15. #15
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Ah OK ! Il te manquait un morceau !!!

    Bon ravi que cela fonctionne.

    @+ Claudius

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Probleme champ type Time
    Par 78alex78 dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 12/02/2006, 14h51
  2. Variable de type TIME
    Par Hervex dans le forum Langage
    Réponses: 1
    Dernier message: 30/01/2006, 11h47
  3. Addition de champs de type time
    Par GianT[971] dans le forum Langage SQL
    Réponses: 8
    Dernier message: 29/04/2005, 22h55
  4. [DB2] Affichage type TIME
    Par christie dans le forum DB2
    Réponses: 2
    Dernier message: 10/06/2004, 11h35
  5. Comment déterminer si un composant est d'un type "TMonT
    Par DanielR dans le forum C++Builder
    Réponses: 2
    Dernier message: 20/03/2004, 18h22

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