Pb objet Eaccess violation 004B8620 [Résolu]

martChamp 6 Messages postés lundi 16 octobre 2006Date d'inscription 24 janvier 2007 Dernière intervention - 23 janv. 2007 à 17:28 - Dernière réponse : martChamp 6 Messages postés lundi 16 octobre 2006Date d'inscription 24 janvier 2007 Dernière intervention
- 24 janv. 2007 à 14:26
Bonjour à tous,

Dans un programme que je devellope, j'utilise une classe objet (intervenant) qui a pour attribut un tableau d'objet (poste)

Description class intervenant

   type
       intervenant = class ( TObject )



   private



       Nom : string;
       Prenom : string;
       Adresse1 : string;
       Adresse2 : string;
       Email : string;
       DateNaiss : string;
       LieuNaiss : string;
       Nationalite : String;
      NumSecu : string;
       NumConge : string;
       Tel : string;
       Fax : string;
       Portable : string;
       DateEmbauche : string;
       lesposte : Array of poste;
       nbposte : integer;


Plus loing dans une procedure je me sert de ma base de donnée pour initialiser mon objet intervenant



procedure intervenant.loadSQL(idinter : integer);



begin
    with bdd.ModuleBDD.ADOQuery_traitementint do
     begin
          Active := false;
          SQL.Clear;
          SQL.Add('SELECT * FROM intervenant WHERE idintervenant LIKE "'+ inttostr(idinter) +'"');
          Active := true;
      end;



  Adresse1 := bdd.ModuleBDD.ADOQuery_traitementint.fields[3].AsString;
  Nationalite  := bdd.ModuleBDD.ADOQuery_traitementint.fields[11].AsString;
  LieuNaiss := bdd.ModuleBDD.ADOQuery_traitementint.fields[10].AsString;
  Adresse2 := bdd.ModuleBDD.ADOQuery_traitementint.fields[4].AsString;
  Tel := bdd.ModuleBDD.ADOQuery_traitementint.fields[5].AsString;
  Fax := bdd.ModuleBDD.ADOQuery_traitementint.fields[6].AsString;
  Portable := bdd.ModuleBDD.ADOQuery_traitementint.fields[7].AsString;
  Email := bdd.ModuleBDD.ADOQuery_traitementint.fields[8].AsString;
  Nom := bdd.ModuleBDD.ADOQuery_traitementint.fields[1].AsString;
  Prenom := bdd.ModuleBDD.ADOQuery_traitementint.fields[2].AsString;
  DateNaiss := bdd.ModuleBDD.ADOQuery_traitementint.fields[9].AsString;
  NumSecu := bdd.ModuleBDD.ADOQuery_traitementint.fields[12].AsString;
  NumConge := bdd.ModuleBDD.ADOQuery_traitementint.fields[13].AsString;
  dateEmbauche := bdd.ModuleBDD.ADOQuery_traitementint.fields[14].AsString;



  with bdd.ModuleBDD.ADOQuery_traitementint do
   begin
       Active := false;
       SQL.Clear;
       SQL.Add('SELECT nomposte, cnc, idintervenant FROM intervenant_poste, poste WHERE    intervenant_poste.numposte = poste.numposte AND idintervenant LIKE "'+ inttostr(idInter) +'"');
       Active := true;
       first;
       while not eof do
       begin
         nbposte := nbposte + 1;
         lesposte[nbposte] := poste.creer(bdd.ModuleBDD.ADOQuery_traitementint.fields[2].AsInteger,idinter,bdd.ModuleBDD.ADOQuery_traitementint.fields[0].AsString,bdd.ModuleBDD.ADOQuery_traitementint.fields[1].AsString);
      next;
    end;
   end;
end;


Delphi me fait une erreur eaccess violation a la ligne mis en rouge, je ne vois pas pk, je pensse que cela vien d'un probléme de pointeur!!!

Je compte sur vous pour méclairer dautant que je suis debutant un delphi.
Merci d'avance
Afficher la suite 

7 réponses

Répondre au sujet
cs_Delphiprog 4580 Messages postés samedi 19 janvier 2002Date d'inscription 9 janvier 2013 Dernière intervention - 23 janv. 2007 à 20:00
+3
Utile
Ton Tableau lesposte n'est pas dimensionné !

