yukioのアウトプット

PowerApps、PowerAutomateなど、勉強した内容、実践した内容を、自分にわかるようにかみ砕いてアウトプットしています。

【Power Automate】Excelの「行の取得」のキー値に日付を使う方法

(この記事は、ある方のツイートとそれに対するMVPからのアドバイス、それを拝見した第三者の私が、アドバイスを紐解いて、自分の備忘録として書きなぐっている記事です。

読みやすい記事ではないかもしれませんがご容赦ください。)

 

少し前にこんなツイートを拝見しました。

 

Power Automate(クラウドフロー)にある、Excelの「行の取得」アクション。

キー列とキー値を設定して、それに合致する行を取得するというものですが、

まるさんは、この「キー列」に日付を設定した時に、うまく行が取得できずに悩まれている様子です。

 

Excelのセルに日付が入力されていても、本当は日付情報ではなくて「シリアル値」で入力されているため、Power Automateの「行の取得」のキー値に「日付情報」を入れてもうまく取得できないという感じでしょうか。

 

私がやっていること

私も同じようなシチュエーションで行を取得したい用事がありました。

その時は以下のようなことで対応しました。

「フローの可読性」といった意味ではいいかもしれませんが、

余計な列を1個作ることになり、なんとなく「スマートじゃない」と思っています。

 

まるさんからは「賢い」とお褒めの言葉を頂きましたが、この方法を取った理由は単純に

シリアル値で考えるのが面倒臭い

と思ったからでした(苦笑)

当時の自分に喝!

 

MVPからのアドバイス

まるさんのツイートに対して、今年Microsoft MVPを受賞されたMiyakeさんから、以下のようなアドバイスがありました。

 

ほうほう、何やら難しいことをやってるぞ!

ちょっと紐解いてみよう!

 

式を見てみると

・ticks関数

・sub関数

・div関数

・add関数

の4種類を使っています。

それぞれの部分で何をしてるかを分析してみたので、自分の備忘録として、以下にまとめてみようと思います。

 

(1)ticks関数

入れ子になっている関数の一番内側「ticks関数」から見ていきます。

公式ドキュメントは以下です。

learn.microsoft.com

 

これによると、ticks関数というのは

1 月 1 日 0001 12:00:00 午前 0 時から指定したタイムスタンプまでの 100 ナノ秒間隔のティック数 (または C# の DateTime.Ticks) を返します。

との事です。

は???

 

でもゆっくり読んでみると何となくわかりました。

 

西暦1年1月1日午前0時00分00秒を始点として、

そこから、

指定されたタイムスタンプまでの秒数を

ナノ秒に変換して

100で割った値を返す。

(↑「100ナノ秒間隔の」と書いてあるので)

 

ということだと思います。

 

(1)ticks関数検証

検証のためにこんなフローを組んでみました。

 

1個目は「西暦1年1月1日0:00:00」

2個目は「その1秒後」

ですね。

 

実行結果はこうなりました。

 

1個目は私の思った通り「0」が返ってきました。

2個目で返ってきた値は「10000000」つまり1000万

 

1秒をナノ秒になおすと「1000000000(10の9乗=10億)」ナノ秒で、

それを100で割ると「10000000(1000万)」

思った通りです。

 

まあ、回りくどい検証をしましたが、

ticks関数はそういった値を返す関数ということです。

 

(2)sub関数

次にやっていることを見るために、式の一部を抜粋すると

sub(ticks('1/6/2023'),ticks('1/1/1900'))

ticks関数で求めた「2023/1/6の値」と「1900/1/1の値」をsub関数で囲っています。

 

sub関数の公式ドキュメントは以下です。

learn.microsoft.com

sub関数は単純に「引き算の関数」ですね。

 

sub(ticks('1/6/2023'),ticks('1/1/1900'))

ということは、(1)で求めた

2023年1月6日の値(ナノ秒÷100)

引く

1900年1月1日の値(ナノ秒÷100)

ということになります。

Excelの「シリアル値」は1900年1月1日を基準にした値なので、

1900年1月1日からどのくらい遠いのか?

を知る必要があり、この引き算を入れているということみたいです。

 

(3)div関数

もう1個外側の関数まで広げて見ていくと

div(sub(ticks('1/6/2023'),ticks('1/1/1900')),864000000000)

subまでで求まった値と864000000000を、div関数で囲っています。

 

div関数の公式ドキュメントは以下です。

learn.microsoft.com

div関数も単純で「割り算の関数」です。

 

div(sub(ticks('1/6/2023'),ticks('1/1/1900')),864000000000)

ということは、

「(2)までで求まった値」÷「864000000000」

をしているということになります。

 

(3)なぜ864000000000?

1日は24時間

1時間は60分

1分は60秒

なので、1日は24×60×60=86400(秒)です。

これをナノ秒に直すと86400000000000

100で割って864000000000

 

これで割ることによって、

単位が[ナノ秒/100]から[日]になり、

1900/1/1から何日たっているか?を知ることができる。

ということみたいですね。

 

(4)add関数

入れ子の最後は

add(div(sub(ticks('1/6/2023'),ticks('1/1/1900')),864000000000),2)

add関数です。

 

add関数の公式ドキュメントは以下です。

learn.microsoft.com

add関数は「足し算の関数」です。

 

といことは(3)までで求まった値に2を足しています。

なぜ?

ここが分からなかったので、ツイートにリプライして聞いてみました。

すると、以下のような返答を頂きました。

 

なるほど、この2つの事情があるがために、

add関数を入れないと2日足りない状況が出来上がるんですね。

 

実際のフローで使うときはどうするか

ここまでは「2023/1/6」という固定の日付でやってましたが、これを実際のフローで動かす場合は、このような形をとるのかなと思います。

肝心の式の部分はこのような入れ方になります。

今回はテストなので、手動でフローを実行した時の時刻をタイムゾーン変換して使いましたが、これが定期的に実行するフローであれば、その時刻になるだろうし、別の方法で日時を取ってくるとか、色々あると思います。

 

まとめ

ここまでちょこちょこ貼り付けた、Power Automateの関数が解説されている公式ドキュメント。

トップページは以下です。

learn.microsoft.com

 

私はこのページをブックマークして時々見ていますが、それだけじゃなかなか定着には至らなくて、今回、一つの事例に対して、頂いたアドバイスを少しずつ紐解いてみたら、より深くPower Automateの関数について知ることができました。

 

きっかけを与えて下さったまるさん

アドバイスを頂いたMiyakeさん

ありがとうございました。

 

(2023/01/10追記)

この内容について、MiyakeさんがQiitaに分かりやすくまとめて下さいました。

qiita.com

合わせて読むと理解が深まりますので、ぜひご覧ください。