Boucle pour modifier le statut d'une partie seulement des champs existants  (Lu 136 fois) Partager ce sujet Imprimer

1 B


Merlin  08 septembre 2017 : 12:29

Est-ce que le problème viendrait du fait que les pages sont toutes des templates ???
C'est une bonne question.
Effectivement, quand j'utilise un script pour numéroter les pages issues d'un template il y a une subtilité pour désigner les numéros de pages en JavaScript.
Je vais regarder ça…

IP archivée


passifacile  07 septembre 2017 : 18:10

Ça marche, mais ça ne marche pas...

Le script, sur un document de 3 pages et env. 300 champs fonctionne parfaitement.

Sur un document de plusieurs centaines de pages et plusieurs milliers de champs, ça reset tous les champs. :mur:
(vive le copier-coller  :Smiley08:)


Est-ce que le problème viendrait du fait que les pages sont toutes des templates ???


IP archivée


passifacile  07 septembre 2017 : 06:33

Je teste dans la journée et reviens avec les nouvelles du front !

IP archivée


Merlin  07 septembre 2017 : 01:06

Avant d'aller plus loin, puisqu'apparement c'est l'array qui sature au niveau mémoire on peut toujours essayer de s'en passer.
Essaye ça (non testé) :

function resetFieldsOnPage(p) {
this.delay = true;
for (var i=0; i<this.numFields; i++) {
var f = this.getField(this.getNthFieldName(i));
if (f == null) {continue;}
if (f.page == p && f.type == "text") {f.readonly = true;}
}
this.delay = false;
}

Pour réinitialiser les champs de la page 1 on appelle la fonction avec :
resetFieldsOnPage(0);

IP archivée


passifacile  06 septembre 2017 : 23:30

Bheu ?
Vais me coucher et reprendrai demain.
Je crois que c'est mon esprit qui doit être plus clair...
 :Smiley01:
Bonne soirée et merci.

IP archivée


Merlin  06 septembre 2017 : 23:20