1/ Soit tu lui attribues une taille dans le constructeur de la classe intervenant si tu la connais lors de l'instanciation d'un objet intervenant. Au passge, essaie d'utiliser la convention d'écriture utilisée par Borland en mettant un "T" devant le nom de la classe. Cela permet de distinguer entre l'instance de la classe et la classe et d'éviter les erreurs de débutants.

2/ soit tu le dimensionnes automatiquement dans le code
       begin
         nbposte := nbposte + 1;
        //redimensionner le tableau dynamiquement
        SetLength(lesposte, nbposte);
         lesposte[nbposte] := poste.creer(bdd.ModuleBDD.ADOQuery_traitementint.fields[2].AsInteger,idinter,bdd.ModuleBDD.ADOQuery_traitementint.fields[0].AsString,bdd.ModuleBDD.ADOQuery_traitementint.fields[1].AsString);
      next;

3/ soit tu utilises un descendant de la classe TObject comme TList, TComponentList ou TObjectList, etc qui facilite la gestion des références et la désallocation de mémoire de manière automatique...

De grâce, utilises le mot clé With pour alléger ton code et le rendre plus lisible...

Un dernier conseil : évites d'utiliser les champs par leur index  retournés par une requête. Si ta base est restructurée, tout ton code est à revoir... 
Exemple : au lieu de
Adresse1 := bdd.ModuleBDD.ADOQuery_traitementint.fields[3].AsString;
Tu peux écrire :
with bdd.ModuleBDD.ADOQuery_traitementint do
begin
  Adresse1 := FieldByName('Adresse1').AsString;
  //...la suite
end;
De cette manière le code est largement plus lisible et plus facile à maintenir.

