In my last post I showed that you can add a native report to Office Accounting. but really the report I created in my example was kind of bla – don’t you think?
Let’s try to add a little meat to the report!
To add filters to the report we have to do a couple of things. First we have to add the filters in the CreateFilters method. If you want to default the filter to a specific value other than the default one this is also the place to do that.
/// Add filters that this report supports.
/// <param name="reportFilters">Filters collection you can add filters to</param>
public void CreateFilters(IReportFiltersV2 reportFilters)
Now to apply the filter to the data shown in the report we have to change the CreateData method. In this example I simply do that by applying a row filter to the DataView, this may not be a very good idea if you have a lot of rows in the database as your performance would be bad … But let’s just keep it like that for now.
public DataView CreateData(
ISmallBusinessInstance instance = engine.SmallBusinessInstance;
DataView view = instance.SalesInvoices.DataView;
IReportFilterNameV2 nameFilter =
case NameFilter.AllCustomers: break;
string filter = null;
for (int i = 0; i < nameFilter.Names.Length; i++)
if (filter != null)
filter += " or ";
filter += "CustomerAccountID = "
view.RowFilter = filter;
default: view.RowFilter = "1=2"; break;
To enable drilldown in the report you have to change two methods.
One is called per line in the report to see in drilldown is possible on that line. If you return true the curser will change into a hand when you hover the line and drilldown is enabled for the line. If you return false drilldown is disabled for the line. Let’s return true…
public bool DrilldownActive(DataRow dataRow)
The other method is called when the user drills down on a row. We don’t really know what you want to do when you drill down but the most common things to do is to open a form or a report, hence we are parsing in the forms factory and the report engine to make it easy to do that. In my example I want to show the document when the user drills down so I use the forms factory…
public void Drilldown(DataRow dataRow, object formsFactory, IReportEngineV2 reportEngine)
IFormsFactory factory = formsFactory as IFormsFactory;
int documentId = (int)dataRow["DocumentId"];
IBaseMasterEntity entity =
if (entity != null)
Form form = factory.CreateForm(entity);
The report is very flat and simple, to give the user an easier overview of the data in the report – and to make it look better :o) - let’s add some groupings! To add grouping to the report we have to implement another interface IReportHasGroupsV2.
The methods in this interface specifies a few things:
What to group by; in this example I am grouping by an idColumn that I have added in the CreateDesign method. I use the id column as the customer name may not be unique.
public void CreateGroupByColumns(IReportGroupByColumnsV2 groupByColumns)
How to sort the groups; to make sure the groups in the report will be sorted the way you want you have to specify what you want them sorted by. In this case I want them sorted by the name column (I keep a reference to the name column in the CreateDesign method).
public void CreateGroupSortByColumns(IReportGroupSortByColumnsV2 groupSortByColumns)
What to do when a group is added to the report; The GroupAdded method is called for every group break in the report. To get the groups to show up in the report you have to specify what to show in this method. In this case I put the CustomerName value from one of the rows within the group in the RowLabel of the Header of the group. You can also put values in the other columns by using this syntax: reportGroup.Header.GroupValues["columnName"] = "Some Value";
public void GroupAdded(IReportGroupV2 reportGroup)
if (reportGroup.GroupDataViewRows().Count > 0)
DataRowView row = reportGroup.GroupDataViewRows();
reportGroup.Header.GroupValues.RowLabel = row["CustomerName"] as string;
reportGroup.Header.GroupValues.RowLabel = string.Empty;
To be able to reference the id and name columns in the IReportHasGroupsV2 methods I changed my CreateDesign method to keep references and to not show the Customer Name any more as it is now shown in the group header
nameColumn = iReportDesign.ReportColumns.CreateReportColumn(
"CustomerName", //Column name in the dataview
"Customer Name", //Caption for the column
ReportColumnType.NotVisible, //Column type
ReportColumnDataType.Text); //Data type
idColumn = iReportDesign.ReportColumns.CreateReportColumn(
"CustomerAccountID", //Column name in the dataview
"", //Caption for the column
"FriendlyDocumentName", //Column name in the dataview
"Document", //Caption for the column
ReportColumnType.RowLabel, //Column type
With these changes the report now has groupings
Add a sample bitmap
To make the report look exactly like the build in reports in the Report bucket it should have a sample bitmap. The sample bitmap is the bitmap shown on the right hand side in the report bucket showing what the report looks like in the sample company. To add that to our new report we have to implement another interface: IReportMenuItemV2
The interface is pretty simple, all it has is one property – returning the bitmap as an image
public System.Drawing.Image SampleBitmap
Now the report looks much better, you will notice the name filter in the header (right now it is set to all). And the customer name is used as a header for the group.
If I can do it you can do it :o)