Mais pourquoi vérifier si le champ est déjà verrouillé (readonly, c'est bien ça?) ?
Parce-que tu dis qu'on ne peut pas verrouiller plusieurs milliers de champs à la fois.
Donc l'idée c'est de les verrouiller par tranche de 300 à la fois puisque ça c'est possible.

S'il y a 3000 champs sur la page, la boucle doit boucler 10 fois de suite sur 300 champs. Dans ce cas ce qui va différencier les champs à traiter de ceux qui ont déjà été traités c'est justement la propriété qu'on vient de modifier (verrouillé ou non).

Si la boucle ne détecte pas les champs qui ont déjà été modifiés par la boucle précédente elle va tourner en boucle infinie sur les 300 premiers champs rencontrés, qu'ils soient verrouillées ou non.

Est-ce plus clair ?

IP archivée


passifacile  06 septembre 2017 : 22:46

Oui, je vois bien le principe.

Mais pourquoi vérifier si le champ est déjà verrouillé (readonly, c'est bien ça?) ?

Est-ce gênant de verrouiller un champ déjà verrouillé ?

IP archivée


Merlin  06 septembre 2017 : 20:11

Il est vrai qu'Acrobat est connu pour sa gestion facétieuse de la mémoire dès qu'il y a débordement…

Si je devais faire ça, je garderais le même script en lui ajoutant deux conditions :
- ne pas dépasser 300 champs (par exemple à tester) dans la boucle pour éviter de saturer la mémoire,
- dans la boucle vérifier, en plus de son type, que le champ ne soit pas déjà verrouillé avant de le rentrer dans l'array.

De façon à répéter la boucle en boucles de 300 champs jusqu'à épuisement des champs non-verrouillés.

Est-ce que je suis clair ?

IP archivée


passifacile  06 septembre 2017 : 19:48

Ça marche, mais ça ne marche pas...

Le script, sur un document de 3 pages et env. 300 champs fonctionne parfaitement.

Sur un document de plusieurs centaines de pages et plusieurs milliers de champs, ça reset tous les champs. :mur:


IP archivée


Merlin  06 septembre 2017 : 09:37

Cessons de parler de faux problèmes qui dérivent d'une mauvaise solution, j'ai retrouvé ce script (non testé) qui permet de réinitialiser les champs sur une seule page.
Il ne reste qu'à modifier la dernière ligne de la fonction pour qu'elle verrouille les champs au lieu de les réinitialiser :
function resetFieldsOnPage(p) {
var fields = [];
for (var i=0; i<this.numFields; i++) {
var f = this.getField(this.getNthFieldName(i));
if (f==null) {continue;}
if (f.page==p) {fields.push(f.name);}
}
this.resetForm(fields);
}


Pour réinitialiser les champs de la page 1 on appelle la fonction avec :
resetFieldsOnPage(0);

 :Smiley15:

IP archivée


passifacile  06 septembre 2017 : 07:29

 :Smiley01: :Smiley01: :Smiley01: :Smiley01:

Ça marche parfaitement ! Merci.

MAIS

ayant (beaucoup) de champs avec hiérarchie (champ.0  /  champ.1) etc., la fonction    if ((oFld.name == "champ")...., le script ne fonctionne plus (j'ai l'impression qu'il a besoin du nom complet, et non pas uniquement du nom générique).
Suis-je obligé de préciser tous les noms de champ (.0, .1, .2, .3 ......  etc.) ?


IP archivée


Merlin  05 septembre 2017 : 23:44

C'est déjà bien que cette boucle arrive à tester quelque chose… :geek:

- Quand on déclare une variable (f) il faut l'utiliser.
- Il manque des parenthèses et des accolades dans la condition if
- Ce n'est pas la valeur (value) du champ qu'il faut tester mais son nom (name).

Ça fonctionne mieux ainsi :
for (var i=0; i<this.numFields; i++) {
var f = this.getField(this.getNthFieldName(i));
if ((f.name == "aaaa") || (f.name == "bbbb")) {
   app.alert("Ce message devrait s'afficher 2 fois");
}
}


Que je préfère écrire ainsi pour ne jamais oublier que la variable oFld est un "objet champ", et donc ni une valeur ni une chaine de caractères :
for (var i=0; i<this.numFields; i++) {
var oFld = this.getField(this.getNthFieldName(i));
if ((oFld.name == "aaaa") || (oFld.name == "bbbb")) {
   app.alert("Ce message devrait s'afficher 2 fois");
}
}

 :Smiley15:

IP archivée


passifacile  05 septembre 2017 : 22:31

Bonsoir, Merlin.

Je ne peux malheureusement pas appliquer ce type de méthode particulièrement sophistiquée ( :Smiley03: :Smiley01:) car le script doit être exploitable par l'utilisateur avec Reader.

Et le script suivant ne fonctionne pas :
for (var i=0; i<this.numFields; i++) {
var f = this.getField(this.getNthFieldName(i));
if(this.getNthFieldName(i)).value=="aaaa" || (this.getNthFieldName(i)).value=="bbbb")
app.alert("Ce message devrait s'afficher 2 fois, une fois à chaque rencontre d'un champ portant l'un des noms du 'if'");
}


la boucle semble ne tester que le premier nom de champ...

Je vais tâcher de créer un petit fichier d'exemple, à moins que le script ci-dessus ne puisse être facilement adapté par un (très) grand Magicien  :Smiley00:

IP archivée


Merlin  04 septembre 2017 : 23:37

Bonjour.

J'ai une méthode très simple pour ne traiter que les champs d'une seule page, ou bien pour exclure tous les champs d'une page.

Dans le premier cas je coupe les champs concernés et je les colle dans un nouveau document, j'exécute mon script, et ensuite re-couper-coller pour replacer les champs dans le document d'origine.

Dans le 2e cas je fais pareil, sauf que j'exécute le script dans le document d'origine.

C'est de la programmation de haut niveau !
 :Smiley03:

IP archivée


passifacile  04 septembre 2017 : 20:04

Bonjour,

Je cherche à modifier le statut de tous les champs d'une, ou plusieurs pages, à l'aide d'une boucle.
Je sais faire pour tous les champs, mais pas pour une partie d'entre-eux :
for (var i=0; i<this.numFields; i++) {
var f = this.getField(this.getNthFieldName(i));
if (f==null) continue;
f.readonly=false;


Je ne peux pas renommer tous les champs (pour pouvoir faire tourner la boucle en filtrant sur les noms de champs, (par exemple : tous les champs, sauf "Page1.")) en raison du travail déjà réalisé et du trop grand nombre de champs.

S'agissant des 300 champs de la dernière page, j'ai pensé que la condition "for (var i=0; i<this.numFields; i++)-300" suffirait. Seulement, la boucle tourne par ordre alphabétique des champs existants...

Si un filtre des champs par page n'est pas possible, je pourrais envisager, en dernier recours, de renommer les champs (en ajoutant "zzz" devant leur nom actuel) de la dernière page pour pouvoir les exclure.
Ou, encore, d'exclure dans la boucles tous les champs de la dernière page... comme suit :

for (var i=0; i<this.numFields; i++) {
var f = this.getField(this.getNthFieldName(i));
if (f==null) continue;
if(this.getNthFieldName(i)).value!="aaaa" || (this.getNthFieldName(i)).value!="aaaa")
f.readonly=false;


Cordialement,


IP archivée