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

Delphi Discussion :

Compatibilité TClientDataSet et TFDMemTable via la propriété commune XMLData ?


Sujet :

Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2015
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2015
    Messages : 3
    Par défaut Compatibilité TClientDataSet et TFDMemTable via la propriété commune XMLData ?
    Bonjour à tous,

    Je souhaiterais avoir de plus amples informations concernant la compatibilité d'un TClientDataSet avec un TFDMemTable.
    Chacun d'eux possède une propriété XMLData, qui selon la documentation Embarcadero, "est utile pour la compatibilité de TClientDataSet" et TFDMemTable.

    En quelques sortes, je cherche à transférer les données TClientDataSet.Data vers TFDMemTable.Data
    Cela n'étant pas possible directement (de part leur façon de stocker leurs données différemment en mémoire), je décide donc de passer par la propriété XMLData et donc de faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FDMemTable.XMLData := ClientDataSet.XMLData
    Malheureusement cela génère une erreur lors de l'écriture de la propriété XMLData:
    Classe d'exception EFDException avec un message '[FireDAC][Stan]-712. Impossible de lire l'objet [Manager]'.
    Sauriez-vous me dire comment résoudre cette erreur ?
    Ai-je manqué quelque chose ? Faut-il que je définisse quelque part un TFDDatSManager ? Si oui, comment ?

    Merci d'avance pour votre aide.


    Pour être un peu plus précis, voici mon code:
    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
    type
      TForm3 = class(TForm)
        btn_cds_to_fdmt: TButton;
    
        SQLConnection1: TSQLConnection;
        SQLDataSet_CCOS: TSQLDataSet;
        DataSetProvider: TDataSetProvider;
    
        FDStanStorageXMLLink1: TFDStanStorageXMLLink;
    
        ClientDataSet: TClientDataSet;
        FDMemTable1: TFDMemTable;
    
        procedure btn_cds_to_fdmtClick(Sender: TObject);
      end;
    
    var
      Form3: TForm3;
    
    implementation
    
    {$R *.fmx}
    
    procedure TForm3.btn_cds_to_fdmtClick(Sender: TObject);
    var
      tmp : string;
    begin
      tmp := ClientDataSet.XMLData;
      FDMemTable1.XMLData := tmp; //L'erreur survient ici
    end;
    
    end.
    Afin d'alimenter mon ClientDataSet, j'ai bien sûr préalablement posé sur ma Form:
    1. TSQLConnection
    2. TSQLDataSet
    3. TDataSetProvider
    convenablement paramétrés.

    (Je précise également que je travaille sur Delphi XE7)
    Merci

  2. #2
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 598
    Billets dans le blog
    65
    Par défaut
    Bonjour,

    juste une chose en première lecture , AMHA tmp ne devrait peut être pas être de type string, il eut mieux valu faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    FDMemTable1.XMLData :=ClientDataSet.XMLData;
    par contre, en effet je pense qu'il manque quelque chose.

    Pourquoi ne pas passer par le bon vieux stream ? (puisque XMLData ne fait qu'être, je cite :" un raccourci de la méthode LodfromStream/savetostream")
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    var aStr : TStream;
    begin
    Cliendataset.SaveToStream(astr,dfXML);
    fdMemTable1.LoadFromStream(aStr,sfXML);
    end;
    à l'heure qu'il est je n'ai pas le temps de faire de test

    attention aussi au format dfXML ou dfXMLUTF8

  3. #3
    Candidat au Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2015
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2015
    Messages : 3
    Par défaut
    D'abord, merci bien pour ton intervention SergioMaster.

    Effectivement, en réalité dans mon code je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FDMemTable1.XMLData :=ClientDataSet.XMLData;
    La variable tmp de type string était là seulement pour montrer que l'erreur venait lors de l'écriture. (Néanmoins, XMLData est bien de type string également).


    Aussi, il m'est bien venu à l'idée également d'utiliser un TStream, et d'écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    var
      astr : TStream;
    begin
      astr := TMemoryStream.Create;
      Clientdataset.SaveToStream(astr,dfXMLUTF8);
      fdMemTable1.LoadFromStream(aStr,sfXML);
    end;
    Mais malheureusement, j'obtiens exactement la même classe d’exception.

    Il semble manquer quelque chose, mais je ne vois vraiment pas encore...

  4. #4
    Membre Expert
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 539
    Billets dans le blog
    10
    Par défaut Peut être la solution :)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
      ClientDataSet1.MergeChangeLog ;
      ClientDataSet1.ApplyUpdates(-1) ;
      ADMemTable1.CopyDataSet(ClientDataSet1, [coStructure, coRestart, coAppend]);
    note : ADMemTable1 en XE3, FDMemTable1 en XE7

    Bonne soirée

  5. #5
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 598
    Billets dans le blog
    65
    Par défaut
    Bonjour,

    pensant à un bug de Firedac (j'en ai déjà trouvé un en XE7),
    je viens de faire un essai rapide en XE8 ( je l'ai) l'instruction passe à la compilation
    et effectivement même erreur à l'exécution , tout d'abord il me demande de rajouter un FDStanStorageXMLLink1 ou de mettre l'unité FireDAC.Stan.StorageXML
    mais évidemment cela ne suffit pas ,
    '[FireDAC][Stan]-712. Impossible de lire l'objet [Manager]'.
    moralité : fouiller dans EDN ou Googler

    pour ce qui est des streams, j'ai plongé dans les sources,
    première différence
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    astr := TMemoryStream.Create;
    à remplacer par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    var
      aStr: TStringStream;
    begin
      aStr := TStringStream.Create('', TEncoding.UTF8); 
    ...
    ...
      Free(aStr);
    mais là , j'ai une erreur
    EDOMParserError
    qui me semble logique quelque part (j'ai juste posé un client dataset, lié à un Filename (C:\Users\Public\Documents\Embarcadero\Studio\16.0\Samples\Data\items.xml) , je doute que cela soit très bon
    je dois avouer ne pas utiliser fréquemment les fichiers XML (1 ou 2 fois en des années)

    je n'abandonne pas mais il est temps de me mettre au boulot

  6. #6
    Membre Expert
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 539
    Billets dans le blog
    10
    Par défaut L'utilisation du format xml
    Citation Envoyé par SergioMaster Voir le message
    Bonjour,

    pensant à un bug de Firedac (j'en ai déjà trouvé un en XE7),
    je viens de faire un essai rapide en XE8 ( je l'ai) l'instruction passe à la compilation
    et effectivement même erreur à l'exécution , tout d'abord il me demande de rajouter un FDStanStorageXMLLink1 ou de mettre l'unité FireDAC.Stan.StorageXML
    mais évidemment cela ne suffit pas ,

    ....
    Bonjour la solution via xml ne semble pas opérationnelle comparer les deux fichiers générés par l'exemple suivant :
    Par contre le CopyDataSet fonctionne ;

    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
    var
      ms1 : TMemoryStream ;
    begin
      ClientDataSet1.MergeChangeLog ;
      ClientDataSet1.ApplyUpdates(-1) ;
      ADMemTable1.CopyDataSet(ClientDataSet1, [coStructure, coRestart, coAppend]);
      ms1 := TMemoryStream.Create;
      ClientDataSet1.SaveToStream(ms1,dfXMLUTF8);
      ms1.Position := 0 ;
      ms1.SaveToFile('A.XML');
      ms1.Free ;
      ms1 := TMemoryStream.Create;
      ADMemTable1.SaveToStream (ms1,sfXML);
      ms1.Position := 0 ;
      ms1.SaveToFile('B.XML');
      ms1.Free ;

  7. #7
    Candidat au Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2015
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2015
    Messages : 3
    Par défaut
    Bonjour,

    Merci à vous deux pour votre participation.

    @ALWEBER
    Effectivement un copyDataSet fonctionne correctement, c'est déjà ça, merci !
    Néanmoins je reste un peu perplexe sur cette propriété XMLData, qui est sensée garantir une "compatibilité" entre les deux.
    J'aurais bien voulu connaître la solution, ne serais-ce que pas curiosité.

    Et en effet, les deux fichiers XML (l'un généré par un ClientDataSet et l'autre par un FDMemTable) ne se ressemblent que très peu.
    Justement, c'est peut être sur ces différences que le fameux "Manager" serait sensé intervenir..?


    @SergioMaster
    J'ai également ajouté un FDStanStorageXMLLink.
    Ensuite, en utilisant un TMemoryStream ou un TStringStream, j'obtiens toujours l'erreur
    [FireDAC][Stan]-712. Impossible de lire l'objet [Manager]'.
    En ce qui concerne l'erreur EDOMParserError, peut être que ton fichier XML n'a pas d'entête.
    Voici, par exemple, un XML pour charger un ClientDataSet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>  <DATAPACKET Version="2.0"><METADATA><FIELDS><FIELD attrname="TYV_ID" fieldtype="i4" required="true"><PARAM Name="PROVFLAGS" Value="7" Type="i4" Roundtrip="True"/></FIELD><FIELD attrname="TYV_CLE" fieldtype="string" WIDTH="30"/><FIELD attrname="TYV_LIB" fieldtype="string" WIDTH="60"/></FIELDS><PARAMS DEFAULT_ORDER="1" PRIMARY_KEY="1" LCID="0"/></METADATA><ROWDATA><ROW TYV_ID="1" TYV_CLE="Cle1" TYV_LIB="Lib 1"/><ROW TYV_ID="2" TYV_CLE="Cle2" TYV_LIB="Lib 2"/><ROW TYV_ID="3" TYV_CLE="Cle3" TYV_LIB="Lib 3"/></ROWDATA></DATAPACKET>

  8. #8
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 598
    Billets dans le blog
    65
    Par défaut
    Citation Envoyé par Jer0me_B Voir le message
    Néanmoins je reste un peu perplexe sur cette propriété XMLData, qui est sensée garantir une "compatibilité" entre les deux.
    J'aurais bien voulu connaître la solution, ne serais-ce que pas curiosité.
    idem
    Et en effet, les deux fichiers XML (l'un généré par un ClientDataSet et l'autre par un FDMemTable) ne se ressemblent que très peu.
    Justement, c'est peut être sur ces différences que le fameux "Manager" serait sensé intervenir..?
    reste à trouver
    En ce qui concerne l'erreur EDOMParserError, peut être que ton fichier XML n'a pas d'entête.
    peur être doute , mais je prendrai ton XML pour vérifier

  9. #9
    Membre Expert
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 539
    Billets dans le blog
    10
    Par défaut Un peu d'histoire
    FireDac ( anciennement anyDAC ) provient du monde Linux
    ClientDataSet+XML provient de la technologie Midas utilisée par Borland
    La fonction de copie entre les deux univers via le CopyDataSet passe par la recréation de structure et le parcours de la table source par un curseur

Discussions similaires

  1. [Débutant] Redimensionnement Via la propriété Anchor
    Par Maniz dans le forum VB.NET
    Réponses: 7
    Dernier message: 10/10/2011, 16h41
  2. Exposer le style d'un contrôle via une propriété?
    Par lutecefalco dans le forum Silverlight
    Réponses: 5
    Dernier message: 04/06/2010, 10h42
  3. Lien entre deux tables via un champ commun ?
    Par [ZiP] dans le forum Débuter
    Réponses: 6
    Dernier message: 06/08/2009, 18h07
  4. Réponses: 6
    Dernier message: 15/09/2008, 22h00
  5. Réponses: 1
    Dernier message: 26/03/2008, 10h56

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