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

C++Builder Discussion :

TClientDataSet exception :"Opération non applicable."


Sujet :

C++Builder

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    218
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 218
    Points : 91
    Points
    91
    Par défaut TClientDataSet exception :"Opération non applicable."
    Bonjour,
    j'ai un application ou il y a :
    un sgbd firebird 4 table
    3 dbgrids
    3 TClientDatset

    Veillez s'il vous plait regarder l'image "Datamodule.JPG " pour voir les composants présents : (si l'image n'apparait pas )




    Ces Dgrids sont liés via le maitre/esclave tel que sont lié dans le sgbd

    Lorsque dans la table maitre(Personne) j'ajoute /je supprime ou je modifie
    que se soit en cache ou le faire réellement les écritures/modification/suppression dans la base de données ne posent pas problème.

    La ou j'ai un bug, c'est quant j'ajoute un enreg dans la table esclave (MAIL)
    l'ajout en cache se fait bien cependant lorsque je quitte

    j'ai ce message :
    Le projet a provoqué une classe d'exception EDBClient avec le message 'Opération non applicable.'. Processus stoppé. Utilisez Pas-à-pas ou Exécuter pour continuer.
    souvent après j'ai une violation d’accès

    Dans le destructeur de TDataModule j'avais mis du code celui faisait des close() des DataSet , j'ai complétement mis en commentaire ce code et re compilée (rebuild all) et j'ai toujours la même erreur

    C'est toujours a ce moment la que se produit l'erreur

    lorsque j'ajoute un élément dans la table maitre (Personne) pas de pb


    Voici le code d'ajout table esclave MAIL :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    DataModule1->CDSMail->Append();
    DataModule1->CDSMail->FieldByName("MAIL")->AsString="toto@free.fr";
    DataModule1->CDSMail->Post();
    after Insert:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void __fastcall TDataModule1::CDSMailAfterInsert(TDataSet *DataSet)
    {
    CDSMail->AggregatesActive=true;
     
      if(VarIsNull(CDSMail->Aggregates->Items[0]->Value())){
          id=0;
      }else{
        id=CDSMail->Aggregates->Items[0]->Value() ; // lit la valeur du champ en cours
      }
     
    _F_ID_MAX_MAIL=id+1 ; // var globale portée classe TDataModule memorise ID_MAIL
    CDSMail->FieldByName("ID_MAIL")->AsInteger=_F_ID_MAX_PERS;
    }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    __fastcall TDataModule1::~TDataModule1()
    {
    //Destructeur : liberation de ressources
    //FreeDataModule();
    }
    Conclusion
    si j'ajoute un ereng dans la table secondaire en cache , je quitte plantage


    D’où peut venir cette exception ?

    merci je tourne en rond

    en vous remerciant
    Images attachées Images attachées  
    Outils utilisés : FireBird 2.1 - IbExert Free - C++ Builder 6 Pro Update 4- Windows Xp pro Sp3

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 455
    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 455
    Points : 24 867
    Points
    24 867
    Par défaut
    Je n'ai pas pratiqué les Master\Detail depuis un bout de temps

    je l'ai proposé pour faciliter un affichage avec 3 requêtes paramètrées chainées, sinon je n'en ai pas fait depuis plus de 6 ans sur DBase !

    TClientDataSet, tu fais un ApplyUdpates pour valider les Post ?
    Regarde le OnBeforeApply... j'ai plus le nom exacte, il te fourni un Delta sous forme d'un autre CDS, tu peux ainsi gérer manuellement tes requêtes UPDATE\INSERT\DELETE, utile pour les jointures

    L'Exception c'est durant le Post ? Apply ? Close ? Free ?
    As-tu penser à retirer le lien durant le Apply ?

    Tu modifies directement depuis la DBGrid ?
    En général, je préfère faire un formulaire de modification en lui passant la PK, il modifie dans son coin (ShowModal) puis l'appelant Grille fait un Refresh pour relire les données (modifiées par le formulaire et peut-être par une session d'un autre utilisateur)

    De même, je n'utilise plus de DataModule, j'encapsule mes DataSet (TSQLQuery, TSimpleDataSet ou TClientDataSet) dans des objets métiers ainsi je peux avoir deux fenêtres sur la même table\requête\jointure, les modifications sur l'une (comme Master, Filter, Locate...) n'impacte le DataSet utilisée par l'autre fenêtre ou pas un autre objet

    Actuellement, je n'ai QUE du ShowModal pour les formulaires de modification, cela simplifie la gestion du Refresh, seuls ces écrans utilisent directement du DataSet, on utilise pas le Post (juste AutoEdit), on utilise TSimpleDataSet comme tampon et un autre objet utilise des SQL prédéfinies ou alors génère les INSERT\UPDATE via RTTI (en gros cela évite le ApplyUpdates et OnBeforeApply...) pour mettre à jour la DB

    Le reste de l'application (c'est un outil de monitoring temps-réel) utilise soit des struct C++ soit des DELPHICLASS selon qui a écrit le code, tout les SQL sont écrit à la main, cela donne une maitrîse totale de ce qui est écrit en DB (on peut ainsi loggué tout ce qui ce passe, le Post\ApplyUpdates lui c'est un peu obscure)
    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
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    218
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 218
    Points : 91
    Points
    91
    Par défaut
    Bonjour,

    pour répondre a tes questions :

    TClientDataSet, tu fais un ApplyUdpates pour valider les Post ?
    non pas du tout , c'est un procédure a par qui fait cela
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TDataModule1::ApplyUpdatePers()
    car j'aivais pas de diffcultés a faire un ApplUpdates

    L’exception c'est durant le Post ? Apply ? Close ? Free ?
    l’exception est quant uniquement je remplie le seconde grille et que par le suite je veux quitter mon application , j'ai une exception qui se lève au niveau du destructeur de ma classe .Si je rempli qu'un seule table(maitre),alors il y a de problème
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TDataModule1::~TDataModule1()
    As-tu penser à retirer le lien durant le Apply ?
    non, je mis pas de temps a arriver la....je comptais faire un nouvelle procedure
    du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TDataModule1::ApplyUpdateMail()
    et ApplyUpdateTel() pour le téléphone

    ce seront ces procédure qui écriront directement dans la base

    est ce comme cela qu'il faut faire?

    comment ajouter ou détruire le lien dynamiquement par code?



    Tu modifies directement depuis la DBGrid ?
    Oui je comptais faire ajout /supp/modif dans trois grille

    que faire ?????

    voila la gueule de mon appli:




    merci bien a toi pour toute l'aide
    Images attachées Images attachées  
    Outils utilisés : FireBird 2.1 - IbExert Free - C++ Builder 6 Pro Update 4- Windows Xp pro Sp3

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    218
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 218
    Points : 91
    Points
    91
    Par défaut
    Bonjour,
    personne peut m'aider ????



    d'avance un très GRANND merci
    Outils utilisés : FireBird 2.1 - IbExert Free - C++ Builder 6 Pro Update 4- Windows Xp pro Sp3

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    218
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 218
    Points : 91
    Points
    91
    Par défaut
    un petit up

    help help help
    Outils utilisés : FireBird 2.1 - IbExert Free - C++ Builder 6 Pro Update 4- Windows Xp pro Sp3

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    218
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 218
    Points : 91
    Points
    91
    Par défaut
    Âpres avoir ajouté un enreg dans la table secondaire via ibexpert et non mon programme je ferme mon application je n'ai pas d’exception

    pazr contre j' ajoute un autre en enreg en memoire


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    DataModule1->CDSMail->Append();
    DataModule1->CDSMail->FieldByName("MAIL")->AsString="toto@free.fr";
    DataModule1->CDSMail->Post();
    et que je ferme j'ai l'exeption qui se déclenche ..

    cependant je pense que c'est un histoire de lien maitre/esclave
    entre les différent DataSource

    question:
    comment faire pour mettre/supprimer un lien entre les TClientDataSet
    par programmation ?(qui lie les different DbGrid)

    merci
    Outils utilisés : FireBird 2.1 - IbExert Free - C++ Builder 6 Pro Update 4- Windows Xp pro Sp3

  7. #7
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 455
    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 455
    Points : 24 867
    Points
    24 867
    Par défaut
    Affecte nil au MasterSource\DataSource du CDSMail
    Puis réaffecte au CDSMail son maître DSPers

    C'est ce que tu as du faire via l'IDE
    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

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    218
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 218
    Points : 91
    Points
    91
    Par défaut
    Bonjour que je fasse ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    __fastcall TDataModule1::~TDataModule1()
    {
     
    //Destructeur : liberation de ressources
    CDSMail->MasterSource=NULL;
    CDSMail->MasterFields=" ";
     
    CDSTel->MasterSource=NULL;
    CDSTel->MasterFields=" ";
     
     
     
    }

    ou cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void __fastcall TFrmAnnu::MnuQuitterClick(TObject *Sender)
    {
     
     
    DataModule1->CDSMail->MasterSource=NULL;
    DataModule1->CDSMail->MasterFields=" ";
     
    DataModule1->CDSTel->MasterSource=NULL;
    DataModule1->CDSTel->MasterFields=" ";
     
    Application->Terminate();
    }


    J'ai toujours mon exception qui apparait ,elle se decleche sur le destructeur du TDataModule la je ne vois pas comment m'en sortir si quelqu’un a une piste autre....

    merci
    Outils utilisés : FireBird 2.1 - IbExert Free - C++ Builder 6 Pro Update 4- Windows Xp pro Sp3

  9. #9
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 455
    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 455
    Points : 24 867
    Points
    24 867
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Application->Terminate();
    C'est moche et brutal, ceci est une méthode plus douce :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Application->MainForm->Close();
    D'ailleurs, suffit d'affecter une action standard (TWindowClose) à ton miQuitter pour fermer sans écrire de code

    Tu as la VA si tu fais le Post et ton ApplyUpdatePers ou ApplyUpdateMail ?
    ou juste le Post ?
    As-tu jouer avec LogChanges ?

    Normalement l'on veut personnaliser ApplyUpdate, il faut utiliser le Delta fourni par BeforeUpdateRecord, il n'est pas nécessaire de faire d'autres méthodes

    Si tu ne lance pas de ApplyUpdate, faudrait peut-être l'annuler
    Il existe une CancelUpdates ! non ?

    As-tu essayé un CDS.Close() explicite ?
    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

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    218
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 218
    Points : 91
    Points
    91
    Par défaut
    Salut

    Tu as la VA si tu fais le Post et ton ApplyUpdatePers ou ApplyUpdateMail ?
    ou juste le Post ?
    comme je te l'ai dis dans la seconde table je travaille encore dans la mémoire , je n'ai pas encore écrit de ApplyUdpateMail() , j’attends de régler ce problème avoir de coder ApplyUdpateMail() et ApplyUdpadteTel()

    La seule méthode qui existe et fonctionne pour l'instant est ApplyUdpadePers()

    Pour les grilles Tel et Mail pour l'instant en mémoire uniquement Post()
    actuellement je travaille uniquement sur la grille Mail

    As-tu jouer avec LogChanges ?
    non

    Si tu ne lance pas de ApplyUpdate, faudrait peut-être l'annuler
    Il existe une CancelUpdates ! non ?
    Sur un autre bt j'ai fait , après avoir fait un ajout avec le code cité dans l'autre fil:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DataModule1->CDSMail->CancelUpdates();
    toujours pareil !


    Voici la première version de mon destructeur qui soit codé ou pas j'ai toujours l'erreur
    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
    void __fastcall TDataModule1::FreeDataModule()
    {
     
    IBQPers->Close();
    CDSPers->Close();
     
    IBQTel->Close();
    CDSTel->Close();
     
    IBQMail->Close();
    CDSMail->Close();
     
    IBTransaction1->Active=false;
    IBDatabase->Close();
    }

    Je me pose une question est les agrégats sur la table secondaire peuvent jour et faire planter?

    J'aurais un question concernant les ApllyUpdate sur plusieurs tables
    mais j'attends de résoudre de cela

    bref la je ne voit plus comment faire

    encore merci et je suis complétement bloqué !
    Outils utilisés : FireBird 2.1 - IbExert Free - C++ Builder 6 Pro Update 4- Windows Xp pro Sp3

Discussions similaires

  1. Opération non applicable sur un TTable
    Par fpascal dans le forum C++Builder
    Réponses: 15
    Dernier message: 22/09/2008, 14h32
  2. Message d'erreur: 'Opération non applicable'
    Par souminet dans le forum Bases de données
    Réponses: 1
    Dernier message: 07/11/2007, 12h06
  3. Réponses: 7
    Dernier message: 03/05/2007, 16h30
  4. [D7][Oracle 8i] "Opération non applicable" + DataS
    Par Magnus dans le forum Bases de données
    Réponses: 3
    Dernier message: 17/11/2005, 08h36
  5. EBDClient "Opération non applicable"
    Par AKSEL dans le forum Composants VCL
    Réponses: 1
    Dernier message: 15/09/2005, 16h34

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