特定のブックの全シートを再計算する

特定ブックの全シートのみを再計算する方法です。
全ブック再計算より処理時間を短縮できます。

'ループ用の変数宣言
Dim zz対象Ws As Worksheet

'特定のブックの全シートを再計算
For Each zz対象Ws In Workbooks("Book1.xlsx").Worksheets
zz対象Ws.Calculate
Next zz対象Ws

再計算を行うには対象のオブジェクトに対して「Calculate」メソッドを使用します。
ただし、Workbookオブジェクトにはこのメソッドが存在しません

そのため、複数のブックを開いている状態で特定のブックだけを再計算するには、対象ブック内の全シートをループして「Worksheet.Calculate」を実行する必要があります。

このコードを利用すれば、複数のブックを開いている場合でも特定のブックだけを再計算することが可能となり、処理に時間のかかる不要なブックの再計算を除外できます

コード解説

コードの流れは非常にシンプルです。
対象のブック内の Worksheet オブジェクトをループ処理し、それぞれに対して再計算を実行するだけです。

'ループ用の変数宣言
Dim zz対象Ws As Worksheet

まずはループ処理で使用するための変数を宣言します。
この変数には Worksheet オブジェクトを代入するため、型は Object 型でも構いませんが、Worksheet 型にしておくとコード入力時にインテリセンスが利用できるので効率的です。

'特定のブックの全シートを再計算
For Each zz対象Ws In Workbooks("Book1.xlsx").Worksheets
    ~~~
Next zz対象Ws

次にループ処理の部分です。
For Each ループを使うことで、特定の Workbook に含まれるすべての Worksheet を順番に処理できます。

ここで注意すべき点として、Excel のシートには複数のオブジェクトが存在します。
主に Worksheets と Sheets があり、特に後者の Sheets オブジェクトはマクロ記録でよく利用されます。
ただし、通常のコード記述では Worksheets を明示的に扱う方が分かりやすく、インテリセンスも効くため効率的にコード作成が行えます。

また、Workbooks(“Book1.xlsx”) の引数の文字列を対象とするブックの名前に変更すれば、任意のブックを指定することができます。

For Each zz対象Ws In Workbooks("Book1.xlsx").Sheets
    ~~~
Next zz対象Ws

このコードのように Worksheet オブジェクトではなく、Sheets オブジェクトとしても多くの場合問題なく動作します

ただし Sheets オブジェクトには、グラフシートやマクロシートなど通常の Excel で使用するワークシート以外のものも含まれます
そのため再計算を目的とする場合は、Worksheet オブジェクトを指定する方が適切です。

zz対象Ws.Calculate

ループ内の処理は Worksheet オブジェクトに対して Calculate メソッドを実行しているだけです。

このようにすることで、複数のブックを開いている状態でも特定のブックのみの全シートを再計算させることができます。
使いどころは限定的ですが、知っていれば処理時間を短縮できる場合もあるため有用です。

「全ブックまとめて再計算したい」という方は、以下の記事をご確認ください。


関連の記事

Excel再計算の実行(全ブック対象)

Application.Calculate は開いている全ブックの必要セルのみを再計算します。Application.CalculateFull は全セルを強制再計算します。

'必要なセルのみ再計算(高速)
Application.Calculate
'全セルを強制再計算(重い処理)
Application.CalculateFull

再計算を行うにはApplication.Calculateメソッドを使用します。
このメソッドは、再計算が必要なセルだけを更新するため、高速に処理できます。

Excelに対して再計算の実行を行いますが、対象は開かれている全てのブックのうち再計算が必要なセルです。
全セルを強制的に再計算したい場合はApplication.CalculateFullメソッドを使用します。

このメソッドは全てのセルを対象とするため処理が重く、負荷が大きくなります。
更新漏れがなくなるという安心感はありますが、通常の処理では基本的にApplication.Calculateメソッドの利用が推奨されます。

利用場面としては、処理中に再計算を手動にして停止している状態で、一度再計算を実行しておきたい時などが挙げられます。
処理の最後に1回だけ実行するなど頻繁に利用しない場合は、実際に使ってみて動作の重さが気になるようであれば切り替える形でも良いでしょう。
なお、自動計算を処理中に手動計算へ切り替えている場合は、自動計算に設定を戻せば再計算されるため、このメソッドを使う必要はありません。

