@netoalmanca/advpl-sensei 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agents/changelog-generator.md +63 -0
- package/agents/code-generator.md +215 -0
- package/agents/code-reviewer.md +145 -0
- package/agents/debugger.md +83 -0
- package/agents/doc-generator.md +67 -0
- package/agents/docs-reference.md +86 -0
- package/agents/migrator.md +84 -0
- package/agents/process-consultant.md +97 -0
- package/agents/refactorer.md +75 -0
- package/agents/sx-configurator.md +67 -0
- package/commands/changelog.md +66 -0
- package/commands/diagnose.md +67 -0
- package/commands/docs.md +81 -0
- package/commands/document.md +67 -0
- package/commands/explain.md +60 -0
- package/commands/generate.md +111 -0
- package/commands/migrate.md +81 -0
- package/commands/process.md +111 -0
- package/commands/refactor.md +65 -0
- package/commands/review.md +60 -0
- package/commands/sxgen.md +98 -0
- package/commands/test.md +103 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +143 -0
- package/dist/index.js.map +1 -0
- package/package.json +30 -0
- package/skills/advpl-code-generation/SKILL.md +163 -0
- package/skills/advpl-code-generation/patterns-fwformbrowse.md +485 -0
- package/skills/advpl-code-generation/patterns-jobs.md +519 -0
- package/skills/advpl-code-generation/patterns-mvc.md +765 -0
- package/skills/advpl-code-generation/patterns-pontos-entrada.md +708 -0
- package/skills/advpl-code-generation/patterns-rest.md +974 -0
- package/skills/advpl-code-generation/patterns-soap.md +639 -0
- package/skills/advpl-code-generation/patterns-treport.md +481 -0
- package/skills/advpl-code-generation/patterns-workflow.md +779 -0
- package/skills/advpl-code-generation/templates-classes.md +1096 -0
- package/skills/advpl-code-review/SKILL.md +72 -0
- package/skills/advpl-code-review/rules-best-practices.md +444 -0
- package/skills/advpl-code-review/rules-modernization.md +290 -0
- package/skills/advpl-code-review/rules-performance.md +333 -0
- package/skills/advpl-code-review/rules-security.md +302 -0
- package/skills/advpl-debugging/SKILL.md +265 -0
- package/skills/advpl-debugging/common-errors.md +1124 -0
- package/skills/advpl-debugging/performance-tips.md +768 -0
- package/skills/advpl-refactoring/SKILL.md +139 -0
- package/skills/advpl-to-tlpp-migration/SKILL.md +293 -0
- package/skills/advpl-to-tlpp-migration/migration-checklist.md +122 -0
- package/skills/advpl-to-tlpp-migration/migration-rules.md +265 -0
- package/skills/changelog-patterns/SKILL.md +99 -0
- package/skills/code-explanation/SKILL.md +66 -0
- package/skills/documentation-patterns/SKILL.md +172 -0
- package/skills/embedded-sql/SKILL.md +379 -0
- package/skills/probat-testing/SKILL.md +226 -0
- package/skills/probat-testing/patterns-unit-tests.md +614 -0
- package/skills/protheus-business/SKILL.md +92 -0
- package/skills/protheus-business/modulo-compras.md +780 -0
- package/skills/protheus-business/modulo-contabilidade.md +874 -0
- package/skills/protheus-business/modulo-estoque.md +876 -0
- package/skills/protheus-business/modulo-faturamento.md +800 -0
- package/skills/protheus-business/modulo-financeiro.md +1015 -0
- package/skills/protheus-business/modulo-fiscal.md +749 -0
- package/skills/protheus-business/modulo-manutencao.md +848 -0
- package/skills/protheus-business/modulo-pcp.md +743 -0
- package/skills/protheus-reference/SKILL.md +119 -0
- package/skills/protheus-reference/native-functions.md +7029 -0
- package/skills/protheus-reference/rest-api-reference.md +1758 -0
- package/skills/protheus-reference/restricted-functions.md +265 -0
- package/skills/protheus-reference/sx-dictionary.md +854 -0
- package/skills/sx-configuration/SKILL.md +184 -0
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
# Protheus TReport Patterns
|
|
2
|
+
|
|
3
|
+
Complete reference for implementing reports using the TReport framework in TOTVS Protheus.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Overview
|
|
8
|
+
|
|
9
|
+
The TReport framework is the standard report engine in TOTVS Protheus. It replaces legacy functions like `SetPrint`, `SetDefault`, `RptStatus`, and `Cabec`. TReport allows users to customize report output (font, color, line style, header, footer) and supports PDF, print, and spreadsheet output.
|
|
10
|
+
|
|
11
|
+
Key classes:
|
|
12
|
+
- **TReport**: The report container. Manages pages, orientation, font, and print dialog.
|
|
13
|
+
- **TRSection**: A data section (layout) that holds cells, breaks, and totalizers. Can contain sub-sections for master-detail reports.
|
|
14
|
+
- **TRCell**: A print cell (column) belonging to a section. Defines what data is printed and its formatting.
|
|
15
|
+
- **TRBreak**: Defines break rules for grouping data, triggering subtotals.
|
|
16
|
+
- **TRFunction**: A totalizer attached to a break or section. Supports SUM, COUNT, MAX, MIN, AVERAGE, ONPRINT, TIMESUM, TIMEAVERAGE.
|
|
17
|
+
|
|
18
|
+
Required includes:
|
|
19
|
+
```advpl
|
|
20
|
+
#Include "TOTVS.CH"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 2. TReport - Report Container
|
|
26
|
+
|
|
27
|
+
### 2.1 Constructor
|
|
28
|
+
|
|
29
|
+
```advpl
|
|
30
|
+
oReport := TReport():New(cName, cTitle, cPergunte, bAction, cDescription, lLandscape)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
| Parameter | Type | Description |
|
|
34
|
+
|-----------|------|-------------|
|
|
35
|
+
| `cName` | Character | Report internal name |
|
|
36
|
+
| `cTitle` | Character | Report title displayed in header |
|
|
37
|
+
| `cPergunte` | Character | Pergunte group code (SX1) for filtering. Use `Nil` if using ParamBox |
|
|
38
|
+
| `bAction` | Block | Code block executed for printing: `{|oReport| PrintFunction(oReport)}` |
|
|
39
|
+
| `cDescription` | Character | Report description |
|
|
40
|
+
| `lLandscape` | Logical | `.T.` for landscape, `.F.` for portrait (optional) |
|
|
41
|
+
|
|
42
|
+
### 2.2 Key Methods
|
|
43
|
+
|
|
44
|
+
| Method | Description |
|
|
45
|
+
|--------|-------------|
|
|
46
|
+
| `SetTitle(cTitle)` | Sets the report title |
|
|
47
|
+
| `SetLandscape()` | Sets page orientation to landscape |
|
|
48
|
+
| `SetPortrait()` | Sets page orientation to portrait |
|
|
49
|
+
| `SetTotalInLine(lInLine)` | `.T.` prints totalizers in line, `.F.` in column |
|
|
50
|
+
| `SetLineHeight(nHeight)` | Sets the line height in printing |
|
|
51
|
+
| `PrintDialog()` | Opens the print configuration dialog |
|
|
52
|
+
| `Print()` | Prints without showing dialog |
|
|
53
|
+
|
|
54
|
+
### 2.3 Key Properties
|
|
55
|
+
|
|
56
|
+
| Property | Type | Description |
|
|
57
|
+
|----------|------|-------------|
|
|
58
|
+
| `nFontBody` | Numeric | Font size for the report body |
|
|
59
|
+
| `lParamPage` | Logical | `.T.` shows parameter page, `.F.` hides it |
|
|
60
|
+
| `oPage` | Object | Page object for paper configuration |
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 3. TRSection - Data Section
|
|
65
|
+
|
|
66
|
+
### 3.1 Constructor
|
|
67
|
+
|
|
68
|
+
```advpl
|
|
69
|
+
oSection := TRSection():New(oReport, cName, aAliases, nOrder, cTitle, lLandscape, lDisable)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
| Parameter | Type | Description |
|
|
73
|
+
|-----------|------|-------------|
|
|
74
|
+
| `oReport` | Object | Parent TReport or TRSection object |
|
|
75
|
+
| `cName` | Character | Section name |
|
|
76
|
+
| `aAliases` | Array | Array of alias names used by this section, e.g. `{"SB1"}` or `{"QRY_REP"}` |
|
|
77
|
+
| `nOrder` | Numeric | Index order for positioning (optional) |
|
|
78
|
+
| `cTitle` | Character | Section title (optional) |
|
|
79
|
+
| `lLandscape` | Logical | `.T.` for landscape (optional) |
|
|
80
|
+
| `lDisable` | Logical | `.T.` to create disabled (optional) |
|
|
81
|
+
|
|
82
|
+
### 3.2 Key Methods
|
|
83
|
+
|
|
84
|
+
| Method | Description |
|
|
85
|
+
|--------|-------------|
|
|
86
|
+
| `SetQuery(cAlias, cQuery, lChangeQuery, aParam, aTCFields)` | Defines a SQL query for data source |
|
|
87
|
+
| `SetFilter(cFilter, cIndexKey, cOrdem, cAlias, nIdxOrder)` | Sets a filter on the section table |
|
|
88
|
+
| `SetTotalInLine(lInLine)` | Sets totalizer display mode for this section |
|
|
89
|
+
| `Print()` | Prints the section |
|
|
90
|
+
| `PrintLine()` | Prints a single data line |
|
|
91
|
+
| `Cell(cName)` | Returns the TRCell object for the given field name |
|
|
92
|
+
|
|
93
|
+
### 3.3 Detail Sections (Master-Detail)
|
|
94
|
+
|
|
95
|
+
A section can contain sub-sections for master-detail reports:
|
|
96
|
+
|
|
97
|
+
```advpl
|
|
98
|
+
// Master section
|
|
99
|
+
oSecMaster := TRSection():New(oReport, "Master", {"SB1"})
|
|
100
|
+
|
|
101
|
+
// Detail section (child of master)
|
|
102
|
+
oSecDetail := TRSection():New(oSecMaster, "Detail", {"SD1"})
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## 4. TRCell - Column Definition
|
|
108
|
+
|
|
109
|
+
### 4.1 Constructor
|
|
110
|
+
|
|
111
|
+
```advpl
|
|
112
|
+
TRCell():New(oSection, cName, cAlias, cTitle, cPicture, nSize, lPixel, bBlock, cAlign, lLineBreak, cHeaderAlign, lCellBreak, nColSpace, lAutoSize, nClrBack, nClrFore, lBold)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
| Parameter | Type | Description |
|
|
116
|
+
|-----------|------|-------------|
|
|
117
|
+
| `oSection` | Object | Parent TRSection object |
|
|
118
|
+
| `cName` | Character | Field name (from SX3 or query alias) |
|
|
119
|
+
| `cAlias` | Character | Table/query alias reference |
|
|
120
|
+
| `cTitle` | Character | Column header title |
|
|
121
|
+
| `cPicture` | Character | Display format mask (optional) |
|
|
122
|
+
| `nSize` | Numeric | Column width |
|
|
123
|
+
| `lPixel` | Logical | `.T.` if size is in pixels (optional) |
|
|
124
|
+
| `bBlock` | Block | Custom print code block (optional) |
|
|
125
|
+
| `cAlign` | Character | Text alignment: `"LEFT"`, `"CENTER"`, `"RIGHT"` (optional) |
|
|
126
|
+
| `lLineBreak` | Logical | Line break after cell (optional) |
|
|
127
|
+
| `cHeaderAlign` | Character | Header alignment (optional) |
|
|
128
|
+
| `lCellBreak` | Logical | Cell break (optional) |
|
|
129
|
+
| `nColSpace` | Numeric | Column spacing (optional) |
|
|
130
|
+
| `lAutoSize` | Logical | Auto-size column (optional) |
|
|
131
|
+
| `nClrBack` | Numeric | Background color (optional) |
|
|
132
|
+
| `nClrFore` | Numeric | Foreground color (optional) |
|
|
133
|
+
| `lBold` | Logical | `.T.` for bold text (optional) |
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## 5. TRBreak - Section Break
|
|
138
|
+
|
|
139
|
+
### 5.1 Constructor
|
|
140
|
+
|
|
141
|
+
```advpl
|
|
142
|
+
oBreak := TRBreak():New(oSection, uBreak, uTitle, lTotalInLine, cName, lPageBreak)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
| Parameter | Type | Description |
|
|
146
|
+
|-----------|------|-------------|
|
|
147
|
+
| `oSection` | Object | Parent TRSection object |
|
|
148
|
+
| `uBreak` | Object/Block | Cell object or code block for break rule |
|
|
149
|
+
| `uTitle` | Block/Character | Break title or code block returning title |
|
|
150
|
+
| `lTotalInLine` | Logical | `.T.` totalizers in line, `.F.` in column |
|
|
151
|
+
| `cName` | Character | Break name (optional) |
|
|
152
|
+
| `lPageBreak` | Logical | `.T.` forces page break on group change (optional) |
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## 6. TRFunction - Totalizers
|
|
157
|
+
|
|
158
|
+
### 6.1 Constructor
|
|
159
|
+
|
|
160
|
+
```advpl
|
|
161
|
+
TRFunction():New(oCell, cId, cFunction, oBreak, cTitle, cPicture, cFormula, lEndSection, lEndReport, lEndPage)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
| Parameter | Type | Description |
|
|
165
|
+
|-----------|------|-------------|
|
|
166
|
+
| `oCell` | Object | TRCell object to totalize |
|
|
167
|
+
| `cId` | Character | Totalizer identifier (optional) |
|
|
168
|
+
| `cFunction` | Character | Aggregate function type (see table below) |
|
|
169
|
+
| `oBreak` | Object | TRBreak object (optional, Nil for section/report total) |
|
|
170
|
+
| `cTitle` | Character | Totalizer title (optional) |
|
|
171
|
+
| `cPicture` | Character | Display format mask (optional) |
|
|
172
|
+
| `cFormula` | Character | Custom formula expression (optional) |
|
|
173
|
+
| `lEndSection` | Logical | Print at end of section (optional) |
|
|
174
|
+
| `lEndReport` | Logical | Print at end of report (optional) |
|
|
175
|
+
| `lEndPage` | Logical | Print at end of page (optional) |
|
|
176
|
+
|
|
177
|
+
### 6.2 Aggregate Function Types
|
|
178
|
+
|
|
179
|
+
| Function | Description |
|
|
180
|
+
|----------|-------------|
|
|
181
|
+
| `"SUM"` | Sum of values |
|
|
182
|
+
| `"COUNT"` | Count of records |
|
|
183
|
+
| `"MAX"` | Maximum value |
|
|
184
|
+
| `"MIN"` | Minimum value |
|
|
185
|
+
| `"AVERAGE"` | Average value |
|
|
186
|
+
| `"ONPRINT"` | Current value at print time |
|
|
187
|
+
| `"TIMESUM"` | Sum of hours |
|
|
188
|
+
| `"TIMEAVERAGE"` | Average of hours |
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## 7. Filtering - Pergunte and ParamBox
|
|
193
|
+
|
|
194
|
+
### 7.1 Using Pergunte (SX1)
|
|
195
|
+
|
|
196
|
+
The traditional approach uses the `Pergunte` group registered in SX1. The report constructor receives the group code as the third parameter.
|
|
197
|
+
|
|
198
|
+
```advpl
|
|
199
|
+
oReport := TReport():New("REL001", "Relatorio de Produtos", "REL001", {|oReport| fPrint(oReport)})
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### 7.2 Using ParamBox
|
|
203
|
+
|
|
204
|
+
For custom parameters without SX1 registration, use `ParamBox` before creating the report:
|
|
205
|
+
|
|
206
|
+
```advpl
|
|
207
|
+
User Function MyReport()
|
|
208
|
+
Local aPergs := {}
|
|
209
|
+
Local oReport := Nil
|
|
210
|
+
Local cProdDe := Space(TamSX3("B1_COD")[1])
|
|
211
|
+
Local cProdAte := StrTran(cProdDe, " ", "Z")
|
|
212
|
+
Local cTipoDe := Space(TamSX3("B1_TIPO")[1])
|
|
213
|
+
Local cTipoAte := StrTran(cTipoDe, " ", "Z")
|
|
214
|
+
Local nOrdem := 1
|
|
215
|
+
|
|
216
|
+
// Define parameters
|
|
217
|
+
aAdd(aPergs, {1, "Produto De", cProdDe, "", ".T.", "SB1", ".T.", 80, .F.})
|
|
218
|
+
aAdd(aPergs, {1, "Produto Ate", cProdAte, "", ".T.", "SB1", ".T.", 80, .T.})
|
|
219
|
+
aAdd(aPergs, {1, "Tipo De", cTipoDe, "", ".T.", "02", ".T.", 40, .F.})
|
|
220
|
+
aAdd(aPergs, {1, "Tipo Ate", cTipoAte, "", ".T.", "02", ".T.", 40, .T.})
|
|
221
|
+
aAdd(aPergs, {2, "Ordenar por", nOrdem, {"1=Codigo", "2=Descricao"}, 100, ".T.", .T.})
|
|
222
|
+
|
|
223
|
+
If ParamBox(aPergs, "Informe os parametros", , , , , , , , , .F., .F.)
|
|
224
|
+
oReport := fReportDef()
|
|
225
|
+
oReport:PrintDialog()
|
|
226
|
+
EndIf
|
|
227
|
+
|
|
228
|
+
Return Nil
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## 8. MenuDef for Reports
|
|
234
|
+
|
|
235
|
+
Reports are typically registered in the Protheus menu with `ADD OPTION`:
|
|
236
|
+
|
|
237
|
+
```advpl
|
|
238
|
+
Static Function MenuDef()
|
|
239
|
+
Local aRotina := {}
|
|
240
|
+
|
|
241
|
+
ADD OPTION aRotina TITLE "Imprimir" ACTION "U_MyReport" OPERATION 2 ACCESS 0
|
|
242
|
+
|
|
243
|
+
Return aRotina
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## 9. Complete Example - Product Report by Group
|
|
249
|
+
|
|
250
|
+
This example creates a report listing products grouped by type, with count totalizer per group.
|
|
251
|
+
|
|
252
|
+
```advpl
|
|
253
|
+
#Include "TOTVS.CH"
|
|
254
|
+
|
|
255
|
+
/*/{Protheus.doc} zRelProd
|
|
256
|
+
Relatorio de Produtos por Grupo com TReport
|
|
257
|
+
@type User Function
|
|
258
|
+
@author Autor
|
|
259
|
+
@since 01/01/2026
|
|
260
|
+
@version 1.0
|
|
261
|
+
/*/
|
|
262
|
+
User Function zRelProd()
|
|
263
|
+
Local aArea := GetArea()
|
|
264
|
+
Local aPergs := {}
|
|
265
|
+
Local oReport := Nil
|
|
266
|
+
Local cProdDe := Space(TamSX3("B1_COD")[1])
|
|
267
|
+
Local cProdAte := StrTran(cProdDe, " ", "Z")
|
|
268
|
+
Local cTipoDe := Space(TamSX3("B1_TIPO")[1])
|
|
269
|
+
Local cTipoAte := StrTran(cTipoDe, " ", "Z")
|
|
270
|
+
|
|
271
|
+
// Parametros de filtro
|
|
272
|
+
aAdd(aPergs, {1, "Produto De", cProdDe, "", ".T.", "SB1", ".T.", 80, .F.})
|
|
273
|
+
aAdd(aPergs, {1, "Produto Ate", cProdAte, "", ".T.", "SB1", ".T.", 80, .T.})
|
|
274
|
+
aAdd(aPergs, {1, "Tipo De", cTipoDe, "", ".T.", "02", ".T.", 40, .F.})
|
|
275
|
+
aAdd(aPergs, {1, "Tipo Ate", cTipoAte, "", ".T.", "02", ".T.", 40, .T.})
|
|
276
|
+
|
|
277
|
+
If ParamBox(aPergs, "Informe os parametros", , , , , , , , , .F., .F.)
|
|
278
|
+
oReport := fReportDef()
|
|
279
|
+
oReport:PrintDialog()
|
|
280
|
+
EndIf
|
|
281
|
+
|
|
282
|
+
RestArea(aArea)
|
|
283
|
+
|
|
284
|
+
Return Nil
|
|
285
|
+
|
|
286
|
+
// =============================================================
|
|
287
|
+
// Report Definition
|
|
288
|
+
// =============================================================
|
|
289
|
+
Static Function fReportDef()
|
|
290
|
+
Local oReport := Nil
|
|
291
|
+
Local oSection := Nil
|
|
292
|
+
Local oBreak := Nil
|
|
293
|
+
|
|
294
|
+
// Cria o relatorio
|
|
295
|
+
oReport := TReport():New("zRelProd", "Relatorio de Produtos por Grupo", Nil, ;
|
|
296
|
+
{|oReport| fRepPrint(oReport)})
|
|
297
|
+
oReport:SetTotalInLine(.F.)
|
|
298
|
+
oReport:SetPortrait()
|
|
299
|
+
oReport:SetLineHeight(50)
|
|
300
|
+
oReport:nFontBody := 10
|
|
301
|
+
oReport:lParamPage := .F.
|
|
302
|
+
|
|
303
|
+
// Secao de dados
|
|
304
|
+
oSection := TRSection():New(oReport, "Produtos", {"QRY_REP"})
|
|
305
|
+
oSection:SetTotalInLine(.F.)
|
|
306
|
+
|
|
307
|
+
// Colunas do relatorio
|
|
308
|
+
TRCell():New(oSection, "B1_COD", "QRY_REP", "Codigo", /*cPicture*/, 15, /*lPixel*/, /*bBlock*/, "LEFT", /*lLineBreak*/, "LEFT")
|
|
309
|
+
TRCell():New(oSection, "B1_DESC", "QRY_REP", "Descricao", /*cPicture*/, 30, /*lPixel*/, /*bBlock*/, "LEFT", /*lLineBreak*/, "LEFT")
|
|
310
|
+
TRCell():New(oSection, "B1_TIPO", "QRY_REP", "Tipo", /*cPicture*/, 05, /*lPixel*/, /*bBlock*/, "LEFT", /*lLineBreak*/, "LEFT")
|
|
311
|
+
TRCell():New(oSection, "B1_UM", "QRY_REP", "Un. Med.", /*cPicture*/, 05, /*lPixel*/, /*bBlock*/, "LEFT", /*lLineBreak*/, "LEFT")
|
|
312
|
+
TRCell():New(oSection, "B1_PRV1", "QRY_REP", "Preco", "@E 999,999.99", 12, /*lPixel*/, /*bBlock*/, "RIGHT", /*lLineBreak*/, "RIGHT")
|
|
313
|
+
|
|
314
|
+
// Quebra por tipo de produto
|
|
315
|
+
oBreak := TRBreak():New(oSection, oSection:Cell("B1_TIPO"), ;
|
|
316
|
+
{|| "Total do Tipo: " + AllTrim((oSection:Cell("B1_TIPO")):cBuffer)}, .F.)
|
|
317
|
+
|
|
318
|
+
// Totalizador: contagem de produtos por quebra
|
|
319
|
+
TRFunction():New(oSection:Cell("B1_COD"), Nil, "COUNT", oBreak, "Qtd Produtos", "@E 999,999,999")
|
|
320
|
+
|
|
321
|
+
// Totalizador: soma de precos no final do relatorio
|
|
322
|
+
TRFunction():New(oSection:Cell("B1_PRV1"), Nil, "SUM", Nil, "Total Geral", "@E 999,999,999.99", Nil, .F., .T.)
|
|
323
|
+
|
|
324
|
+
Return oReport
|
|
325
|
+
|
|
326
|
+
// =============================================================
|
|
327
|
+
// Print Logic
|
|
328
|
+
// =============================================================
|
|
329
|
+
Static Function fRepPrint(oReport)
|
|
330
|
+
Local cQuery := ""
|
|
331
|
+
Local cAlias := GetNextAlias()
|
|
332
|
+
Local oSection := oReport:Section(1)
|
|
333
|
+
|
|
334
|
+
// Monta query com filtros do ParamBox
|
|
335
|
+
cQuery := "SELECT B1_COD, B1_DESC, B1_TIPO, B1_UM, B1_PRV1 "
|
|
336
|
+
cQuery += "FROM " + RetSqlName("SB1") + " SB1 "
|
|
337
|
+
cQuery += "WHERE SB1.D_E_L_E_T_ = ' ' "
|
|
338
|
+
cQuery += "AND B1_FILIAL = '" + xFilial("SB1") + "' "
|
|
339
|
+
cQuery += "AND B1_COD >= '" + MV_PAR01 + "' "
|
|
340
|
+
cQuery += "AND B1_COD <= '" + MV_PAR02 + "' "
|
|
341
|
+
cQuery += "AND B1_TIPO >= '" + MV_PAR03 + "' "
|
|
342
|
+
cQuery += "AND B1_TIPO <= '" + MV_PAR04 + "' "
|
|
343
|
+
cQuery += "ORDER BY B1_TIPO, B1_COD "
|
|
344
|
+
|
|
345
|
+
TCQuery cQuery New Alias (cAlias)
|
|
346
|
+
|
|
347
|
+
// Configura a secao para usar o alias da query
|
|
348
|
+
oSection:BeginQuery()
|
|
349
|
+
|
|
350
|
+
While !(cAlias)->(Eof())
|
|
351
|
+
oSection:PrintLine()
|
|
352
|
+
(cAlias)->(DbSkip())
|
|
353
|
+
EndWh
|
|
354
|
+
|
|
355
|
+
oSection:EndQuery()
|
|
356
|
+
|
|
357
|
+
(cAlias)->(DbCloseArea())
|
|
358
|
+
|
|
359
|
+
Return Nil
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## 10. Using SetQuery for Automatic Processing
|
|
365
|
+
|
|
366
|
+
Instead of manually iterating records, you can use `SetQuery` to let TReport handle the data loop automatically:
|
|
367
|
+
|
|
368
|
+
```advpl
|
|
369
|
+
Static Function fReportDef()
|
|
370
|
+
Local oReport := Nil
|
|
371
|
+
Local oSection := Nil
|
|
372
|
+
Local cQuery := ""
|
|
373
|
+
|
|
374
|
+
oReport := TReport():New("zRelAuto", "Relatorio Automatico", Nil, ;
|
|
375
|
+
{|oReport| oReport:Section(1):Print()})
|
|
376
|
+
oReport:SetTotalInLine(.F.)
|
|
377
|
+
oReport:SetPortrait()
|
|
378
|
+
|
|
379
|
+
// Secao com query automatica
|
|
380
|
+
oSection := TRSection():New(oReport, "Produtos", {"TMP"})
|
|
381
|
+
|
|
382
|
+
cQuery := "SELECT B1_COD, B1_DESC, B1_TIPO, B1_UM, B1_PRV1 "
|
|
383
|
+
cQuery += "FROM " + RetSqlName("SB1") + " SB1 "
|
|
384
|
+
cQuery += "WHERE SB1.D_E_L_E_T_ = ' ' "
|
|
385
|
+
cQuery += "AND B1_FILIAL = '" + xFilial("SB1") + "' "
|
|
386
|
+
cQuery += "ORDER BY B1_TIPO, B1_COD "
|
|
387
|
+
|
|
388
|
+
oSection:SetQuery("TMP", cQuery)
|
|
389
|
+
|
|
390
|
+
// Colunas
|
|
391
|
+
TRCell():New(oSection, "B1_COD", "TMP", "Codigo", /*cPicture*/, 15, /*lPixel*/, /*bBlock*/, "LEFT")
|
|
392
|
+
TRCell():New(oSection, "B1_DESC", "TMP", "Descricao", /*cPicture*/, 30, /*lPixel*/, /*bBlock*/, "LEFT")
|
|
393
|
+
TRCell():New(oSection, "B1_TIPO", "TMP", "Tipo", /*cPicture*/, 05, /*lPixel*/, /*bBlock*/, "LEFT")
|
|
394
|
+
TRCell():New(oSection, "B1_UM", "TMP", "Un. Med.", /*cPicture*/, 05, /*lPixel*/, /*bBlock*/, "LEFT")
|
|
395
|
+
TRCell():New(oSection, "B1_PRV1", "TMP", "Preco", "@E 999,999.99", 12, /*lPixel*/, /*bBlock*/, "RIGHT")
|
|
396
|
+
|
|
397
|
+
Return oReport
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
---
|
|
401
|
+
|
|
402
|
+
## 11. Master-Detail Report
|
|
403
|
+
|
|
404
|
+
Example of a report with two related sections (order header + order items):
|
|
405
|
+
|
|
406
|
+
```advpl
|
|
407
|
+
Static Function fReportDef()
|
|
408
|
+
Local oReport := Nil
|
|
409
|
+
Local oSecMaster := Nil
|
|
410
|
+
Local oSecDetail := Nil
|
|
411
|
+
|
|
412
|
+
oReport := TReport():New("zRelMD", "Pedidos e Itens", Nil, ;
|
|
413
|
+
{|oReport| fRepPrintMD(oReport)})
|
|
414
|
+
oReport:SetLandscape()
|
|
415
|
+
oReport:SetTotalInLine(.F.)
|
|
416
|
+
|
|
417
|
+
// Secao master (cabecalho do pedido)
|
|
418
|
+
oSecMaster := TRSection():New(oReport, "Pedidos", {"SC7"})
|
|
419
|
+
|
|
420
|
+
TRCell():New(oSecMaster, "C7_NUM", "SC7", "Numero", /*cPicture*/, 10, /*lPixel*/, /*bBlock*/, "LEFT")
|
|
421
|
+
TRCell():New(oSecMaster, "C7_EMISSAO","SC7", "Emissao", /*cPicture*/, 10, /*lPixel*/, /*bBlock*/, "LEFT")
|
|
422
|
+
TRCell():New(oSecMaster, "C7_FORNECE","SC7", "Fornecedor", /*cPicture*/, 10, /*lPixel*/, /*bBlock*/, "LEFT")
|
|
423
|
+
|
|
424
|
+
// Secao detail (itens do pedido) - filha da master
|
|
425
|
+
oSecDetail := TRSection():New(oSecMaster, "Itens", {"SC7"})
|
|
426
|
+
|
|
427
|
+
TRCell():New(oSecDetail, "C7_ITEM", "SC7", "Item", /*cPicture*/, 05, /*lPixel*/, /*bBlock*/, "LEFT")
|
|
428
|
+
TRCell():New(oSecDetail, "C7_PRODUTO","SC7", "Produto", /*cPicture*/, 15, /*lPixel*/, /*bBlock*/, "LEFT")
|
|
429
|
+
TRCell():New(oSecDetail, "C7_QUANT", "SC7", "Quantidade", "@E 999,999.99", 10, /*lPixel*/, /*bBlock*/, "RIGHT")
|
|
430
|
+
TRCell():New(oSecDetail, "C7_PRECO", "SC7", "Preco Unit", "@E 999,999.99", 12, /*lPixel*/, /*bBlock*/, "RIGHT")
|
|
431
|
+
TRCell():New(oSecDetail, "C7_TOTAL", "SC7", "Total", "@E 999,999.99", 12, /*lPixel*/, /*bBlock*/, "RIGHT")
|
|
432
|
+
|
|
433
|
+
// Totalizador no final da secao detail
|
|
434
|
+
TRFunction():New(oSecDetail:Cell("C7_TOTAL"), Nil, "SUM", Nil, "Total Pedido", "@E 999,999,999.99")
|
|
435
|
+
|
|
436
|
+
Return oReport
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
---
|
|
440
|
+
|
|
441
|
+
## 12. Common Patterns
|
|
442
|
+
|
|
443
|
+
### 12.1 Custom Cell with Code Block
|
|
444
|
+
|
|
445
|
+
Use a code block to format or compute cell values at print time:
|
|
446
|
+
|
|
447
|
+
```advpl
|
|
448
|
+
// Celula com codigo customizado
|
|
449
|
+
TRCell():New(oSection, "SITUACAO", "QRY_REP", "Situacao", /*cPicture*/, 15, /*lPixel*/, ;
|
|
450
|
+
{|| IIf(QRY_REP->B1_MSBLQL == "1", "Bloqueado", "Ativo")}, "LEFT")
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
### 12.2 Landscape Configuration
|
|
454
|
+
|
|
455
|
+
```advpl
|
|
456
|
+
oReport := TReport():New("zRelLand", "Relatorio Paisagem", Nil, ;
|
|
457
|
+
{|oReport| fPrint(oReport)})
|
|
458
|
+
oReport:SetLandscape()
|
|
459
|
+
oReport:oPage:SetPaperSize(9) // A4
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
### 12.3 Multiple Breaks and Totalizers
|
|
463
|
+
|
|
464
|
+
```advpl
|
|
465
|
+
// Quebra por grupo
|
|
466
|
+
oBreak1 := TRBreak():New(oSection, oSection:Cell("B1_GRUPO"), ;
|
|
467
|
+
{|| "Grupo: " + AllTrim((oSection:Cell("B1_GRUPO")):cBuffer)}, .F.)
|
|
468
|
+
|
|
469
|
+
// Quebra por tipo dentro do grupo
|
|
470
|
+
oBreak2 := TRBreak():New(oSection, oSection:Cell("B1_TIPO"), ;
|
|
471
|
+
{|| "Tipo: " + AllTrim((oSection:Cell("B1_TIPO")):cBuffer)}, .F.)
|
|
472
|
+
|
|
473
|
+
// Totalizadores por quebra
|
|
474
|
+
TRFunction():New(oSection:Cell("B1_PRV1"), Nil, "SUM", oBreak1, "Total Grupo", "@E 999,999.99")
|
|
475
|
+
TRFunction():New(oSection:Cell("B1_PRV1"), Nil, "AVERAGE", oBreak1, "Media Grupo", "@E 999,999.99")
|
|
476
|
+
TRFunction():New(oSection:Cell("B1_COD"), Nil, "COUNT", oBreak2, "Qtd por Tipo", "@E 999,999")
|
|
477
|
+
|
|
478
|
+
// Totalizador geral (sem break, no final do relatorio)
|
|
479
|
+
TRFunction():New(oSection:Cell("B1_PRV1"), Nil, "SUM", Nil, "Total Geral", "@E 999,999,999.99", Nil, .F., .T.)
|
|
480
|
+
TRFunction():New(oSection:Cell("B1_COD"), Nil, "COUNT", Nil, "Total Registros", "@E 999,999", Nil, .F., .T.)
|
|
481
|
+
```
|