🥞

Power Automate Desktop サンプル ファイルのコピー

2023/10/14に公開

ファイルのコピー/移動

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

手動でのファイル操作が面倒になったので作りました。

最初はバッチ処理で自動化していたのですが、エンコードミスをやらかすたびに差し替えていたので、目視で確認後に手動で行うようにしました。⇒今度はファイル操作のミスをやらかすので、自動化することにしました。


説明

  1. 指定のフォルダーにファイルを置いて実行
  2. コピーする
  3. コピーするものとしないものがある(外部ファイル(json)で照合する)
  4. 移動する

コード

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\\FileStore\\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

Main

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 CopyAutoDestDir TO Settings['AppSettings']['CopyAutoDestDir']
    SET CopyFilterDestDir TO Settings['AppSettings']['CopyFilterDestDir']
    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

Init

Filter
FUNCTION Filter GLOBAL
    CALL Now
    Text.AppendLine Text: Log LineToAppend: $'''%CurrentDateTime% INFO Copy all 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
    File.Copy Files: Files Destination: CopyAutoDestDir IfFileExists: File.IfExists.DoNothing
    ON ERROR REPEAT 1 TIMES WAIT 20
    ON ERROR InvalidDestinationFolderError
        SET ErrorMsg TO $'''%CopyAutoDestDir%が存在しません。'''
        CALL Err
        THROW ERROR
    ON ERROR CopyFileError
        SET ErrorMsg TO $'''コピーできません。'''
        CALL Err
        THROW ERROR
    END
    CALL Now
    Text.AppendLine Text: Log LineToAppend: $'''%CurrentDateTime% INFO Copy filter process.''' Result=> Log
    LOOP FOREACH 対象ファイル IN Files
        **REGION 比較
        LOOP FOREACH 比較リスト IN filtering.filters
            IF Contains(対象ファイル.Name, 比較リスト.text, True) THEN
                SET isExclude TO True
                EXIT LOOP
            END
        END
        **ENDREGION
        # 一致しなければコピー
        IF isExclude = False THEN
            CALL Now
            Text.AppendLine Text: Log LineToAppend: $'''%CurrentDateTime% INFO %対象ファイル.NameWithoutExtension%''' Result=> Log
            File.Copy Files: 対象ファイル Destination: CopyFilterDestDir IfFileExists: File.IfExists.DoNothing
                        ON ERROR REPEAT 1 TIMES WAIT 20
                        ON ERROR InvalidDestinationFolderError
                            SET ErrorMsg TO $'''%CopyFilterDestDir%が存在しません。'''
                            CALL Err
                            THROW ERROR
                        ON ERROR CopyFileError
                            SET ErrorMsg TO $'''%対象ファイル.Name%をコピーできません。'''
                            CALL Err
                            THROW ERROR
                        END
        ELSE
            SET isExclude TO False
        END
    END
    CALL Now
    Text.AppendLine Text: Log LineToAppend: $'''%CurrentDateTime% INFO Move process.''' Result=> Log
    File.Move Files: Files Destination: MoveDestDir IfFileExists: File.IfExists.Overwrite
    ON ERROR REPEAT 1 TIMES WAIT 20
    ON ERROR InvalidDestinationFolderError
        SET ErrorMsg TO $'''%MoveDestDir%が存在しません。'''
        CALL Err
        THROW ERROR
    ON ERROR MoveFileError
        SET ErrorMsg TO $'''移動できません。'''
        CALL Err
        THROW ERROR
    END
END FUNCTION

Filter 1
Filter 2

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
    • 監視先のフォルダー
  • CopyAutoDestDir
    • コピー先のフォルダー
  • CopyFilterDestDir
    • コピー先のフォルダー (カスタムフィルターを適用する)
  • MoveDestDir
    • 移動先のフォルダー
  • FileNameFilter
    • 処理対象のファイル
    • 正規表現文字列
AppConfig.json
{
    "AppSettings": {
        "StrategyFile": "\\filter.json",
        "StoreLog": "\\fslog.txt",
        "WatchDirectory": "G:\\tmp",
        "CopyAutoDestDir": "\\\\192.168.xxx.xxx\\aaa",
        "CopyFilterDestDir": "D:\\hogehoge\\bbb",
        "MoveDestDir": "F:\\hogehoge\\ccc",
        "FileNameFilter": "*.mp4"
    }
}

カスタムフィルター

  • filter.json で定義して、任意の除外フィルターを構築できる
  • 上から順に比較する。ヒットすると以降の照合はしない
filter.json
{
    "filters": [
        {
            "text": "FileName1"
        },
        {
            "text": "FileName2"
        },
        {
            "text": "FileName3"
        }
    ]
}

あとがき

PADでエラーハンドリング弄るの面倒くさいですね。

Discussion