なお指定のブックのみを再計算する場合は、Workbookオブジェクトに直接「Calculate」メソッドは存在しません
そのため、対象ブックの全シートをループして「Worksheet.Calculate」を実行する方法が一般的です。
同様に、セル範囲単位では「Range.Calculate」を使えます。
必要に応じてループ処理を組み合わせることで柔軟に再計算を制御できます。
詳しくは以下の記事で解説しています。

PowerQueryでコメントを利用する

PowerQueryの処理ステップにコメントを残す方法について

PowerQueryにコメントを記載することが出来ます
これはExcel数式では出来ない便利な機能です

コメントが挿入されたことを示すアイコン表示状態の画像

この画像のステップ行にコメントが加えられるとアイコンが表示されます

コメントが表示された状態の画像

コメントが作成されたステップにマウスオーバーすると、こちらの画像の様にコメントがポップアップ表示されますので画面上の邪魔になることがありません

VBAと同じくステップ数が増えると、後々確認するとなんのためのステップか分からなくなります、もう絶対なります
そんなときのためにコメントを残して置きましょう

PowerQueryでコメントを残すには2通りの方法があります

プロパティの開き方の画像

1つ目は、ステップ名で右クリックを押すと表示されるメニュー項目のプロパティです

プロパティの設定画面が表示された状態の画像

これを開くとコメント入力ができる画面が表示されます
説明というのがコメントになります
改行も気にせず書くことが可能です

詳細エディターを開くボタンの場所の画像

もう一つは、詳細エディターで編集する方法です
ホームタブにある詳細エディターをクリックすると画面が表示されます

詳細エディター画面でコメントが表示されていることを確認している画像

こちらの画像ではすでにコメントが入力されている箇所があります
プロパティで設定したコメントもここにしっかり反映されます
コメント記号についてはVBAとは違いますので注意してください

1行のコメントの場合は「//」と入力します
その後に続けてコメント文を記載します

複数行コメントの場合の入力方法の画像

複数行にしたい場合は「/*」と「*/」で囲みます
改行をどれだけおこなっても問題ない形になります

実際のところ、この詳細エディターでの編集は1つのステップに対して行う場合は必要ありません
複数のステップをまとめてコメント追記する場合にいちいち画面を設定画面を開きなおさなくて良いのでそういった場面で利用します
この詳細エディターでコメントを記載すると、実際はこのプログラムでPowerQueryが動作していることがよく感じられます

コメントはクドいくらいが丁度いいので、有効に活用してください

セル内文字列を置き換えする

セルに入力された文字列の置き換えについてのコードです(完全・部分一致)

'ABC列で部分一致の検索置換を実行する
Range("A:C").Replace What:="検索文字", Replacement:="置換文字", LookAt:=xlPart
'ABC列で完全一致の検索置換を実行する
Range("A:C").Replace What:="検索文字", Replacement:="置換文字", LookAt:=xlWhole

セル内文字列の置き換えには「Replace」メソッドを使用します
Excelの標準機能と同じように、セルに入力された内容と条件一致するものを検索して、見つかった場合に置き換えを実行する際に使用します

引数の「What」が検索対象の文字列です
置き換えする文字列は「Replacement」に指定します
この2つの指定により、任意の文字列を検索して置き換えを実行することができます

引数「LookAt」の設定で部分一致か完全一致かの選択ができます
部分一致の場合は「xlPart」を設定し、完全一致の場合は「xlWhole」と設定します
検索処理でも同じ事を言えますが引数の設定は前回実行した設定が引き継がれます
なので引数の設定は必要のない部分でも一応設定しておくほうが安心です
部分一致と完全一致が意図せず入れ替わっていたりします

完全一致とすれば、セルの中にある文字列全体が検索と全く同じ時のみ置換の対象になります
部分一致にすれば、セルの中にある文字列の一部だけを置換することが出来ますが、複数当てはまる場合は全て置換対象になる点だけ注意してください
あまりにも短い文字を検索対象にしていると、意図しない変換が行われてしまいます

マイクラ(統合版)で「Code Connection for Minecraft」を利用可能に出来た方法について

マイクラ統合版に「Code Connection for Minecraft」の接続エラーをなんとか回避できた方法について

2022年12月24日に子供の学習用プログラミングアプリの「Code Connection for Minecraft」を導入した際の話です
※Windows10環境の記事となります

