1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[AutoHotKey]FileSelectFileのクソ野郎を置き換える関数

Last updated at Posted at 2018-06-16

動機

  • FileSelectFileはクソ野郎だ
  • 引数としてファイルパスを受け取るスクリプトで、引数がなかったときにファイル選択……とかやろうとすると、処理が複雑になってしまう
  • ファイルを選択して、ファイルパスのリストに直す関数を書こう

FileSelectFileの出力をフルパスに直す

基本的には前やったアレ

関数内でFileSelectFileして出力をなんとかする

関数から複数のファイルパスを取り出す方法

基本的に、上に書いたものほどスマートだと思う。

配列

配列を関数の戻り値とすることで、For indexでのループ処理ができる。

sample.ahk
; 変数に格納してもおk
; Array2 := FileSelect(Public . "\Pictures")
; For index, element in Array2

; 配列に格納されたファイルパスを表示する
For index, element in FileSelect(Public . "\Pictures")
{
    MsgBox % "Element number " . index . " is " . element
}
Return

FileSelect(Dir="",PromptTitle="",ExtFilter=""){
    Array := Object() ; 配列オブジェクトを作成

    ; ファイルの選択
    FileSelectFile, OutputVar , M, %Dir%, %PromptTitle%, %ExtFilter%

    If ErrorLevel = 1 ; ファイルを選択せずダイアログを閉じた場合
    {
        MsgBox, , %A_scriptname%, ファイルが選択されていません
        Exit
    }

    Loop, Parse, OutputVar ,`n
    {
        if A_Index = 1
        {
            SelectedDir = %A_LoopField%
        }
        Else If not A_LoopField = ""
        {
            Array.Insert(SelectedDir . "\" . A_LoopField)
        }
    }
    Return, Array ; 配列を戻り値とする
}

ByRefパラメータによる変数参照

ByRefパラメータを設定することで、パラメータとして指定した変数名の変数に、関数内で格納した内容を参照することができる。
適当なデリミタ(下記コードでは改行)区切りでひとつの変数に格納すれば、Loop, Parseでループ処理ができる。

また、普通にReturnすれば、戻り値としても得ることができる。

sample.ahk
ResultVar2 := FileSelect(ResultVar, Public . "\Pictures\Capture")
MsgBox, , %A_scriptname%,
(
ResultVar = %ResultVar%
ResultVar2 = %ResultVar2%
)
Return

FileSelect(ByRef OutputVar,Dir="",PromptTitle="",ExtFilter=""){
    FileSelectFile, SelectedFiles , M, %Dir%, %PromptTitle%, %ExtFilter%
    If ErrorLevel = 1 ; ファイルを選択せずダイアログを閉じた場合
    {
        MsgBox, , %A_scriptname%, ファイルが選択されていません
        Exit
    }

    Loop, Parse, SelectedFiles ,`n
    {
        if A_Index = 1
        {
            SelectedDir := A_LoopField
        }
        Else If not A_LoopField = ""
        {
            OutputVar := OutputVar . SelectedDir . "\" . A_LoopField . "`n"
        }
    }
    StringTrimRight, OutputVar, OutputVar, 1 ; 最後の改行を削除
    Return, OutputVar ; ついでに戻り値としても出力する
}

グローバル変数

これはちとややこしい。

関数のパラメータとして変数名を与えれば、関数内で可変変数として内容を格納することができる。
さらに、グローバル変数として宣言することで、その内容を関数外からも参照できる。
やはりLoop, Parseでの処理になる。

宣言は関数外で行ってもよいが、関数内で宣言したほうが手間がない。
ただし、global %OutputVar%のように、可変変数を宣言することはできない。
関数の最初の行にglobalとだけ記述すれば、関数内で宣言された変数は全てグローバル変数になるので、今回はこの方法を取る。
この場合、%OutputVar%と宣言される変数、つまり、OutputVarパラメータの内容を変数名とする変数が該当する。下記のコードでいえば、変数ResultVarのこと。

ただし、色々試したが、Returnで返すことはできなかった。

sample.ahk
FileSelect("ResultVar", "", "hoge", "画像ファイル(*.jpg;*.png;*gif)")
MsgBox, , %A_scriptname%, ResultVar = %ResultVar%

Return


FileSelect(OutputVar,Dir,PromptTitle,ExtFilter){
    global
    local SelectedDir ; 関数内で定義される変数なので、外部参照されないようlocal宣言する

    FileSelectFile, SelectedFiles , M, %Dir%, %PromptTitle%, %ExtFilter%

    If ErrorLevel = 1 ; ファイルを選択せずダイアログを閉じた場合
    {
        MsgBox, , %A_scriptname%, ファイルが選択されていません
        Exit
    }

    Loop, Parse, SelectedFiles ,`n
    {
        if A_Index = 1
        {
            SelectedDir := A_LoopField
        }
        Else If not A_LoopField = ""
        {
            %OutputVar% := %OutputVar% . SelectedDir . "\" . A_LoopField . "`n"
        }
    }
    StringTrimRight, %OutputVar%, %OutputVar%, 1 ; 最後の改行を削除
    ; Return, %OutputVar% ; なんかできない
}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?