[转]在水晶报表中实现任意选择指定字段显示

Technorati 标签:

原文地址:http://www.cnblogs.com/babyt/archive/2005/04/21/142309.html

 

 

本文的C#改进版本请参见:http://www.cnblogs.com/babyt/archive/2008/01/03/1024941.html

很多次被问到如下问题:
水晶报表能否做到由客户选择要显示的字段进行自定义显示?

我也迷惑了好久,后来还是仔细看了一海波的文章,终于有点眉目

如何在水晶报表中动态添加字段
http://blog.csdn.net/haibodotnet/archive/2003/11/09/21504.aspx
如何向 CrystalReportViewer 和 ReportDocument 传递参数
http://blog.csdn.net/haibodotnet/archive/2003/11/16/21516.aspx

实际操作了一下,没想象得那么困难.
开发环境: VS2003(VB.Net) + 水晶报表10高级专业开发版 + Win2003


要创建一个ADO.Net的水晶报表,具体过程我就不写了
看这里http://www.cnblogs.com/babyt/articles/118097.html

Step1: xsd文件结构
我们的表结构是这样子

有时候你并不是从数据库里取的一个完整表,那么你可以自己编辑这个xsd文件

有一点需要注意,这个文件里必须包含所有你将要显示的字段



Step2:下面我们开始创建模板

在这里,我加了6个字段,但是不要在报表上放置任何的数据字段。
新建立6个公式,名字取得别太好听,一定要按顺序来,如myField1,myField2..myField6
将公式依次放到详细资料节
删除自动产生的表头
新建立6个参数字段,同样,按顺序来,叫myParaField1,myParaField2..myParaField6

格式什么的这里就先不管了,咱们主要是先要实现功能。

Step3:程序设计
设计程序界面如下图所示,大家一下就看明白了,代码我写了详尽的注释,就不多说了。

' *************************************************************************
'
**模 块 名:CR_DefineFields
'
**说 明:Facesun.cn 版权所有2005 - 2006(C)
'
**创 建 人:Babyt(阿泰) http://www.cnblogs.com/babyt
'
**日 期:2005-04-20
'
**修 改 人:
'
**日 期:
'
**描 述:自定义字段显示报表
'
**版 本:V1.0.0
'
*************************************************************************
Imports CrystalDecisions.CrystalReports.Engine
Imports CrystalDecisions. Shared
Imports System.Data
Imports System.Data.OleDb
Public Class Form1
Inherits System.Windows.Forms.Form
'查看CrystalReport1的定义可以查看对应的报表类
Dim crReportDocument As CrystalReport1

''ADO.NET Variables
Dim adoOleDbConnection As OleDbConnection
Dim adoOleDbDataAdapter As OleDbDataAdapter
Dim dataSet As dataSet

#Region " Windows 窗体设计器生成的代码 "

Public Sub New()
MyBase.New()

'该调用是 Windows 窗体设计器所必需的。
InitializeComponent()

'在 InitializeComponent() 调用之后添加任何初始化

End Sub


'窗体重写 dispose 以清理组件列表。
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub


'Windows 窗体设计器所必需的
Private components As System.ComponentModel.IContainer

