皆もすなるQiitaといふものを、儂もしてみむとてするなり。
と言う訳で、こん**は!はなっち!です。
★★★この記事はUiPathブログ発信チャレンジ2021サマー、7月31目の記事です。★★★
振り返り
前回は、「VBA を呼び出し」アクティビティで遭遇するエラーについてまとめました。
で、.basファイルは"SJIS"で記述した、引数の属性もInteger型に対して、ロボもInt32型で定義した、これでもうバッチリですね!
落とし穴はそこにある!
Int32型の変数を、「VBA を呼び出し」アクティビティのObject型経由で、VBAのInteger側に渡して処理をしていきます。
例えば、VBAのInteger側に渡された値が、固定値Xと、固定値X+3の間にある時、Trueを返すFunction関数を作成したとします。
こんな範囲チェックのFunction関数を用意しなくても、条件分岐アクティビティで実装できるぢゃん!とお思いでしょうが、そこは堪えて、お読みください。
Function関数のテストパタンとしては、
表 テスト時の値とその予想結果
値 | 結果 | 備考 |
---|---|---|
X - 1 | False | |
X | True | 下限閾値 |
X + 1 | True | |
X + 3 | True | 上限閾値 |
X + 4 | False |
一通り、試験は合格する訳ですが、折角Int32型を使っているので、Int32型の最大値(Int32.MaxValue)を指定して試験してみました。
図1 Int32型の変数に、Int32.MaxValueを設定した
Int32.MaxValueの場合、何が起こったか
結果は「範囲外です」となりました。Int32型とInteger型。同じInt系の型ではないか?と首をかしげる方もいらっしゃると思いますが、ここがポイントなのです。
UiPathで、と言うか、.Netでの各数値系型の取りうる値を見てみましょう!
型 | 最小値 | 最大値 |
---|---|---|
Int16 | -32,768 | 32,767 |
Int32 | -2,147,483,648 | 2,147,483,647 |
Int64 | -9,223,372,036,854,775,808 | 9,223,372,036,854,775,807 |
Long | -9,223,372,036,854,775,808 | 9,223,372,036,854,775,807 |
Single | -3.402823E+38 | 3.402823E+38 |
Double | -1.79769313486232E+308 | 1.79769313486232E+308 |
巨大ですねぇ。
一方、VBAでの各数値系型の取りうる値を見てみましょう!
型 | 最小値 | 最大値 |
---|---|---|
Integet | -32,768 | 32,767 |
Long | -2,147,483,648 | 2,147,483,647 |
Single | -3.402823E+38 | 3.402823E+38 |
Double | -1.79769313486232E+308 | 1.79769313486232E+308 |
これを見ると、Int32型のMaxValueは、Integer型には格納できない事が分かりますね。これが先の「範囲外エラー」に繋がるのです。
どうしたらいいか?
対策は3つあると考えています。
1)Int16型を使用し、VBAのInteger型に十分格納できるようにする。
2)Int32型を使用し、VBAのLong型に変更し、ロジックで制御する
3)渡す値の範囲を予め決めてしまい、論理的に十分格納できるようにする。
1)、2)に関して言うと、.Netでの型定義と、VBAでの型定義が違うということを理解すれば、どちらを採用すべきか自ずと判断付きますね。
3)は、ロボ側で、その範囲を予め決めてしまい、それをVBA側の型で十分格納できるようにしてあげる方法で、実際にはMathクラスを駆使して、実装します。
例)どんな数が来ても、業務的な最小値2,最大値5とする。
代入アクティビティ
左辺:変数X(Int32型)
右辺:Math.Max(2, Math.Min(5, 変数X))
変数X | 計算式 | 評価 |
---|---|---|
-1 | Math.Max(2, Math.Min(5, -1)) | 5と-1の最小値(=-1)と2との最大値(=2) |
0 | Math.Max(2, Math.Min(5, 0)) | 5と0の最小値(=0)と2との最大値(=2) |
2 | Math.Max(2, Math.Min(5, 2)) | 5と2の最小値(=2)と2との最大値(=2) |
4 | Math.Max(2, Math.Min(5, 4)) | 5と4の最小値(=4)と2との最大値(=4) |
5 | Math.Max(2, Math.Min(5, 5)) | 5と5の最小値(=5)と2との最大値(=5) |
6 | Math.Max(2, Math.Min(5, 6)) | 5と6の最小値(=5)と2との最大値(=5) |
この処理結果を、「VBA を呼び出し」アクティビティのエントリメソッドのパラメーターに指定してあげれば、「範囲外です」と言うエラーは発生しません。
おわりに
いかがでした?
「VBA を呼び出し」アクティビティのエントリメソッドのパラメーターに定義する型、
VBAとして定義する型についてまとめました。同じ系列の型でも、コンピューターの内部ではその長さと言うのを意識して使ってくれているのですね。どうせなら、一致した作りにしておいてくれれば...と思うのですがね(^^♪
そういう型と型の取りうる値の範囲を頭に入れつつ、正しく引数を指定し、正しく戻り値を処理し、業務効率化を進めてまいりましょう!
是非UiPathでのロボ開発の一助になればと思っています。
ありがとうございました!