制作报表动态列的问题

wea1978 2006-05-20 10:35:04
标准工具: VB自带的datareport.
选用工具:activereport或者水晶报表.
数据源:
已知列(code,codename,nsum)
动态列(1 to 31)或(A to Z)


'-------------以上是条件,就是说一个报表中包含不确定的列,应该作怎样的设计?
'这个问题好像没有很好的解决方案,欢迎各位大侠讨论...
'谢谢!
'不要使用Excel的显示方式,最基本的就是希望可以在VB自带的datareport上实现..
...全文
586 46 打赏 收藏 转发到动态 举报
写回复
用AI写文章
46 条回复
切换为时间正序
请发表友善的回复…
发表回复
wea1978 2006-05-29
  • 打赏
  • 举报
回复
谢谢wxlys() ...
研究一下...
wea1978 2006-05-29
  • 打赏
  • 举报
回复
谢谢楼上,研究一下....
wxlys 2006-05-27
  • 打赏
  • 举报
回复
'======================================================================================================
strTxtName = "F" & Right("00" & i, 2) ' oPrintGrid.Columns(I).DataField
Set FldCtrl = GsReportModel.Sections("Detail").Controls.Add("DDActiveReports2.Field") '添加字段
With FldCtrl
If strColPrams(11, i) = "1" Then '翻译
.Tag = strColPrams(9, i)
End If
.Visible = True
.Font.Name = "宋体"
.Font.Size = 9
.MultiLine = CBool(Abs(Val(strColPrams(5, i))))
.Name = strTxtName
.DataField = strColPrams(9, i) 'strTxtName '绑定字段名
If strColPrams(12, i) <> "" Then '固定值
.Text = strColPrams(12, i)
End If
.Alignment = strColPrams(10, i) ' oPrintGrid.Columns(i).Alignment
.VerticalAlignment = ddTXMiddle
.OutputFormat = strColPrams(7, i) 'oPrintGrid.Columns(i).NumberFormat
.Top = 0
.Left = lngLeft
.Width = strColPrams(8, i) ' oPrintGrid.Columns(i).Width
.Height = 375
.Border.BottomStyle = ddBLSolid
.Border.LeftStyle = ddBLSolid
If intShow = UBound(sPrint) - 1 Then
.Border.RightStyle = ddBLSolid
End If
If (UBound(sGroup) <= 0 Or UBound(sSubTotal)) <= 0 And (UBound(sTotal) <= 0) Then
lngLeft = lngLeft + .Width
End If
End With
'===============小计========================================================
If UBound(sGroup) > 0 And UBound(sSubTotal) > 0 Then
If i = 0 Then
GsReportModel.Sections("GroupHeader2").DataField = sGroup(0) ' oPrintGrid.GroupColumns(0).DataField
End If
Set FldCtrl = GsReportModel.Sections("GroupFooter2").Controls.Add("DDActiveReports2.Field") '添加字段
With FldCtrl
.Visible = True
.Font.Name = "宋体"
.Font.Size = 9
.BackColor = &HE0E0E0
.BackStyle = 1
.MultiLine = False
.Alignment = strColPrams(10, i) ' oPrintGrid.Columns(i).Alignment
.VerticalAlignment = ddTXMiddle
.OutputFormat = strColPrams(7, i) ' oPrintGrid.Columns(i).NumberFormat
.Top = 0
.Left = lngLeft
.Width = strColPrams(8, i) ' oPrintGrid.Columns(i).Width
.Height = 375
.Border.BottomStyle = ddBLSolid
.Border.LeftStyle = ddBLSolid
If intShow = UBound(sPrint) - 1 Then
.Border.RightStyle = ddBLSolid
End If
If UBound(sSubTotal) > 0 Then
For X = 0 To UBound(sSubTotal) - 1
If UCase(sSubTotal(X)) = UCase(strColPrams(9, i)) Then
.DataField = sSubTotal(X)
.SummaryGroup = "GroupHeader2"
.SummaryRunning = ddSRGroup
.SummaryType = ddSMSubTotal
Else
If intShow = 0 Then
.Text = "小计"
Else
.Text = ""
End If
End If
Next X
End If
If UBound(sTotal) <= 0 Then
lngLeft = lngLeft + .Width
End If
End With
End If
'===========================================================================
'======================================合计=================================
If UBound(sTotal) > 0 Then
Set FldCtrl = GsReportModel.Sections("ReportFooter").Controls.Add("DDActiveReports2.Field") '添加字段
With FldCtrl
.Visible = True
.Font.Name = "宋体"
.Font.Size = 9
' .ForeColor = vbRed
.BackColor = &HE0E0E0
.BackStyle = 1
.MultiLine = False
.Alignment = strColPrams(10, i) ' oPrintGrid.Columns(i).Alignment
.VerticalAlignment = ddTXMiddle
.OutputFormat = strColPrams(7, i) ' oPrintGrid.Columns(i).NumberFormat
.Top = 0
.Left = lngLeft
.Width = strColPrams(8, i) ' oPrintGrid.Columns(i).Width
.Height = 375
' .Border.BottomStyle = ddBLSolid
' .Border.LeftStyle = ddBLSolid
' If i = oPrintGrid.Columns.Count - 1 Then
' .Border.RightStyle = ddBLSolid
' End If
' If UBound(strTotal) > 0 Then
For X = 0 To UBound(sTotal) - 1
If UCase(sTotal(X)) = UCase(strColPrams(9, i)) Then
.DataField = sTotal(X)
' .SummaryGroup = "GroupHeader1"
.SummaryRunning = ddSRAll
.SummaryType = ddSMGrandTotal
Else
If intShow = 0 Then
.Text = "合计"
Else
.Text = ""
End If
End If
Next X
' End If
lngLeft = lngLeft + .Width
End With
End If
intShow = intShow + 1
'===========================================================================
Hnext:
Next i
GsReportModel.Line1.X2 = lngLeft
GsReportModel.Line2.X2 = lngLeft
Call SetSetting
' ShowReport GsReportModel
DoEvents
GsReportModel.Show vbModal
Call ReleaseRpt(GsReportModel)
Exit Sub
ErrH:
Err.Clear
Resume Next
'</EhFooter>
End Sub
wxlys 2006-05-27
  • 打赏
  • 举报
