就在我以为我理解了 Eval 和 Expr 时......我已经研究这个问题两天了,查看了这个讨论组中的条目,阅读了脚本指南等,但我仍然无法找出问题所在。
我正在尝试使用变量来引用列。从脚本行 65-75(就在 For Each Row 之前),我尝试了各种方法来使用 Expr 和 Eval 以及 Name Expr 和 As Column 等来实现这一点。当前脚本仅显示最近的迭代。
根据 aggOption 的值,我希望 Agg Minute (Option 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
)
)
);
但在我看来,As Column() 使用起来更烦人,所以我不怎么用它...除非当我将它与 Name Expr() 一起使用时,我正在尝试构建一些需要您具有 :col 格式的东西,或者只是更清晰地使用这种格式的列(就像在公式中一样)。