Enfin ,si je puis me permettre un dernier conseil d'optimisation, est-ce bien utile d'utiliser un prédicat comme Like (très gourmand en temps de traitement) dans tes requêtes SQL quand il ne s'agit que de comparer avec une valeur entière ?
'SELECT * FROM intervenant WHERE idintervenant LIKE "'+ inttostr(idinter) +'"'
Suggestion :
'SELECT * FROM intervenant WHERE idintervenant = '+ inttostr(idinter) +'''

Bon courage pour la suite

May Delphi be with you !
<hr color="#008000" />
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
http://www.afipa.net/
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de cs_Delphiprog
jace1975 84 Messages postés mardi 31 mai 2005Date d'inscription 12 octobre 2007 Dernière intervention - 23 janv. 2007 à 19:38
0
Utile
yo,

déjà ton code pas très clair avec tes dd.ModuleBDD.ADOQuery_traitementint
bon c'est pas tres grave mais c'est chiant a lire sur 20 lignes alors 50000 je te raccontes pas

sur ton problème, je vois deux choses  :
- tu utilises un objet poste, mis je ne vois pas dans ton code un truc du genre
poste:=tposte.create( param);

donc forcément tu essaye d'acceder à une procédure de ton objet poste qui n'a pas été défini en mémoire donc....

- array of poste , mouais pourquoi pas mais ton tableau n'est jamais défini ni dynamiquement ni à la déclaration donc ca risque de coincer aussi ici  ( perso y'a longtemps que j'ai abandonné les array pour gérer des object -> tobjectlist )

tschusssss
Commenter la réponse de jace1975
Guillemouze 1015 Messages postés samedi 25 octobre 2003Date d'inscription 29 août 2013 Dernière intervention - 23 janv. 2007 à 19:55
0
Utile
il faut que tu fasse un SetLength(lesposte, TAILLE) pour allouer des emplacements memoire à ton tableau dynamique.
NB: les indices de ton tableau commencent à 0.
NB : jette un coup d'oeil a l'aide : tableaux dynamiques = > tableaux dynamiques (Reference du langage delphi)

nbPoste := 0;
with bdd.ModuleBDD.ADOQuery_traitementint do
   begin
       Active : = false;
       SQL.Clear;
       SQL.Add('SELECT
nomposte, cnc, idintervenant FROM intervenant_poste, poste
WHERE    intervenant_poste.numposte = poste.numposte AND idintervenant
LIKE "'+ inttostr(idInter) +'"');
       Active := true;
       first;
       while not eof do
       begin
         nbposte := nbposte + 1;
       setLength(lesposte, nbposte);
         lesposte[nbposte -1 ]
: =
poste.creer(bdd.ModuleBDD.ADOQuery_traitementint.fields[2].AsInteger,idinter,bdd.ModuleBDD.ADOQuery_traitementint.fields[0].AsString,bdd.ModuleBDD.ADOQuery_traitementint.fields[1].AsString);
      next;
    end;
   end;
Commenter la réponse de Guillemouze
cs_Delphiprog 4580 Messages postés samedi 19 janvier 2002Date d'inscription 9 janvier 2013 Dernière intervention - 23 janv. 2007 à 20:04
0
Utile
Erratum : au lieu de :
lesposte[nbposte] := poste.creer(bdd.ModuleBDD.ADOQuery_traitementint.fields[2].AsInteger,idinter,bdd.ModuleBDD.ADOQuery_traitementint.fields[0].AsString,bdd.ModuleBDD.ADOQuery_traitementint.fields[1].AsString);

Il faut lire :
lesposte[nbposte - 1] := poste.creer(bdd.ModuleBDD.ADOQuery_traitementint.fields[2].AsInteger,idinter,bdd.ModuleBDD.ADOQuery_traitementint.fields[0].AsString,bdd.ModuleBDD.ADOQuery_traitementint.fields[1].AsString);

Je suis tout à fait d'accord avec jayce1975 pour dire ques tableaux c'est bien et qu' il y a très longtemps que je ne les utilise plus non plus.

May Delphi be with you !
<hr color="#008000" />
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
http://www.afipa.net/
Commenter la réponse de cs_Delphiprog
Guillemouze 1015 Messages postés samedi 25 octobre 2003Date d'inscription 29 août 2013 Dernière intervention - 23 janv. 2007 à 20:07
0
Utile
j'ai ete si lonb que ca a repondre !!!

@jace :
    - je ne vois pas de variable "poste", je vois bien un intervenant.loadSQL. Et si l'objet n'existait pas, ca aurait planté sur une ligne precedente, comme Adresse1 := bdd.ModuleBDD.ADOQuery_traitementint.fields[3].AsString; par exemple
    - il est vrai que dans ce cas, une TObjectList serait plus appropriée

De plus je ne vois pas de fermeture de tes requetes SQL.
un petit ADOQuery_traitementint.freeou un ADOQuery_traitementint.active := false; ferait pas de mal.
Commenter la réponse de Guillemouze
Guillemouze 1015 Messages postés samedi 25 octobre 2003Date d'inscription 29 août 2013 Dernière intervention - 23 janv. 2007 à 20:17
0
Utile
je crois qu'il y a un leger souci de conception, la condition
idintervenant LIKE "'+ inttostr(idinter) +'"
me semble tres etrange.
En effet, l'utilisation du like et des guillemets me laissent penser que c'est un champ texte, et que martChamp utilise seulement des entiers dans ce champ. Ou est donc l'interet de ne pas utiliser un champ de type entier qui sera beaucoup plus rapide pour ces traitements?!!

Une autre petite remarque (pour delphiprog notament) : je suis d'accord que l'utilisation du like dans ce cas est completement sans interet, mais je pense qu'un SGBD digne de ce nom doit etre capable de voir qu'il n'y a pas de caractere "%" dans la valeur, et donc qu'il faut simplement le remplacer par un "=" pour obtenir le meme resultat.
Commenter la réponse de Guillemouze
martChamp 6 Messages postés lundi 16 octobre 2006Date d'inscription 24 janvier 2007 Dernière intervention - 24 janv. 2007 à 14:26
0
Utile
bonjour et mercie beaucoup pour votre reponsse sa marche ainssi, il et clair qu'avec un type tobjectlist se serait plus simple, je vais me pencher la dessus.
Enfin mercie encor de m'avoir débloquer , longue vie a la prog
Commenter la réponse de martChamp

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.