當公式包含缺少的列時,我會發現錯誤。在下列範例中,表格包含 2 列。新增使用不存在列的新列,結果缺少結果(正確),並且出現一個阻止我的腳本的錯誤,我無法捕獲該錯誤,因為 try 語句不起作用。有解決方法嗎?
dt= New Table( "Test",
Add Rows( 1 ),
New Column( "A",
Numeric,
"Continuous",
Format( "Best", 12 ),
Set Values( [2] )
),
New Column( "B",
Numeric,
"Continuous",
Format( "Best", 12 ),
Set Selected,
Set Values( [1] )
)
);
formula=":Name(\!"C\!") - :Name(\!"B\!")";
try(
eval(parse("dt << new column(\!"value\!", Numeric, \!"Continuous\!", Formula(" ||formula || "))"));
,
error="missing column";
);
@antonio-domenic ,我相信您想要的是在嘗試基於公式創建列之前確定該表是否包含給定公式的適當列?如果您能夠在嘗試創建列之前確定這一點,您將不太可能遇到腳本停止錯誤。
好消息是,確定公式所依賴的所有外部名稱非常簡單——它們應該只是當前數據表的列名。(最好的做法是不要讓公式依賴於當前範圍內的變量,該變量將在將來的某個時候失去範圍,從而導致公式出錯)。
下面是一些示例代碼,其中包含一個函數,可以遞歸地解析任何懸空名稱的表達式(公式當然只是表達式)。然後可以檢查表的列名,如果列名滿足公式就應用:
Names Default to Here( 1 );
dt= New Table( "Test",
Add Rows( 1 ),
New Column( "A",
Numeric,
"Continuous",
Format( "Best", 12 ),
Set Values( [2] )
),
New Column( "B",
Numeric,
"Continuous",
Format( "Best", 12 ),
Set Selected,
Set Values( [1] )
)
);
//recursively find all unassigned names within the formula -- we can test these against the column names
get dangling names = Function( {formula},
{Default Local},
parse formula = Function( {expr, names = {}, assigns = {}},
{Default Local},
If( Contains( Head Name( expr ), "[" ) & Contains( Head Name( expr ), "]" ), // deal with the exceptional case where JMP doesn't arg-parse out this pattern...
items = Words( Head Name( expr ), "[" );
Summation( i = 1, N Items( items ),
Try(
item = Word( 1, items[i], "]" );
If( Is Missing( Num( item ) ),
{n, a} = Recurse( Parse( item ) );
Insert Into( names, n );
Insert Into( assigns, a );
)
);<BR /> 0
)
,
If( Head Name( expr ) == "Assign", // if a variable is assigned within the formula then we don't care to check it (the formula shouldn't be direclty affecting other columns, it bad practice!)
Insert Into( assigns, Char( Arg( expr, 1 ) ) )
,
Head Name( expr ) != Char( Name Expr( expr ) ), // Need to recursively parse here
Summation( i = 1, N Arg( expr ),
{n, a} = Recurse( Arg( expr, i ) );
Insert Into( names, n );
Insert Into( assigns, a );
0
);
,
Insert Into( names, Char( Name Expr( expr ) ) ) // found a name
);
);
Eval List( {Associative Array( names ) << Get Keys, Associative Array( assigns ) << Get Keys} )
);
{names, assigns} = parse formula( Name Expr( formula ) );
names = Associative Array( names );
assigns = Associative Array( assigns );
names << Remove( assigns );
names = names << Get Keys;
names
);
formulas = {};
Insert Into( formulas, Expr( :Name("C") - :Name("B") ) );
local var = [1 => 3, 2 => 4];
Insert Into( formulas, Eval Expr(
var = Expr( local var );
var[:C][:F] + :D
);
);
Insert Into( formulas, Expr( :A + :B ) );
Insert Into( formulas, Expr( :A + :B - Sin( :D</img> + Cos( :E - :Name("flamingo@fish" ) ) ) ) );
For( i = 1, i <= N Items( formulas ), i++,
table columns = dt << Get Column Names( "String" );
Write( "\!N" );
Show( table columns );
formula references = get dangling names( formulas[i] );
refs = {};
For( j = 1, j <= N Items( formula references ), j++,
refs[j] = Contains( table columns, formula references[j] ) > 0
);
Show( formulas[i] );
Show( formula references );
Print( If( Sum( refs ) == N Items( formula references ), "OKAY", "NOT OKAY" ) );
If( Sum( refs ) == N Items( formula references ), // The table contains all the necessary columns, okay to add the new column!
Eval( Eval Expr(
dt << New Column( "FORMULA", <<FORMULA></FORMULA>如果您有任何問題,請告訴我!
約旦,
在創建公式列之前進行測試可能會更好。 因此,執行 if 語句以查看該列是否存在...如果不存在,則不要創建公式列。
謝謝,不過用處不大。 問題是我自動提取了一些數據(通過腳本)並且它們中的任何一個都可能丟失(但我事先不知道是否以及丟失了哪些)。 當找到丟失的列時腳本停止,這是真正的問題。 一個好的解決方案可能是 try 語句,但它不起作用。
如果缺少該列,我不確定您希望最終結果是什麼,但以下是處理該問題的一種方法
dt = New Table( "Test",
Add Rows( 1 ),
New Column( "A",
Numeric,
"Continuous",
Format( "Best", 12 ),
Set Values( [2] )
),
New Column( "B",
Numeric,
"Continuous",
Format( "Best", 12 ),
Set Selected,
Set Values( [1] )
)
);
If( Try( dt:c << get name, "" ) == "",
type = "character";
formula = "\!"missing column\!"";
,
type = "numeric/continuous";
formula = ":Name(\!"C\!") - :Name(\!"B\!")";
);
Eval(
Parse(
"dt << new column(\!"value\!"," || type || ", Formula(" || formula
|| "))"
)
);