🕌

Power Automate Desktop サンプル ファイルの振り分け

2023/11/23に公開

ファイルの振り分け

趣味で作ったフローです。

手動でファイルの振り分けが面倒なので放置していた作業を自動化するものを作りました。

指定のフォルダーにあるファイルを条件に従ってそれぞれのサブフォルダーに移動します。

ファイルの書き出し時にそれぞれ指定のフォルダーに出力することもできるのですが、
別にいいかなあと思って最初に設定しなかったら、あとから修正が面倒になって放置していました。
まあ、溜まったらまとめて削除しているので別に今のままでもいいんですけど。
せっかくなので定期的に整理しようかなあ。と。……どっちみち消しますが。


説明

  1. NAS上のファイルを整理
  2. ファイルを条件に従って振り分ける(外部ファイル(json)で照合する)

コード

Main
FUNCTION Main_copy GLOBAL
    **REGION 読み込み
    CALL Now
    SET Log TO $'''%CurrentDateTime% INFO Store process.'''
    # Configファイルのパスを環境に合わせて書き換える
    System.GetEnvironmentVariable.GetEnvironmentVariable Name: $'''OneDrive''' Value=> OneDrive
    SET AppConfig TO $'''%OneDrive%\\hogehoge\\TsStore\\AppConfig.json'''
    File.GetPathPart File: AppConfig Directory=> BaseDir
    CALL Init
    **ENDREGION
    CALL Filter
    **REGION 最終処理
    CALL Now
    Text.AppendLine Text: Log LineToAppend: $'''%CurrentDateTime% INFO Process is succeed.''' Result=> Log
    File.WriteText File: StoreLog TextToWrite: Log AppendNewLine: True IfFileExists: File.IfFileExists.Append Encoding: File.FileEncoding.Unicode
    **ENDREGION
END FUNCTION
Init
FUNCTION Init GLOBAL
    **REGION 設定ファイル
    Text.AppendLine Text: Log LineToAppend: $'''%CurrentDateTime% INFO Check config.''' Result=> Log
    File.ReadTextFromFile.ReadTextAsList File: AppConfig Encoding: File.TextFileEncoding.UTF8 Contents=> FileContents
    ON ERROR DirectoryNotFoundError
        SET ErrorMsg TO $'''ディレクトリが見つかりません。'''
        CALL Err
        THROW ERROR
    ON ERROR FileNotFoundError
        SET ErrorMsg TO $'''ファイルが見つかりません。'''
        CALL Err
        THROW ERROR
    ON ERROR ReadFromFileError
        SET ErrorMsg TO $'''ファイルを読み取れませんでした。'''
        CALL Err
        THROW ERROR
    END
    Variables.ConvertJsonToCustomObject Json: FileContents CustomObject=> Settings
    ON ERROR ParseJsonError
        SET ErrorMsg TO $'''構文エラーです。'''
        CALL Err
        THROW ERROR
    END
    SET StrategyFile TO $'''%BaseDir%%Settings['AppSettings']['StrategyFile']%'''
    SET StoreLog TO $'''%BaseDir%%Settings['AppSettings']['StoreLog']%'''
    SET WatchDirectory TO Settings['AppSettings']['WatchDirectory']
    SET MoveDestDir TO Settings['AppSettings']['MoveDestDir']
    SET FileNameFilter TO Settings['AppSettings']['FileNameFilter']
    **ENDREGION
    **REGION フィルターリスト
    Text.AppendLine Text: Log LineToAppend: $'''%CurrentDateTime% INFO Check filter list.''' Result=> Log
    SET settingsFile TO StrategyFile
    File.ReadTextFromFile.ReadText File: settingsFile Encoding: File.TextFileEncoding.UTF8 Content=> FileContents
    ON ERROR DirectoryNotFoundError
        SET ErrorMsg TO $'''ディレクトリが見つかりません。'''
        CALL Err
        THROW ERROR
    ON ERROR FileNotFoundError
        SET ErrorMsg TO $'''ファイルが見つかりません。'''
        CALL Err
        THROW ERROR
    ON ERROR ReadFromFileError
        SET ErrorMsg TO $'''ファイルを読み取れませんでした。'''
        CALL Err
        THROW ERROR
    END
    Variables.ConvertJsonToCustomObject Json: FileContents CustomObject=> filtering
    ON ERROR ParseJsonError
        SET ErrorMsg TO $'''構文エラーです。'''
        CALL Err
        THROW ERROR
    END
    Text.AppendLine Text: Log LineToAppend: $'''%CurrentDateTime% INFO Check OK.''' Result=> Log
    **ENDREGION
