cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Choose Language Hide Translation Bar
hcarr01
Level VI

Script

Bonjour à tous,
 
Je dispose d’une base de données dans laquelle j’aimerais créer une nouvelle colonne à partir d’une formule ou d’un script.
 
Voici un aperçu de la base de données :
 
hcarr01_1-1689685617209.png

 

- la colonne T représente des opérations à effectuer
- la colonne X_3 représente une particularité
- La colonne op représente des objets
 
Le but est de créer une colonne « bilan » dans laquelle on ajoute « ko » et le numéro correspondant à « op » lorsque la somme des défauts est différente de 0 d’une ligne à une autre pour un même « obj » (ici valeur égale à A).
 
Dernière particularité, la colonne bilan doit être remplie pour la numéro des opérations « 3061 ».
Il s’agit ici d’un aperçu de la base de données, la colonne obj vaut « A » mais dans la base de données cette colonne change de valeur.
 
Merci pour vos réponses !
27 REPLIES 27
hcarr01
Level VI

Re: Script

Dans la base de données, les valeurs de la colonne :T ne sont pas forcement rangés dans l'ordre croissant pour un même type d'objet. C'est une autre colonne :OPE qui elle, ses éléments sont rangés dans l'ordre croissant. Les colonnes :T et :OPE sont étroitement liées, elles sont uniques pour chaque type d'objet.
 
Les :OPE qui sont inférieures aux valeurs :OPE correspondantes à la valeur 3061 on ne doit rien mettre dans la colonne bilan.
Lorsque les valeurs de :OPE sont supérieures aux valeurs :OPE correspondantes à la valeur 3061 alors on réalise l'opération déjà décrite dans les premiers messages.
 
Voir la BD ci-dessous comme exemple :
 
hcarr01_0-1689749640225.png

 


 

 

Merci pour vos réponses !!

jthi
Super User

Re: Script

Add additional checks for :OPE values. If :OPE value for row is lower than the :OPE value for "3061" ignore it. It might be a bit difficult to keep track with different indices and rows, but adding debug prints helps with this. Also if there can be more than one "3061" for one object, the calculation gets more complicated.

-Jarmo
hcarr01
Level VI

Re: Script

Oui je vois ce que vous voulez dire !
J'imagine quelque chose qui ressemble à cela :
 