'注意: 以下过程是 Windows 窗体设计器所必需的
'可以使用 Windows 窗体设计器修改此过程。
'不要使用代码编辑器修改它。
Friend WithEvents CheckBox1 As System.Windows.Forms.CheckBox
Friend WithEvents CheckBox2 As System.Windows.Forms.CheckBox
Friend WithEvents CheckBox3 As System.Windows.Forms.CheckBox
Friend WithEvents CheckBox4 As System.Windows.Forms.CheckBox
Friend WithEvents CheckBox5 As System.Windows.Forms.CheckBox
Friend WithEvents CheckBox6 As System.Windows.Forms.CheckBox
Friend WithEvents Button1 As System.Windows.Forms.Button
Friend WithEvents CrystalReportViewer1 As CrystalDecisions.Windows.Forms.CrystalReportViewer
Friend WithEvents Label1 As System.Windows.Forms.Label
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.CheckBox1 = New System.Windows.Forms.CheckBox
Me.CheckBox2 = New System.Windows.Forms.CheckBox
Me.CheckBox3 = New System.Windows.Forms.CheckBox
Me.CheckBox4 = New System.Windows.Forms.CheckBox
Me.CheckBox5 = New System.Windows.Forms.CheckBox
Me.CheckBox6 = New System.Windows.Forms.CheckBox
Me.Button1 = New System.Windows.Forms.Button
Me.CrystalReportViewer1 = New CrystalDecisions.Windows.Forms.CrystalReportViewer
Me.Label1 = New System.Windows.Forms.Label
Me.SuspendLayout()
'
'CheckBox1
'
Me.CheckBox1.Location = New System.Drawing.Point(24, 32)
Me.CheckBox1.Name = "CheckBox1"
Me.CheckBox1.Size = New System.Drawing.Size(48, 24)
Me.CheckBox1.TabIndex = 0
Me.CheckBox1.Text = "编号"
'
'CheckBox2
'
Me.CheckBox2.Location = New System.Drawing.Point(96, 32)
Me.CheckBox2.Name = "CheckBox2"
Me.CheckBox2.Size = New System.Drawing.Size(88, 24)
Me.CheckBox2.TabIndex = 1
Me.CheckBox2.Text = "材料名称"
'
'CheckBox3
'
Me.CheckBox3.Location = New System.Drawing.Point(184, 32)
Me.CheckBox3.Name = "CheckBox3"
Me.CheckBox3.Size = New System.Drawing.Size(64, 24)
Me.CheckBox3.TabIndex = 2
Me.CheckBox3.Text = "品牌"
'
'CheckBox4
'
Me.CheckBox4.Location = New System.Drawing.Point(264, 32)
Me.CheckBox4.Name = "CheckBox4"
Me.CheckBox4.Size = New System.Drawing.Size(56, 24)
Me.CheckBox4.TabIndex = 3
Me.CheckBox4.Text = "单价"
'
'CheckBox5
'
Me.CheckBox5.Location = New System.Drawing.Point(344, 32)
Me.CheckBox5.Name = "CheckBox5"
Me.CheckBox5.Size = New System.Drawing.Size(48, 24)
Me.CheckBox5.TabIndex = 4
Me.CheckBox5.Text = "数量"
'
'CheckBox6
'
Me.CheckBox6.Location = New System.Drawing.Point(424, 32)
Me.CheckBox6.Name = "CheckBox6"
Me.CheckBox6.Size = New System.Drawing.Size(80, 24)
Me.CheckBox6.TabIndex = 5
Me.CheckBox6.Text = "采购日期"
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(536, 32)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(64, 23)
Me.Button1.TabIndex = 6
Me.Button1.Text = "生成报表"
'
'CrystalReportViewer1
'
Me.CrystalReportViewer1.ActiveViewIndex = -1
Me.CrystalReportViewer1.DisplayGroupTree = False
Me.CrystalReportViewer1.Location = New System.Drawing.Point(16, 72)
Me.CrystalReportViewer1.Name = "CrystalReportViewer1"
Me.CrystalReportViewer1.ReportSource = Nothing
Me.CrystalReportViewer1.ShowGroupTreeButton = False
Me.CrystalReportViewer1.Size = New System.Drawing.Size(592, 344)
Me.CrystalReportViewer1.TabIndex = 7
'
'Label1
'
Me.Label1.Location = New System.Drawing.Point(16, 8)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(152, 16)
Me.Label1.TabIndex = 8
Me.Label1.Text = "选择要显示的字段"
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(6, 14)
Me.ClientSize = New System.Drawing.Size(624, 445)
Me.Controls.Add(Me.Label1)
Me.Controls.Add(Me.CrystalReportViewer1)
Me.Controls.Add(Me.Button1)
Me.Controls.Add(Me.CheckBox6)
Me.Controls.Add(Me.CheckBox5)
Me.Controls.Add(Me.CheckBox4)
Me.Controls.Add(Me.CheckBox3)
Me.Controls.Add(Me.CheckBox2)
Me.Controls.Add(Me.CheckBox1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)

End Sub


#End Region


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Dim ConnectionString As String = ""
Dim sqlString As String = ""
'保持字段的字符串
Dim FieldString As String = ""
'保持字段名称的数组
Dim FieldArray() As String
Dim i As Integer, j As Integer

