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