我有一个运行各种Crystal Reports的VB 2012 Windows窗体应用程序。其中一份报告用于为推荐其他客户在组织内成为会员的客户打印优惠券。报告的布局使用报告集的详细信息A部分中的8位PNG图像,以在“专家”部分中的“底层跟随部分”。详细信息B部分包含打印客户名称的字段以及创建的每个优惠券的唯一条形码。我正在创建一个12x18文档的报告,报告设置为格式化多列,这样我就可以在1个页面中的2列中放入6张优惠券(每列3张优惠券)。
创建报告时,我遇到的问题是每个优惠券上的图像并不总是重复。客户名称和条形码都打印在正确的位置,但图稿图像丢失。多次运行报告将导致每次运行时丢失的图像位于不同的记录中。大多数情况下,在遇到缺少底衬图像的优惠券之前,我可以获得50张左右的优惠券。
我不能为我的生活找出造成这种情况的原因。这是我用来生成报告的代码,如果有帮助的话。应用程序将带有引用的数据或订单的CSV文件导入名为ordersTable的DataTable中。我还有一个客户数据的CSV文件,该文件被导入到一个名为membersTable的DataTable中。我的报告系统没有与我可以查询的数据库连接,所以我必须使用这些CSV文件。这两组数据可以在NameID值上连接。在订单文件中,此NameID表示推荐下订单的客户的客户,而客户文件包含可以推荐新客户的成员的名称和地址。
Private Sub ReferralCouponReport()
LoadingForm.Show()
Application.DoEvents()
'create data tables to hold both import files
Dim membersTable As DataTable
Dim ordersTable As DataTable
'import files into the datatable objects
Dim imp As New Fmca.Common.ImportHelper.ImportHelper
membersTable = imp.importCSVtoDataTable(membersText.Text, True)
ordersTable = imp.importCSVtoDataTable(ordersText.Text, True)
'create table of MembershipNo and MembershipName values from membersTable for each record in ordersTable using NameID as a cross reference value
Dim query = (From o In ordersTable
Select o.Field(Of String)("NameID")).ToList
'need a new table to add values to
Dim couponsTable As New DataTable
With couponsTable.Columns
.Add("MembershipNo")
.Add("MembershipName")
.Add("CouponId")
End With
'Need a value for CouponId
Dim sqlParams() As System.Data.SqlClient.SqlParameter
ReDim sqlParams(2)
sqlParams(0) = New System.Data.SqlClient.SqlParameter
sqlParams(0).ParameterName = "@CouponType"
sqlParams(0).DbType = DbType.String
sqlParams(0).Value = My.Settings.CouponType
sqlParams(1) = New System.Data.SqlClient.SqlParameter
sqlParams(1).ParameterName = "@CouponType"
sqlParams(1).DbType = DbType.Int32
sqlParams(1).Value = My.Settings.CouponSeries
sqlParams(2) = New System.Data.SqlClient.SqlParameter
sqlParams(2).ParameterName = "@CouponSid"
sqlParams(2).DbType = DbType.Int32
sqlParams(2).Value = My.Settings.CouponSid
Dim couponSid As Integer
'Put the couponId assignment in Try block because the SQL could raise an error
Try
Dim couponId As DataSet = Fmca.Common.DBHelper.DBHelper.ExecuteDataset(Fmca.Common.DBEnum.DBEnum.DBServers.CONVERT, "sp_elan_GetCouponSid", sqlParams)
couponSid = couponId.Tables(0).Rows(0).Item(2).ToString
For Each value As String In query
Application.DoEvents()
'Get data from membersTable where NameId equals the NameID from the record in ordersTable
Dim coupon = (From m In membersTable
Where m.Field(Of String)("NameID") = value
Select m).ToList
If coupon.Count > 0 Then
Dim memNum = coupon.Item(0).Item(1).ToString
Dim memName = coupon.Item(0).Item(2).ToString
Dim row As DataRow
row = couponsTable.NewRow
With row
.Item(0) = memNum
.Item(1) = memName
.Item(2) = couponSid
End With
couponsTable.Rows.Add(row)
End If
'Increment CouponSid
couponSid += 1
Next
Catch ex As Exception
MessageBox.Show(ex.Message, "Error creating coupons", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
'Update Coupon in database for the next available CouponSid
ReDim sqlParams(2)
sqlParams(0) = New System.Data.SqlClient.SqlParameter
sqlParams(0).ParameterName = "@CouponType"
sqlParams(0).DbType = DbType.String
sqlParams(0).Value = "MemberRecruitment_New"
sqlParams(1) = New System.Data.SqlClient.SqlParameter
sqlParams(1).ParameterName = "@CouponType"
sqlParams(1).DbType = DbType.Int32
sqlParams(1).Value = 99
sqlParams(2) = New System.Data.SqlClient.SqlParameter
sqlParams(2).ParameterName = "@CouponSid"
sqlParams(2).DbType = DbType.Int32
sqlParams(2).Value = couponSid + 1
Fmca.Common.DBHelper.DBHelper.ExecuteNonQuery(Fmca.Common.DBEnum.DBEnum.DBServers.CONVERT, "sp_elan_UpdateCouponSid", sqlParams)
'Count number of coupons produced and send to Accounting to track as a liability on the GL
Dim count As Integer = couponsTable.Rows.Count
'Do nothing if the email sends successfully
If SendEmailNotification(My.Settings.AccountingEmailAddress, count) = False Then
Dim msg As String = ""
msg += "The email notification could not be sent to " & My.Settings.AccountingEmailAddress & " at this time." & vbCrLf & vbCrLf
msg += "Please notify the Accounting Department of the number of coupons and total liability amount that are shown below." & vbCrLf & vbCrLf
msg += "Number of coupons: " & count & vbCrLf
msg += "Total liability: $" & count * 10 & ".00"
MessageBox.Show(msg, "Email Notification Failed!", MessageBoxButtons.OK, MessageBoxIcon.Warning)
End If
Dim rptDoc As New CrystalDecisions.CrystalReports.Engine.ReportDocument
rptDoc = New RefCoupon
rptDoc.SetDataSource(couponsTable)
ReportForm.CrystalReportViewer1.ReportSource = rptDoc
LoadingForm.Dispose()
couponsTable.Dispose()
ReportForm.ShowDialog()
rptDoc.Close()
ReportForm.CrystalReportViewer1.ReportSource = Nothing
ReportForm.CrystalReportViewer1.Refresh()
ReportForm.Dispose()
End Sub