前提として、Minecraft(以降、マイクラ)にはPC版の購入が必要なので無料で利用することは出来ません
以下のエディションを購入する必要があります
※「Education Edition」は教育用となり買い切りではないです

https://www.minecraft.net/ja-jp/store/minecraft-java-bedrock-edition-pc(公式サイト)
※Amazonなどでも購入可能です、同じエディションを探してみてください

またこれとは別に「Code Connection for Minecraft」も取得する必要がありますが、こちらは無料のアプリとなっており、MicrosoftStoreで「Code Connection for Minecraft」を検索すれば、すぐに見つかります

ただし、本記事執筆時点(2023年1月12日時点)において、両アプリともMicrosoftStoreから取得してもプログラミングを行うことができません
Code Connection for Minecraftがマイクラと接続が出来ないエラーが発生します
色々試しましたが、アプリの設定や修復・再インストなどではどうにもなりませんでした


接続が出来た方法を記載しますが外部Webサイトよりファイルのダウンロードを行う必要が発生しますので自己責任にて対応を行ってください

まず前提として、両アプリともバージョンを動作する古いバージョンに変更する必要があります

・マイクラ本体のバージョンを「1.18.12」にする
・Code ConnectionをStoreからではなく直接ダウンロードする


この2つを行ったところ、接続が出来てAgent君が登場するようになりました

マイクラ本体のバージョンについては「MCLuncher」を利用することで古いバージョンに更新することが出来ます
ただ接続のためであれば上記のバージョンにすればいいだけなので、Launcherをダウンロードしなくても上記バージョンのファイルをダウンロード出来るサイトも多数あるのでそちらで十分です

Code Connectionについては以下のWebサイトから直接ダウンロードすることが出来ます
https://minecraft.makecode.com/setup/minecraft-windows10

アプリを開くと分かりますがバージョンはStore配信と同じ「1.50」です
またマイクラ本体と違って、別のアプリとして認識されますのでStore取得したままの場合は起動するアプリの選択に注意してください

バージョン更新により、こんな手間をかけなくても接続できるようになるかもしれませんがアプリのコメントなど見る限り、いたちごっこになっているようなので1度起動可能環境をビシッと整えておくといいです

ちなみに、バージョンが古いとマルチプレイが出来なくなります
プログラミングはソロプレイでするものと割り切って下さい
ただ最新バージョンにすればマルチプレイが可能なので、Storeで最新バージョンに更新すれば良いです
プログラミングをする場合にはまたバージョンを戻せば良いだけです(めんどくさい話ですが)

テキストファイルを一括読み込みする

FileSystemObjectを利用して、テキストファイルを一括で読み込みを行うコードについて

'FSOの宣言
Dim bhFSO As Object, bhFSOT As Object
Set bhFSO = CreateObject("Scripting.FileSystemObject")
'指定テキストファイルを開く
Set bhFSOT = bhFSO.OpenTextFile("指定テキストファイルの絶対パス")

'開いたテキストを1つのデータに一括読み込み
Dim bhTxt As String
bhTxt = bhFSOT.ReadAll

'FSOの解放
Set bhFSOT = Nothing
Set bhFSO = Nothing

テキストファイルの文字列を1つのデータに一括で読み込みをするコードです
通常VBAでテキストファイルを読み込む場合は以下のInputステートメントを利用します

ただ、このコードの場合にはデータが配列として分割されます
たとえばテキストデータ全体で検索や置換をしたい場合にそのようなデータとなった場合配列をループでまわして検証する必要が出てきてしまいます
またあえて1セルにまとめて入力したい場面も想定されます
これは新しいテキスト関数が非常に便利になったので実務上有用です

そんな場合に記事コードを利用します
このコードを利用すると文字列変数に一括でデータを読み込むことで
全体的な処理や関数処理が行いやすくなります

指定フォルダー直下の構成を複製する

PowerAutomateDesktopを利用して、指定したフォルダー直下のフォルダー構成を複製するフローです

Display.SelectFolder Description: $'''複製をするフォルダーの選択''' IsTopMost: True SelectedFolder=> SelectedFolder ButtonPressed=> ButtonPressed
IF ButtonPressed <> $'''OK''' THEN
    EXIT Code: 0
