Morning Girl

Web API, Windows, C#, .NET, Dynamics 365/CRM etc..

Dynamics 365(CRM)の監査ログをExcelに出力する:CData Excel-Addin for Dynamics 365を使用

最近、Dynamics 知り合いの方から、「Dynamics 365 for Customer Engangement の監査ログをExcel エクスポートしたいんだけど、できないのー。なんとかしてー」という、質問(?)をもらいました。

確かにDynamics 365の監査ログって、取得しづらいんですよね。

Excel エクスポートボタンが画面についていないですし、

f:id:sugimomoto:20181209170041p:plain

内部構造も若干複雑で、Web API経由で取得するのもちょっと面倒な代物です。

でも、取得できると、ユーザーが普段どんなエンティティを使っているのか? どんな操作をしているのか? いつWeb アクセスしているか? などの情報が取れるので、Dynamics 365(CRM)を活用していくにあたって、結構重要な情報なので用途は多いと思います。

通常であれば、Web APISDKを使って、ガリゴリするところですが、CData Excel-Addinを利用することで、かなり簡単に監査データにアクセスできたので、紹介してみたいと思います。

あと、個人的に CData Excel-Addinでどこまで取得できるのかなーという自分自身の純粋な興味もありました。

どんな情報が取得できるのか?

のっけから結論ですが、CData Excel Add-In だと以下のような感じで、Excelにデータがエクスポートできます。

レコードのCreateやUpdateの情報は対象のエンティティ、レコードのGUID、プライマリのタイトル、実行したユーザーなどが。

フィールド情報は残念ながらColumnNumberしか取れません。ちょっとこの辺はAttributeと掛け合わせて解析する必要があります。

f:id:sugimomoto:20181209170055p:plain

ユーザーアクセスはDynamics 365画面上から見ることができる通りに取得できますね。

ただ、注意したいのが、この記録はDynamics 365の仕様上、ログインした時間ではなく、ログインを実施していれば操作や一定時間ごとに取得される情報なので、この数が多いからと言って、ログインが多いユーザーとは限りません(アクセスは間違いなくしていますが)

f:id:sugimomoto:20181209170106p:plain

では、実際にこのデータの取得方法を説明していきたいと思います。

必要なもの

・CData Dynamics CRM Excel-Addin ・Dynamics 365 for Customer Enagement アカウント

実施手順

まず、CData Dynamics CRM Excel-Addinをダウンロードします。

Dynamics 365 Salesでもいいのですが、Web APIの仕様上、若干取得できるデータが異なるので、監査ログであれば、Dynamics CRM タイプがおすすめです。

https://www.cdata.com/jp/drivers/dynamicscrm/excel/

f:id:sugimomoto:20181209170126p:plain

ダウンロードしインストーラーを立ち上げると、以下の画面で製品インストールを進めることができます。

f:id:sugimomoto:20181209170136p:plain

インストール後、Excelを起動するとリボンに「CData」タブが追加されています。

ここから、取得元 Dynamics CRM を選択し

f:id:sugimomoto:20181209170148p:plain

ログイン情報、「User」「Password」「Url」を入力し、「OK」をクリックしてください。

f:id:sugimomoto:20181209170636p:plain

「サーバーに接続できました」とメッセージが表示できれば、OKです。

f:id:sugimomoto:20181209170215p:plain

監査ログを取得できるテーブルはAuditテーブルです。

Audit テーブルを選択し、取得条件などを入力して、OKをクリックすれば

f:id:sugimomoto:20181209170223p:plain

以下のようにデータを取得できます。

f:id:sugimomoto:20181209170235p:plain

初期状態では100件上限ですが、日付などでフィルタリングもできるので用途に応じて、調整してみてください。

CData ADO.NET Provider が .NET Coreに対応したので、試しにXamarin サンプルアプリ を Dynamics 365 のタスク管理アプリにしてみる

この記事は「C# その2 Advent Calendar 2018」の記事です。

qiita.com

手前味噌なんですが、最近 CData ADO.NET Provider が .NET Standard に対応しました! やったね!

https://www.cdata.com/jp/ado/

