SAP Crystal Reports for Microsoft Visual Studio バージョン 13.0.14.1720 を使用しています。C# Windows フォーム アプリケーションでレポートを表示しようとしています。現在、レポートは ArgumentOutOfRangeException で失敗しています。スタック トレースは次のとおりです。
System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
at System.Collections.ArrayList.get_Item(Int32 index)
at CrystalDecisions.Shared.PageRender.draw_FieldObjectInstance(FieldObjectInstance fieldObject, Graphics g)
at CrystalDecisions.Shared.PageRender.draw_ReportObjectInstance(ReportObjectInstance instance, Graphics g, Rectangle clipRect)
at CrystalDecisions.Shared.PageRender.draw_SectionInstance(SectionInstance section, Graphics g, Rectangle clipRect)
at CrystalDecisions.Shared.PageRender.Render(PageObject page, Graphics g, Graphics device_g)
at CrystalDecisions.Windows.Forms.PageControl.OnPaint(PaintEventArgs e)
at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
at System.Windows.Forms.Control.WmPaint(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ContainerControl.WndProc(Message& m)
at System.Windows.Forms.UserControl.WndProc(Message& m)
at CrystalDecisions.Windows.Forms.PageControl.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
これを Visual Studio 2015 で実行し、エラーで実行を停止しました。このフィールドでエラーが発生しています:
Field name: #SiteError2
ObjectName: SiteError11
Size: 120x221
OffsetInSection: 5528x0
SectionKind: GroupFooter
Section: GroupFooterSection2
レポート定義を見ると、このフィールドはグループ フッターにあります。このフィールドは、実行中の合計エラーの最大値を取得しています。現在の合計はすべてのレコードを評価し、グループの変更時にリセットされます。
エラーが 1 つでもある場合、フィールドにはアスタリスクが表示されます。それ以外の場合は、空白です。したがって、表示文字列には次の式があります。
iif(CurrentFieldValue > 0, "*", "")
値が <= 0 の場合に "" 以外を使用するように表示文字列式の定義を変更すると、エラーは発生しません。たとえば、次の表示文字列では、エラーは発生しません。
iif(CurrentFieldValue > 0, "*", "N")
表示文字列は、他の列で累計を実行する同じグループ フッター内の他の列と同じです。実際、グループ フッターには、これと同一のフィールドがいくつかあります。
フィールドを最初から削除して再作成してみました。同じエラーが発生します。
「データベースの NULL 値をデフォルトに変換」および「他の NULL 値をデフォルトに変換」のレポート オプションを変更しようとしましたが、それでもエラーが発生します。
また、レポート形式を古いバージョンから最新のものにアップグレードしてみました。
レポート列の定義は次のとおりです。グループ ヘッダーのフィールドは、以下の _Error 列の最大値を計算しています。これらの列は整数として定義されます。
<xs:element name="DRSiteAnalystSummary_Column_1_Error" type="xs:int" minOccurs="0" />
<xs:element name="DRSiteAnalystSummary_Column_2_Error" type="xs:int" minOccurs="0" />
<xs:element name="DRSiteAnalystSummary_Column_3_Error" type="xs:int" minOccurs="0" />
GAC の CrystalDecisions.Shared.dll で JetBrains dotPeek を実行しました。PageRender.draw_FieldObjectInstance メソッドを逆コンパイルすると、いくつかの配列インデックス参照が表示されます。これは私にとって際立っています:
private void draw_FieldObjectInstance(FieldObjectInstance fieldObject, Graphics g)
{
...
if (fieldObject.IsFieldNumeric)
{
fieldObjectInstance = (NumericFieldObjectInstance) fieldObject;
num7 = (int) g.MeasureString(fieldObjectInstance.PrefixReserve, font, this.m_layout, stringFormat).Width;
SizeF sizeF2 = g.MeasureString(fieldObjectInstance.SuffixReserve, font, this.m_layout, stringFormat);
num8 = (int) sizeF2.Width;
sizeF2 = g.MeasureString(fieldObjectInstance.FixedLeftReserve, font, this.m_layout, stringFormat);
num9 = (int) sizeF2.Width;
sizeF1 = g.MeasureString(fieldObjectInstance.FixedRightReserve, font, this.m_layout, stringFormat);
num10 = (int) sizeF1.Width;
if (!fieldObjectInstance.AllowClipping)
{
sizeF1 = g.MeasureString((string) fieldObject.TextLines[0], font, this.m_layout, stringFormat);
if ((int) sizeF1.Width + num7 + num8 + num9 + num10 > width)
{
flag2 = true;
alignment = Alignment.LeftAlign;
int num11 = width;
sizeF1 = g.MeasureString('#'.ToString(), font, this.m_layout, stringFormat);
int num12 = (int) sizeF1.Width;
int count = num11 / num12;
**fieldObject.TextLines[0] = (object) new string('#', count);**
}
}
}
上記のコードは、テキスト行があると想定しているようです。エラーが発生した時点で、TextLines プロパティの長さは 0 です。IsFieldNumeric が true で、fieldObjectInstance.AllowClipping が false であるため、このコードが実行されて失敗するようです。