END
Folder.GetSubfolders Folder: SelectedFolder FolderFilter: $'''test*''' IncludeSubfolders: False FailOnAccessDenied: True SortBy1: Folder.SortBy.NoSort SortDescending1: False SortBy2: Folder.SortBy.NoSort SortDescending2: False SortBy3: Folder.SortBy.NoSort SortDescending3: False Subfolders=> Folders
Folder.GetSpecialFolder SpecialFolder: Folder.SpecialFolder.DesktopDirectory SpecialFolderPath=> SpecialFolderPath
Folder.Create FolderPath: SpecialFolderPath FolderName: $'''作成用フォルダー''' Folder=> NewFolder
LOOP FOREACH CurrentItem IN Folders
    Folder.Create FolderPath: NewFolder FolderName: CurrentItem.Name
END
System.RunApplication.RunApplication ApplicationPath: $'''explorer''' CommandLineArguments: NewFolder WindowStyle: System.ProcessWindowStyle.Normal

フォルダーの選択で指定したフォルダーの直下にあるフォルダ構成をデスクトップに複製するフローです
年や月などで、同じ構成のフォルダーを作成する場合に利用します
例えば、毎月月初に担当者ごとのフォルダを作成するとか、顧客ごとのフォルダを作成するという場合です
前提として、フォルダーの中身は複製しませんので階層構造になっているフォルダーも複製は行いません
このフローの前提として、直下フォルダの構成以外は新規で利用することを想定しているからです

フロー解説

1行目:フォルダーの選択ダイアログを表示
2~4行目:IFによる選択キャンセル時のフロー終了
1~4行目のアクション

1行目は構成を複製するフォルダーを指定するためのダイアログ表示のアクションとなっています
ここで選択したフォルダーの直下にあるフォルダーを複製することになります

2~4行目は、そのダイアログで選択をキャンセルした場合の終了処理になっています
これが無いと後続で未選択時にエラーが発生します

5行目のアクション
「フォルダー内のサブフォルダーを取得」アクションの設定画面の画像
設定画面

5行目は指定したフォルダーの直下にあるフォルダーを全て取得するアクションです
ここで「フォルダーフィルター」という項目を設定することで、任意のフォルダーに制限をかけることが可能となります
例えば、直下にあるフォルダーのうちでも特別に作成したフォルダーであり複製は不要なフォルダーがある場合は、その名前で除外を行うことが可能となります
ただ所詮は名前の文字列だけでしかないので複雑な判定が必要な場合は、初期値の「*」だけにして全てを複製してから手動で削除対応を行う形となります
例の場合で言えば、「test」で始まるフォルダーを対象としています

ちなみにこの項目のうち、サブフォルダーを含めるをオンにした場合は
直下以降の階層構造全てを複製の対象には出来ますが、あまり不要かと思いますので例コードではオフとしています

6行目:特別なフォルダーを取得
7行目:フォルダーの作成
6~7行目のアクション

6行目では複製フォルダーの保存先としてデスクトップを対象とするため、デスクトップのパスを取得しています

7行目で複製フォルダーの格納用フォルダーを作成しています
同名フォルダーがあった場合は何も起きません
基本的にはここで複製したものは移動する前提のため、デスクトップに同じ名称のフォルダーは存在しない想定です

8~10行目のループによるフォルダー作成のアクション画像
8~10行目のアクション

8行目と10行目はループ処理のアクションとなっています
ここで取得したサブフォルダーの要素を全てループしています

9行目でサブフォルダーの名前で新規にフォルダーを作成して、デスクトップの作成用フォルダーの中に保管をしています
これをループにより、取得したサブフォルダーの個数分処理します

作成用フォルダーを開くアクションの画像
11行目のアクション

11行目はデスクトップに作成した作成用フォルダーをエクスプローラーで開くアクションです
デスクトップに作成しているので、探す必要はほぼ無いので蛇足のアクションではありますので削除しても問題はありません
こちらのアクションについては以下の記事で解説を行っています

指定ファイルを指定のフォルダに任意の名前を付けて保管する

指定のファイルを任意の名前に変更して保管用フォルダーに移動する処理

Display.SelectFileDialog.SelectFile Title: $'''対象ファイルを選択してください''' FileFilter: $'''TEST*.csv''' IsTopMost: True CheckIfFileExists: False SelectedFile=> SelectedFile ButtonPressed=> ButtonPressed
IF ButtonPressed <> $'''Open''' THEN
    EXIT Code: 0