回复
'用ActiveReport2.0画报表的一个例子,不知道对你有没有用


Public Sub SetGridToReport(oPrintGrid As TrueOleDBGrid80.tDBgrid, sAdoSource As String, strColPrams() As Variant, sGroup() As String, _
sTotal() As String, sSubTotal() As String, sGroup2() As String, sGroup3() As String, sPrint() As String)
' adoGrid As ADODB.Recordset, Optional SubTotalFields As String,
' Optional bSubTotal As Boolean = False, Optional TotalFields As String, Optional bTotal As Boolean = False)
'<EhHeader>
On Error GoTo ErrH
'</EhHeader>
Dim adoRsRpt As ADODB.Recordset
Dim strSQL As String
Dim lblCtrl As Object
Dim i, J, X As Integer
Dim lngLeft As Long
Dim FldCtrl As Object
Dim strFldName As String
Dim strLbName As String
Dim strTxtName As String
Dim lngGroupLeft As Long
Dim intShow As Integer

lngLeft = 0
lngGroupLeft = 0
intShow = 0
Set GsReportModel.objGrid = oPrintGrid
GsReportModel.AdoDC.ConnectionString = GSG_DBConn.GStrGetConn
GsReportModel.AdoDC.Source = sAdoSource
J = 0
If UBound(sGroup) <= 0 Then
GsReportModel.Sections("PageHeader").Height = GsReportModel.Sections("PageHeader").Height + 600
End If
For i = 0 To UBound(strColPrams, 2) ' oPrintGrid.ApproxCount - 1
If strColPrams(1, i) = "0" Then GoTo Hnext '不打印
If Trim(strColPrams(0, i) & "") = "" Then GoTo Hnext
'============分组=================================================
If UBound(sGroup) > 0 Then '需要分组
If J = 0 Then
GsReportModel.Sections("GroupHeader1").DataField = sGroup(J) 'oPrintGrid.GroupColumns(j).DataField
GsReportModel.Sections("GroupHeader1").KeepTogether = True
GsReportModel.Sections("GroupHeader1").GrpKeepTogether = ddGrpAll
GsReportModel.Sections("GroupHeader1").Repeat = 3
If UBound(sGroup) > 0 Then
GsReportModel.Sections("GroupHeader1").Height = 375 + (oPrintGrid.HeadLines * oPrintGrid.RowHeight)
End If
End If
If J = 0 Then
For J = 0 To UBound(sGroup) - 1 'oPrintGrid.GroupColumns.Count - 1
Set lblCtrl = GsReportModel.Sections("GroupHeader1").Controls.Add("DDActiveReports2.label")
With lblCtrl
.Visible = True
.Font.Name = "宋体"
.Font.Size = 9
' .BackColor = &HE0E0E0
' .BackStyle = 1
.Caption = sGroup2(J) & ":" ' Trim(oPrintGrid.GroupColumns(j).Caption & "") & ":" '列名称
.VerticalAlignment = ddTXMiddle
.Left = lngGroupLeft
.Top = 0
.Width = (Len(sGroup2(J)) + 1) * 200
.Height = 375
lngGroupLeft = lngGroupLeft + (Len(sGroup2(J)) + 1) * 200
End With
Set FldCtrl = GsReportModel.Sections("GroupHeader1").Controls.Add("DDActiveReports2.Field")
With FldCtrl
.Visible = True
.Font.Name = "宋体"
.Font.Size = 9
.MultiLine = False
.Name = UCase("G" & sGroup(J))
If strColPrams(12, i) <> "" Then
.Text = strColPrams(12, i)
Else
.DataField = sGroup(J) ' oPrintGrid.GroupColumns(j).DataField '绑定字段名
End If
' .Alignment = oPrintGrid.GroupColumns(j).Alignment
.VerticalAlignment = ddTXMiddle
.Top = 0
.Left = lngGroupLeft
.Width = sGroup3(J) ' oPrintGrid.Columns(i).Width
.Height = 375
lngGroupLeft = lngGroupLeft + .Width + 500
End With
Next J
End If
End If
'======================================================================================================
If UBound(sGroup) > 0 Then
Set lblCtrl = GsReportModel.Sections("GroupHeader1").Controls.Add("DDActiveReports2.label") '添加列头
Else
Set lblCtrl = GsReportModel.Sections("PageHeader").Controls.Add("DDActiveReports2.label") '添加列头
End If

