Web パーツのエラーでページが表示できない場合のトラブルシューティング 2

対象製品:

SharePoint Server 2010

SharePoint Server 2013

 

関連記事:

Web パーツのエラーでページが表示できない場合のトラブルシューティング

 

こんにちは。SharePoint サポートチームの多田信吾です。

前回「Web パーツのエラーでページが表示できない場合のトラブルシューティング」の記事で、Web パーツのエラーでページが表示できないパターンを 4 つ紹介しました。今回は 5 つ目のパターンを紹介します。

 

要因 5. リストの列が 67 ~ 70 列を超えている

============================

SharePoint Designer で XSLT の記述形式を使用してデザインをカスタマイズしており、かつリストの列が 67 ~ 70 列を超えている場合、以下のエラーメッセージが表示されます。

 

エラーメッセージ

^^^^^^^^^^^

この Web パーツを表示できません。この問題のトラブルシューティングを行うには、Microsoft SharePoint Foundation と互換性のある Microsoft SharePoint Designer などの HTML エディターでこの Web ページを開いてください。問題が解決しない場合は、Web サーバーの管理者に問い合わせてください。

 

リストの各列の定義はひとつの xsl:template 要素内に含まれております。アイテムの新規作成ページや変更ページを表示する際に、ひとつのスタックに xsl:template 要素内の列定義が積まれるため、列数が多すぎると StackOverflowException が発生します。診断ログには以下のメッセージが記録されます。

 

--- 診断ログ ---

Error while executing web part: System.StackOverflowException: この操作によってスタック オーバーフローが発生しました。

場所 Microsoft.Xslt.NativeMethod.CheckForSufficientStack()    

場所 <xsl:template name="dvt_1.rowedit">(XmlQueryRuntime , XPathNavigator , Double , Double )    

