Dynamics CRM 4.0 は標準でEntityのデータをエクスポートしてくれる機能はありません。マスタとして使用しているEntity がある場合、本番環境とステージング環境でデータの不一致などを調べるためにEntityのデータをCSV形式などで、エクスポートできれば非常に便利です。

今回は、Codeplex 上に公開されているBuld Data Export Tool を紹介します。Export Tool は 指定したEntityの全データ(FilteredViewと同等)をCSV形式でエクスポートしてくれる便利なツールです。

CRM 4.0 Bulk Data Export Tool
http://www.codeplex.com/mscrmbulkdataexport

Dymamics CRM Team のツールに関するブログ
http://blogs.msdn.com/crm/archive/2008/04/30/crm-4-0-bulk-data-export-tool.aspx

ただし、こまったことに、このツール現時点でダウンロードできるv1.0 はつぎの問題があります。3番目の問題は、本番とステージング環境でCSVを比較するときに列の順番が一致していないとひたすら面倒(Excel で対応できると思いますが) なので問題としてあげています。

  • バイナリ版だと途中で落ちるorz
  • Entity名にファイル名に使用できな文字が含まれていると落ちる
  • 出力されるCSVの列の順番が環境によってことなる。

そのため、codeplex で公開されているソースを修正して、次のことに対応します。

  • ちゃんと動くようにする
  • Entity名にファイルに使用できな文字が含まれるケースに対応する
  • フィールドの物理名(not 表示名) にソートしてファイルをエクスポートする

動作確認環境

  • Windows Server 2003 Enterprise Edition 32bit 上に構築してDynamics CRM with Rollup 5.0 オールインワン環境。
  • プログラムの実行も同環境上で行っています。

また、MSCRM 4.0 Buld Data Export Tool はOnPremise(AD認証)かLive 認証に対応しています。動作確認はAD認証でのみ行っています。

1. MSCRM 4.0 Bulk Data Export Tool を取得する

MSCRM 4.0 Bulk Data Export ToolのDownloadページにアクセスします。
http://mscrmbulkdataexport.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=12682

ダウンロードつきでソースつきのソリューションをダウンロードします。執筆時点で、CrmDataExport-1.0-Src.zip をダウンロードしました。zipを右クリックして、プロパティを選択します。プロパティダイアログの全般タブで下部にブロックの解除ボタンが表示される場合は解除ボタンをクリックしてください。

同ページにはバイナリバージョンCrmDataExport-1.0-Binary.zip がありますが、解答して実行すると、処理の途中で次のエラーダイアログが表示されます。

2. ソースの修正

ダウンロードした zip ファイルを展開して、Visual Studio 2008 でソリューションを開きます。以降、本記事の冒頭で記載した修正を行います。

2.1 動くようにする

プログラムがクラッシュする原因は、古いCSM SDK のdll を参照してビルドされていることが原因です。

まず、ソリューションで参照されているmicrosoft.crm.sdk.dll と microsoft.crm.sdktypeproxy.dll の参照を削除します。

次に、最新の Dynamics CRM 4.0 の SDK をダウンロードし、SDKの sdk\bn に含まれる、microsoft.crm.sdk.dll と microsoft.crm.sdktypeproxy.dll
を参照に追加します。
(64bit環境でコンパイルする場合はsdk\bin\64bitフォルダのdllを参照に追加して下さい)。

ソリューションをリビルドす、エラーがなければ実行できるようになりました。

CRMがインストールされたサーバ上でプログラムを実行する場合は、ソリューションのDebug(or Release) フォルダにコピーされたmicrosoft.crm.sdk.dll と microsoft.crm.sdktypeproxy.dllは必要ありません。GACに適切なdllがインストールされているのでなくても動作します。

32bit マシンでコンパイルしたdll を 64 bit の非CRM サーバで実行する場合は、64bit 用のmicrosoft.crm.sdk.dll と microsoft.crm.sdktypeproxy.dllを実行ファイルと同じフォルダに配置して実行します。

2.2 エンティティ名にファイル禁止文字がふくまれると落ちる問題に対処する

Bulk Export Tool は エクスポートするエンティティ名をファイル名にもつCSV ファイルを作成します。
表示名に<> 記号などファイル名として不適切な文字が含まれるとExport Toolは
容赦なく落ちます。その修正お行います。

DataExportHelper.cs ファイルのExportEntityDataメソッドを修正します。修正箇所は302行目あたりの、"#region 追加:禁止文字が含まれる場合の対応"と記載している領域部分です。