f:id:sugimomoto:20181208172504p:plain

それじゃあ、Unityt でも Xamarin でも使えるではないか! ということで、個人的にあまり今まで触れてこなかったXamarin を体験しながら、試してみた! というのが本記事の趣旨になります。

CData ADO.NET Provider って何?

通常SQL ServerMySQLといったRDBにアクセスするために提供されているADO.NETを、Dynamics 365 や SalesforceTwitterFacebookといったWeb APIを提供しているサービスに接続できるようにしてしまうというDriver製品です。

例えばTwitter であれば、「Select * From Tweets」とクエリすれば、タイムラインの一覧が取得でき

「Insert into Tweets(Text)values('Hello World!')」とクエリすれば、ツイートができるという、摩訶不思議(?)なライブラリです。

ついでに Dynamics 365 って何?

Microsoft が提供する 次世代のビジネス アプリケーション!!

つまるところ、マイクロソフトが提供するCRMERPクラウドサービスです。(Office365と間違えないでね)

f:id:sugimomoto:20181208172532p:plain

用途に応じて様々なエディションがあるのですが、今回はDynamics 365 for Customer Engagement(旧Dynamics CRM)を使います。

Dynamics 365 for Customer Engagement では Web API(OData・SOAP)が提供されているので、これを使って外部連携のアプリケーションを開発することが可能です。

出来上がりはこんな感じ

せっかくなので作ったXamarin アプリをAmazon Fire HDで動かして、ムービーを撮ってみました。

Dynamics 365 のタスク情報を 参照・作成・更新・削除 できる Xamarin です。

面倒なことはせず、モバイル アプリテンプレートを使って、処理部分だけ拡張しています。

youtu.be

サンプルでは「MockDataStore」で生成されたメモリ上のアイテムですが、IDataStoreを継承したクラスを作成して、そこからDynamics 365 のデータソースへADO.NET Proivder 経由でアクセスしているだけといえばだけです。

大した実装はしていないですが、ソースコードは以下に置いています。

github.com

必要な環境

・Visual Stduio 2017 (Xamarin開発用のモジュールを入れておきます)

Android Studio(Emulater)、Java SDKなどXamarin Android開発用のモジュール一式

・Dynamics 365 トライアルアカウント

・CData ADO.NET Providr for Dynamics 365

CData ADO.NET Providr for Dynamics 365 のインストール

今回使うCData ADO.NET Providr for Dynamics 365 を予めインストールしておきます。(トライアルがあるので、それを使います。)

以下はDynamics CRMと書かれていますが、Dynamics 365 for Customer Engagement にも接続可能です。

https://www.cdata.com/jp/drivers/dynamicscrm/ado/

Xamarinテンプレートを使って雛形を作成

Visual Stduio を立ち上げてあらたらしく「モバイルアプリ(Xamarin.Forms)」を作成します。

f:id:sugimomoto:20181208172635p:plain

テンプレートは「Master-Detail」を選択し、これをベースに改良します。

f:id:sugimomoto:20181208172859p:plain

参照の追加

プロジェクトを作成したら、まずは先程インストールしたCData ADO.NET Providerの参照です。

以下のフォルダにある.NET Standard ライブラリ「System.Data.CData.DynamicsCRM.dll」を参照します。

C:\Program Files\CData\CData ADO.NET Provider for Dynamics CRM 2018J\lib\netstandard2.0

f:id:sugimomoto:20181208172906p:plain

実装

これで準備は整いました。あとは心置きなく改良します。

今回は「Master-Detail」テンプレートに最初から備わっている「MockDataStore.cs」を差し替える感じにします。

新しく「Dynamics365DataStore」というクラスを作成して、以下のように構成しました。

github.com

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.CData.DynamicsCRM;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CDataSampleApp.Models;

namespace CDataSampleApp.Services
{
    class Dynamics365DataStore : IDataStore<Item>
    {
        private string connectionString = "User=XXXXX@XXXXX.onmicrosoft.com;Password=XXXXXX;URL=https://XXXXXXX.crm7.dynamics.com/;CRM Version=CRM Online;RTK=XXXXXXX;";

