Very confused with the Report control

I have designed a report with some static data and some which is populated when the report is run. However, I can’t work out how to run the thing now.

It wants a dataset, which I don’t have as the dynamic values are filled in via controls on a window, and I can’t get passed this. What am I doing wrong?

This is a snippet of the code I use to add in the dynamic data:

Dim myReport As New repBusiness

myReport.lblCompanyName.Text = txtName.Text
myReport.lblBackground.Text = taDescription.Text
myReport.lblDateGenerated.Text = DateTime.Now.SQLDateTime

<some how run the report and show it on screen, or save it as PDF and then open the PDF>

What step am I missing or do I have this all backwards?

Reports are meant to be run with data. If you’re not using a database then you interface with the report as if you were with a Dataset.

Static fields like headers and labels you can set the way you have, but the actual data the report runs needs to come from somewhere.

OK, so create a dataset, stuff my dynamic values in there, then pass it to the Run method of the report? Could I use a DictionaryObject also for the Dataset?

Yes, that’s the process.

You could back your dataset with a dictionary if you wish to, but you will still need to create a class that implements the Dataset interface.

The Report is going to operate on the class instance you provide it as if it were a RowSet from a Database. The basic idea is to mimic the behavior so that you can provide your own values. Have you used a RowSet yourself? It would help to be familiar with how those work so that you know what the Report is going to expect.

Here’s the documentation on adding an Interface to a Class definition.
You’ll want to select the Reports.DataSet interface.

1 Like

Reports seem the most bizarre, backwards, and unintuitive feature of Xojo ever! I’ve given up with them completely now. My use case is so simple, and i really like the IDE to create a report, but then running it is bonkers complicated!

I created the class, dataset, and the lot. but just couldn’t get it working. rage deleted all the code :frowning:

All i want to do is create a report that is 75% static data, and then fill in a few fields at run time. It is a single page report, not using rows of data from any dataset. I could (sort of) get it working by drawing onto a canvas, but not to a PDF.

/rant

1 Like

If you have access to MBS plugins you can use BuildRecordSetMBS to create a RecordSet from your Dictionary which simplifies things a lot.

In this case my report is named SampleTag

Private Sub PrintSampleTagData(sampleData as Dictionary)
  dim fields() as string
  dim records() as string
  
  for i as integer = 0 to sampleData.Count-1
    fields.Append sampleData.Key(i)
    records.Append sampleData.Value(sampleData.Key(i))
  next
    
  fields.Append "createdby"
  records.Append "Created by: " + SystemInformationMBS.UserName
  
  fields.Append "datecreated"
  records.Append DateTime.Now.SQLDateTime
  
  dim rs as RecordSet = BuildRecordSetMBS(fields,records)
  
  dim ps as new PrinterSetup
  dim tag as new SampleTag
  
  ps.MaxHorizontalResolution = 300
  ps.MaxVerticalResolution = 300
  ps.Landscape = false
  
  dim g as graphics
  g = OpenPrinterDialog(ps)
  
  if g <> nil then
    
    if tag.Run(rs,ps) then 
      tag.Document.Print(g)
    end
    
  end
End Sub

I solved it in the end. I ditched the class definition and just created a SQLite DB in memory and put my data in that. Just overly complicated on every level.

Anyway, here is my code to save the pain for anyone else! I’ve dropped out the code that is not 100% required

Dim db As New SQLiteDatabase

If Not db.Connect Then
  
  MessageBox("Failed to connect to in-memory database.")
  Return False
  
End If

Try
  
  db.ExecuteSQL("CREATE TABLE ReportData (CompanyName TEXT, CompanyDescription TEXT, DateGenerated TEXT, uid TEXT)")
  
Catch e As DatabaseException
  
  MessageBox("Error creating table: " + e.Message)
  Return False
  
End Try


Dim CompanyName As String = txtName.Text
Dim CompanyDescription As String = taDescription.Text
Dim DateGenerated As String = DateTime.Now.Year.ToString + "/" + DateTime.Now.Month.ToString + "/" + DateTime.Now.Day.ToString
Dim UID As String = GetUID()
Dim ps As New PrinterSetup

Try
  
  db.ExecuteSQL("INSERT INTO ReportData (CompanyName, CompanyDescription, DateGenerated, uid) VALUES (?, ?, ?, ?)", CompanyName, CompanyDescription, DateGenerated, UID)
  
Catch e As DatabaseException
  
  MessageBox("Error inserting data: " + e.Message)
  Return False
  
End Try


If rpt.Run(rs, ps) Then
  
  If rpt.Document <> Nil Then
    
   mReportDocument = rpt.Document  ' a report property
   mCurrentPage = 1 ' an integer property
   Viewer.Refresh 'this is a canvas container
    
  End If
  
Else
  
  MessageBox("Failed to run report.")
  Return False
  
End If

So you’re running an entire report just for a single line? Seems like there ought to be a better way.

the limitation of Reports in Xojo. it requires a dataset even for a single record