UiPath Activity Creatorを使ってみる。(その3:Wizardでの各設定とUI・コードの関係について)


このドキュメントの概要

 前回 はActivity Creator のWizardを使った簡単なアクティビティの作成とプロパティの設定について見ていきました。
 今回は、最初にActivity Creator のWizardでの各設定が、最終的にUiPath Studio上でどのように見えるかを確認し、その後各設定によってどのようなコードが自動生成されているかを確認します。

Wizardの設定とアクティビティのUIとの関係

 Wizard上の設定に対して、アクティビティのUIがどのようになるかを確認します。まず下図のようにWizardを使ってActivityを作成します。赤字の番号は設定項目とUIの各項目を紐づけるためにつけています。

アクティビティの設定

プロパティの設定

【注意事項】
 今回は見た目の見やすさを優先して、プロパティ名にマルチバイト文字を使用しておりますが、Wizardが自動生成するコードは、一部で変数名等を大文字、小文字の違いだけで識別・自動生成している箇所があり、大文字小文字の区分がない日本語では、生成したコードにエラーを含んだ状態になります。そのため、特にプロパティ名については基本的にはASCII文字での利用をお勧めします。
 Resourceファイルを使った多言語化にも対応していますので、マルチバイトの表示は基本的にそちらで対応した方が良いと思います。

 Wizard上でこのように設定したものが、UiPath Studioのアクティビティ上でどのよに反映されるかを示したものが下図になります。

・アクティビティパネル

Wizard上のアクティビティ定義の(1)Name欄がアクティビティ名に、(2)Description欄がヒントの表示になります。

・デザイナパネルとプロパティパネル

Wizard上のアクティビティ定義の(1)Name欄が表示名のデフォルトになります。また(3)Timeoutを有効にすると、TimeoutとContinueOnErrorの各プロパティが表示され有効となります。
プロパティ定義の(4)Categoryはカテゴリに、(5)のNameはそれぞれそのままプロパティの名称になります。
(6)Descriptionはテキストボックス内の説明になります。(7)(8)は表示上わからないので一旦飛ばして、(9)のRequiredを有効にすると、未入力時エラーのValidationが設定されるとともに、デザイナパネルのアクティビティ上にテキストボックスとして表示されます。

設定と自動生成コードとの関係

Wizard上の設定によって自動生成コードが変化する箇所について確認します。

Activity定義のTimeout設定

まず(3)のTimeout設定ですが、無効の場合はアクティビティはBaseAsyncCodeActivityクラスの派生クラスとして定義されます。

public class TestSum : BaseAsyncCodeActivity

Timeout設定を有効にするとアクティビティはContinuableAsyncCodeActivityクラスの派生クラスとして定義されます。

public class TestSum : ContinuableAsyncCodeActivity

このContinuableAsyncCodeActivityは以下のようなTimeoutおよびContinueOnErrorのプロパティを持っており、これに関するメソッドも定義されているため、これらが機能する形になります。

        /// <summary>
        /// If set, continue executing the remaining activities even if the current activity has failed.
        /// </summary>
        [LocalizedCategory(nameof(Resources.Common_Category))]
        [LocalizedDisplayName(nameof(Resources.ContinueOnError_DisplayName))]
        [LocalizedDescription(nameof(Resources.ContinueOnError_Description))]
        public override InArgument<bool> ContinueOnError { get; set; }

        [LocalizedCategory(nameof(Resources.Common_Category))]
        [LocalizedDisplayName(nameof(Resources.Timeout_DisplayName))]
        [LocalizedDescription(nameof(Resources.Timeout_Description))]
        public InArgument<int> TimeoutMS { get; set; } = 60000;

        #endregion

Wizard上では、Timeoutの項目とContinueOnErrorが連動して設定されますがマニュアルでコードを変更すれば、Timeoutプロパティあり、ContinueOnErrorプロパティなしの組み合わせも可能です。具体的には例えば継承するクラスをTimeoutAsyncCodeActivity に変更し、不足するプロパティおよびメソッドを追加すればOKです。

Property定義のDirectionとType

(7)Directionおよび(8)Typeの設定ですが、下記のような形で自動生成されます。

        #region Properties

        [LocalizedDisplayName(nameof(Resources.アクティビティ名_プロパティ名1_DisplayName))]
        [LocalizedDescription(nameof(Resources.アクティビティ名_プロパティ名1_Description))]
        [LocalizedCategory(nameof(Resources.Input_Category))]
        public InArgument<string> プロパティ名1 { get; set; }

        [LocalizedDisplayName(nameof(Resources.アクティビティ名_プロパティ名2_DisplayName))]
        [LocalizedDescription(nameof(Resources.アクティビティ名_プロパティ名2_Description))]
        [LocalizedCategory(nameof(Resources.Input_Category))]
        public InArgument<string> プロパティ名2 { get; set; }

        #endregion

Property定義のOptions - Required

(9)のRequiredを有効にすると、アクティビティ上にテキストボックスが表示されるとともに、下記のようなValidationのコードが自動生成されます。コードからもわかる通りNullチェックだけしかできません。内容的には各プロパティ定義に[RequiredArgument]属性をつけるのと同じようです。
なお仕様上InArgument<T>型で入力された中身のチェックは、実行時にしかできません。

        protected override void CacheMetadata(CodeActivityMetadata metadata)
        {
            if (プロパティ名1 == null) metadata.AddValidationError(string.Format(Resources.ValidationValue_Error, nameof(プロパティ名1)));

            base.CacheMetadata(metadata);
        }

もしNullだけではなく、InArgument<T>型で入力された中身のチェックは以下のようにします。
仮にInArgument<int>として定義されたIntervalというプロパティがあり、正の数以外はエラーとしたい場合、

                var intervalValue = (Literal<int>)Interval.Expression;
                if (intervalValue != null)
                {
                    if (intervalValue.Value <= 0) { metadata.AddValidationError("Interval must be positive"));}
                }

となります。

次回はアクティビティのデザイナー部分について説明します。

(その3おわり)

その1 その2 その3 その4 その5 その6