END FUNCTION
Filter
FUNCTION Filter GLOBAL
    CALL Now
    Text.AppendLine Text: Log LineToAppend: $'''%CurrentDateTime% INFO Move process.''' Result=> Log
    Folder.GetFiles Folder: WatchDirectory FileFilter: FileNameFilter IncludeSubfolders: False FailOnAccessDenied: True SortBy1: Folder.SortBy.NoSort SortDescending1: False SortBy2: Folder.SortBy.NoSort SortDescending2: False SortBy3: Folder.SortBy.NoSort SortDescending3: False Files=> Files
    ON ERROR FolderNotFoundError
        SET ErrorMsg TO $'''%WatchDirectory%が存在しません。'''
        CALL Err
        THROW ERROR
    ON ERROR RetrieveFilesError
        SET ErrorMsg TO $'''ファイルの一覧を取得できません。'''
        CALL Err
        THROW ERROR
    END
    LOOP FOREACH 対象ファイル IN Files
        **REGION 比較
        LOOP FOREACH 比較リスト IN filtering.filters
            IF Contains(対象ファイル.Name, 比較リスト.text, True) THEN
                EXIT LOOP
            END
        END
        **ENDREGION
        CALL Now
        Text.AppendLine Text: Log LineToAppend: $'''%CurrentDateTime% INFO %対象ファイル.NameWithoutExtension% ⇒ %MoveDestDir%%比較リスト.storeDir%''' Result=> Log
        File.Move Files: 対象ファイル Destination: $'''%MoveDestDir%%比較リスト.storeDir%''' IfFileExists: File.IfExists.DoNothing
                ON ERROR REPEAT 1 TIMES WAIT 20
                ON ERROR InvalidDestinationFolderError
                    SET ErrorMsg TO $'''%MoveDestDir%%比較リスト.storeDir%が存在しません。'''
                    CALL Err
                    THROW ERROR
                ON ERROR MoveFileError
                    SET ErrorMsg TO $'''%対象ファイル.Name%を移動できません。'''
                    CALL Err
                    THROW ERROR
                END
    END
END FUNCTION

Filter

Err
FUNCTION Err GLOBAL
    CALL Now
    Text.AppendLine Text: Log LineToAppend: $'''%CurrentDateTime% ERROR Process is failure. %ErrorMsg%''' Result=> Log
    File.WriteText File: StoreLog TextToWrite: Log AppendNewLine: True IfFileExists: File.IfFileExists.Append Encoding: File.FileEncoding.Unicode
END FUNCTION
Now
FUNCTION Now GLOBAL
    DateTime.GetCurrentDateTime.Local DateTimeFormat: DateTime.DateTimeFormat.DateAndTime CurrentDateTime=> CurrentDateTime
END FUNCTION

設定ファイル

  • BaseDir
    ├ AppConfig.json
    └ filter.json

AppConfig.json

  • StrategyFile
    • フィルターファイル
  • StoreLog
    • ログファイル
  • WatchDirectory
    • 監視先のフォルダー
  • MoveDestDir
    • 移動先のフォルダー (カスタムフィルターを適用する)
  • FileNameFilter
    • 処理対象のファイル
    • 正規表現文字列
AppConfig.json
{
    "AppSettings": {
        "StrategyFile": "\\filter.json",
        "StoreLog": "\\fslog.txt",
        "WatchDirectory": "\\\\hogehoge\\hoge",
        "MoveDestDir": "\\\\hogehoge\\hoge",
        "FileNameFilter": "*.ts"
    }
}

カスタムフィルター

  • MoveDestDir
    ├ [dir1]
    ├ [dir2]
    └ [dir3]
  • filter.json で定義して、任意のキーワードフィルターを構築できる
  • 上から順に比較する。ヒットすると以降の照合はしない
filter.json
{
    "filters": [
        {
            "storeDir": "\\dir1",
            "text": "text1"
        },
        {
            "storeDir": "\\dir1",
            "text": "text2"
        },
        {
            "storeDir": "\\dir2",
            "text": "text3"
        },
        {
            "storeDir": "\\dir3",
            "text": ""
        }
    ]
}

あとがき

使いまわしました。他にも、
ファイル関連の手抜きで何か思いつけばどんどん使いまわそうと思います。

Discussion