ファイルの複数移動について rpa(初心者)

いつもお世話になっております。

今回は、ファイルの複数移動について考えております。
For Eachで複数回できるみたいなのですが、いまいちイメージがつかめません。

作成したい理想イメージとしましては、
Aフォルダ内に以下3つのファイルが存在した場合
「aファイル、bファイル、cファイル」
bとcのファイルのみコピーし別フォルダにペーストさせたい所存です。
移動させるファイルは2つなので「ファイルをコピー」アクティビティを2つ作成したら可能なのですが、後学のためFor Eachで作成したいと考えています。

また、bファイルの名前の頭5文字が一致したら移動するという
プログラムの記述方法もご存じの方はご教示お願いいたします。
(例)“あいうえおかきくけこ.text” → "あいうえお"一致したから移動!
のような処理を行いたいです。

※“ファイルパス+頭5文字のファイル名” + 「*(アスタリスク)」
で行いましたところ不発でした。。。

以上、よろしくお願いいたします。

for each

純粋にフルパスのフォルダ情報(“A”)から、ファイル名を取得する方法だと、

System.io.path.GetFileName(“A”)
で取得できます。

コピー対象外とするファイル情報が固定なら、
System.io.path.GetFileName(“A”).Equals(“aファイル”)
がTrueの時に、コピー対象外に出来ますね。

これに先頭5文字が。。。って条件を加えると、
System.io.path.GetFileName(“A”).Substring(0,5).Equals(“あいうえお”)

となります。

もし、ファイル拡張子でコピー対象を判断するのでしたら、
System.io.path.GetExtension(“A”)

でファイル拡張子が取れます。

1 Like

大変わかりやすいご説明ありがとうございます。
質問の回答につきまして、いくつかご質問がございます。
初歩的な質問になり、申し訳ございません。

>System.io.path.GetFileName(“A”).Substring(0,5).Equals(“あいうえお”)
上記の記述は(foreach 「item」 in 「●●(コレクション)」)の●●に記述するのでしょうか

また、以下条件式をTrueでFor Each内で処理させる場合
以下の記述のみでよろしいのでしょうか
VBAの記述のように If = Then といった記述が必要なのでしょうか
>System.io.path.GetFileName(“A”).Equals(“aファイル”)

以上、よろしくお願いいたします。

いえ、●●の箇所ではなく、Bodyの中に、条件分岐を入れてあげ、Falseのところにファイルコピーの処理を記述します。

※System.io.path.GetFileName(“A”).Substring(0,5).Equals(“あいうえお”)
の結果値はTrueかFalseになります。

同様に、System.io.path.GetFileName(“A”).Equals(“aファイル”)も条件分岐のFalseのところにファイルコピーの処理を記述します。

対象外とするファイルをどの様に管理、利用するかによって条件分岐のConditionに記述する式は変わりますが、今の質問の範囲では、条件分岐を連ねる方法でいいと考えます

お疲れ様です。
素早い回答ありがとうございます。

上記方法を試してみました。
記述方法、処理方法が違うのかうまく動いてくれません。

どの部分でひっかかっているかご教示いただけますでしょうか。

並列繰り返し(Foreach [item] in [System.io.path.GetFileName(“フォルダ名”)])

条件分岐
Condition(System.io.path.GetFileName(“フォルダ名”).Equals(“ファイル名”)) = True
true(処理なし)
False(条件分岐)

False(条件分岐)
Condition(System.io.path.GetFileName(“Aフォルダ名”).Substring(0,14).Equals(“該当のファイル”)) = True

ファイルをコピーアクティビティで指定のフォルダを指定

以上、よろしくお願いいたします。

条件分岐

ん~~、多分GetFileName(“フォルダ名”)は、GetFileName(item.ToString)になるかと。。。

For Each でコレンションを指定したら、itemには、その一つ一つが渡されます。ですので、フルパスのファイル名情報がitemに格納されます

1 Like

