正當我以為我理解了 Eval 和 Expr 的時候...我已經研究這個問題兩天了,現在正在審查這個討論組中的條目,瀏覽腳本指南等,但我仍然可以找出問題所在。
我正在嘗試使用變數來引用列。從腳本第 65-75 行(就在 For Each Row 之前),我正在嘗試各種方法來使用 Expr 和 Eval 以及 Name Expr 和 As Column 等來完成這項工作。當前腳本僅顯示最近的迭代。
根據 aggOption 的值,我希望 Agg Minute(選項 1)列以三種不同方式之一填入。如果您用實際的列名稱:「Agg Minute (Option 1)」n 代替 Eval( colName3),它將按預期工作。但是,無論我在定義變數或評估變數時使用 Eval、Expr 等的哪種組合,我都會收到以下錯誤訊息...

...或腳本執行時沒有錯誤,但該列未填寫。
所以看來賦值的左側沒有被解釋為列名。
我確信這一定是我對 Eval 和 Expr 如何運作或 Choose 函數如何運作的一些簡單誤解。但我似乎無法弄清楚它是什麼。
有人了解我做錯了什麼嗎?
一如既往地感謝。
Names Default To Here( 1 );
// SETUP: Create Raw Data Table
Try( Close( "Interpolated Data"));
Try( Close( "Test rt"));
rt = New Table( "Test rt",
Add Rows( 5 ),
New Column( "Timestamp", Continuous, Format( "m/d/y h:m", 19 ), set values( [3742070400, 3742070880, 3742071360, 3742071840, 3742072320] ) ),
New Column( "Data", set values( [899.084, 897.387, 898.518, 897.575, 897.387] ) )
);
t1 = column( rt,1) << Get Name;
t2 = column( rt,2) << Get Name;
timeCol = Parse(":" || t1);
dataCol = Parse(":" || t2);
Print( timeCol);
Print( dataCol);
rtRows = N Rows( rt );
startTime = rt:Timestamp[1];
endTime = rt:Timestamp[rtRows];
minDuration = (endTime - startTime) / 60;
// CREATE SECONDARY TABLE
dt = New Table( "Interpolated Data Temp" );
dt << New Column( "Timestamp", Format( "m/d/y h:m", 19 ), Set Display Width( 250 ) );
dt << Add Rows( minDuration );
For Each Row( dt, :Timestamp[] = Sequence( startTime, endTime, 60 ) );
// JOIN BOTH TABLES
dt << Join(
With( rt ),
Suppress formula evaluation( 0 ),
Select( :Timestamp ),
SelectWith( Name Expr(dataCol)),
By Matching Columns( :Timestamp = :Timestamp ),
Drop multiples( 0, 0 ),
Include Nonmatches( 1, 0 ),
Preserve main table order( 1 ),
Output Table( "Interpolated Data" )
);
dt2 = Data Table( "Interpolated Data" );
Close( dt, NoSave );
Close( rt, NoSave );
// CREATE AGG MINUTE/AGG QUADRANT COLUMNs
// These are the columns that will define which minutes are included in each quadrant and how the quadrant will be labled.
// The choice of how the columns will be filled depends on the Option chosen above.
// **************************************************************************
aggOption = 1;
colName1 = "Agg Minute (Option " || char(aggOption) || ")";
colName2 = "Agg Quadrant (Option " || char(aggOption) || ")";
Print( colName1);
Print( ColName2);
colName3 = Name Expr(":" || colName1);
colName4 = Name Expr(":" || colName2);
Print( colName3);
Print( colName4);
New Column(colName1, Numeric, "Ordinal", Format("Best", 12), Set Display Width(116)); // To Do: Add chosen agg option to column name
New Column(colName2, Numeric, "Ordinal", Format("Best", 12), Set Display Width(116)); // To Do: Add chosen agg option to column name
For Each Row(dt2,
Eval(colName3) = Choose(aggOption, // Substituting an actual column name (:"Agg Minute (Option 1)"n works)
If(
Minute(:Timestamp) < 15, 15, // Option 1
Minute(:Timestamp) < 30, 30,
Minute(:Timestamp) < 45, 45,
0
),
If(
Minute(:Timestamp) < 15, 0, // Option 2
Minute(:Timestamp) < 30, 15,
Minute(:Timestamp) < 45, 30,
45
),
If(
0 < Minute(:Timestamp) <= 15, 15, // Option 3
15 < Minute(:Timestamp) <= 30, 30,
30 < Minute(:Timestamp) <= 45, 45,
0
)
)
);自動化和腳本編寫回覆:正當我以為我了解 Eval 和 Expr 時...幾乎不需要開始搞亂“:”(將“:”作為字串添加),甚至不需要使用 Parse()。當您使用 For Each Row 設定值到列時,您可以執行類似的操作
For Each Row(
dt2,
Column(dt2, colName1)[Row()] = Choose(aggOption, // Substituting an actual column name (:"Agg Minute (Option 1)"n works)
If(
Minute(:Timestamp) < 15, 15, // Option 1
Minute(:Timestamp) < 30, 30,
Minute(:Timestamp) < 45, 45,
0
),
If(
Minute(:Timestamp) < 15, 0, // Option 2
Minute(:Timestamp) < 30, 15,
Minute(:Timestamp) < 45, 30,
45
),
If(
0 < Minute(:Timestamp) <= 15, 15, // Option 3
15 < Minute(:Timestamp) <= 30, 30,
30 < Minute(:Timestamp) <= 45, 45,
0
)
)
);
這不是唯一的選擇,但它非常簡單。如果你真的想開始搞亂表達式,這是一種方法
Eval(EvalExpr(
For Each Row(
dt2,
Expr(Name Expr(AsColumn(dt2, colName1))) = Choose(aggOption, // Substituting an actual column name (:"Agg Minute (Option 1)"n works)
If(
Minute(:Timestamp) < 15, 15, // Option 1
Minute(:Timestamp) < 30, 30,
Minute(:Timestamp) < 45, 45,
0
),
If(
Minute(:Timestamp) < 15, 0, // Option 2
Minute(:Timestamp) < 30, 15,
Minute(:Timestamp) < 45, 30,
45
),
If(
0 < Minute(:Timestamp) <= 15, 15, // Option 3
15 < Minute(:Timestamp) <= 30, 30,
30 < Minute(:Timestamp) <= 45, 45,
0
)
)
);
));
EvalExpr 的一個好處(與 Substitute 的處理相同)是,如果使用 Eval,您可以輕鬆地看到將要計算的表達式,但是選擇 EvalExpr() 部分,然後執行該表達式

