你好,
我正在開發一個加載項,以水平連接來自 OSIsoft-PI 連接器的值,因為它在單獨的表上打開每個標籤,其中列 (1) 是時間戳,列 (2) 是標籤的值。我找到了一種解決方法“更新”哪個工作正常. 但是我最初的計劃是使用“加入”避免在時間戳未對齊時收集行,並避免像“更新”策略一樣刪除行的最後一步。不幸的是,我遇到了各種錯誤消息,並希望更好地理解如何使加入工作(用於進一步的腳本工作)。 查找附加的 Word 文檔,其中包含有關步驟和錯誤的更多詳細信息,以及腳本(更新有效,而加入失敗)和數據表。
感謝您的幫助,我願意參加團隊會議或文檔。
伊曼紐爾
嗨 Emmanuel,您可以試試這個,它循環連接過程並且只有最少的表達式處理。
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 );
如果您在查看後有任何問題,請告訴我,我很樂意詳細說明/致電。
乾杯,
布雷迪
謝謝布雷迪,有用.
現在我要睡覺了,明天(或星期一)我會嘗試理解確切地這個怎麼運作
。
謝謝你。
修理Script_Concatenate_Tags_w_JOIN_Fail_2 :
將第 70 行更改為: Expr (dt_joined = dt_joined << Join(
刪除第 80 行: Expr (dt_joined), 當前數據表 () ,
在我看來,當前數據表()應該只用於在腳本開始時獲取當前表,因為這是您確定它所引用的表(用戶最後觸摸的表)的少數幾次之一。 在許多其他情況下,當前表可能因運行而異,具體取決於正在執行的操作、它們花費的時間、用戶在處理事情時是否觸摸了另一個表、底層代碼的更改是否導致了當前表一個版本中的表格以在下一個版本中更改,等等。 你使用的方式當前數據表()這就是您的腳本“有效”的原因(它將文件中的第二個表與您選擇的表連接起來)。 我堅信應該只明確引用表。 這就是在新的第 70 行中所做的事情,您可以肯定地知道它既是正在發送消息的表,也是傳遞結果表的變量。
使用表達式將列名輸入平台是很棘手的,特別是當參數可以採用多個列時。 在找到有效的方法之前,我幾乎總是需要嘗試一些不同的方法。 我相當肯定這個功能多年來一直在發展,幸運的是變得更好(更靈活)。 儘管如此,這仍然是一個挑戰。 @Mark_Bailey有一篇關於使用專欄的精彩文章我建議閱讀。
在裡面Script_Concatenate_Tags_w_JOIN_Fail_1腳本,第一個加入塊,問題不在於解析,但嘗試將對該列的引用插入到列表中(JMP 找不到該列)。 雖然你可以有多個語句代替(我經常這樣做),在這種情況下你不需要。 可以直接放入加入使用它的名稱而不是它的號碼(我無法上班)。 最重要的是,您可以從連接表中獲取所有列,以及從表中獲取除第一列之外的所有列來加入它。 我重新排列了代碼,以便可以顯式引用表和列並刪除我不需要的表。
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;
);
我已經在代碼的頂部整理了一些東西,你不需要創建一個表來收集表名。 將名稱放入列表並從中工作要簡單得多。 如果桌子很大,這可能有點笨拙。 最好用無形的或者私人的隱藏中間表。 問題是,據我所知,沒有辦法使用消息取消隱藏決賽桌。 您可以使用整個表格製作一個子集來重新顯示它。
你好唐,謝謝!
*為了Script_Concatenate_Tags_w_JOIN_Fail_2,正如你所說,我用過當前數據表()使它起作用,但我懷疑這不是最好的方法。 現在我知道解決方案與 dt_joined = dt_joined << Join() 非常接近,但我自己永遠不會想到它(現在我明白了“表消息和結果表傳遞到的變量“我希望將來會考慮它)。
*對於 Script_Concatenate_Tags_w_JOIN_Fail_1,使用正確的命令確實要簡單得多(例如 name[i] = Head Name(name[i] or colList2 = Remove(Data Table(name[f]) << Get Column Names(),1 )
而不是構建複雜的東西來實現它(很高興知道)。
再次感謝你。