Ciao,
Sto lavorando su un componente aggiuntivo per concatenare orizzontalmente i valori provenienti dal connettore OSIsoft-PI poiché apre ciascun tag su tabelle separate per le quali Colonna (1) è il timestamp e la colonna (2) è il valore del tag.Ho trovato una soluzione alternativa utilizzando "Aggiornare" quale funziona bene . Tuttavia il mio piano iniziale era di utilizzare "Giuntura" per evitare di raccogliere righe quando i timestamp sono disallineati ed evitare l'ultimo passaggio di eliminazione delle righe come con la strategia "Aggiorna".Purtroppo ho riscontrato vari messaggi di errore e vorrei capire meglio come far funzionare il Join (per ulteriori lavori di scripting). Trova in allegato un documento Word con maggiori dettagli su passaggi ed errori, nonché script (l'aggiornamento funziona, mentre l'unione non riesce) e tabelle di dati.
Grazie per l'aiuto, sono aperto per una riunione o documentazione del team.
Emanuele
Buongiorno, @Emmanuel_Romeu ,
Non vedo la parola documento che hai citato.
Ciao Emmanuel, potresti provare questo, che scorre il processo di unione e ha solo una gestione minima delle espressioni.
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 );
Grazie Brady, funziona .
Adesso vado a letto e domani (o lunedì) ci provo comprendere Esattamente come funziona
.
Grazie.
Per favore fatemi sapere se avete domande dopo averlo esaminato, sarò felice di elaborare / chiamare.
Saluti,
Brady
Aggiustare Script_Concatenate_Tags_w_JOIN_Fail_2 :
Cambia la riga 70 in: Espr (dt_joined = dt_joined << Join(
Elimina riga 80: Expr (dt_joined), tabella dati corrente() ,
Secondo me, Tabella dati corrente() dovrebbe essere usato solo per ottenere la tabella corrente all'inizio dello script perché è una delle poche volte in cui saprai con certezza a quale tabella fa riferimento (l'ultima che l'utente ha toccato). In molte altre circostanze la tabella corrente può differire da un'esecuzione all'altra a seconda delle operazioni in corso, del tempo impiegato, se l'utente ha toccato un'altra tabella durante l'elaborazione, se le modifiche al codice sottostante hanno causato quello che era il tabella in una versione da modificare nella successiva, ecc. Il modo in cui hai usato Tabella dati corrente() ecco perché il tuo script "ha funzionato" (si è unito alla seconda tabella dal file con la tabella che hai selezionato). Credo fermamente che le tabelle debbano essere referenziate solo in modo esplicito. Questo è ciò che viene fatto nella nuova riga 70, dove sai per certo che è sia la tabella che viene inviata al messaggio sia la variabile a cui viene passata la tabella risultante.
Ottenere i nomi delle colonne nelle piattaforme usando le espressioni è complicato, in particolare quando l'argomento può occupare più colonne. Ho quasi sempre bisogno di provare alcune cose diverse prima di trovare qualcosa che funzioni. Sono abbastanza certo che questa funzionalità si sia evoluta nel corso degli anni, fortunatamente cambiando in meglio (più flessibile). Comunque è una sfida. @Mark_Bailey ha un bel commento su come lavorare con la colonna che consiglierei di leggere.
Nel Script_Concatenate_Tags_w_JOIN_Fail_1 copione, il primo Giuntura blocco, il problema non è con Analizza , ma tentando di inserire un riferimento alla colonna in un elenco (JMP non riesce a trovare la colonna). Mentre puoi avere più dichiarazioni in Sostituto (Lo faccio spesso), in questo caso non è necessario. Puoi inserirlo direttamente Giuntura usando il suo nome invece del suo numero (che non sono riuscito a far funzionare). Inoltre, puoi prendere tutte le colonne dalla tabella unita e tutte tranne la prima dalla tabella con cui unirti. Ho riorganizzato il codice in modo da poter fare riferimento in modo esplicito alle tabelle e alle colonne ed eliminare immediatamente la tabella di cui non ho bisogno.
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;
);
Ho riordinato le cose nella parte superiore del codice, non è necessario creare una tabella per raccogliere i nomi delle tabelle. Molto più semplice mettere i nomi in un elenco e lavorare da quello. Questo può essere un po' ingombrante se i tavoli sono grandi. Meglio da usare Invisibile o Privato per nascondere le tabelle intermedie. Il problema è che, per quanto ne so, non c'è modo di mostrare il tavolo finale usando i messaggi. Puoi creare un sottoinsieme usando l'intera tabella per mostrarlo di nuovo.
Ciao Don, grazie!!
*per Script_Concatenate_Tags_w_JOIN_Fail_2, come hai detto l'ho usato tabella dati corrente () per farlo funzionare ma sospettavo che non fosse il modo migliore per farlo. Ora capisco che la soluzione era molto vicina con dt_joined = dt_joined << Join() ma non ci avrei mai pensato da solo (ora capisco "il messaggistica della tabella e la variabile a cui viene passata la tabella risultante" si spera che ci penserò in futuro).
*per Script_Concatenate_Tags_w_JOIN_Fail_1, in effetti è molto più semplice quando si usa il comando giusto (es. name[i] = Head Name(name[i] o colList2 = Remove(Data Table(name[f]) << Get Column Names(),1 )
piuttosto che costruire cose complesse per raggiungerlo (buono a sapersi).
Grazie ancora.