//Make sure we do page by page retrieval with max of 5000 records per page
pageNo = 0;
query.PageInfo = new PagingInfo();
while (true)
{
     query.PageInfo.PageNumber = ++pageNo;
     query.PageInfo.Count = recordCount;

     RetrieveMultipleResponse retrieved = RetrieveMultipleEntityRows(query, entityName);

     if (retrieved == null)
        break;
     crmEntityDataTable.Clear();
     fileHelper.AddRecordsToDataTable(retrieved, crmEntityDataTable);

     //Export the dataset of the entity to CSV.
    string fileName = row.ItemArray[0].ToString();
     //string fileName = entityName;
     #region 追加:禁止文字が含まれる場合の対応
      char[] invalidChars = System.IO.Path.GetInvalidFileNameChars();
     foreach (char invalidchar in invalidChars)
     {
          if (fileName.IndexOf(invalidchar) >= 0)
          {
              fileName = fileName.Replace(invalidchar, ' ');
          }
      }
      fileName = fileName.Trim();
      #endregion

      if (fileName.Contains("/"))
             fileName = dirPath + "\\" + fileName.Replace("/", " ") + ".csv";
      else
             fileName = dirPath + "\\" + fileName + ".csv";
     //Export the data in Data Table to the CSV.
      fileHelper.ExportCsv(entityName, fileName, fieldDelimiter, dataDelimiter, crmEntityDataTable, pageNo);
      if (retrieved.BusinessEntityCollection.BusinessEntities.Count < recordCount)
           break;
       query.PageInfo.PagingCookie = retrieved.BusinessEntityCollection.PagingCookie;
}

2.3 エンティティの列名でソートしてCSV ファイルをエクスポートする

列名の順番が本番、ステージング環境でエクスポートしたファイルの列の順番が異なっていると、Diff ツールで比較するのが面倒です。エクスポートしたファイルをExcel でがんばって列順を変更すれば対応できますが、毎回行うのは面倒です。プログラムを守勢して、列の物理名(表示名ではありません)にソートしてCSVファイルを出力させるようにします。

修正するのは、引き続きDataExporthelper.cs のExportEntityDataメソッドです。修正内容は以下のコード参照。オリジナルソースの245行目あたりから修正を入れています。2か所追加、1か所コメント化と追加を行っています。#region で修正箇所を示してあります。

if (selectedEntityList.Contains(row.ItemArray[0].ToString()))
{
    string entityName = row.ItemArray[0].ToString();
    exportStatusText = "Exporting data for Entity: " + entityName + "...";
    int totalColumns = 0;
     // Create the ColumnSet that indicates the properties to be retrieved.
    ColumnSet cols = new ColumnSet();

     //Process all the attributes and add the columns to the Entity table
     #region 追加:列の物理名でソートするため修正
      System.Collections.Generic.SortedList<string, string> columns = new System.Collections.Generic.SortedList<string, string>();
     #endregion

     for (int attributeIndex = 0; attributeIndex < crmMetadataDataSet.Tables["AttributeMetadata"].Rows.Count; attributeIndex++)
     {
         row1 = crmMetadataDataSet.Tables["AttributeMetadata"].Rows[attributeIndex];
         if (row1.ItemArray[2].ToString() == entityName)
         {
             attributeName = row1.ItemArray[3].ToString();
             #region 追加とコメントアウト:列の物理名でソートするため修正
               columns.Add(attributeName, attributeName);
             //crmEntityDataTable.Columns.Add(attributeName);
             //cols.AddColumn(attributeName);
             #endregion
             totalColumns++;
          }
     }
     #region 追加:列の物理名でソートするため修正
      foreach (System.Collections.Generic.KeyValuePair<string, string> key in columns)
     {
          crmEntityDataTable.Columns.Add(key.Value);
           cols.AddColumn(key.Value);
      }
      #endregion
     // Create the QueryExpression object.
       QueryExpression query = new QueryExpression();

上記対応でCSV 形式は常に決まった列順で出力されるようになります。

3. CSV 比較ツールで比較する

エクスポートされたファイルはDynamics CRM のインポート機能を使用してインポートできます。新環境を作成する場合など、非常に便利です。そのままインポートしようとするとGUID も含めてインポートするので注意してください。

上記の用途以外の変更の管理や、比較を行うことに使用できます。Dynamics は Entity のレコードをGUID で管理したり、修正日、作成日など、比較対象としたくないごみ列もあるので、 WinMerge や DF などDiff ツールでそのまま比較すると加工が必要になります。

そこで使用したいのがCSV 用に特化された Diff ツールです。私が使用しているのがCSVDFというツールです。CSVDF は比較する次のようなことが行えて素敵です。キー列をしてすると、行がソートされていなくてもキーを突合して比較してくれるので便利です。ただし、CSVDFはShift-JIS 文字コードではないと文字化けを起こします。Export Tool はそのままではUnicode 形式でファイルをエクスポートします。

  • カラム単位の比較
  • キー列の指定
  • 比較対象外の列指定

詳細は作者様のページを参照して下さい。

CSVDF 紹介ページ
http://www.ne.jp/asahi/net/sakuya/htl12.htm
次のページからダウンロードできます。
http://www.ne.jp/asahi/net/sakuya/GM_FRAME.HTM

ほかにもフリーで公開されているCSV用のエクスポートツールはあると思いますが一例としてCSVDFを紹介させていただきました。

4. まとめ

今回の説明は以上です。 Dynamics CRM は データがGUID で管理されるので、マスタデータ管理など Bulk Export Tool が役に立つのではないかと思います。