GetFileName ってフルパスから拡張子付きのファイル名取ってくるメソッドですが、なぜそれをFor Eachで回すんですか?
フォルダのフルパス一覧は、最初に出ている通り Directory.GetFiles メソッドですね。
Stringの配列が返ってくるのでFor eachなどで各フルパスを処理してください。
あと、ダラダラ長くすると、どこがダメなのかわからなくなるのでちゃんと代入したほうが良いですよ。
Foreach [szFilePath (String) ] in [System.IO.Directory.GetFiles (“フォルダ名”)])
szFileName = Path.GetFileName(szFilePath )
szFilePreName = szFileName.Substring(0,5)
szFilePreName.Equals(“あいうえお”)
とか分けておくと、デバッグ実行すればどこがおかしいかすぐわかります。

ともかく、.NETのメソッドの説明をお読みになるのが初心者脱出の近道ですよ^^

「 Path.GetFileName メソッド」

「Directory.GetFiles メソッド」

2 Likes

ご回答ありがとうございます。
今一度、HANACCHIさん、Chukiさんから頂いた情報を調べ
試行錯誤しようと思います。

変数の代入について調べましたが、下記画像の方法がでてきました。
もう少しスマートな方法はないのでしょうか。

既定値へ 変数(szFileName) 既定値 szFileName = Path.GetFileName(szFilePath )
の代入を試みましたが、エラーが発生しました。
書く場所が異なると思いますが、どこで記述すればよいかご教示いただけますでしょうか。

以上、よろしくお願いいたします。

すいません、r-chinenさんが考えるスマートな表記というのがどういう状態なのか想像できないので何とも。シーケンスに名前つけてその中で複数の代入処理を実施し普段は折り畳んでおくとかしておくと散らばっては見えなくなるので私はそうするか、または別ファイルに分けています。別ファイルに分けるとテストしやすいので。

あと、エラーが出たといわれても、どのように書いてどのようなエラーが出たのかが分からないのでなんとも・・・。
もし、既定値の右辺値に変数を入れてるのなら、その時点で確実に既定値に入れている変数に値が入っているかどうかを確認してください。なんとなく想像するに、変数パネルでスコープが内側だけの別の同名の変数を作って代入しようとしているように見えます。宣言したときに別の変数ができるのでどんな動きをするのか想像できません。

【エラー】
条件分岐: インデックスおよび長さは文字列内の場所を参照しなければなりません。
パラメーター名:length

条件分岐のアクティビティが赤枠になってエラーが出ているということは、たぶんそのアクティビティで設定している変数の内容がおかしいのだと思います。条件式を確認してみてください。

おそらく、5文字以下のファイルが含まれているのだと思います。

その場合は、5文字切り取ろうとして、そんな場所ないよと怒られています。

対応案を2つほど

1.事前に文字数が5文字以上か判定する
例:szFilePreName.Length < 5 の条件で判定を抜ける

2.比較しようとする文字列に無理やり文字を足して判定する
例:szFilePreName = (szFileName & “00000”).Substring(0,5)
※前後は同じ

※_Chukiさんのおっしゃる

>ダラダラ長くすると、どこがダメなのかわからなくなるのでちゃんと代入したほうが良いですよ。

というTipsが見事に効いてますね。。

1 Like

お疲れ様です。
ご質問のご回答ありがとうございます。

恐らく、私は変数の取り扱い方を誤っているのでは、、、
と思ってきました(;‘∀’)。。。

_Chukiさんがおっしゃっていた代入を複数代入アクティビティで
szFileName = Path.GetFileName(szFilePath )
szFilePreName = szFileName.Substring(0,5)
を変数として作成しました。
するとデバック時にエラーが、、

【エラー】
※複数代入:szFileName.Substring(0,5)をszFilePreNameに割り当てられません。

繰り返し(コレクションの各要素)
要素[szFilePath (String)] コレクション[System.IO.Directory.GetFiles(“フォルダ名”)]
でフォルダパス一覧メソッドを要素に格納

条件分岐
Condition[szFileName.Equals(“コピー対象外のファイル名”)]
Elseの場合条件分岐
Then条件なし

条件分岐
Condition[szFilePreName.Equals(“5文字の名前が一致したファイル名”)]
Thenの場合コピーして移動
Else条件なし(今はなし)

条件分岐の条件式の書き方がいまちち不明な点と
なぜ、代入ができないのか、、、、
2つの疑問点をご教示いただけますでしょうか。

質問の回答をすでに上記Tipsでしておりましたらすいません。m(__)m

条件分岐については要件が不明なのでアレですが多分あってそう。

