スクリプト ツールのキャンセル動作について

ツールを実行しているときに、キャンセル ボタンを使用して、それ以降のツールの処理を停止できます。 デフォルトでは、スクリプト ツールまたは Python ツールボックスのツールをキャンセルすると、スクリプト コードの現在の行の後の部分がキャンセルされ、ツールは適切なエラー メッセージ (''Cancelled script <tool_name>... (ユーザーにより (<ツール名>) が中断されました。') を伴って失敗します。これが発生すると、キャンセルが最後の処理になります。つまり、キャンセルが行なわれた後には、どのコードも実行されません。スクリプトによっては、この処理で十分ですが、キャンセル後に処理が必要になることもあります。たとえば、データをクリーンアップしたり、カスタム ツール メッセージを提供するなどの動作を実行する場合です。

arcpy.env クラスには、キャンセル動作を制御するための 2 つのプロパティ (autoCancelling および isCancelled) が含まれています。デフォルトでは、ツールがキャンセルされたときに、そのキャンセルが現在の行の後に発生するように、autoCancellingTrue に設定されます。autoCancellingFalse に設定さた場合、スクリプトは、ユーザーが停止を選択するまで実行を継続します。ツールがキャンセルされると、読み取り専用の isCancelled プロパティが False から True に切り替わります。

プロパティ説明

arcpy.env.autoCancelling

autoCancellingTrue に設定すると、キャンセル時にスクリプトは現在の行で終了します。Falseに設定すると、キャンセル時に isCancelled プロパティが True に設定され、実行が継続します。デフォルトでは、autoCancellingTrue に設定されます。

arcpy.env.isCancelled

autoCancellingFalse に設定してツールがキャンセルされた場合、isCancelledTrueに設定されます。isCancelled は、デフォルトで False に設定される読み取り専用のプロパティです。

以下の例は、デモ ツールを示しています。このデモ ツールは、複数のテーブルを受け取ってコピーを作成し、それらの中間テーブルを 1 つにマージします。autoCancelling をデフォルト値の True のままにした場合、キャンセル発生時に、スクリプトは現在の行の後で停止します。この特定のツールの性質により、背後で複数の中間テーブルが作成されるため、キャンセルを含むいずれの場合でも、それらの中間テーブルをクリーンアップする必要があります。autoCancellingFalse に設定することで、キャンセルが遅延し、スクリプトは、isCancelled プロパティを評価することで、選択したコード内の任意の間隔または場所を監視することができます。isCancelledTrue に変わったときに、ツールがキャンセルされたことがわかり、ツールが終了する前に、直ちにデータが削除されます。

import arcpy
arcpy.env.autoCancelling = False
class CustomCancelException(Exception):
    """Custom exception for geoprocessing tool cancellations"""
    pass
def my_function(tables, output):
    temp_tables = []
    try:
        for table in tables:
            temp_tables.append(arcpy.CopyRows_management(table, '#')[0])
            # If isCancelled is True this means that the cancel button
            # has been pressed
            if arcpy.env.isCancelled:
                raise CustomCancelException('Tool has been cancelled')
        arcpy.Merge_management(tables, output)
    except CustomCancelException as err:
        arcpy.AddError(err)
    finally:
        # If tool is cancelled or finishes successfully, clean up intermediate data
        if temp_tables:
            for temp_table in temp_tables:
                arcpy.Delete_management(temp_table)
      
if __name__ == '__main__':
    inputs = arcpy.GetParameter(0)
    out_fc = arcpy.GetParameterAsText(1)
    my_function(inputs, out_fc)