0
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?

2つのDataverseテーブルをPower Automateで比較して差分を求める

0
Posted at

遅ればせながら、最近Dataverseを使うようになりました。

早いし、安定しているし、ソリューションで管理できるし環境ごとに存在してソリューションの更新を使ってもデータはちゃんと保持されるのでテーブルIDを管理しなくてよいし、トランザクション処理もできるし。

今までDataverseの良さを過小評価していました。
2つのDataverseテーブルから、差分を抽出する必要があったので、試行錯誤した結果を共有する記事を書いてみます。

テーブルのサンプル

今回は新規の入職者に対して、教育受講を促すメールを送信し、受講が確認できたら受講済みテーブルに入れるような処理を例として使います。

image.png

上記の青いテーブルのユーザーにメールを送ります。
黒いテーブルとの差分を入手し、黒いテーブルに存在するユーザーを青いテーブルから削除します。
これによって、青いテーブルには受講を催促するべきユーザーが常に残ります。適切なタイミングで青いテーブルのユーザー全員にリマインドメールを送信すれば良くなります。

テーブルを作ってみる「グループメンバーシップの確認(V2)」

Excelで作った構成をDataverseのテーブルにしてみます

image.png
image.png

リレーションを使わない場合

Dataverseは複数のテーブルをリレーションでつなぐことができます。
しかし、今回はあえてリレーションを使わずにPower Automateを使って差分を抽出したいと思います。
Employeeテーブルはあくまで催促送信を想定しているからです。

※後日行削除せず、リレーションを使う方法も試してみる予定です。

FetchXML をつかう

リレーションを作成しない状態でFetchXMLでOnboardingTrainingテーブルに存在しないEmployeeテーブルのユーザーを抽出してみます。

FetchXML
<fetch>
  <entity name="dd_employee">

    <attribute name="dd_name" />
    <attribute name="dd_email_address" />
    <attribute name="dd_hire_date" />

    <link-entity
      name="dd_onboardingtraining"
      from="dd_email_address"
      to="dd_email_address"
      alias="training"
      link-type="outer">

      <attribute name="dd_onboardingtrainingid" />

    </link-entity>

    <filter>
      <condition
        entityname="training"
        attribute="dd_onboardingtrainingid"
        operator="null" />
    </filter>

  </entity>
</fetch>

image.png

実行した結果はこのようになりました。
受講済みテーブルに存在する2名を除く、催促が必要なユーザーが取得できました。

出力
[
  {
    "@odata.etag": "W/\"7777811\"",
    "dd_employeeid": "ede69e8c-9bbf-f111-aaaf-70a8a53d89f2",
    "dd_name": "山田 太郎",
    "dd_hire_date@OData.Community.Display.V1.FormattedValue": "2026/04/01",
    "dd_hire_date": "2026-04-01T00:00:00Z",
    "dd_email_address": "yamada.taro@example.com"
  },
  {
    "@odata.etag": "W/\"7777813\"",
    "dd_employeeid": "efe69e8c-9bbf-f111-aaaf-70a8a53d89f2",
    "dd_name": "佐藤 花子",
    "dd_hire_date@OData.Community.Display.V1.FormattedValue": "2026/04/01",
    "dd_hire_date": "2026-04-01T00:00:00Z",
    "dd_email_address": "sato.hanako@example.com"
  },
  {
    "@odata.etag": "W/\"7777818\"",
    "dd_employeeid": "c1406a9b-9bbf-f111-aaaf-70a8a53d89f2",
    "dd_name": "伊藤 健太",
    "dd_hire_date@OData.Community.Display.V1.FormattedValue": "2026/05/15",
    "dd_hire_date": "2026-05-15T00:00:00Z",
    "dd_email_address": "ito.kenta@example.com"
  },
  {
    "@odata.etag": "W/\"7777820\"",
    "dd_employeeid": "c2406a9b-9bbf-f111-aaaf-70a8a53d89f2",
    "dd_name": "渡辺 彩",
    "dd_hire_date@OData.Community.Display.V1.FormattedValue": "2026/06/01",
    "dd_hire_date": "2026-06-01T00:00:00Z",
    "dd_email_address": "watanabe.aya@example.com"
  },
  {
    "@odata.etag": "W/\"7777822\"",
    "dd_employeeid": "fca318a4-9bbf-f111-aaaf-70a8a53d89f2",
    "dd_name": "中村 拓海",
    "dd_hire_date@OData.Community.Display.V1.FormattedValue": "2026/06/15",
    "dd_hire_date": "2026-06-15T00:00:00Z",
    "dd_email_address": "nakamura.takumi@example.com"
  },
  {
    "@odata.etag": "W/\"7777823\"",
    "dd_employeeid": "fda318a4-9bbf-f111-aaaf-70a8a53d89f2",
    "dd_name": "小林 優奈",
    "dd_hire_date@OData.Community.Display.V1.FormattedValue": "2026/07/01",
    "dd_hire_date": "2026-07-01T00:00:00Z",
    "dd_email_address": "kobayashi.yuna@example.com"
  },
  {
    "@odata.etag": "W/\"7777825\"",
    "dd_employeeid": "ebf144ab-9bbf-f111-aaaf-70a8a53d89f2",
    "dd_name": "加藤 翔",
    "dd_hire_date@OData.Community.Display.V1.FormattedValue": "2026/07/15",
    "dd_hire_date": "2026-07-15T00:00:00Z",
    "dd_email_address": "kato.sho@example.com"
  },
  {
    "@odata.etag": "W/\"7777826\"",
    "dd_employeeid": "ecf144ab-9bbf-f111-aaaf-70a8a53d89f2",
    "dd_name": "吉田 真央",
    "dd_hire_date@OData.Community.Display.V1.FormattedValue": "2026/08/01",
    "dd_hire_date": "2026-08-01T00:00:00Z",
    "dd_email_address": "yoshida.mao@example.com"
  }
]

受講管理の別案

リレーションを使わないテーブル間の差分を取得してみました。
今回はOnbordingTrainingテーブルが大きくなった場合に、トレーニングをすでに受講したかどうかを確認するために上記のような比較を実行しましたが、受講日などを管理しなくて良いならば、もっとシンプルな方法もありそうです。

受講済みユーザーはセキュリティグループに入れていき、催促メールを送るループのなかで、受講済みグループに存在するかどうかをチェックすればよいのです。

当初、グループの一覧を取得してその配列のなかから探す実装をイメージしましたが、なんのことはない。グループにユーザーが存在するかどうかを調べることができます。

「グループメンバーシップの確認(V2)」アクションは、ユーザーとグループIDを与えると、存在していればグループIDが返ってきます。
グループIDは複数与えることができて、その中のどのグループに指定したユーザーが存在するかを調べてくれる便利なアクションです。

image.png

よく考えてみれば、私自身もGraph APIを使ってグループからユーザーの存在を調べる方法について最近Qiitaに記事を書いていました。

まあ、実装にはいろんな方法があるということですね。
Graph APIで実装したときには「グループメンバーシップの確認(V2)」なんてあるの知らなかったし。
OH! 車輪の再発明。

まとめ

  • リレーションなしでもDataverseの複数テーブルから差分をFetchXMLをつかって抽出できる
  • Dataverseを使わなくてもセキュリティグループを使って簡易的に受講済みかどうかを判定させることもできる
  • グループならメールアドレスが変わっても問題ないので、むしろこっちのほうが良いかも。

お粗末様でした。

0
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
0
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?