'参数字段集合
Dim ParamFields As New ParameterFields
'参数字段
Dim ParamField As ParameterField
'离散值
Dim DiscreteVal As New ParameterDiscreteValue

'---------------------------------------------------------------------
'获取选取的字段并进行处理
'此处写的比较笨拙,用控件数组更方便
If CheckBox1.Checked = True Then
FieldString
= CheckBox1.Text
End If
If CheckBox2.Checked = True Then
FieldString
= FieldString & "," & CheckBox2.Text
End If
If CheckBox3.Checked = True Then
FieldString
= FieldString & "," & CheckBox3.Text
End If
If CheckBox4.Checked = True Then
FieldString
= FieldString & "," & CheckBox4.Text
End If
If CheckBox5.Checked = True Then
FieldString
= FieldString & "," & CheckBox5.Text
End If
If CheckBox6.Checked = True Then
FieldString
= FieldString & "," & CheckBox6.Text
End If
If FieldString = "" Then
MessageBox.Show(
"请选择要显示的字段")
Exit Sub
End If
'删除第一个逗号,使字串最终显示为 "字段1,字段2,字段3"
If FieldString.Substring(0, 1) = "," Then
FieldString
= FieldString.Substring(1, FieldString.Length - 1)
End If
'分割成数组,每个元素为一个字段名称
FieldArray = FieldString.Split(",")

'---------------------------------------------------------------------
'数据获取与组织部分
'以下为数据获取段,你可以根据自己的实际情况任意更改数据获取方式
ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Application.StartupPath & "/BBT_Crystal.mdb"

''打开数据库联接
adoOleDbConnection = New OleDbConnection(ConnectionString)

''Sql语句
'sqlString = "Select * From 材料采购明细"
sqlString = "Select " & FieldString & " From 材料采购明细"

''执行语句
adoOleDbDataAdapter = New OleDbDataAdapter(sqlString, adoOleDbConnection)

''创建Dataset实例
dataSet = New DataSet
''填充dataSet
adoOleDbDataAdapter.Fill(dataSet, "材料采购明细")

'---------------------------------------------------------------------
''创建一个强类型报表实例
crReportDocument = New CrystalReport1
''crReportDocument.Database.Tables("材料采购明细").SetDataSource(dataSet)

'开始以数组为依据依次顺序设置表头和公式字段
For i = 0 To UBound(FieldArray)
'设置第一个离散值并将其传递给该参数
'传递参数做为表头
'--------------------------------------
'参数设置部分
ParamField = New ParameterField
ParamField.ParameterFieldName
= "myParaField" & (i + 1).ToString
'离散值
DiscreteVal = New ParameterDiscreteValue
DiscreteVal.Value
= FieldArray(i)
'赋值
ParamField.CurrentValues.Add(DiscreteVal)
'将该字段加如到字段集合中
ParamFields.Add(ParamField)
'不允许该字段弹出提示
ParamField.AllowCustomValues = False

'将公式绑定到具体字段
crReportDocument.DataDefinition.FormulaFields("myField" & (i + 1).ToString).Text = "{材料采购明细." & FieldArray(i) & "}"
Next

'设置剩余的未使用到的参数,防止出现提示
'具体操作同上,只是给一个空值
For j = i + 1 To 6
'设置第一个离散值并将其传递给该参数
'传递参数做为表头
ParamField = New ParameterField
ParamField.ParameterFieldName
= "myParaField" & (j).ToString
ParamFields.Add(ParamField)
DiscreteVal
= New ParameterDiscreteValue
DiscreteVal.Value
= ""
ParamField.CurrentValues.Add(DiscreteVal)
ParamFields.Add(ParamField)
ParamField.AllowCustomValues
= False
Next
'将参数字段集合绑定到浏览器
CrystalReportViewer1.ParameterFieldInfo = ParamFields

''将Dataset传递给报表
crReportDocument.SetDataSource(dataSet)

''将报表传递给浏览器
CrystalReportViewer1.ReportSource = crReportDocument
End Sub

End Class

 


运行结果

在这里下载完整代码
http://files.cnblogs.com/babyt/CR_DefineFields.rar

