はじめに
コードソースファイルとは、UiPath Studio v23.10で追加された機能の1つです。
タイトルの内容を検証してみます。公式ドキュメントの説明は以下です。
正直、自分にはドキュメントをサラッと読んだけでは意味が分かりませんでした。
じっくり…ゆっくり…読んだら理解できた気がしたので、実際に作って動かしてみました。
コード化されたワークフロー、コード化されたテストケースの概要は以下の記事に記載しています。ご興味があればご参照ください。
コード化されたワークフロー、コード化されたテストケースとの違いを端的に言えば、
実行する側ではなく、呼び出される側(≒ 部品のようなもの)であることです。
紹介する機能および当記事の内容について、ある程度のプログラム言語の知識をお持ちの方が対象になっています。
「コードソースファイル」を理解するためだけの処理を作ってみます。
機能の理解を目的とし、とても簡単なものを作ってみます。
まずは「コードソースファイル」を作成する手順です。
① 右クリック > コードソースファイル をクリックします。
② デフォルトの「ソースファイル」の名前のまま、作成をクリックします。
プロジェクト内に「ソースファイル.cs」が作成されます。
つづいて、"Hello World!!" を出力してみます。
① 「ソースファイル.cs」は以下のように実装してみます。
当記事では、プロジェクト名は 「コードを使ってみる」 という名前にしました。
コード内の namespace
の値にプロジェクト名が設定されます。呼び出し時にこの値を使うので意識しておきましょう。
using System;
using System.Collections.Generic;
using System.Data;
using UiPath.Core;
using UiPath.Core.Activities.Storage;
using UiPath.Orchestrator.Client.Models;
using UiPath.Testing;
using UiPath.Testing.Activities.TestData;
using UiPath.Testing.Activities.TestDataQueues.Enums;
using UiPath.Testing.Enums;
using UiPath.UIAutomationNext.API.Contracts;
using UiPath.UIAutomationNext.API.Models;
using UiPath.UIAutomationNext.Enums;
//using コードを使ってみる.ObjectRepository; ← 実験的にコメント化して動かしました。
namespace コードを使ってみる
{
public class ソースファイル
{
public static string helloWorld(string s) {
Console.WriteLine( "受け取った値です。--->" + s);
return "[Hello World!!]を返します!";
}
}
}
public static
とついている点がポイントです。
static
の指定によりclass.関数
という形で呼び出すことができます。
(公式ドキュメントで説明されている方法です)
今回は stringを返す helloWorld 関数として用意しました。
static
でないclass
での実行も可能でした、後述の章をご参照ください。
呼び出し方の解釈は以下のような形です。
namespace名.class名.関数名(引数)
namespace名はリネームしていないければ、プロジェクト名になっているはずです。
実行したところ、ログ出力は以下のようになりました。
Console.WriteLine の「こんにちは、世界!」も、
メッセージをログ アクティビティの「Hello World!!」も確認できました
ちなみに公式ドキュメントの説明は、こんな処理です。
上記の公式ドキュメントにも一通り説明が記載されていますが、ブロックごとに分かれていて全体像の理解に時間が掛かりました。
改めてこの内容を確認していきます。
引数として渡した2つの値の範囲でランダムなTimeSpanを生成する、という処理のようです。
この処理自体の意味ということよりも、この手法の応用で共通部品が作成できる…という点をご理解いただけると嬉しいです。
実装は以下。
こちらではnamespace
はsampleという名前にしています。
デフォルトがプロジェクト名であるだけで、任意の名前に変更することもできます。
// ~
//using ブロックは省略します
// ~
namespace sample
{
public class TimeSpanHelper
{
// ランダムな値を生成するために使います
private static Random _random = new Random();
// スレッドを保護しながら、複数のスレッドが同時に処理できるようにします
private static object _lockObj = new object();
// パブリックな静的メソッドを実装します。
public static TimeSpan GetRandomTimeSpanBetween(int lowerBoundMs, int upperBoundMs)
{
// スレッドを保護しながら、複数のスレッドが同時に処理されるようにします。
lock (_lockObj)
{
// ランダムな整数値を生成し、
var ms = _random.Next(lowerBoundMs, upperBoundMs);
// 生成されたランダム値を TimeSpan オブジェクトに変換します
return TimeSpan.FromMilliseconds(ms);
}
}
}
}
簡単な補足をすると…
private static Random _random
という変数定義にもstatic
がついています。staticの関数から利用するために必要な指定です。
lock (_lockObj)
は同時に処理された際の不整合を予防するための記述です。
呼び出しは下図。
(当実装は、公式ドキュメントの記載に則ってみました。TimeSpanをログ出力すること自体に意味はなさそうですね…)
値の詳細 は以下です。
sample.TimeSpanHelper.GetRandomTimeSpanBetween(2000, 4000)
以上、C#で共通部品ができました!
サンプル自体はあまり意味の無さそうな処理ですが、同時処理を考慮したスレッドセーフな書き方になっているので、応用の元としては良さそうです。
まとめ
正直、公式ドキュメントの理解が追い付かず「コードソースファイル」についてはスルーしていました。
ただ理解を深めると「これはもしかしたら強力かもしれない…!?」と感じてきました。
- ライブラリやワークフローだけでは難しい処理要件がある…とか、
- Qiitaで見つけたコードやChatGPTで生成したコードをコピペで部品化してみる…とか、
- ローコード実装で煩雑になりすぎた処理をC#でリファクタリングする…とか、
…私は上記のようなシーンで使ってみたいと感じました。
ちなみに… 「コードを呼び出し」 アクティビティ でも同じようなことは可能です。
https://docs.uipath.com/ja/activities/other/latest/workflow/invoke-code
ただ以下のような点に、細かいように見えるけれど大きな違いがあると感じます。
- 再利用しやすい
- コードを書きやすい
- 開発環境への依存度が下がるため、部品としてテストや保守がしやすい
具体的なアドバンテージとしては、ブレークポイントを設定してのステップイン実行も可能です。よりデバッグがしやすくなっています。
「あともうちょっとなんだけど…」と諦めていた所に、部分的に使える有効な手段ではないかと思います。
以上、なにか活用にヒントになれば幸いです。
補足: staticではない関数でも利用可能です。
staticではない関数でも実行可能でした。何か制約があるのかな、と思ったりしたのですが、C#の基本的な使い方はできるようです。
ログ出力は全く同じでしたので省略します。利用のポイントは以下をご参照ください。
コードは下図です。
static
のみを除いた「ソースファイル1」を作成しています。
ワークフローからの呼び出しもほぼ同じですが、New
がついている点が違いです。
(細かいところですが「ソースファイル1」を指定している点も違います)
(当然、生成したインタンスを変数に設定することも可能です。先の章の書き方の対比としてこのような呼び方としています)
呼び出し方の解釈は以下のような形です。
class名の後ろに() カッコ
がついていることがstatic
指定との違いです。
New namespace名.class名().関数名(引数)
※ プログラムが分かる方向けの補足ですが、検証したところ独自のコンストラクターを定義した呼び出しも可能でした。
以上です。