Step 8 of 9: Add Code to Create and Remove Reports
To remove reports from the list, use the DeleteReport method. The DeleteReport method simply removes the selected item from the report list, clears the Report property of the designer control, then makes a new selection if the list is not empty.
Add the following code to remove reports using the DeleteReport method:
' remove current report from the list
Private Sub DeleteReport()
' a report must be selected
Dim index As Integer = _list.SelectedIndex
If (index < 0) Then Return
' remove report from the designer and from the list
_c1rd.Report = Nothing
_list.Items.RemoveAt(index)
' select another report if we can
If (index > _list.Items.Count – 1) Then
index = _list.Items.Count - 1
If (index > - 1) Then
_list.SelectedIndex = index
End If
End If
' done
_dirty = True
UpdateUI()
End Sub
• C#
// remove current report from the list
private void DeleteReport()
{
// a report must be selected
int index = _list.SelectedIndex;
if (index < 0) return;
// remove report from the designer and from the list
_c1rd.Report = null;
_list.Items.RemoveAt(index);
// select another report if we can
if (index > _list.Items.Count-1)
index = _list.Items.Count-1;
if (index > -1)
_list.SelectedIndex = index;
// done
_dirty = true;
UpdateUI();
}
The AddReport method is a little more complex. In the full-fledged report designer, this command invokes a wizard that allows the user to select a data source, grouping options, layout, and style. When implementing your designer, you can use the wizard code as-is or customize it to suit your needs.
Rather than just creating a blank new report, the simple designer prompts the user for an MDB file, selects the first table it can find, then the first five fields, and creates a report based on that.
Add the following code to create reports using the AddReport method:
Private Sub NewReport()
' select a data source (just mdb files in this sample)
Dim dlg As New OpenFileDialog()
dlg.FileName = "*.mdb"
dlg.Title = "Select report data source"
If dlg.ShowDialog() <> Windows.Forms.DialogResult.OK Then Return
' select first table from data source
Dim connString As String = String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}", dlg.FileName)
Dim tableName As String = GetFirstTable(connString)
If tableName.Length = 0 Then
MessageBox.Show("Failed to retrieve data from the selected source.")
Return
End If
' create new report
Dim rpt As New C1Report()
rpt.ReportName = tableName
' set data source
rpt.DataSource.ConnectionString = connString
rpt.DataSource.RecordSource = tableName
' add a title field
Dim s As Section = rpt.Sections(SectionTypeEnum.Header)
s.Visible = True
s.Height = 600
Dim f As Field = s.Fields.Add("TitleField", tableName, 0, 0, 4000, 600)
f.Font.Bold = True
f.Font.Size = 24
f.ForeColor = Color.Navy
' add up to 5 calculated fields
Dim fieldNames As String() = rpt.DataSource.GetDBFieldList(True)
Dim cnt As Integer = Math.Min(5, fieldNames.Length)
' add a page header
s = rpt.Sections(SectionTypeEnum.PageHeader)
s.Visible = True
s.Height = 400
Dim rc As New Rectangle(0, 0, 1000, s.Height)
Dim i As Integer
For i = 0 To cnt - 1
f = s.Fields.Add("TitleField", fieldNames(i), rc)
f.Font.Bold = True
rc.Offset(rc.Width, 0)
Next
' add detail section
s = rpt.Sections(SectionTypeEnum.Detail)
s.Visible = True
s.Height = 300
rc = New Rectangle(0, 0, 1000, s.Height)
For i = 0 To cnt - 1
f = s.Fields.Add("TitleField", fieldNames(i), rc)
f.Calculated = True
rc.Offset(rc.Width, 0)
Next
' add new report to the list and select it
_list.Items.Add(New ReportHolder(rpt))
_list.SelectedIndex = _list.Items.Count - 1
' done
_dirty = True
UpdateUI()
End Sub
• C#
private void NewReport()
{
// select a data source (just mdb files in this sample)
OpenFileDialog dlg = new OpenFileDialog();
dlg.FileName = "*.mdb";
dlg.Title = "Select report data source";
if (dlg.ShowDialog() != DialogResult.OK) return;
// select first table from data source
string connString =
string.Format(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};",
dlg.FileName);
string tableName = GetFirstTable(connString);
if (tableName == null || tableName.Length == 0)
{
MessageBox.Show("Failed to retrieve data from the selected source.");
return;
}
// create new report
C1Report rpt = new C1Report();
rpt.ReportName = tableName;
// set data source
rpt.DataSource.ConnectionString = connString;
rpt.DataSource.RecordSource = tableName;
// add a title field
Section s = rpt.Sections[SectionTypeEnum.Header];
s.Visible = true;
s.Height = 600;
Field f = s.Fields.Add("TitleField", tableName, 0, 0, 4000, 600);
f.Font.Bold = true;
f.Font.Size = 24;
f.ForeColor = Color.Navy;
// add up to 5 calculated fields
string[] fieldNames = rpt.DataSource.GetDBFieldList(true);
int cnt = Math.Min(5, fieldNames.Length);
// add a page header
s = rpt.Sections[SectionTypeEnum.PageHeader];
s.Visible = true;
s.Height = 400;
Rectangle rc = new Rectangle(0, 0, 1000, (int)s.Height);
for (int i = 0; i < cnt; i++)
{
f = s.Fields.Add("TitleField", fieldNames[i], rc);
f.Font.Bold = true;
rc.Offset(rc.Width, 0);
}
// add detail section
s = rpt.Sections[SectionTypeEnum.Detail];
s.Visible = true;
s.Height = 300;
rc = new Rectangle(0, 0, 1000, (int)s.Height);
for (int i = 0; i < cnt; i++)
{
f = s.Fields.Add("TitleField", fieldNames[i], rc);
f.Calculated = true;
rc.Offset(rc.Width, 0);
}
// add new report to the list and select it
_list.Items.Add(new ReportHolder(rpt));
_list.SelectedIndex = _list.Items.Count-1;
// done
_dirty = true;
UpdateUI();
}
The following code uses a helper function GetFirstTable that opens a connection, retrieves the db schema, and returns the name of the first table it finds. Add the following code:
Private Function GetFirstTable(connString As String) As String
Dim conn As New OleDbConnection(connString)
Try
' get schema
conn.Open()
Dim dt As DataTable = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, Nothing)
Dim dr As DataRow
For Each dr In dt.Rows
' check the table type
Dim type As String = dr("TABLE_TYPE").ToString().ToUpper()
If (type <> "TABLE" AndAlso type <> "VIEW" AndAlso type <> "LINK" Then
'skip this one
Else
' get the table name
tableName = dr("TABLE_NAME").ToString()
Exit For
End If
Next
' done
conn.Close()
Catch
End Try
' return the first table we found
Return tableName
End Function
• C#
private string GetFirstTable(string connString)
{
string tableName = null;
OleDbConnection conn = new OleDbConnection(connString);
try
{
// get schema
conn.Open();
DataTable dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
foreach (DataRow dr in dt.Rows)
{
// check the table type
string type = dr["TABLE_TYPE"].ToString().ToUpper();
if (type != "TABLE" && type != "VIEW" && type != "LINK")
continue;
// get the table name
tableName = dr["TABLE_NAME"].ToString();
break;
}
// done
conn.Close();
}
catch {}
// return the first table we found
return tableName;
}
|