場所 <xsl:template name="dvt_1.body">(XmlQueryRuntime , XPathNavigator , Double , IList`1 )    

場所 <xsl:template name="dvt_1">(XmlQueryRuntime , XPathNavigator , Double )    

場所 Root(XmlQueryRuntime )    

場所 System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer, Boolean closeWriter)    

場所 System.Xml.Xsl.XmlILCommand.Execute(IXPathNavigable contextDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter results)    

場所 System.Xml.Xsl.XslCompiledTransform.Transform(IXPathNavigable input, XsltArgumentList arguments, XmlWriter results)    

場所 Microsoft.SharePoint.WebPartPages.DataFormWebPart.ExecuteTransform(XslCompiledTransform xslCompiledTransform, XsltArgumentList xmlArguments, Boolean bDeferExecuteTransform)    

場所 Microsoft.SharePoint.WebPartPages.DataFormWebPart.PrepareAndPerformTransform(Boolean bDeferExecuteTransform)

----------------

 

対処策

^^^^

本来はパフォーマンスを考慮し、可能な限り 67 列を超えないリスト設計を推奨いたしますが、要件により 67 列以上を使用する場合は、以下の方法にて各列の定義を分散して xsl:template要素に配置することでエラーメッセージを防ぐことが可能です。

 

1. SharePoint Designer にて該当のカスタムフォームを開きます。

2. 以下の部分を探します。

 

<xsl:call-template name="dvt_1.rowedit"/>

 

3. 上記の記述を以下のように 3 つから 5 つぐらいコピー & ペーストし、以下のように name 属性を変更します。

 

<xsl:call-template name="dvt_1.rowedit"/> <xsl:call-template name="dvt_1.rowedit2"/> <xsl:call-template name="dvt_1.rowedit3"/> <xsl:call-template name="dvt_1.rowedit4"/> <xsl:call-template name="dvt_1.rowedit5"/>

 

4. 以下の部分を探します。以下の xsl:template 要素内に列の定義が記載されております。

 

<xsl:template name="dvt_1.rowedit">

 

5. xsl:template 要素内の列の定義を除いた外側の部分のみを 3 つから 5 つぐらいコピー & ペーストします。

 

xsl:template要素例

---

<xsl:template name="dvt_1.rowedit">

  <xsl:param name="Pos" select="position()"/>

  <tr>

   <td>

    <table border="0" cellspacing="0" width="100%">

 

    </table>

   </td>

  </tr>

</xsl:template>

---

 

6. コピー & ペーストした各 xsl:template 要素の name 属性を、手順 3 で作成した call-template 要素と整合が合うように、それぞれ以下のように変更します。

 

---

<xsl:template name="dvt_1.rowedit2">

  <xsl:param name="Pos" select="position()"/>

  <tr>

   <td>

    <table border="0" cellspacing="0" width="100%">

 

    </table>

   </td>

  </tr>

</xsl:template>

 

<xsl:template name="dvt_1.rowedit3">

  <xsl:param name="Pos" select="position()"/>

  <tr>

   <td>

    <table border="0" cellspacing="0" width="100%">

 

    </table>

   </td>

  </tr>

</xsl:template>

 

---

 

7. もとの xsl:template 要素内の列の定義をコピー & ペーストした各 xsl:template 要素に分散します。例えば 1 番から 100 番までのテキストボックス列があった場合は、以下のように分散します。

 

・<xsl:template name="dvt_1.rowedit"> の要素内 : 1 番から 20 番までのテキストボックス列の定義

・<xsl:template name="dvt_1.rowedit2"> の要素内 : 21 番から 40 番までのテキストボックス列の定義

・<xsl:template name="dvt_1.rowedit3"> の要素内 : 41 番から 60 番までのテキストボックス列の定義

・<xsl:template name="dvt_1.rowedit4"> の要素内 : 61 番から 80 番までのテキストボックス列の定義

・<xsl:template name="dvt_1.rowedit5"> の要素内 : 81 番から 100 番までのテキストボックス列の定義

 

ひとつの列の定義は以下のような <tr> 要素によって定義されております。コピー & ペーストした各 xsl:template 要素への分散はこの <tr> 要素単位で行います。

 

テキストボックス列の定義例

-----

<tr>

<td width="25%" class="ms-vb">

   <b>84:</b>

</td>

<td width="75%" class="ms-vb">

   <SharePoint:FormField runat="server" id="ff352{$Pos}" ControlMode="New" FieldName="_x0038_4" __designer:bind="{ddwrt:DataBind('i',concat('ff352',$Pos),'Value','ValueChanged','ID',ddwrt:EscapeDelims(string(@ID)),'@_x0038_4')}" /> 

<SharePoint:FieldDescription runat="server" id="ff160description192{$Pos}" FieldName="_x0038_4" ControlMode="Edit" />

</td>

</tr>

-----

 

補足 : 列の定義が正しく認識されない場合は SharePoint Designer のデザインビューにて列がエラーとして表示されます。この状態で保存した場合はカスタムフォームが表示できない場合があります。

 

8. カスタムフォームを保存し、カスタムフォームにて 70 列以上の列が正常に表示されることを確認します。

 

補足情報

^^^^

上記の対処策を実施した場合においても、前回のブログ記事にて紹介した「要因 4. XSLT の初回レンダリング時にコンパイルが失敗する」が発生する可能性があります。このため、パフォーマンスを考慮する意味でも列の数を 67 よりも少なくすることを推奨いたします。

しかしながら、列の数を 67 列以上表示する場合は、Visual Studio にてリストを表示する Web パーツを作成することで、XSLT を使用せずにデータを表示できるため、要因 4 の発生を防ぐことができます。

- 参考資料
タイトル : SharePoint 2010 の視覚的 Web パーツを作成する
アドレス : https://msdn.microsoft.com/ja-jp/library/office/ff597539(v=office.14).aspx

タイトル : SharePoint 2010 コントロールを使用して視覚的 Web パーツを作成する
アドレス : https://msdn.microsoft.com/ja-jp/library/office/ff728094(v=office.14).aspx

タイトル : 方法: SharePoint Web パーツを作成する
アドレス : https://msdn.microsoft.com/ja-jp/library/vstudio/ee231519(v=vs.110).aspx

タイトル : 10 行でズバリ!! SharePoint のサンドボックス ソリューションの作成 (C#)
アドレス : https://code.msdn.microsoft.com/office/10-SharePoint-C-f18f22a6

タイトル : LINQ を使用して SharePoint 2010 Web パーツでデータにアクセスする
アドレス : https://msdn.microsoft.com/ja-jp/library/office/ff742312(v=office.14).aspx