With lblCtrl
.Visible = True
.Font.Name = "宋体"
.Font.Size = 9
.BackColor = &HE0E0E0
.BackStyle = 1
.MultiLine = True
.Caption = strColPrams(0, i) ' Trim(oPrintGrid.Columns(i).Caption & "") '列名称
.VerticalAlignment = ddTXMiddle
.Alignment = ddTXCenter
.Border.TopStyle = ddBLSolid
.Border.LeftStyle = ddBLSolid
.Border.BottomStyle = ddBLSolid
If intShow = UBound(sPrint) - 1 Then
.Border.RightStyle = ddBLSolid
End If
If UBound(sGroup) > 0 Then
.Top = 375
Else
.Top = 1990
End If
.Left = lngLeft
.Width = strColPrams(8, i) ' oPrintGrid.Columns(i).Width
.Height = oPrintGrid.HeadLines * oPrintGrid.RowHeight
End With
wea1978 2006-05-26
  • 打赏
  • 举报
回复
看来没有更好的解决方法了...
郁闷中...
wea1978 2006-05-24
  • 打赏
  • 举报
回复
如果确实一页不可显示完,是否可以使用分页呢?就是说列要作分列...
请教各位大侠,谢谢!
vbman2003 2006-05-23
  • 打赏
  • 举报
回复
上面有误,应该是用临时表,不是自定义记录集
vbman2003 2006-05-23
  • 打赏
  • 举报
回复
如果分组内容比较复杂,比如涉及的表比较多,统计有难度等等,也可以自定一个记录集,将查询到数据按分组要求添加到其中,然后用ADO的SHAPE命令实现分组和统计。
vbman2003 2006-05-23
  • 打赏
  • 举报
