使用显示字符串属性显示Crystal报表会导致ArgumentOutOfRangeException

时间:2015-09-23 13:40:35

标签: c# crystal-reports crystal-reports-formulas

我有适用于Microsoft Visual Studio版本13.0.14.1720的SAP Crystal Reports。我试图在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, "*", "")

如果我将显示字符串公式的定义更改为使用&#34;&#34;以外的任何内容。当值<&lt; = 0时,则没有错误。例如,以下显示字符串,不会发生错误:

iif(CurrentFieldValue > 0, "*", "N")

显示字符串与同一组页脚中的其他列相同,后者在其他列上执行运行总计。实际上,组页脚上有几个字段与此字段相同。

我尝试从头开始删除并重新创建字段。发生同样的错误。

我尝试更改&#34;将数据库空值转换为默认值&#34;的报告选项。和&#34;将其他NULL值转换为默认值&#34;,但错误仍然存​​在。

我还尝试将报告格式从旧版本升级到最新版本。

报告列定义如下。组头上的字段正在计算下面_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,因此看起来此代码将运行并失败。

1 个答案:

答案 0 :(得分:0)

在Visual Studio中,我在CrystalDecisions.Shared.PageRender.draw_ReportObjectInstance中设置断点,然后调用CrystalDecisions.Shared.PageRender.draw_FieldObjectInstance。我检查了报告中的每个字段实例。除此字段外,每个数字对象都将AllowClipping设置为true。

该字段为数字(IsNumeric为true),AllowClipping为false。这意味着它将在我上面的问题中列出的draw_FieldObjectInstance代码中达到索引引用假设。

我没有解释为什么这个领域不同。也许有人在不同版本的Crystal Reports for Visual Studio中创建了它。将此字段的AllowClipping更改为true可以绕过问题。

不幸的是,该选项在字段的格式编辑器中不可见。 “数字”选项卡甚至不可见。以下是我如何设置&#34;允许字段剪辑&#34;选项为true:

  1. 我从报表设计器区域中删除了该字段,并将字段资源管理器中的运行总计字段添加回报告。
  2. 我右键单击该字段并选择了Format Object。我注意到“数字”选项卡可见。
  3. 我选择了自定义样式数字格式并按下了#34;自定义...&#34;按钮。
  4. 在自定义样式表单上,我选择了&#34;允许字段剪辑&#34;选项并按下确定。
  5. 在Common上我输入了与我的问题相同的显示字符串,然后按OK:

    iif(CurrentFieldValue > 0, "*", "")
    
  6. 数字标签立即消失。显然添加显示字符串使Crystal Reports不再将该字段视为数字字段。

  7. 当我测试报告时,错误不再发生。

    这感觉就像Crystal Reports中的一个错误。我无法查看或更改“#34;允许字段剪辑”的隐藏设置。在此报告字段上,但此设置的值导致错误。

相关问题