        public async Task<bool> AddItemAsync(Item item)
        {
            var sql = $"insert into Task(Subject,Description)values('{item.Text}','{item.Description}')";
            var result = ExecuteForDynamics365(sql);

            return await Task.FromResult(result);
        }

        public async Task<bool> UpdateItemAsync(Item item)
        {
            var sql = $"Update Task set Subject = '{item.Text}', Description = '{item.Description}' where Id = '{item.Id}'";
            var result = ExecuteForDynamics365(sql);

            return await Task.FromResult(result);
        }

        public async Task<bool> DeleteItemAsync(string id)
        {
            var sql = $"Delete from Task where Id = '{id}'";
            var result = ExecuteForDynamics365(sql);

            return await Task.FromResult(result);
        }

        public async Task<Item> GetItemAsync(string id)
        {
            var resultItem = QueryForDynamics365ById(id);
            return await Task.FromResult(resultItem);
        }

        public async Task<IEnumerable<Item>> GetItemsAsync(bool forceRefresh = false)
        {
            var resultItems = QueryForDynamics365();
            return await Task.FromResult(resultItems);
        }

        private bool ExecuteForDynamics365(string sql)
        {
            var response = 0;

            using (var connection = new DynamicsCRMConnection(connectionString))
            {
                var cmd = new DynamicsCRMCommand(sql, connection);
                response = cmd.ExecuteNonQuery();
            }

            return response == 0 ? false : true;
        }

        private Item QueryForDynamics365ById(string id)
        {
            return QueryForDynamics365(id).FirstOrDefault();
        }

        private List<Item> QueryForDynamics365()
        {
            return QueryForDynamics365(null);
        }

        private List<Item> QueryForDynamics365(string id)
        {
            List<Item> items = new List<Item>();

            using (var connection = new DynamicsCRMConnection(connectionString))
            {
                var sql = "SELECT Id, Subject, Description FROM Task";
                sql += id == null ? "" : $" where Id = '{id}'";

                var dataAdapter = new DynamicsCRMDataAdapter(sql, connection);
                var table = new DataTable();
                dataAdapter.Fill(table);

                foreach (DataRow row in table.Rows)
                    items.Add(new Item()
                    {
                        Id = row["Id"].ToString(),
                        Text = row["Subject"].ToString(),
                        Description = row["Description"].ToString()
                    });
            }

            return items;
        }


    }
}

見てもらえば分かる通り、通常であればDynamics 365 Web APIをHTTPリクエストして、JSONをパースなりなんなりするところですが、全部ADO.NET Provider経由で「DataAdapter」を利用しながら実装しています。

(本当はEntityFramework Coreを使えればよかったんですが、まだCData ADO.NET Provider が対応していないので、、、。)

「SELECT Id, Subject, Description FROM Task」でレコードの一覧が

接続文字列は今回わかりやすいようにソースコードに加えていますが、実際にはユーザーからの入力を受け取るなり、Settingで保持するなり対処する必要があるかと思います。

あとは、もともとMockDataStoreをインスタンス化していた、「BaseViewModel」を差し替えるだけです。

