After we input some data into the system, we might want to get it back in the form of a printable document. In other words, we might need a report. There are two major ways of getting reports in 1C:Enterprise.
Let’s start with the so-called template-based approach.
Here is a perfectly simple and very basic example of a template-based report for you. I’m going to the Sales document context menu and selecting this Print wizard.
The wizard suggests it creates a new command called Print, which I have no objections against.
Now I need to pick the report’s header attributes, which sounds like a perfect place for all the documents fields.
Next: the list of the Products with all the attributes, except for the LineNumber.
Next: the footer which I want to put the AmountPaid in. The command is to go to the Important group. And...
Wow. What just happened? OK. Let’s see.
First of all, the wizard added to the document a command called Print. The command gets called from the Sales document form, and the current Sales document reference is passed to this client-side procedure.
The procedure creates a new spreadsheet and passes it to the server-side procedure called Print along with the document’s reference. This server-side procedure calls the Sales document Print method where all the magic happens and the spreadsheet gets filled out with the report data to be shown to a user after that.
As for the magic itself - here it goes. This is the main Print procedure, created by the wizard in the Sales document manager module. And the procedure’s very first line explains why this approach is called template-based.
What’s going on here is that we go to the Sales document metadata object, read the template also called Print, and assign it to this Template variable.
So what exactly is a template? You can think of templates as of files attached to metadata objects. It can be virtually anything you might want living along with your object, including any binary file uploaded from the disk.
But in our case it’s a spreadsheet document created by the wizard and looking like this. What we have here is, basically, a form waiting to be filled out with the data.
So, let’s see what we’ve got here and how we work with it from the source code. First off, the Print procedure reads the document’s data with this query. Which is perfectly straightforward except for this unusual syntax over here.
Let me debug this piece of code and show you how this query works. So, I’m opening the Sales document, triggering the Print command and we are back in the Designer. One little trick like this, and here is the query result with the only record inside.
The record is perfectly normal and contains all boring single-value document attributes and this Products table. You heard me right. The entire table, with all the current document’s products list living inside of a single field.
So, this is what this syntax does. OK.
Next, the code reads these named areas from the template. These areas are just named row groups you can create yourself just like this. You can make a named area from whatever’s on hand: rows, columns or just a bunch of neighboring cells.
And all of them will be accessible by name from your source code. OK.
Now we’re clearing up the report spreadsheet (just in case), initializing the InsertPageBreak flag, and entering the cycle going through all the records returned by the query.
Which is not particularly wise from the wizard side, because it knows for sure there is the only record there. But anyway.
And this is where the magic starts. We take the first named area from the template spreadsheet, and copy it to the report spreadsheet.
This whole affair is copied as is: with the specific row size, merged columns, typeface and font size and whatever is written down here. The next line is just a little bit more complex.
Let me show you.
Whenever you write anything in a spreadsheet cell, you can set this FillType property to Parameter and then assign any value to it using this Fill method.
The method assumes there are many parameters in the template, so you can pass an object of any type and any complexity down here.
The Fill method will take the first template parameter, look up the object property with the same name take its value and fill up the parameter with it. The same happens with the rest of the parameters after which the entire Header area gets copied to the report spreadsheet.
The rest is pretty obvious. We copy the Products list header to the report, get the Products list from the query results and cycle through the list filling out the Products table. Then we fill out the footer, and here we go.
This is our report spreadsheet with the data from the current Sales document. This is how we build template-based reports.