0

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 であるため、このコードが実行されて失敗するようです。

4

1 に答える 1

0

Visual Studio では、CrystalDecisions.Shared.PageRender.draw_FieldObjectInstance を呼び出す前に、CrystalDecisions.Shared.PageRender.draw_ReportObjectInstance にブレークポイントを設定しました。レポートのすべてのフィールド インスタンスを調べました。このフィールドを除いて、すべての数値オブジェクトの AllowClipping が true に設定されていました。

フィールドは数値 (IsNumeric は true) で、AllowClipping は false でした。つまり、上記の質問に記載した draw_FieldObjectInstance コードのインデックス参照の仮定にヒットすることになります。

なぜこの分野が違うのか、私には説明がつきません。Crystal Reports for Visual Studio の別のバージョンで誰かが作成した可能性があります。このフィールドの AllowClipping を true に変更すると、問題が回避されました。

残念ながら、このオプションはフィールドのフォーマット エディターに表示されませんでした。数値タブも表示されませんでした。「フィールドクリッピングを許可する」オプションをtrueに設定する方法は次のとおりです。

  1. レポート デザイナー領域からフィールドを削除し、フィールド エクスプローラーから現在の合計フィールドをレポートに追加しました。
  2. フィールドを右クリックし、[オブジェクトの書式設定] を選択しました。[数値] タブが表示されていることに気付きました。
  3. Custom Style 数値形式を選択し、[Customize...] ボタンを押しました。
  4. カスタム スタイル フォームで、[フィールド クリッピングを許可する] オプションを選択し、[OK] を押しました。
  5. Common で、質問と同じ表示文字列を入力し、[OK] を押しました。

    iif(CurrentFieldValue > 0, "*", "")
    
  6. 数値タブはすぐに消えました。どうやら表示文字列を追加すると、Crystal Reports はフィールドを数値フィールドとして扱わなくなりました。

レポートをテストしたところ、エラーは発生しなくなりました。

これは、Crystal Reports のバグのように感じます。このレポート フィールドの [フィールド クリッピングを許可] の非表示の設定を表示または変更することはできませんでしたが、この設定の値が原因でエラーが発生していました。

于 2015-09-23T16:10:00.767 に答える