数式に欠落している列が含まれている場合、エラーが発生します。次の例では、テーブルに 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";
);
列が欠落している場合、最終結果をどうしたいか正確にはわかりませんが、以下は問題を処理する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] )
)
);
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
|| "))"
)
);ありがとうございますが、あまり役に立ちません。 問題は、(スクリプトによって) 一部のデータを自動的に抽出し、それらのいずれかが欠落している可能性があることです (ただし、事前にわからない場合もあります)。 欠落している列が見つかると、スクリプトは停止します。これが実際の問題です。 良い解決策は try ステートメントかもしれませんが、うまくいきません。
これは、数式列を作成する前にテストすることをお勧めします。 そのため、if ステートメントを実行して、列が存在するかどうかを確認します...存在しない場合は、数式列を作成しないでください。
@アントニオ・ドメニック、数式に基づいて列を作成する前に、テーブルに特定の数式に適した列が含まれているかどうかを判断する必要があると思いますか?列を作成する前にこれを判断できれば、スクリプト停止エラーが発生する可能性は低くなります。
幸いなことに、式が依存するすべての外部名を決定するのは非常に簡単です。これは、現在のデータ テーブルの列名のみである必要があります。(将来のある時点でスコープを失い、数式がエラーになる原因となる、現在スコープ内の変数に数式を依存させないことをお勧めします)。
以下は、ぶら下がっている名前の式 (式はもちろん単なる式です) を再帰的に解析する関数を使用したサンプル コードです。次に、テーブルの列名を確認し、列名が次の式を満たす場合に適用できます。
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>ご不明な点がございましたら、お気軽にお問い合わせください。
ヨルダン、