莫大なアイテム数のリストから、アイテムの取得[オンライン・オンプレ]

2017/05/07

プログラムにて、SharePoint非常にアイテム数の多いリストやドキュメントライブラリから、確実にアイテムを取得する方法について記載しています。

 

1.複数回に分けて取得する

 

 非常にアイテム数が多いリストやドキュメントライブラリから、アイテムを取得することを考えます。ここで、全アイテムが取得できるはずのSPList.Itemsを使用すると、リストビューの閾値の制限やタイムアウトの発生により、全アイテムを一度に取得できない場合があり、推奨されていません。
 また、ドキュメントライブラリにおいては、SPList.Itemsはファイルは返しますがフォルダは返さないため、限定的な利用しかできません。そもそも、オンライン用のCSOMやJSOMにはこれに相当するものは存在しません。

 

 このため、非常にアイテム数が多いリストやドキュメントライブラリからアイテムを取得する際には、CAMLクエリーにより取得範囲を制限しながら、複数回に分けて取得する方法を取ります。

 また、ドキュメントライブラリの場合には、更にフォルダを指定してファイルアイテムを取得します。

 複数回に分けて取得する際には、リスト内で一意となるキーが必要ですので、これにはIDを使用します。IDを限定することで取得範囲を絞りながら、複数回に分けて取得します。

 

これを実現するには、以下のようなプログラムとなります。(CSOMです。)

 

 

ここで、DEF_LISTVIEW_TACT_COUNTの値で、一回に取得するアイテムの数を指定します。これを、リストビューの閾値以下の適当な数値とします。

 

 

2.フォルダ内リストアイテムのIDの最小値と最大値を取得する

 

 上記のプログラムでは、フォルダ内のリストアイテムIDの最小値と最大値を固定としていますが、本来はこれは対象のフォルダ毎に、プログラムによって取得すべきものです。

最大値は以下のようなコードで取得できるように思われますが...(TypeScript+JSOMです。)

 

 

 ところが、このCAMLクエリーでは、フォルダ内のサブフォルダのIDの最大値が返されてしまい、アイテムのIDの最大値は取得できません。

 

 フォルダではなくアイテムのIDの最大値を取得するために、コンテンツタイプにて、フォルダのコンテンツタイプ以外を取得する方法が考えられます。実際には、フォルダを継承したコンテンツタイプも外す必要があるので、コンテンツタイプIDが0x0120を頭に持つもの以外を取得するといった方法です。

(コンテンツタイプIDについては、こちらに記載しています。)

 ですが、CAMLクエリーでは、<BeginsWith>とか<Contains>の様に「〇〇を含む」といったクエリーは書けますが、「〇〇を含まない」を一文で表現することはできません。

 

 そのため、多分に裏技のようですが、「FSObjType」というフィールドを使う方法を取ります。このようなコードとなります。

 

 

以上を元に、フォルダ内のアイテムのIDの最大値を取得する関数は以下の様になります。

 

 

同様にして、フォルダ内のアイテムのIDの最小値を取得する関数は、

Ascending='TRUE'

として、以下の様になります。

 

 

 

3.コードの全体

 

 フォルダ内のリストアイテムのIDの最大値と最小値が取得できたので、「1.複数回に分けて取得する」にて記載したIDの最大値と最小値をこれで置き換えれば、フォルダ内に非常に多くのアイテムが存在しても、全てのアイテムを確実に取得することができます。

 

 ただし、JSOMではSharePointサーバーへのアクセスが非同期となるため、for文が上手く動作しないので、以下のようなコードにします。

 

 

以上となります。

 

サンプル用に記載したため、エラー処理がいい加減になっていますので、利用される際は注意してください。

 

 

 

 

 

 

 

Share on Facebook
Share on Twitter
Please reload

RECENT POST
Please reload

Copyright© 2017  Aiprovide Corporation all Right Reserved.

  • Aiprovide Coroporation
  • Aiprovide Corporation