namespace CDataSampleApp.ViewModels
{
    public class BaseViewModel : INotifyPropertyChanged
    {
        // ここの new MockDataStore を new Dynamics365DataStore に変更
        public IDataStore<Item> DataStore => DependencyService.Get<IDataStore<Item>>() ?? new Dynamics365DataStore();

あと、初期状態では、Insertしかテンプレートが対応していないので、UpdateとDeleteのボタンとかも、GitHubには追加しています。(もうちょっと調整が必要ですが、、、。)

最後に

Xamarin は Xamarin でおそらくモバイルアプリ的データ操作のお作法がいろいろとあるかと思うのですが、今回は単純にクラウドサービスにつないで見るということを主眼にやっちゃってます。

CData ADO.NET ProviderにはローカルのSQL Liteに取得したテーブルをキャッシュ用としてレプリケートしてしまう機能があるので、それと組み合わせられると、パフォーマンス的な観点やオフライン動作なども対応できないなかーと考えたりです。

仙台で12月16日(日)にものすごく面白そうな勉強会「テクノロジードリブンでビジネスインパクトを生み出す!-最前線でチャレンジをするチームの取組事例を大公開-」を勝手に紹介してみる

f:id:sugimomoto:20181128132143p:plain

仙台で12月16日(日)にものすごく面白そうな勉強会「テクノロジードリブンでビジネスインパクトを生み出す!-最前線でチャレンジをするチームの取組事例を大公開-」が開催されるのですが、公開されてそれなりに経つのに、申込みが少なすぎる! 

techplay.jp

なので、私自身がいろいろと調べた内容も交えて、紹介も含めながら、もっと参加者が増えろー! という祈りもこめつつ、個人的な気になるポイントを垂れ流そうと思います!(あと、個人的に勉強会は参加する前に下調べしておいたほうが得られるものが多いと思っているので。タグは勝手につけました。非公式)

続きを読む

APIのためのKPIはどう考えるべきか? APIを公開し、APIエコノミーに携わる人々が見るべきドキュメント APIs for KPIs の和訳

f:id:sugimomoto:20180707214339p:plain

先々月に行われたAPI x PM #01で「APIを公開したけど、KPI,KGIをどう測るか? 何を指標にするかが難しい」というお話がサイボウズの北川さんからありました。(公開するの忘れてた)

kageura.hatenadiary.jp

確かに指標としてアクセス数やコール数、接続先のドメイン数など、ある程度考えられるものはありましたが、はっきりとKPIとはこう捉えるべきだ、という指針・ナレッジは私の中にもありませんでした。

せっかくなので、と思い調べていたところ、以下のドキュメントにめちゃくちゃ感動! しまして、これはもっと広まるべきだ! と思い、慣れないながらも和訳を実施してみました。

www.slideshare.net

なお、ただスライドベースで載せても伝わりづらいので、結構私なりの解釈も交えながら意訳している部分もあります。 また、日本でも一般的になっているようなキーワードはあえて和訳していません。

続きを読む

Mulesoft Anypoint って何? どんなサービス? 既存のサービスと比較しながら

最近ちまちまと触り始めたMuleSoft Anypoint。

去年Salesforceが買収したことで、日本でも少しづつ認知度があがってきたとは思いますが、まだまだ日本語の情報は少なく、取っつきづらさがあります。

ただ、ちょうど先週MuleSoft Meetupに参加して、自分なりにも色々触ってみて、これはナカナカなるほどなー、という製品だったので、個人的な調べ物の記録として、書き留めておきたいと思います。

【抄訳】セールスフォース・ドットコム、MuleSoft 買収の最終契約を締結 - セールスフォース・ドットコム

f:id:sugimomoto:20180920182954p:plain

続きを読む

中堅SIerから開発者向けツールベンダー CData Software Japanに転職しました!(1年経ってるけど)

せっかくなので一回書きたいなー、書きたいなーと思っていた、退職・転職エントリ。

SI・SES系からWeb系に転職する人、コンサルに行く人、それなりに居る気がしますが、ツールベンダーに転職する人の記事は見たことが無いなぁと思っていました。

それに1年経っていろいろとわかってきたこともあるので、ここいらで投下してみようと思います。(遅いですかね。でも逆に落ち着いて、今の会社を見れるようになったので、それはそれでいいかなと思ったり)

それはそれとして、色々と転職で悩んでいる人の参考になれば幸いです。

続きを読む

主要クラウドサービスのPMが自社のAPIを語る! API x PM #01 参加レポート

f:id:sugimomoto:20180703191135j:plain

参加対象者が「製品やサービスをProduct Manager、Product Owner、製品企画として運営する方で「API」が守備範囲の方」!

サイボウズ・Sansan・CloudSign・freee」現在のクラウドサービス最前線でAPIに関わるPMの方々が自社のAPIの狙い、戦略、苦労を語る、というかなり舵を振り切った勉強会、API x PM #01に参加してきました。

apipm.connpass.com

こんなところでやりました

会場は サイボウズ 東京オフィスでした。こんな感じでおしゃれなカフェみたいなところ!

続きを読む