If( col = Loc(dt[Row(), :OPE] < Loc(dt[Row(), :T=="3061")),
	continue();
	,
		script...
);
Par contre il est impossible que le même objet possède 2 fois le numéro 3061.
 
hcarr01
Level VI

Re: Script

Cela ne fonctionne pas, savez vous comment je peux réaliser un tel script @jthi (les dernières vérifications à faire) ?

Merci encore de votre aide !

jthi
Super User

Re: Script

Get all :OPE values for unique_object, then get the :OPE value for the 3061 row. After that check from the list of all :OPE values the indices which are higher than the :OPE value for 3061 (Loc() can do this).

-Jarmo
hcarr01
Level VI

Re: Script

Oui c'est ce que je me suis dis, j'ai pensé à quelque chose comme cela mais la difficulté reste de définir les variables a et b.

 

dt = current data table();
b = // all values :OPE for unique_object
a = // values :OPE for 3061
test = Loc(dt[Row(), b]) > Loc(dt[Row(),a]);

If( test=0 ,
		continue();
	,
		script...;
);

 

jthi
Super User

Re: Script

Similar method as used for values variable which stores :SOMME DEFAUT values for specific unique object

	values = dt[object_rows, "SOMME DEFAUT"];

add debug prints and try running the script one line at the time by using only one object

-Jarmo
hcarr01
Level VI

Re: Script

Oui merci j'ai écris un code comme ceci qui me permet d'avoir les infos dont j'ai besoin :

 

dt = current data table();
For Each({unique_objects}, unique_objects,
	object_rows = Loc(m_obs, unique_objects);
	b = dt[object_rows, "OPE"];
	show(b);
	
	a = dt << Get Rows Where( :T == "3061");
	valeurs_OPE = :OPE[a];
	show(valeurs_OPE);
	valeurs_OPE_3061_obj = dt[unique_objects, "valeurs_OPE"];
	show(valeurs_OPE_3061_obj);
	
);

Cependant je n'arrive pas à avoir les valeurs de OPE correspondantes à la tache 3061 par :obj (variable "valeurs_OPE_3061_obj").

Seulement la variable "valeurs_OPE" regroupe toutes les données de OPE correspondantes à la tache 3061.

jthi
Super User

Re: Script

It is easier to test if you just ignore For Each (for now). Start with something like this

Names Default To Here(1);

// dt = Open("$DOWNLOADS/AAA.jmp");
// dt = Current Data Table();

dt = New Table("AAA(1)",
	Add Rows(12),
	Compress File When Saved(1),
	New Column("obj", Character(16), "Nominal", Set Values({"A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "C", "C"})),
	New Column("T",	Character(4), "Ordinal", Set Values({"3052", "3061", "3082", "3940", "4012", "5010", "2890", "4060", "3061", "3081", "5010", "3061"})),
	New Column("OPE", Numeric, "Continuous", Format("Best", 12), Set Values([12, 20, 32, 44, 56, 125, 210, 54, 60, 80, 45, 50])),
	New Column("X__3", Character(4), "Nominal", Set Values({"rien", "rien", "incl", "ret", "ret", "rien", "incl", "incl", "ret", "incl", "ret", "rien"})),
	New Column("SOMME DEFAUT", Numeric, "Continuous", Format("Best", 12), Set Values([0, 0, 1, 2, 1, 0, 2, 1, 2, 1, 1, 0])),
	New Column("op", Character(12), "Nominal", Set Values({"40", "32", "55", "212", "510", "180", "2100", "2240", "2100", "500", "", ""})),
	New Column("correct", Character, "Nominal", Set Values({"", "ko - 55 / ko - 212 / ko - 510 / ko - 2100", "", "", "", "", "", "", "ko - 500", "", "", "."}))
);

dt << New Column("bilan", Character, Nominal);

Summarize(dt, unique_objects = by(:obj));
m_obs = dt[0, "obj"];

unique_object = unique_objects[2];
object_rows = Loc(m_obs, unique_object);
input_loc = Loc(dt[object_rows, "T"], "3061"); // location of 3061 for unique_object
show(input_loc); // index within object_rows
show(object_rows[input_loc]); // real row number

opes = dt[object_rows, "OPE"]; // all OPE values for unique_object
valid_ope_idx = Loc(...//
-Jarmo
hcarr01
Level VI

Re: Script

 

J'ai continué avec le script suivant :

 

Names Default To Here(1);

dt = current data table();
dt << New Column("BILAN", Character, Nominal);


Summarize(dt, unique_objects = by(:obj));
m_obs = dt[0, "obj"];



dt = current data table();
For Each({unique_objects}, unique_objects,
	object_rows = Loc(m_obs, unique_objects); // lignes pour chaque obj
	b = dt[object_rows, "OPE"]; // les différentes opé pour chaque obj
	show(b);
	input_loc = Loc(dt[object_rows, "T"], "3061"); // localiser 3061 pour chaque objet
	z = object_rows[input_loc]; // localiser les lignes OPE 3061 pour chaque obj
	value_OPE_3061 = :OPE[z]; // valeur de l'ope 3061 pour chaque obj
	show(value_OPE_3061); 

	//valid_ope_idx = Loc(b > value_OPE_3061);
//show(valid_ope_idx); For( i = 1, i <= N Items(b), i++, If(N Items(input_loc) < 1 & b[i] <= value_OPE_3061, continue(); , values = dt[object_rows, "SOMME DEFAUT"]; ops = dt[object_rows[Loc(values)], "op"]; result_str = "ko - " || Concat Items(ops, " / ko - "); dt[object_rows[input_loc], "BILAN"] = Repeat({result_str}, N Items(input_loc)); ); ); );

J'ai d'abord utilisé la fonction Loc() pour déterminer les indices des lignes mais ensuite je ne sais pas comment continuer le script . Alors j'ai essayé avec une boucle "For" et le résultat n'est toujours pas correct. Pouvez-vous m'aider à avancer ?

 

Merci d'avance pour toute réponse !