回覆:正當我以為我了解 Eval 和 Expr 時...謝謝,賈莫。
我確實嘗試了帶有解析和帶有或不帶有前導冒號的選項,但沒有成功。但是,我沒有嘗試您上面顯示的組合。一旦你看到它完成了,它就完全有意義了。
回覆:正當我以為我了解 Eval 和 Expr 時...有趣的是,如果使用列的實際名稱,則不需要 Row() 函數。我不會猜到這一點。
回覆:正當我以為我了解 Eval 和 Expr 時...這只是我的首選方法,只要有可能就使用 Column(dt, colname) (您也可以刪除 Row() 並只使用 Column()[])。我認為也應該與 As Column() 一起使用
For Each Row(
dt2,
As Column(dt2, colName1) = Choose(aggOption, // Substituting an actual column name (:"Agg Minute (Option 1)"n works)
If(
Minute(:Timestamp) < 15, 15, // Option 1
Minute(:Timestamp) < 30, 30,
Minute(:Timestamp) < 45, 45,
0
),
If(
Minute(:Timestamp) < 15, 0, // Option 2
Minute(:Timestamp) < 30, 15,
Minute(:Timestamp) < 45, 30,
45
),
If(
0 < Minute(:Timestamp) <= 15, 15, // Option 3
15 < Minute(:Timestamp) <= 30, 30,
30 < Minute(:Timestamp) <= 45, 45,
0
)
)
);
但在我看來,由於 Column() 使用起來更煩人,所以我不使用那麼多...除非我將它與 Name Expr() 一起使用,並且我正在嘗試構建一些需要您擁有的東西:col 格式或使用該格式的列更清晰(就像在公式中一樣)。