はじめに
この記事では、AutoHotkey v2 で hotstring を利用して、今年の指定日の年月日+曜日を素早く入力するプログラムを学習します。hotstring を実行するとダイアログが開くので、そこに取得したい月日を入力し、「Enter」キーを押すと、年月日+曜日の形式で文字が入力されます。
メール文や記事を書くとき、カレンダーを参照せず曜日を含めて素早く文字入力できます。
AutoHotkey v1.1 利用者が詰まる要所
v2 では後方互換性は犠牲となっており、v1.1 のために書かれたスクリプトは基本的に動作せず、改修の必要があります。
必要な前提知識
AutoHotkey v2 は Windows で動作する、自動化に役立つツールです。
インストール
AutoHotkey
AutoHotkey をダウンロードします。このプログラムは v2.0 で書かれているので、ダウンロードページで「Download v2.0」の方をダウンロードし、動作させる Windows 機にインストールします。
AutoHotkey Plus Plus
VSCode をご利用の方は、「AutoHotkey Plus Plus」をインストールしましょう。コーディングが快適になります。
コマンド
AHK++を使用すると、キーボードショートカットを使用してスクリプトをコンパイル、デバッグ、および実行できます。選択範囲をスタンドアロン スクリプトとして実行することもできます。
- デバッグ:Ctrl + Alt + F9
- ヘルプを開く:Ctrl + F1
- 実行:Ctrl + F9
- 選択範囲の実行:Ctrl + F8
手順
実装する内容
「t[[」と順番に入力するとテキスト入力できるダイアログが開き、例として「0101」と射ち込むと「2023 年 1 月 1 日(日)」と入力されるようにします。
ダイアログ、Gui の操作
まず、Gui でダイアログを表示させてみます。
{
TestGui := Gui(,"今年日付入力")
TestGui.Add("Text",, "指定日[4ケタ]")
TestGui.show() ; Gui を表示する
}
TestGui := Gui(,"今年日付入力")
- まず Gui() で Gui を生成します。第二引数の文字列は、ダイアログのタイトルになります。
TestGui.Add("Text",, "指定日[4ケタ]")
- TestGui に Add()でテキストを追加します。
TestGui.show() ; Gui を表示する
- TestGui を show() で表示させます。
{
; 中略
TestGui.Add("Edit", "vTargetDay")
TestGui.show() ; Gui を表示する
}
TestGui.Add("Edit", "vTargetDay")
- Add("Edit") で編集可能なフォームを表示します。オプションの「vTargetDay」は、入力された内容が変数「TargetDay」に代入されます。
{
; 中略
TestGui.Add("Edit", "vTargetDay Limit4 Number")
TestGui.show() ; Gui を表示する
}
Add("Edit")のオプションに文字入力制限を追加します。
- Limit4:入力可能文字数を 4 文字に制限します。
- Number:入力可能文字を数字だけに制限します。
{
; 中略
TestGui.Add("Button", "default", "OK")
TestGui.Add("Button", " x+20" , "Cancel")
TestGui.show() ; Gui を表示する
}
ダイアログに「OK」ボタンと「Cancel」ボタンを追加します。
- 「OK」ボタンの第二引数のオプションである「default」は、「Enter」キーを押したときと同じ動作として設定されます。
- 「Cancel」ボタンのオプション「x+20」は、「OK」ボタンと横並びになるよう X 軸に対して 20 ずらしています。
{
; 中略
TestGui.Add("Button", " x+20" , "Cancel").OnEvent("Click", CloseWindow)
TestGui.show() ; Gui を表示する
}
; MyGui を閉じる関数
CloseWindow(*)
{
TestGui.Destroy()
}
「OK」ボタンの処理は多いので、まず「Cancel」ボタンの機能を実装します。
- Add().OnEvent()とつなげて記述し、ボタンクリック時に CloseWindow 関数を実行します。
- 引数を取らない関数の記述で詰まったのですが、CloseWindow()とカッコに何も書かないと「Invalid callback function」エラーが出ます。そのため、「*」アスタリスクを記述します。
- ダイアログを閉じるのは、ウィンドウとそのすべてのコントロールを削除する Destroy() 関数を使います。これで、「Cancel」ボタンを押すと、ダイアログが閉じます。
{
; 中略
TestGui.OnEvent("Escape", CloseWindow) ; [ESC] キーでダイアログを閉じる
TestGui.show() ; Gui を表示する
}
ダイアログを開いた後、「ESC」キーで閉じる機能の実装です。これはマニュアルを読んでもわからなかったのですが、TestGui.OnEvent() のようにつなげて、「Escape」を指定して第二引数に先ほどの CloseWindow 関数を設定すると、正しく動作します。
{
; 中略
TestGui.Add("Button", "default", "OK").OnEvent("Click", InsDateExec)
TestGui.show() ; Gui を表示する
}
InsDateExec(*)
{
Saved := TestGui.Submit()
TargetDay := Saved.TargetDay
MsgBox(TargetDay)
}
;ダイアログに「0101」と入力
;ダイアログに「0101」と表示される
「OK」ボタンを押されたときの InsDateExec() 関数の中身を記述します。
- Add().OnEvent()とつなげて記述し、「OK」ボタンクリック時に InsDateExec 関数を実行します。
- Add("Edit") で設定した、ユーザー入力による変数を取得します。Submit()関数は、名前付きコントロールから値を収集し、オブジェクトに合成します。
- 変数「TargetDay」に、ユーザーの入力した 4 桁の数字をオブジェクト「Saved.TargetDay」から取得して代入します。
- 表示されたダイアログに「0101」と入力すると、ダイアログが開いて「0101」と表示されます。
InsDateExec(*)
{
; 中略
;今年の年を取得
YearString := SubStr((FormatTime(,"ShortDate")), 1, 4)
;取得した月日のテキストから曜日を取得
dayString := FormatTime(YearString . TargetDay . "000000" ,"WDay")
;取得したテキストから年月日を取得
targetString := FormatTime(YearString . TargetDay . "000000" ,"LongDate")
;曜日を(月)の形式に変換
dowstr := get_dowstr(dayString)
MsgBox(targetString . dowstr)
}
;ダイアログに「0101」と入力
;ダイアログに「2023年1月1日(日)」と表示される
ユーザーが入力した日付から、今日の日付を年月日+曜日の形式で取得します。
- 変数「YearString」に今年の西暦を代入します。
- FormatTime()のオプション「ShortDate」は、例として「2023/10/05」のような形式で日付を返してきます。それを SubStr()関数で頭の西暦だけを取得します。
- 変数「dayString」に指定日の曜日を「WDay」形式で取得します。FormatTime()の第一引数に「今年の年+ユーザー入力の月日+時間」の数字を入れると、指定日をオプションで指定した形式で取得できます。
- 変数「targetString」も同様にユーザー入力の月日を使い、年月日を取得します。
- 変数「dowstr」で取得する曜日の日本語形式は、「get_dowstr() 関数を使って引数の「downum」で曜日を指定し、「(曜日)」の形式で曜日を取得」で説明したものと同等の働きです。
- 表示されたダイアログに「0101」と入力すると、ダイアログが開いて「2023年1月1日(日)」と表示されます。
InsDateExec(*)
{
; 中略
A_Clipboard := targetString . dowstr
Send "+{INSERT}"
}
クリップボードに「年月日+曜日」を代入して、「(クリップボードを)貼り付け」を実行します。
コード
完成したコードは、下記の通りです。
::t[[::
{
{
TestGui := Gui(,"今年日付入力")
TestGui.Add("Text",, "指定日[4ケタ]")
TestGui.Add("Edit", "vTargetDay Limit4 Number")
TestGui.Add("Button", "default", "OK").OnEvent("Click", InsDateExec) ; ダイアログの「OK」ボタンの表示。オプションに"default"とつけることで、テキストを入力後に「Enter」キーを押したときの動作として設定する
TestGui.Add("Button", " x+20" , "Cancel").OnEvent("Click", CloseWindow) ; キャンセルボタン、ダイアログを閉じる
TestGui.OnEvent("Escape", CloseWindow) ; [ESC] キーでダイアログを閉じる
TestGui.show() ; Gui を表示する
}
; MyGui を閉じる関数
CloseWindow(*)
{
TestGui.Destroy()
}
; ダイアログに入力された四桁の数字を年月日+曜日に変換し、入力する関数
InsDateExec(*)
{
Saved := TestGui.Submit()
TargetDay := Saved.TargetDay
;今年の年を取得
YearString := SubStr((FormatTime(,"ShortDate")), 1, 4)
;取得した月日のテキストから曜日を取得
dayString := FormatTime(YearString . TargetDay . "000000" ,"WDay")
;取得したテキストから年月日を取得
targetString := FormatTime(YearString . TargetDay . "000000" ,"LongDate")
;曜日を(月)の形式に変換
dowstr := get_dowstr(dayString)
A_Clipboard := targetString . dowstr
Send "+{INSERT}"
}
}
;曜日をカッコつきで返す
get_dowstr(theNum)
{
dowtable := "日月火水木金土"
; Wday は日曜日が 1、
dowstr := SubStr(dowtable, theNum, 1)
return "(" . dowstr . ")"
}
::t[[::
{コード}
- 先ほどのコードを Hotstring の中カッコでくくることで、「t[[」と連続してキーボードを入力するとダイアログが開き、取得したい日付を 4 桁の数字で入力すると、年月日+曜日の形式でテキストが入力されます。
- get_dowstr() の処理は割愛します。
注意点
- Gui 周りの処理がややこしいので、ステップを追って動作を確認していきましょう。
結論
- この Hotstring を使えば、今年であれば、入力したい曜日を知らなくても、「t[[」と入力し、ダイアログに取得したい日付を四桁の数字で入力することで、年月日+曜日の形式で入力できます。
- エラー処理をしていないので、2 月 31 日のように入力したら、「(金)」とだけ入力されます。年月日を取得できない場合は処理を中断するようにしましょう。
- AutoHotkey をインストールした後に付属する「Ahk2Exe」を使えば、AutoHotkey のプログラムを.exe 化できます。それを利用すれば、AutoHotkey をインストールしていない Windows 機でも hotstring が使えるようになります。
- また、作成した.exe ファイルを「Windows 10 の起動時に自動的に実行するアプリ」として登録しておけば、起動時に自動的に立ち上がり、hotstring が利用可能になります。