エラーが出る原因はすでに指摘のある通りファイル名に5文字以下のものがあるのではないかと想像します。
エラーが出る直前の行で1行書き込みアクティビティでファイル名を書き出してみてはいかがでしょうか。
また、ファイル名の一覧作成時にワイルドカード使って絞り込む方法についてブログ化したのでもしご参考になれば。
http://blogs.wankuma.com/chuki/archive/2020/06/30/1784056.aspx

お世話になっております。

たくさんの方のご支援のおかげでForEach文の理解が深まりました。

恐らく、複数コピー関連の質問は最後になりますが、、、
コピーの方法についてご教示お願いいたします。

変数
sp2FileName = System.IO.Path.GetFileName(“フォルダ.ファイル名パス”)
sp2FilePreName = sp2FileName.Substring(0,8)

現在
※For文は端折ります

sp2FileName.Equals(“ファイルabc”)
Then 処理なし
Else 条件分岐

【条件分岐】
sp2FilePreName.Equals(“該当するファイル8文字”)
Then ファイルの移動処理
Else 処理なし

【ファイルの移動処理】
移動元
ファルダA.ファイルabcパス

移動先
フォルダB.ファイルabcパス

移動は現在「ファイルを移動」アクティビティで上記の方法で行っております。
ですが、こちらの方法で一つ懸念材料がございます。
たとえば、「ファイルabc」とファイルのフルパスを記述した場合
「ファイルabc」の移動はできても
「ファイルarr」や「ファイルade」といったファイルを移動させようとした場合
エラーでファイルがないと出る認識です
これらを解決する方法はございますでしょうか。

※上記方法でファイルの移動は成功しております

【追記】
自分の理想である、ファイルの複数取得
「aaaが一致したら移動するプログラム(条件分岐)」
【Then】
移動元
フォルダA.ファイルaaabbbccc

移動先
フォルダB.ファイルaaabbbccc

もし空フォルダAに「ファイルaaabbbeee」を格納し
RPAツールを動かした場合ファイルは移動されない認識です。

以下メソッドを使用すれば解決できますでしょうか。
また、メソッドは同じでも条件式さえ変えれば可能でしょうか

現在は
System.IO.Path.GetFileName(“フォルダ名”)
を使用し、ファイル名と拡張子の取得元のパス文字列を返してますが

以下の
System.IO.Directory.GetFiles(String, String)
指定したディレクトリ内の指定した検索パターンに一致するファイル名 (パスを含む) を返します。
を使用した方が理想に近づけるのではと思いました。

認識が異なってる点がございましたら、ご教示お願いいたします。

以上、よろしくお願いいたします。

前提:
beforeフォルダに
abc.txt
aaabbbccc.txt
aaabbbeee.txt
ファイルがある場合に
afterフォルダに
aaabbbccc.txt
aaabbbeee.txt
を移動させたいとしました。

ふまえて、sampleを作成してみました。
sample.zip (2.7 キロバイト)
※ほぼ回答を順番にならべただけですが。。。

_Chukiさんの回答より
Foreach [szFilePath (String) ] in [System.IO.Directory.GetFiles (“フォルダ名”)]

HANACCHIさんの回答より
szFileName = Path.GetFileName(szFilePath )

私の回答から
szFilePreName = (szFileName & “00000”).Substring(0,5)

r-chinenさんの書き込みから
※一部意訳していますが。。
【条件分岐】
sp2FilePreName.Equals(“該当するファイル8文字”)
Then ファイルの移動処理
Else 処理なし

【ファイルの移動処理】
移動元
ファルダA.ファイルabcパス

移動先
フォルダB.ファイルabcパス

2 Likes

あえて、書いてないのか違う書き方をしたのが存じませんが、その上側のGetFilesでファイルの一覧を取得してループしていると存じます。この時繰り返し処理の各行を受る変数(szFilePath)にはフルパスが入っているので、これを移動に使えば済むように見えました。

1 Like

お疲れ様です
御礼が遅れてしまい申し訳ございませんでした。

_Chukiさんのご指摘、kyd_hasさんのサンプルをみて気がつきました。
代入をFor文の前に行ってました、、、
動くはずないですよね(;‘∀’)

無事、ご教示いただいた方法で理想の形になりました!!!

このスキルを活かしUiPathでできる範囲を広げようと思います!

長い間お付き合いいただきありがとうございました。

3 Likes

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.