回复
分组的话道理一样吧,只是在不同的标头上设置而已
vbman2003 2006-05-23
  • 打赏
  • 举报
回复
不在手边,这二天不在公司,也没VB环境。
道理很简单,用你的例子来说,就是自定义一个数据类型,枚举你34个字段,函数根据记录集字段名称返回你定义的该字段的宽度。只是调试的时候麻烦一点而已,要得到每个字段内容的宽度值。
wea1978 2006-05-23
  • 打赏
  • 举报
回复
如果是要对它进行分组又有什么简便的方法呢?
还要进行统计...
wea1978 2006-05-23
  • 打赏
  • 举报
回复
请问可以看看你那个调整宽度的函数吗?
谢谢!
vbman2003 2006-05-23
  • 打赏
  • 举报
回复
因为列不确定,所以调整Width是比较麻烦的。我是写了个函数,枚举了所有字段列宽这样做的。能按内容调整当然最好,这个没做过。
wea1978 2006-05-23
  • 打赏
  • 举报
回复
谢谢!
请问各位有没有更方便的方式呢?
wea1978 2006-05-22
  • 打赏
  • 举报
回复
vbman2003(家人) 的方法值得一试, 谢谢了!
测试ing....
vbman2003 2006-05-22
  • 打赏
  • 举报
回复
不知道下面的示例能不能解决你的问题:
Private Sub DataReport_Initialize()

Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim i As Integer
Dim mLeft As Long

cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Persist Security Info=False;" & _
"Data Source=" & App.Path & "\db1.mdb"
rs.Open "select * from tb1", cn, adOpenKeyset, adLockOptimistic
Set DataReport1.DataSource = rs
'以上部分是设置 DataReport 的数据源

Dim dTextCol As New Collection
Dim Ctl As Object

'根据情况,预先在报表上添加多个相关控件
'下面以RptTextBox控件为例
For Each Ctl In DataReport1.Sections.Item("Section1").Controls
If TypeName(Ctl) = "RptTextBox" Then
Ctl.DataField = rs.Fields.Item(0).Name '先将所有TextBox(RptTextBox) 控件绑定到某一字段
dTextCol.Add Ctl
End If
Ctl.Left = 0
Ctl.Top = 0
Ctl.Height = 400
Ctl.Width = 600
Ctl.Visible = False
Next Ctl

For i = 0 To rs.Fields.Count - 1
With dTextCol.Item(i + 1)
.Visible = True
.DataField = rs.Fields.Item(i).Name '重新绑定字段
.Left = mLeft
mLeft = .Left + .Width
'重新定位。还有Width等等比较复杂,要根据具体情况写代码判断
End With
Next i
DataReport1.Sections.Item("Section1").Height = 400

End Sub
wea1978 2006-05-22
  • 打赏
  • 举报
回复
如果不赋值的话,是否会出错呢?
因为你不可能事先知道要多少个控件的,如果知道的话,就不是动态的了...
feiyun0112 2006-05-22
  • 打赏
  • 举报
回复
但不能实时加载数据到RptTextbox中...

当然可以,负不同的字段
if ... then
set .Sections(2).Controls("txt01").datafield="a"
else
set .Sections(2).Controls("txt01").datafield="b"
endif

a,b为记录集中不同的字段
wea1978 2006-05-22
  • 打赏
  • 举报
回复
可能有人会直接赋值给网络控件,然后直接把网格控件的内容列印出来,这样做也是可以,
不过却没有达到最好的效果,而且直接列印出来的东西效果往往很差...
wea1978 2006-05-22
  • 打赏
  • 举报
回复
像 .Sections(2).Controls("RptLabel01").Caption = Lbl4.Caption
这样的作法适合更改标题,及动态说明.
但不能实时加载数据到RptTextbox中...

建议大家关注一下这个问题,看有没有其它变通的解决方法...不要说可以使用中间件什么的...
谢谢!
加载更多回复(25)

1,216

社区成员

发帖
与我相关
我的任务
社区描述
VB 数据库(包含打印,安装,报表)
社区管理员
  • 数据库(包含打印,安装,报表)社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