使用显示字符串 属性 显示 Crystal 报告导致 ArgumentOutOfRangeException
Displaying Crystal Report With Display String Property Causes ArgumentOutOfRangeException
我有 SAP Crystal Microsoft Visual Studio 版本 13.0.14.1720 的报告。我正在尝试在 C# Windows Forms 应用程序中显示报告。该报告现在因 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
查看报表定义,此字段位于组页脚上。该字段正在获取 运行ning 错误总数的最大值。 运行ning 总数评估每条记录并在组更改时重置。
如果至少有 1 个错误,该字段应该显示星号。否则,它是空白的。因此显示字符串具有以下公式:
iif(CurrentFieldValue > 0, "*", "")
如果我将显示字符串公式的定义更改为在值 <= 0 时使用“”以外的任何内容,则不会出现错误。比如下面的Display String,不会出现错误:
iif(CurrentFieldValue > 0, "*", "N")
显示字符串与同一组页脚中的其他列相同,对其他列执行 运行ning 总计。事实上,组页脚上有几个字段与此相同。
我尝试从头开始删除并重新创建字段。出现同样的错误。
我尝试更改 "Convert Database NULL Values to Default" 和 "Convert Other NULL Values to Default" 的报告选项,但错误仍然存在。
我也试过将报告格式从旧版本升级到最新版本。
报表列定义如下。组 header 上的字段正在计算下面 _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" />
我 运行 JetBrains dotPeek 在 GAC CrystalDecisions.Shared.dll 上。反编译 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 为真而 fieldObjectInstance.AllowClipping 为假,因此看起来此代码将 运行 并失败。
在Visual Studio中,我在CrystalDecisions.Shared.PageRender.draw_ReportObjectInstance调用CrystalDecisions.Shared.PageRender.draw_FieldObjectInstance之前设置了一个断点。我检查了报告中的每个字段实例。除此字段外,每个数字对象都将 AllowClipping 设置为 true。
该字段为数字(IsNumeric 为 true),AllowClipping 为 false。这意味着它将达到我在上面的问题中列出的 draw_FieldObjectInstance 代码中的索引参考假设。
我无法解释为什么这个字段不同。也许有人在 Visual Studio 的 Crystal 报告的不同版本中创建了它。将此字段的 AllowClipping 更改为 true 可绕过该问题。
遗憾的是,该选项在该字段的格式编辑器中不可见。数字选项卡甚至不可见。以下是我将 "Allow Field Clipping" 选项设置为 true 的方法:
- 我从报表设计器区域中删除了该字段,并将字段资源管理器中的 运行 合计字段添加回报表。
- 我右键单击该字段并选择了格式化对象。我注意到“数字”选项卡可见。
- 我选择了自定义样式数字格式并按下了 "Customize..." 按钮。
- 在“自定义样式”表单中,我选择了 "Allow Field Clipping" 选项并按下“确定”。
在 Common 上,我输入了与问题中相同的显示字符串,然后按确定:
iif(CurrentFieldValue > 0, "*", "")
“数字”选项卡立即消失。显然添加显示字符串使得 Crystal 报告不再将字段视为数字字段。
当我测试报告时,错误不再出现。
这感觉像是 Crystal 报告中的错误。我无法看到或更改此报告字段中 "Allow Field Clipping" 的隐藏设置,但此设置的值导致错误。
我有 SAP Crystal Microsoft Visual Studio 版本 13.0.14.1720 的报告。我正在尝试在 C# Windows Forms 应用程序中显示报告。该报告现在因 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
查看报表定义,此字段位于组页脚上。该字段正在获取 运行ning 错误总数的最大值。 运行ning 总数评估每条记录并在组更改时重置。
如果至少有 1 个错误,该字段应该显示星号。否则,它是空白的。因此显示字符串具有以下公式:
iif(CurrentFieldValue > 0, "*", "")
如果我将显示字符串公式的定义更改为在值 <= 0 时使用“”以外的任何内容,则不会出现错误。比如下面的Display String,不会出现错误:
iif(CurrentFieldValue > 0, "*", "N")
显示字符串与同一组页脚中的其他列相同,对其他列执行 运行ning 总计。事实上,组页脚上有几个字段与此相同。
我尝试从头开始删除并重新创建字段。出现同样的错误。
我尝试更改 "Convert Database NULL Values to Default" 和 "Convert Other NULL Values to Default" 的报告选项,但错误仍然存在。
我也试过将报告格式从旧版本升级到最新版本。
报表列定义如下。组 header 上的字段正在计算下面 _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" />
我 运行 JetBrains dotPeek 在 GAC CrystalDecisions.Shared.dll 上。反编译 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 为真而 fieldObjectInstance.AllowClipping 为假,因此看起来此代码将 运行 并失败。
在Visual Studio中,我在CrystalDecisions.Shared.PageRender.draw_ReportObjectInstance调用CrystalDecisions.Shared.PageRender.draw_FieldObjectInstance之前设置了一个断点。我检查了报告中的每个字段实例。除此字段外,每个数字对象都将 AllowClipping 设置为 true。
该字段为数字(IsNumeric 为 true),AllowClipping 为 false。这意味着它将达到我在上面的问题中列出的 draw_FieldObjectInstance 代码中的索引参考假设。
我无法解释为什么这个字段不同。也许有人在 Visual Studio 的 Crystal 报告的不同版本中创建了它。将此字段的 AllowClipping 更改为 true 可绕过该问题。
遗憾的是,该选项在该字段的格式编辑器中不可见。数字选项卡甚至不可见。以下是我将 "Allow Field Clipping" 选项设置为 true 的方法:
- 我从报表设计器区域中删除了该字段,并将字段资源管理器中的 运行 合计字段添加回报表。
- 我右键单击该字段并选择了格式化对象。我注意到“数字”选项卡可见。
- 我选择了自定义样式数字格式并按下了 "Customize..." 按钮。
- 在“自定义样式”表单中,我选择了 "Allow Field Clipping" 选项并按下“确定”。
在 Common 上,我输入了与问题中相同的显示字符串,然后按确定:
iif(CurrentFieldValue > 0, "*", "")
“数字”选项卡立即消失。显然添加显示字符串使得 Crystal 报告不再将字段视为数字字段。
当我测试报告时,错误不再出现。
这感觉像是 Crystal 报告中的错误。我无法看到或更改此报告字段中 "Allow Field Clipping" 的隐藏设置,但此设置的值导致错误。