Bonjour,
Je travaille sur un complément pour concaténer horizontalement les valeurs provenant du connecteur OSIsoft-PI car il ouvre chaque balise sur une table distincte pour laquelle la colonne (1) est l'horodatage et la colonne (2) est la valeur de la balise.J'ai trouvé une solution de contournement en utilisant "Mise à jour" qui fonctionne bien . Cependant, mon plan initial était d'utiliser "Rejoindre" pour éviter de rassembler des lignes lorsque les horodatages sont mal alignés et éviter la dernière étape de suppression de lignes comme avec la stratégie "Mettre à jour".Malheureusement, j'ai rencontré divers messages d'erreur et j'aimerais mieux comprendre comment faire fonctionner la jointure (pour d'autres travaux de script). Trouvez ci-joint un document Word avec plus de détails sur les étapes et les erreurs, ainsi que des scripts (la mise à jour fonctionne, tandis que la jointure échoue) et des tables de données.
Merci pour l'aide, je suis ouvert pour une réunion d'équipe ou de la documentation.
Emmanuel
Bonjour, @Emmanuel_Romeu ,
Je ne vois pas le mot document que vous avez mentionné.
Bonjour Emmanuel, Vous pouvez essayer ceci, qui parcourt le processus de jointure et n'a qu'une gestion minimale des expressions.
Names Default To Here( 1 );
// List of opened files
file = Get Data Table List();
n_files = N Items( file );
joinCol = "Timestamp";
joinedDt = file[1];
For Each( {i}, 2 :: (n_files), // i =2;
Eval(
Eval Expr(
joinedDt = joinedDt << Join(
With( file[i] ),
By Matching Columns( Expr( Parse( Eval Insert( ":^joinCol^" ) ) ) = Expr( Parse( Eval Insert( ":^joinCol^" ) ) ) ),
Drop multiples( 0, 0 ),
Include Nonmatches( 0, 0 ),
Preserve main table order( 1 ),
invisible
)
)
);
//set first column to join column name
Column( joinedDt, 1 ) << set name( joinCol );
//delete working files and prepare for next time through loop
Close( file[i], nosave );
Try( Close( oldJoin, nosave ) );
oldJoin = joinedDt;
);
Close( file[1], nosave );
//remove extra join columns
For Each( {i}, N Col( joinedDt ) :: 2,
If( Lowercase( Left( Column( joinedDt, i ) << get name, 9 ) ) == Lowercase( joincol ),
joinedDt << delete columns( i )
)
);
joinedDt << show window( 1 );
Merci Brady, Ça marche .
Maintenant je vais me coucher et demain (ou lundi) j'essaierai de comprendre exactement Comment ça fonctionne
.
Merci.
S'il vous plaît laissez-moi savoir si vous avez des questions après l'avoir examiné, je serai heureux de développer / avoir un appel.
Acclamations,
brady
A réparer Script_Concatenate_Tags_w_JOIN_Fail_2 :
Remplacez la ligne 70 par : Expr (dt_joined = dt_joined << Join(
Supprimez la ligne 80 : Expr (dt_joined), table de données courante() ,
À mon avis, Tableau de données actuel() ne doit être utilisé que pour obtenir la table actuelle au début du script car c'est l'une des rares fois où vous saurez avec certitude à quelle table il fait référence (la dernière à laquelle l'utilisateur a touché). Dans de nombreuses autres circonstances, la table actuelle peut différer d'une exécution à l'autre selon les opérations en cours, leur durée, si l'utilisateur a touché une autre table pendant le traitement, si des changements dans le code sous-jacent ont causé ce qui était le courant table dans une version pour changer dans la suivante, etc. La façon dont vous avez utilisé Tableau de données actuel() c'est pourquoi votre script "a fonctionné" (il a rejoint la deuxième table du fichier avec la table que vous avez sélectionnée). Je crois fermement que les tables ne devraient être référencées qu'explicitement. C'est ce qui est fait dans la nouvelle ligne 70, où vous savez avec certitude qu'il s'agit à la fois de la table en cours de message et de la variable à laquelle la table résultante est transmise.
Obtenir des noms de colonne dans les plates-formes à l'aide d'expressions est délicat, en particulier lorsque l'argument peut prendre plusieurs colonnes. J'ai presque toujours besoin d'essayer différentes choses avant de trouver quelque chose qui fonctionne. Je suis à peu près certain que cette fonctionnalité a évolué au fil des ans, heureusement en s'améliorant (plus flexible). Pourtant, c'est un défi. @Mark_Bailey a une belle écriture sur le travail avec la colonne que je recommanderais de lire.
Dans le Script_Concatenate_Tags_w_JOIN_Fail_1 scénario, le premier Rejoindre bloc, le problème n'est pas avec Analyser , mais en tentant d'insérer une référence à la colonne dans une liste (JMP ne trouve pas la colonne). Bien que vous puissiez avoir plusieurs déclarations dans Remplaçant (Je le fais fréquemment), vous n'en avez pas besoin dans ce cas. Vous pouvez le mettre directement dans Rejoindre en utilisant son nom au lieu de son numéro (que je n'ai pas pu mettre au travail). En plus de cela, vous pouvez saisir toutes les colonnes de la table jointe et toutes sauf la première de la table pour la joindre. J'ai réorganisé le code afin de pouvoir référencer explicitement les tables et les colonnes et supprimer la table dont je n'ai pas besoin immédiatement.
name = Get Data Table List(); <BR />For(i=1,i<=N Items(name),i++, name[i] = Head Name(name[i]));<BR /><BR />join1 = Data Table(1);
for (f=2, f<= N Items(name),f++,
colList1 = join1 << Get Column Names();
colList2 = Remove(Data Table(name[f]) << Get Column Names(),1);
Eval(
Substitute(
Expr (
dt_joined = join1 << Join(
With( join2 ),
Select(cl1),
SelectWith( cl2 ),
By Matching Columns( join1Col1 = join2Col1),
Drop multiples( 0, 0 ),
Include Nonmatches( 0, 0 ),
Preserve main table order( 1 )
)
) ,
Expr (join2), Data Table(name[f]),
Expr(cl1), Name Expr(colList1),
Expr(cl2), Name Expr(colList2),
Expr (join1Col1), Column(join1,1),
Expr (join2Col1), Column(Data Table(name[f]),1),
)
);
Close(join1,No Save);
Close(Data Table(name[f]),No Save);
join1 = dt_joined;
);
J'ai rangé les choses en haut du code, vous n'avez pas besoin de créer une table pour rassembler les noms de table. Beaucoup plus simple de mettre les noms dans une liste et de travailler à partir de là. Cela peut être un peu lourd si les tables sont grandes. Meilleur à utiliser Invisible ou Privé pour masquer les tables intermédiaires. Le problème est que, pour autant que je sache, il n'y a aucun moyen d'afficher la table finale à l'aide de messages. Vous pouvez créer un sous-ensemble en utilisant le tableau entier pour le réafficher.
Bonjour Don, merci !!
*pour Script_Concatenate_Tags_w_JOIN_Fail_2, comme vous l'avez dit, j'ai utilisé tableau de données actuel () pour le faire fonctionner, mais je soupçonnais que ce n'était pas la meilleure façon de le faire. Maintenant je comprends que la solution était très proche avec dt_joined = dt_joined << Join() mais je n'y aurais jamais pensé par moi-même (maintenant je comprends "le table en cours de message et la variable à laquelle la table résultante est transmise" J'espère y penser à l'avenir).
*pour Script_Concatenate_Tags_w_JOIN_Fail_1, en effet c'est beaucoup plus simple en utilisant la bonne commande (par exemple name[i] = Head Name(name[i] ou colList2 = Remove(Data Table(name[f]) << Get Column Names(),1 )
plutôt que de construire des trucs complexes pour y parvenir (bon à savoir).
Merci encore.