后记1:
你可以对该例增加字段显示的先后顺序排列功能
后记2:
2005年4月21日在wp的帮助下实现格线表现方式,见
http://www.cnblogs.com/babyt/articles/142908.html
后记3:
2008年1月3日
本文的C#改进版本请参见:http://www.cnblogs.com/babyt/archive/2008/01/03/1024941.html
-------Over------------------
希望这篇文章对你有所帮助。
阿泰 20050420

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现方法: 1. 在ALV报表的布局,添加一个隐藏/显示字段的按钮。 2. 在程序定义一个全局变量,用于记录当前字段显示状态,初始值为真(即显示)。 3. 在按钮的点击事件,判断当前的显示状态,如果为真,则将需要隐藏的字段的可见性设为假,并将按钮的文字改为“显示”,同时将全局变量的值改为假;如果为假,则将需要显示字段的可见性设为真,并将按钮的文字改为“隐藏”,同时将全局变量的值改为真。 4. 最后调用REUSE_ALV_GRID_DISPLAY函数刷新ALV报表即可。 示例代码如下: DATA: gv_hide_field TYPE abap_bool VALUE 'X'. * 定义按钮事件处理程序 DATA: lcl_event_receiver TYPE REF TO cl_gui_alv_grid. CLASS lcl_event_receiver DEFINITION. PUBLIC SECTION. METHODS: on_toolbar FOR EVENT toolbar OF cl_gui_alv_grid IMPORTING e_object e_alv_toolbar. ENDCLASS. CLASS lcl_event_receiver IMPLEMENTATION. METHOD on_toolbar. DATA: l_button TYPE salv_s_toolbar_button. * 添加一个隐藏/显示字段的按钮 l_button-function = 'HIDE_SHOW_FIELD'. l_button-icon = 'ICON_HIDE_SHOW'. l_button-quickinfo = 'Hide/Show Field'. l_button-text = 'Hide Field'. l_button-user_command = 'HIDE_SHOW_FIELD'. APPEND l_button TO e_alv_toolbar->salv_toolbar. ENDMETHOD. ENDCLASS. * 定义隐藏/显示字段的按钮事件处理程序 DATA: lcl_event_handler TYPE REF TO lcl_event_receiver. CLASS lcl_event_handler DEFINITION. PUBLIC SECTION. METHODS: on_user_command FOR EVENT user_command OF cl_gui_alv_grid IMPORTING e_ucomm e_selfield. ENDCLASS. CLASS lcl_event_handler IMPLEMENTATION. METHOD on_user_command. DATA: l_layout TYPE lvc_s_layo. CASE e_ucomm. WHEN 'HIDE_SHOW_FIELD'. * 判断当前显示状态 IF gv_hide_field = abap_true. l_layout-hide = abap_true. " 需要隐藏的字段 e_selfield-layout = l_layout. e_selfield-refresh = abap_true. e_selfield-free = abap_true. SET CURSOR FIELD 'HIDE_SHOW_FIELD'. e_selfield-text = 'Show Field'. gv_hide_field = abap_false. ELSE. l_layout-hide = abap_false. " 需要显示字段 e_selfield-layout = l_layout. e_selfield-refresh = abap_true. e_selfield-free = abap_true. SET CURSOR FIELD 'HIDE_SHOW_FIELD'. e_selfield-text = 'Hide Field'. gv_hide_field = abap_true. ENDIF. ENDCASE. ENDMETHOD. ENDCLASS. * 初始化报表 DATA: gt_outtab TYPE TABLE OF <your_data_type>. CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY' EXPORTING i_callback_program = sy-repid i_callback_top_of_page = 'TOP_OF_PAGE' i_callback_user_command = 'USER_COMMAND' i_callback_pf_status_set = 'PF_STATUS_SET' is_layout = gs_layout TABLES t_outtab = gt_outtab EXCEPTIONS program_error = 1 OTHERS = 2. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. ENDIF. * 添加隐藏/显示字段的按钮 CREATE OBJECT lcl_event_receiver. * 添加按钮事件处理程序 CREATE OBJECT lcl_event_handler. SET HANDLER lcl_event_handler->on_user_command FOR lcl_event_receiver.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值