END
File.RenameFiles.Rename Files: SelectedFile NewName: $'''OutDate''' KeepExtension: True IfFileExists: File.IfExists.Overwrite RenamedFiles=> SelectedFile
File.Move Files: SelectedFile Destination: $'''保存先の絶対パス''' IfFileExists: File.IfExists.Overwrite MovedFiles=> SelectedFile
# 以下、保存先のフォルダを開くアクションのため不要であれば削除
System.RunApplication.RunApplication ApplicationPath: $'''explorer''' CommandLineArguments: SelectedFile[0].Directory WindowStyle: System.ProcessWindowStyle.Normal

この処理は指定したファイルの名前を変更して、指定のフォルダに移動します
これの利用場面としてはWeb等から取得したcsvファイルなどをデータ保管用フォルダに格納します、さらにこの先の流れとしてPowerQueryを想定しています
PowerQueryは絶対パスで読み込み先を指定するので、この処理により前回取得時情報を更新するために活用します

この処理は1件だけの処理となっておりますが、実務上は複数のファイルを同様の操作を行うことが想定されるのでその場合はファイル数×作業頻度の度合いでかなり楽になります
さらにこの処理は最後に保管したフォルダをエクスプローラで開いていますが
これも後続作業を想定したものとなりますので不要であれば削除して問題ありません

フロー解説

1行目のファイル選択ダイアログを表示するアクションの画像
1行目のフロー
ファイルの選択ダイアログを表示のアクションの設定画面
設定項目画面

1行目は対象となるファイルを指定するためのダイアログを表示させるアクションです
このアクションの設定項目としては2項目を編集します

「初期フォルダー」ダイアログ表示時に最初に開かれるフォルダの指定です
例コードでは空白となっております、この場合は前回開いたフォルダが開かれます
Webからのダウンロードファイルを想定している場合はここをダウンロードフォルダに設定したりします

「ファイルフィルター」ここで指定した文字列がファイルの制限になります
VBAの様に拡張子の制限では無く、拡張子を含めたファイル名の制限になります
この制限はワイルドカードの利用も可能となっております
例コードの場合では頭文字に「TEST」が含まれたcsvファイルを対象としています

ここをより明確に設定することで、同じcsvファイルであってもダイアログに表示させないことが可能となるのでファイル選択間違いを抑制出来ます

ファイル名の制限をかけた状態が分かる画像
表示制限がかかった状態

この画像は左がPADで表示したダイアログ、右はエクスプローラーの画面です
今回の場合は頭文字に「TEST」となっているものが条件です
そのため、同じ個所に保存されているcsvファイルでも「Sub_20221009.CSV」が表示されていないことが確認できます

そして、ワイルドカードを利用することでダウンロードした際に日時などが追記されるファイル名となっていたとしても対象に含めることが可能です
この指定をより細かく指定すれば、ファイル名で22年10月分だけ表示する、という事も可能です

2~4行目のアクションの画像
2~4行目のアクション

2~4行目はダイアログでキャンセルをした際に処理を終了させるアクションです
ここを作成していないと後続でファイル未選択によりエラーとなります
ダイアログの開くボタンをクリックすると「Open」が返されるので、それ以外のものであれば処理は終了させています

5行目の「ファイルの名前を変更する」アクションの画像
5行目のアクション
ファイルの名前を変更するアクションの設定項目画面の画像
設定項目画面

ここで変更するのは「新しいファイル名」の1つで十分です
ここを最終的に保存をしておくファイル名を指定します
基本的に処理の流れ上、同じ場所にファイルが存在する可能性はありませんが
あった場合には上書きする設定にしています

ちなみに、このアクション以降含め生成された変数は「SelectedFile」に格納しています
これは後続処理がこのファイルを対象としているので変数をアクション数分作成する意味が無いからです
ダイアログで返された変数をどんどん上書きしていきます
また拡張子を保持する設定にしているので「.csv」は指定に含めません

「ファイルの移動」アクションの画像
6行目のアクション
「ファイルの移動」アクションの設定項目画面の画像
設定項目画面

