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

Oracle Discussion :

[8i][forms 6i] dupliquer un enregistrement


Sujet :

Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Par défaut [8i][forms 6i] dupliquer un enregistrement
    Bonjour,

    Dans un écran réalisé sous forms 6i, je souhaiterais permettre à l'utilisateur de dupliquer un enregistrement.

    Actuellement voici l'algorithme que j'utilise :
    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
    DECLARE
      /* déclaration d'autant de variables locales qu'il existe d'items base table */
    BEGIN
      GO_BLOCK('X_1');
      -- sauvegarde des items base table dans les variables temporaires déclarées à cet effet
     
      GO_BLOCK('X_2');
      -- sauvegarde des items base table dans les variables temporaires déclarées à cet effet
     
      GO_BLOCK('X_n');
      -- sauvegarde des items base table dans les variables temporaires déclarées à cet effet
     
      IF :SYSTEM.MODE = 'ENTER-QUERY' THEN
        CLEAR_FORM(NO_VALIDATE);
        EXIT_FORM(NO_VALIDATE);
      END IF;
      CREATE_RECORD;
     
      -- restauration des items table grâce aux variables temporaires
      ...
     
      EXECUTE_TRIGGER('KEY-COMMIT');
    END;
    Cette méthode qui fonctionne quasiment présente l'énorme inconvénient d'être étroitement liée aux structures des tables sous-jacentes.

    On ne peut pas faire mieux ?
    Merci d'avance à tou(te)s.

  2. #2
    Membre Expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Par défaut
    1. Peux-tu être plus précis, je ne comprends pas ce que tu veux faire.

    2. Je ne comprends pas à quoi sert :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      IF :SYSTEM.MODE = 'ENTER-QUERY' THEN 
        CLEAR_FORM(NO_VALIDATE); 
        EXIT_FORM(NO_VALIDATE); 
      END IF;
    Si tu es en mode ENTER-QUERY, la duplication sert à rien, non ?

    3. Il est conseillé d'utiliser
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    do_key ('COMMIT_FORM');
    plutôt que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    EXECUTE_TRIGGER('KEY-COMMIT');
    pour toutes les déclencheurs associés à des touches

  3. #3
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    n'y a-t-il pas une procédure DUPLICATE_RECORD en standard ?

  4. #4
    Membre Expert

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Par défaut
    Salut à vous 2 et merci du coup de main,

    Citation Envoyé par plaineR
    1. Peux-tu être plus précis, je ne comprends pas ce que tu veux faire.
    Admettons que l'utilisateur manipule l'écran en question qui contient un ensemble de données (base table ou non, peu importe ici) et que, pour des raisons de commodité, il décide de dupliquer toutes les données qu'il visualise car il souhaite modifier 1 ou 2 zones et conserver toutes les autres telles qu'elles ont été saisies dans "le modèle".
    Le bouton de duplication associé à ce code doit lui permettre de réaliser cette copie identique pour 90 % des données.

    Citation Envoyé par plaineR
    2. Je ne comprends pas à quoi sert :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      IF :SYSTEM.MODE = 'ENTER-QUERY' THEN 
        CLEAR_FORM(NO_VALIDATE); 
        EXIT_FORM(NO_VALIDATE); 
      END IF;
    Si tu es en mode ENTER-QUERY, la duplication sert à rien, non ?
    Je travaille sur forms que depuis quelques mois et dans un cadre bien précis : une grande quantité d'écrans résulte d'une migration de cobol et de forms 3 d'après ce qu'on m'a expliqué.
    Par conséquent, j'ai pu remarqué que pour créer un enregistrement dans un quelconque écran, il fallait systématiquement effectuer ce bout de code.
    Après le "END IF" la variable :SYSTEM.MODE vaut "NORMAL" et non "INSERT" ou "NEW" comme on pourrait s'y attendre...
    Je t'avouerai que ces subtilités m'ont surpris et me surprennent encore...

    Citation Envoyé par plaineR
    3. Il est conseillé d'utiliser
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    do_key ('COMMIT_FORM');
    plutôt que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    EXECUTE_TRIGGER('KEY-COMMIT');
    pour toutes les déclencheurs associés à des touches
    Thanks pour le conseil, ce choix résulte de la migration.

    Citation Envoyé par Fred_D
    n'y a-t-il pas une procédure DUPLICATE_RECORD en standard ?
    Heu...si.
    Je n'avais pas consulé la doc forms car je la trouve "obscure" dans certains cas et justement suite à ton conseil, voici ce que je lis à propos de cette méthode :
    Permet de copier la valeur de chaque élément de l'enregistrement portant le numéro de séquence précédent dans les éléments correspondants de l'enregistrement en cours. L'enregistrement en cours ne doit pas correspondre à une ligne de la base de données. Si c'est le cas, une erreur se produit.
    Remarque*: L'enregistrement en double n'hérite pas de l'état d'enregistrement de l'enregistrement source*; son état d'enregistrement est INSERT.
    Je ne comprends vraiment pas ce qu'est ce numéro de séquence dont ils parlent et qu'ils utilisent dans l'exemple associé.
    Tu peux m'en dire plus ?

  5. #5
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    j'ai pas forms sous la main et pas pratiqué depuis longtemps mais j'imagine que cela correspond au numéro du record sachant que le 1° du block a le numéro 1

    Il faut juste comprendre que cela permet de dupliquer la ligne précédente.

  6. #6
    Membre Expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Par défaut
    Citation Envoyé par Magnus
    Admettons que l'utilisateur manipule l'écran en question qui contient un ensemble de données (base table ou non, peu importe ici) et que, pour des raisons de commodité, il décide de dupliquer toutes les données qu'il visualise car il souhaite modifier 1 ou 2 zones et conserver toutes les autres telles qu'elles ont été saisies dans "le modèle".
    Le bouton de duplication associé à ce code doit lui permettre de réaliser cette copie identique pour 90 % des données.
    Dans ce cas duplicate_record doit en effet permettre de résoudre ton problème. Attention néanmoins aux blocks maître-détail.

    Citation Envoyé par Magnus
    Je ne comprends vraiment pas ce qu'est ce numéro de séquence dont ils parlent et qu'ils utilisent dans l'exemple associé.
    Tu peux m'en dire plus ?
    Le numéro de séquence correspond au numéro de l'enregistrement sur lequel tu es (:system.cursor_record).
    Dans l'exemple, c'est la clé unique de l'enregistrement (c'est juste pour rappeler qu'avant de commiter il faut la modifier )

  7. #7
    Membre Expert

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Par défaut
    Ok je comprends ce que vous dîtes mais en lisant la description fournie dans l'aide, j'ai l'impression que cette méthode s'applique (UNIQUEMENT ?) aux blocs de données non base table et probablement multi-enregistrements.
    Or, l'enregistrement du 1er bloc que je cherche à dupliquer contient des items base table et surtout ce 1er bloc de données n'affiche qu'un seul enregistrement à la fois.
    Par conséquent, je ne vois pas trop comment invoquer cette méthode

    Merci encore pour votre aide les gars.
    Citation Envoyé par Magnus
    Permet de copier la valeur de chaque élément de l'enregistrement portant le numéro de séquence précédent dans les éléments correspondants de l'enregistrement en cours. L'enregistrement en cours ne doit pas correspondre à une ligne de la base de données. Si c'est le cas, une erreur se produit.
    Remarque*: L'enregistrement en double n'hérite pas de l'état d'enregistrement de l'enregistrement source*; son état d'enregistrement est INSERT.

  8. #8
    Membre Expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Par défaut
    Citation Envoyé par Magnus
    j'ai l'impression que cette méthode s'applique (UNIQUEMENT ?) aux blocs de données non base table
    Absolument pas.

    Citation Envoyé par Magnus
    et probablement multi-enregistrements.
    Oui, mais uniquement dans le sens propriété "Single record" = false (et non dans le sens un seul enregistrement affiché).

    Citation Envoyé par Magnus
    Or, l'enregistrement du 1er bloc que je cherche à dupliquer contient des items base table et surtout ce 1er bloc de données n'affiche qu'un seul enregistrement à la fois.
    Par conséquent, je ne vois pas trop comment invoquer cette méthode
    En faisant quelque chose comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    BEGIN 
      GO_BLOCK('X_1'); 
      CREATE_RECORD;
      DUPLICATE_RECORD;
      GO_BLOCK('X_n'); 
      CREATE_RECORD;
      DUPLICATE_RECORD;
    CUTE_TRIGGER('KEY-COMMIT'); 
    END;

  9. #9
    Membre Expert

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Par défaut
    Ce n'est pas que je mette de la mauvaise volonté (loin de là) mais quand je bloque c'est pour de bon
    D'autre part, si je mets un certain temps à répondre c'est que je prends le temps de tester et que j'ai simplifié mon contexte - en particulier j'utilise des timers qui me déclenche des erreurs lorsque je n'invoque pas le key-commit explicitement.

    Donc, en résumé, j'ai réussi à écrire le code pour dupliquer mais je n'arrive vraiment pas à utiliser DUPLICATE_RECORD car :
    - il ne copie aucune valeur de mon enregistrement précédent et
    - j'obtiens un message d'erreur me demandant si je veux enregistrer mes modifications.

    Voici mon code (simplifié) avec en commentaire l'alternative que j'ai développée pour implémenter le traitement voulu (et qui pourrait donc être remplacé par une invocation de DUPLICATE_RECORD).

    Désolé, le Français ça n'est vraiment pas mon truc...
    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
    DECLARE
    	LC_an_type		B2800.AN_TYPE%TYPE;
    	LC_an_agre		B2800.AN_AGRE%TYPE;
    [...]
     
    BEGIN
    	IF MSG_BOX2('Voulez-vous réellement dupliquer cet enregistrement ?',
    							'Confirmation de duplication',
    							'ALERT_DEFAUT2') = '2' THEN
    		RETURN;
    	END IF;
     
    	-- bloc B2800
    	GO_BLOCK('B2800');
    /*
    	LC_an_type		:= :B2800.AN_TYPE;
    	LC_an_agre		:= :B2800.AN_AGRE;
    	LC_an_num			:= :B2800.AN_NUM;
    	LC_t48_lieu		:= :B2800.T48_LIEU;
    	LC_t49_aire		:= :B2800.T49_AIRE;
    	LC_em_num			:= :B2800.EM_NUM;
    	LC_em_niv			:= :B2800.EM_NIV;
    	LC_st_code		:= :B2800.ST_CODE;	
    	LC_tty_typvin	:= :B2800.TTY_TYPVIN;
    	LC_t17_coul		:= :B2800.T17_COUL;
    	LC_t15_appel	:= :B2800.T15_APPEL;
    	LL_an_comment	:= :B2800.AN_COMMENT;
    	LC_an_avis		:= :B2800.AN_AVIS;
    	LC_an_conf		:= :B2800.AN_CONF;
    	LC_an_raison	:= :B2800.AN_RAISON;
    	LN_an_nbnconf	:= :B2800.AN_NBNCONF;
    */
    	CREATE_RECORD;
    	DUPLICATE_RECORD;
     
    	CLEAR_FORM(NO_VALIDATE);
    	-- ATTENTION : suite au CLEAR_FORM, B0.TRA_MODE | TRA_ROW sont à NULL
    	-- tant que l'on n'a pas invoqué INIT_ECRAN
    	INIT_ECRAN;
     
    	IF :SYSTEM.MODE = 'ENTER-QUERY' THEN
    		EXIT_FORM(NO_VALIDATE);
    	END IF;
     
    	CREATE_RECORD;
     
    	BEGIN
    		-- génération AN_CODE
    		SELECT LPAD(S_AN_CODE.NEXTVAL, 8, '0')
    		INTO 	 :B2800.AN_CODE
    		FROM 	 DUAL;
    		EXCEPTION WHEN NO_DATA_FOUND THEN
    			RAISE FORM_TRIGGER_FAILURE;
    		WHEN TOO_MANY_ROWS THEN
    			RAISE FORM_TRIGGER_FAILURE;
    	END;
     
    	-- copie des variables temporaires (B2800)
    	:B2800.AN_TYPE  	:= LC_an_type;
    	:B2800.AN_AGRE		:= NULL;
    	IF LC_an_agre IS NOT NULL THEN
    		:B2800.AN_AGRE	:= 'A' || SUBSTR( :B2800.AN_CODE, (LENGTH(:B2800.AN_CODE)-1)*(-1) );
    	END IF;
    	:B2800.AN_NUM 		:= NULL;
    	IF LC_an_num IS NOT NULL THEN
    		:B2800.AN_NUM		:= 'B' || SUBSTR( :B2800.AN_CODE, (LENGTH(:B2800.AN_CODE)-1)*(-1) );
    	END IF;
    	:B2800.T48_LIEU		:= LC_t48_lieu;
    	:B2800.T49_AIRE		:= LC_t49_aire;
    	:B2800.EM_NUM			:= LC_em_num;
    	:B2800.EM_NIV			:= LC_em_niv;
    	:B2800.ST_CODE		:= LC_st_code;
    	:B2800.TTY_TYPVIN	:= LC_tty_typvin;
    	:B2800.T17_COUL		:= LC_t17_coul;
    	:B2800.T15_APPEL	:= LC_t15_appel;
    	:B2800.AN_COMMENT	:= LL_an_comment;
    	:B2800.AN_AVIS		:= LC_an_avis;
    	:B2800.AN_CONF		:= LC_an_conf;
    	:B2800.AN_RAISON	:= LC_an_raison;
    	:B2800.AN_NBNCONF	:= LN_an_nbnconf;
     
    	DO_KEY('COMMIT_FORM');
    END;

  10. #10
    Membre Expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Par défaut
    Citation Envoyé par Magnus
    - il ne copie aucune valeur de mon enregistrement précédent
    tu fais un clear_form après avoir dupliqué ton enregistrement avec duplicate_record;

    Citation Envoyé par Magnus
    - j'obtiens un message d'erreur me demandant si je veux enregistrer mes modifications.
    Je pense que cela vient une fois encore du clear_form :
    les modifications du duplicate_record ne sont pas enregistrées.

    Citation Envoyé par Magnus
    Désolé, le Français ça n'est vraiment pas mon truc...
    On a vu bien pire

  11. #11
    Membre Expert

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Par défaut
    Citation Envoyé par plaineR
    Citation Envoyé par Magnus
    - il ne copie aucune valeur de mon enregistrement précédent
    tu fais un clear_form après avoir dupliqué ton enregistrement avec duplicate_record;
    Ah ben oui

    Avec l'appel bien placé, j'ai quasiment le comportement voulu.
    Le dernier inconvénient qu'il reste est un message me demandant si je veux enregistrer mes modifications bien que j'ai supprimé l'appel à CLEAR_FORM.

    Voici le code actuel :
    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
    BEGIN
    	IF :SYSTEM.MODE = 'ENTER-QUERY' THEN
    		EXIT_FORM(NO_VALIDATE);
    	END IF;
     
    	GO_BLOCK('B2800');
    	CREATE_RECORD;
    	DUPLICATE_RECORD;	
     
    	BEGIN
    		-- génération AN_CODE
    		SELECT LPAD(S_AN_CODE.NEXTVAL, 8, '0')
    		INTO 	 :B2800.AN_CODE
    		FROM 	 DUAL;
    		EXCEPTION WHEN NO_DATA_FOUND THEN
    			RAISE FORM_TRIGGER_FAILURE;
    		WHEN TOO_MANY_ROWS THEN
    			RAISE FORM_TRIGGER_FAILURE;
    	END;
     
    	MSG_BOX('L''identifiant attribué au duplicata est : ' || :B2800.AN_CODE);
    	DO_KEY('COMMIT_FORM');
    END;
    PS : tu as remarqué l'appel à DO_KEY et non à EXECUTE_TRIGGER ?

  12. #12
    Membre Expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Par défaut
    Citation Envoyé par Magnus
    Le dernier inconvénient qu'il reste est un message me demandant si je veux enregistrer mes modifications bien que j'ai supprimé l'appel à CLEAR_FORM.
    N'as-tu pas une relation maître détail ?
    Sinon, il faudrait repérer à quel moment il te demande d'enregistrer les modifications...

    Citation Envoyé par Magnus
    PS : tu as remarqué l'appel à DO_KEY et non à EXECUTE_TRIGGER ?
    Oui, oui, j'ai vu !

  13. #13
    Membre Expert

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Par défaut
    Citation Envoyé par plaineR
    N'as-tu pas une relation maître détail ?
    Effectivement
    Dans ce cas je comprends mieux pourquoi ma solution n'est pas complètement fonctionnelle : lorsque je duplique un enregistrement dans le bloc maitre alors cette relation maitre détail détecte une anomalie car il n'existe pas d'enregistrement dans le bloc détail connexe ?

    Pourtant, j'ai aussi dupliqué les données du bloc détail (pour lequel je ne peux pas utiliser la méthode DUPLICATE_RECORD).
    Remarque : comme ce bloc détail n'est pas concerné par la méthode DUPLICATE_RECORD alors j'ai supprimé tout ce qui le concerne dans mes extraits de codes.

    1/ Par conséquent, cette technique n'est peut être pas la bonne - ou à compléter - pour satisfaire cette relation maitre / détail ?

    2/ Enfin, même si la solution avec DUPLICATE_RECORD n'est pas encore parfaite, un point m'échappe encore : que vient faire le CURSOR_RECORD ou line_sequence qu'ils mettent à jour dans l'exemple de la doc ? Pour l'instant, je ne mets à jour aucun indicateur de numéro d'enregistrement.

    PS : j'ai essayé d'incrémenter :SYSTEM.CURSOR_RECORD après l'invocation de DUPLICATE_RECORD mais cette variable système n'est accessible qu'en consultation.

  14. #14
    Membre Expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Par défaut
    Quand j'ai un relation maître-détail, voici ce que je fais (je ne sais pas si c'est la meilleure méthode, mais cela a l'avantage de fonctionner) :
    1. Je regarde pour si pour au moins un des blocs détail qui doit être dupliqué si le statut a changé. Si c'est le cas je demande a l'utilisateur s'il veut committer avant de dupliquer.
    2. Je duplique le bloc maître avec duplicate_record
    3. Je duplique les blocs détail avec des insert ... select ...
    4. Je raffraichis tous les blocs détail avec execute_query.

    NB : si la clé de la relation est une séquence, je la change a l'étape 2 pour la reporter sur les blocs détail. Si c'est une clé fonctionnelle, je demande avant de commencer ma phase de duplication vers quelle(s) valeur(s) dupliquer.

  15. #15
    Membre Expert

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Par défaut
    Citation Envoyé par plaineR
    Quand j'ai un relation maître-détail, voici ce que je fais (je ne sais pas si c'est la meilleure méthode, mais cela a l'avantage de fonctionner) :
    1. Je regarde pour si pour au moins un des blocs détail qui doit être dupliqué si le statut a changé. Si c'est le cas je demande a l'utilisateur s'il veut committer avant de dupliquer.
    2. Je duplique le bloc maître avec duplicate_record
    3. Je duplique les blocs détail avec des insert ... select ...
    4. Je raffraichis tous les blocs détail avec execute_query.

    NB : si la clé de la relation est une séquence, je la change a l'étape 2 pour la reporter sur les blocs détail. Si c'est une clé fonctionnelle, je demande avant de commencer ma phase de duplication vers quelle(s) valeur(s) dupliquer.
    Ok.
    J'ai enfin tout compris : cette relation maitre / détail implique que soit :
    - je ne fais pas appel à CLEAR_FORM et dans ce cas un message demande à l'utilisateur s'il veut enregistrer ces modifications
    - je fais appel à CLEAR_FORM et dans ce cas je n'ai pas de message d'interaction mais alors le DUPLICATE_RECORD n'a plus aucune donnée à copier car elles ont été effacées par l'appel à CLEAR_FORM.

    Conclusion : si je veux utiliser cette méthode je suis obligé de demander à l'utilisateur à un moment ou à un autre d'enregistrer ses modifications.
    Comme je ne souhaite pas d'interaction avec l'utilisateur (et donc que ses modifications ne soient pas sauvegardées), je vais conserver la solution où je "réinvente la roue" c'est-à-dire que je duplique manuellement chaque item.

    Merci encore pour ta patience et la clarté de tes explications plaineR.

  16. #16
    Membre Expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Par défaut
    Tu peux également faire un clear_block (no_validate) pour les blocs détail, dans ce cas tu n'auras pas d'intéraction avec l'utilisateur, et le duplicate_record fonctionnera pour le bloc maître

  17. #17
    Membre Expert

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Par défaut
    Citation Envoyé par plaineR
    Tu peux également faire un clear_block (no_validate) pour les blocs détail, dans ce cas tu n'auras pas d'intéraction avec l'utilisateur, et le duplicate_record fonctionnera pour le bloc maître
    Je n'ai pas testé mais il devrait dupliquer sans message d'erreur mais aussi sans données à cause du CLEAR_FORM

    C'est pour cela que ma technique fonctionne et c'est ce qui me fait dire que, dans mon contexte, je ne peux (dois ?) pas invoquer DUPLICATE_RECORD.
    En effet, peu importe que le CLEAR_FORM efface le contenu de chaque item dans la mesure où j'ai sauvegardé ces valeurs dans des variables temporaires et d'autre part, ce CLEAR_FORM m'évite l'apparition d'un message destiné à l'utilisateur lui demandant s'il veut sauvegarder ses modifications.

    Que penses-tu de mon raisonnement ?

  18. #18
    Membre Expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Par défaut
    Je te parlais de CLEAR_BLOCK et non de CLEAR_FORM

  19. #19
    Membre Expert

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Par défaut
    Citation Envoyé par plaineR
    Je te parlais de CLEAR_BLOCK et non de CLEAR_FORM
    Encore une victoire de plaineR car voici le traitement que je cherchais à mettre en place AVEC duplicate_record :
    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
    DECLARE
      TYPE TREC_pa  IS RECORD (LC_t37_code		 B2801.T37_CODE%TYPE,
      												 LC_ta_lib  		 B0300.TA_LIB%TYPE,
      												 LC_an1_montant  B2801.AN1_MONTANT%TYPE,
                               LC_an1_libel    B2801.AN1_LIBEL%TYPE,
                               LC_an1_type		 B2801.AN1_TYPE%TYPE,
                               LC_t37_ordre 	 B2801.T37_ORDRE%TYPE);
      TYPE LTY_tbl  IS TABLE OF TREC_pa INDEX BY BINARY_INTEGER;
      LTY_t         LTY_tbl;
      LN_i          BINARY_INTEGER := 0;
      CURSOR LCU_2801 IS
    		SELECT 	 T37_CODE, TA_LIB, AN1_MONTANT, AN1_LIBEL, AN1_TYPE, T37_ORDRE
    		FROM 		 B2801, B0300
    		WHERE 	 AN_CODE  = :B2800.AN_CODE
    		AND			 TA_TABLE = '37'
    		AND			 TA_CODE  = T37_CODE
    		ORDER BY T37_ORDRE;
    BEGIN
    	-- bloc B2800
    	GO_BLOCK('B2800');
     
    	-- bloc B2801
      OPEN LCU_2801;
      LOOP
        LN_i := LN_i + 1;
        FETCH LCU_2801 INTO LTY_t(LN_i);
        EXIT WHEN LCU_2801%NOTFOUND;
      END LOOP;
      CLOSE LCU_2801;
     
    	GO_BLOCK('B2801');
    	CLEAR_BLOCK(NO_VALIDATE);
    	GO_BLOCK('B2800');
     
    	CREATE_RECORD;
    	DUPLICATE_RECORD;
     
    	BEGIN
    		-- génération AN_CODE
    		SELECT LPAD(S_AN_CODE.NEXTVAL, 8, '0')
    		INTO 	 :B2800.AN_CODE
    		FROM 	 DUAL;
    		EXCEPTION WHEN NO_DATA_FOUND THEN
    			RAISE FORM_TRIGGER_FAILURE;
    		WHEN TOO_MANY_ROWS THEN
    			RAISE FORM_TRIGGER_FAILURE;
    	END;
     
    	-- bloc B2801
    	DESACTIVER_AN_TYPE;
     
    	-- copie des variables temporaires (B2801)
    	GO_BLOCK('B2801');
      FOR LN_i IN LTY_t.FIRST..LTY_t.LAST
      LOOP
    		CREATE_RECORD;
    		:B2801.AN_CODE 			:= :B2800.AN_CODE;
    		:B2801.T37_CODE 		:= LTY_t(LN_i).LC_t37_code;
    		:B2801.TA_LIB				:= LTY_t(LN_i).LC_ta_lib;
    		:B2801.AN1_MONTANT 	:= LTY_t(LN_i).LC_an1_montant;
    		:B2801.AN1_LIBEL 		:= LTY_t(LN_i).LC_an1_libel;
    		:B2801.AN1_TYPE 		:= LTY_t(LN_i).LC_an1_type;
    		:B2801.T37_ORDRE 		:= LTY_t(LN_i).LC_t37_ordre;
    	END LOOP;
     
    	FIRST_RECORD;
    	GO_ITEM('B2800.T48_LIEU');
     
    	MSG_BOX('L''identifiant attribué au duplicata est : ' || :B2800.AN_CODE);
    	DO_KEY('COMMIT_FORM');
    END;

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

Discussions similaires

  1. dupliquer un enregistrement dans un table liée
    Par RICHARDSEBIRE dans le forum Access
    Réponses: 9
    Dernier message: 24/02/2006, 11h57
  2. Réponses: 7
    Dernier message: 29/11/2005, 11h07
  3. Comment dupliquer un enregistrement via le code ?
    Par massol joel dans le forum Access
    Réponses: 2
    Dernier message: 11/11/2005, 19h01
  4. Dupliquer un enregistrement complet d'une table paradox
    Par sylvie cl dans le forum Bases de données
    Réponses: 10
    Dernier message: 21/09/2005, 14h16
  5. Réponses: 7
    Dernier message: 06/10/2004, 22h13

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