6行目はファイルを指定フォルダに移動しています
ここで設定するのは「宛先フォルダー」です
移動先のフォルダを絶対パスで指定します
この移動の際に同じファイル名があった場合は上書きしています
処理の想定が古いファイルのデータを上書きすることなのでここは重要です

7行目「コメント」と8行目「アプリケーションの実行」アクションのフロー画像
7~8行目のアクション

7行目はコメントで、8行目は保存先のフォルダをエクスプローラーで開きます
これはこの保存後に使用するファイルが保存されているところを開くことで使用ファイルを開く手間を少し楽にする目的で追加しています
ここは完全に蛇足の処理なので不要であれば2行とも削除して問題ありません
8行目の処理については以下の記事で解説しています

印刷時のカラーとモノクロを切り替える

特定のシートの印刷時のカラーとモノクロの印刷配色設定を切り替えるコードについて

'モノクロ印刷に設定する
Worksheets("Sheet1").PageSetup.BlackAndWhite = True

「Sheet1」をモノクロ印刷にする

'カラー印刷に設定する
Worksheets("Sheet1").PageSetup.BlackAndWhite = False

「Sheet1」をカラー印刷にする

印刷を行う際にカラーかモノクロかを切り替えるには、SheetオブジェクトのPageSetup.BlackAndWhiteプロパティを利用します

このプロパティにTrueを設定することでモノクロ印刷となり
Falseを設定することでカラー印刷となります

印刷する際に確認用はモノクロで、提出用にカラー印刷を行うような場合の処理作成で活用できます
プリンターのプロパティから設定をいちいち切り替える必要が無くなります
そもそもプリンターのプロパティはVBAでは設定を変更できません

モノクロ印刷時の印刷プレビューの画面の画像
モノクロ印刷時の印刷プレビュー(設定:True)
カラー印刷設定時の印刷プレビューの画像
カラー印刷設定時の印刷プレビュー(設定:False)

上記の画像の通りで、プロパティをそれぞれに設定することで簡単に印刷時の配色設定を変更することが出来ます

この設定はページ設定になるのでプリンターでの印刷だけでなく
PDF出力に対しても有効な点は注意が必要です

利用したフォルダをエクスプローラで開く

PowerAutomateDesktopで任意のフォルダをエクスプローラで開いてウィンドウを表示します

System.RunApplication.RunApplication ApplicationPath: $'''explorer''' CommandLineArguments: $'''開きたいフォルダ絶対パス''' WindowStyle: System.ProcessWindowStyle.Normal

エクスプローラでパスを指定して実行する

新しく追加されたDesktopフロー例に、この内容のフローがあります
その中で利用したいのがこの1行だけのフローです

フローの設定項目
設定項目画面

設定項目の「コマンドライン引数」に開きたいフォルダの絶対パスを直接していします
エクスプローラと連動はさせていないので、フローの最後に利用することが多い場面になります
途中でウィンドウが開いても処理に影響を与える可能性があります

使用例

File.GetTempPath TempFile=> TempFile
System.RunApplication.RunApplication ApplicationPath: $'''explorer''' CommandLineArguments: TempFile.Directory WindowStyle: System.ProcessWindowStyle.Normal
Display.ShowMessageDialog.ShowMessage Message: $'''%TempFile.FullName%を削除します''' Icon: Display.Icon.None Buttons: Display.Buttons.OK DefaultButton: Display.DefaultButton.Button1 IsTopMost: True
File.Delete Files: TempFile.FullName
コードをコピーして作成されたフローの画像
フローの画像

コードをコピーすると画像のように4つのアクションが作成されます

行っている処理は、一時ファイルを作成して、そのファイルのフォルダをエクスプローラで開きます
処理は停止しないので、ファイルが作成されたことを確認するためのメッセージを表示して、そのメッセージが消されたら一時ファイルは削除します

このように、Excelなどのファイル作成を行った場合に自動的にフォルダに格納するような処理だと処理が完了した後にユーザーがそのファイルを確認したい場合にフォルダをいちいち開かなくてはいけなくなります

なら、最初から作成ファイルを終了しなければ良いとの話になりますが
Automateの仕様で、Excelをフロー中に終了させないとプロセスが残ったままになることがあるのでなるべくフローで操作したExcelは終了させたいです

処理の最後にこのフォルダを開くアクションを作成しておくと、非常にファイル確認が楽になります
なくても良いけど、あるとすごく便利なアクションです