C++Builder 단 한 줄의 코드로 완성하는 C++ CUSTOMER/SALES 애플리케이션
2020.11.09 16:42
다음은 데이비드 아이(David I)가 작성한 기술문서를 번역한 글입니다.
요새 노 코드(No Code), 로우코드(Low Clode) 개발에 대한 이야기가 많죠. 얼마전에는 엠바카데로 책임 관리자 아타나스 포포브가 로우 코드 개발을 주제로 기술 컨텐츠를 작성하기도 했었습니다. 아타나스 글에서는 이렇게 소개합니다. “요즘 로우코드 개발이 유행이죠. 가트너 등 많은 연구단체들이 2019년 로우코드 애플리케이션 개발 플래폼 시장 규모를 약 100억 달러로 잡고 2020년부터 2027년까지 CAGR 프로젝트가 20% 이상 성장할 것으로 예상하기도 했습니다.” 아타나스는 이 컨텐츠를 통해 델파이 개발자들에게 로우코드가 왜 중요한지를 잘 정리해주었습니다 (그리고 저는 이번 컨텐츠를 통해 C++빌더 개발자분들에게 그 중요성을 설명하고자 합니다).
이 글을 통해 단 1줄의 코드만으로 C++을 이용해 윈도우용 Customer/Sales 관리, Master/Detail/Chart 기능이 있는 Customer/Sales 관리 애플리케이션을 완성할 수 있습니다.
필요한 건 C++빌더, 몇몇 RTL (라이브바인딩, 파이어닥, TeeChart 등)입니다. 이것만으로도 윈도우용 Customer/Sales 관리 프로그램을 멋지게 완성할 수 있습니다.
활용할 항목들은 다음과 같습니다:
- IDE의 폼 디자이너
- VCL
- 필드 에디터와 파이어닥 (FireDAC) 연동
- 비주얼 라이브 바인딩
- 단 한 줄의 C++코드
- 이 단 한 줄의 소스코드 조차도 필요 없는 방법을 아시는 분이 있다면, 알려주세요! 그럼 기쁘게 업데이트 하도록 하겠습니다 ^^
UI 화면
C++빌더를 실행하고 File | New | C++Builder VCL application 메뉴를 선택하세요. 폼 상단에 TPanel을 하나 올려주세요. 그리고 사용할 컴포넌트들 – 체크박스(checkbox), TDBNavigator, TDBGrid 컴포넌트 2개 (하나는 고객 리스트용이고, 다른 하나는 선택한 고객에 대한 세일즈 체크용입니다), Steema 소프트웨어의 TDBChart (파이 차트를 보여줄거에요), TSplitter 컴포넌트 2개 (하나는 고객 리스트확장용, 다른 하나는 영업 정보와 파이 차트 확장용), 파이어닥 컴포넌트들 (TFDConnection, TFDQuery 3개), TDataSource 2개 – 폼 위에 배치해주세요. TPanel을 하나 더 올려볼까요? 여기에는 세일즈 정보와 파이 차트가 표시되도록 할 것입니다.
사용한 컴포넌트들과 TPanel에 올라가있는 항목들은 스트럭처(Structure) 화면에서 확인할 수 있습니다.
데이터베이스 컴포넌트와 SQL 쿼리
데이터베이스는 인터베이스 Employee.gdb 샘플을 사용해보겠습니다. 이 샘플 DB에는 Customer, Sales 테이블이 이미 포함되어 있습니다.
데이터 익스플로러(Data Explorer) 화면에서 Employee.gdb 파일 구조를 확인할 수 있습니다.
이번 예제에서 사용할 TFDQuery 컴포넌트들은 FireDAC Query Editor를 통해서 각각의 상세 내용들을 확인할 수 있습니다 – TFDQuery 컴포넌트를 마우스 오른쪽 버튼으로 클릭해서 확인할 수 있습니다 – customer 쿼리, sales by customer 쿼리, customer에 대한 sales by item type 이 각 항목들에 대한 SQL 구문을 생성하고 테스트할 수 있죠.
TFDQuery들을 마우스 오른쪽 버튼으로 클릭하면 필드 에디터를 가져올 수 있습니다. 여기에는 각 쿼리들에서 가져온 컬럼 값들이 포함되어 있습니다.
각 쿼리 결과 데이터를 TDBGrid, TDBChart와 연동합니다. TDataSource 컴포넌트 속성들도 아래와 같이 설정합니다.
customer (master), sales (detail) 쿼리들을 연결하기 위해서는 오브젝트 인스펙터(Object Inspector)에서 SalesQuery에 대한 MasterFields 속성과 MasterSource를 설정해줍니다. SalesByItemTypeForCustomerQuery 도 동일한 방법으로 진행해주세요.
비주얼 라이브 바인딩 (Visual Live Bindings)
데이터베이스 연동과 UI에서 쿼리 결과값 연동을 해보겠습니다. C++빌더에서 자체 제공하는 기능인 비주얼 라이브 바인딩 기술을 사용하면 매우 쉽습니다. 라이브바인딩은 데이터를 바인딩할 수 있는 표현식 기반의 프레임워크입니다. 직접 눈으로 보면서 (또는 코드로도 가능) 객체들간의 연동 또는 객체와 데이터셋 필드 연동이 가능합니다. 라이브바인딩은 객체들의 속성들과 연계되어 있는 바인딩 표현식들을 사용해 다른 객체들과 연동이 가능합니다. 라이브바인딩 표현식들은 단방향, 양방향 모두 가능합니다.
라이브바인딩 디자이너는 연동하고자 하는 항목에서 할 수 있습니다. 해당 항목을 마우스 오른쪽 버튼으로 클릭하면 팝업 메뉴가 뜨면서 “Bind Visually…”를 클릭하면 됩니다.
그럼 해당 폼에 포함되어 있는 비주얼/논비주얼 컴포넌트들까지 모두 폼 아래 화면에 나타납니다. 각 객체(object) 오른쪽 아래에 있는 “…”를 클릭해 바인딩 식에 필요한 속성 목록을 불러올 수 있습니다.
이 예제에서는 Checked 속성과 CheckedState를 사용해보려고 합니다. 마우스를 CheckedState 속성과 각 쿼리의 Active 속성을 드래그해서 연결해줍니다. 실행될 때 바인딩 표현식에 따라 각 SQL 쿼리가 실행됩니다.
라이브바인딩 디자이너를 줌 인/아웃도 할 수 있습니다. 보기에 너무 복잡하면 바인딩 일부를 레이어를 생성해 숨겨 놓을 수도 있고, 디자인 화면을 비트맵 파일로 저장할 수도 있습니다.
Steema 사의 TeeChart를 활용한 파이 차트(Pie Chart) – Customer Sales by Item Type 차트로 표현하기
C++빌더에는 TeeChart 컴포넌트 기본 세트가 이미 포함되어 있습니다. 필요하다면 Steema Software 홈페이지를 통해서 더 많은 기능을 제공하는 에디션으로 업그레이드도 할 수 있습니다.
개발 화면 우측 하단에 보면 팔레트(Palette) 화면이 있습니다. 여기서 TeeChart Std 모음 중 TDBChart 컴포넌트를 마우스 오른쪽 버튼으로 클릭해보세요. 그럼 다양한 컴포넌트 에디터 항목들을 확인할 수 있습니다.
“Edit Chart…” 항목을 클릭해봅시다. 그럼 세 가지 탭이 나오는 화면이 나올텐데 그 중 “Series”를 클릭합니다. 이 예제에서는 파이 차트를 사용할텐데요. 만약 “Series”를 클릭해서 파이 차트가 보이지 않는다면 ‘Add…’ 버튼을 클릭해서 추가해주세요. 참고로 파이(Pie) 차트는 TeeChart 스탠다드 에디션에 포함되어 있는 항목입니다.
DBChart1을 열어서 좌측 메뉴 중 Series 아래에 ‘Series 1’이 보이시죠? 이걸 클릭하고 ‘Data Source’ 탭을 선택하세요. 이제 데이터셋(Dataset)을 “SalesByItemTypeForCustomerQuery”로 설정하고 Labels 값은 ITEM_TYPE으로, Pie는 SUM 으로 설정해줍니다.
차트 타이틀은 “Sales by Item Type for Customer”로 입력해주겠습니다. 하단의 [Close] 버튼을 눌러 파이 차트 설정을 완료합니다.
폼 설정 완료하기
지금까지 디자인한 폼 화면을 텍스트 소스코드로 확인해볼까요? 폼 디자이너 화면에서 마우스 오른쪽 버튼을 클릭하고 “view as text”를 선택해보세요. 사용한 UI 컴포넌트들, 파이어닥(FireDAC), 티차트(TeeChart), 라이브바인딩(LiveBinding) 컴포넌트와 설정 항목들을 모두 확인할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
|
object MasterDetailForm: TMasterDetailForm
Left = 0
Top = 0
Caption = ‘Customer and Orders Master Detail Using Live Bindings (C++ VCL)’
ClientHeight = 509
ClientWidth = 736
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = –11
Font.Name = ‘Tahoma’
Font.Style = []
OldCreateOrder = False
OnShow = FormShow
PixelsPerInch = 96
TextHeight = 13
object Splitter1: TSplitter
Left = 0
Top = 161
Width = 736
Height = 3
Cursor = crVSplit
Align = alTop
ExplicitLeft = 24
ExplicitTop = 210
ExplicitWidth = 159
end
object Panel1: TPanel
Left = 0
Top = 0
Width = 736
Height = 33
Align = alTop
TabOrder = 0
object DBNavigator1: TDBNavigator
Left = 159
Top = 4
Width = 225
Height = 23
DataSource = CustomerDataSource
VisibleButtons = [nbFirst, nbPrior, nbNext, nbLast, nbRefresh]
TabOrder = 0
end
object DatabaseActiveCheckBox: TCheckBox
Left = 24
Top = 9
Width = 97
Height = 17
Caption = ‘Database Active’
TabOrder = 1
end
end
object CustomerDBGrid: TDBGrid
Left = 0
Top = 33
Width = 736
Height = 128
Align = alTop
DataSource = CustomerDataSource
TabOrder = 1
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = –11
TitleFont.Name = ‘Tahoma’
TitleFont.Style = []
end
object Panel2: TPanel
Left = 0
Top = 164
Width = 736
Height = 345
Align = alClient
TabOrder = 2
object Splitter2: TSplitter
Left = 305
Top = 1
Height = 343
ExplicitLeft = 208
ExplicitTop = 120
ExplicitHeight = 100
end
object SalesDBGrid: TDBGrid
Left = 1
Top = 1
Width = 304
Height = 343
Align = alLeft
DataSource = SalesDataSource
TabOrder = 0
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = –11
TitleFont.Name = ‘Tahoma’
TitleFont.Style = []
end
object DBChart1: TDBChart
Left = 308
Top = 1
Width = 427
Height = 343
Title.Text.Strings = (
‘Sales by Item Type for Customer’)
View3DOptions.Elevation = 315
View3DOptions.Orthogonal = False
View3DOptions.Perspective = 0
View3DOptions.Rotation = 360
Align = alClient
TabOrder = 1
DefaultCanvas = ‘TGDIPlusCanvas’
ColorPaletteIndex = 13
object Series1: TPieSeries
DataSource = SalesByItemTypeForCustomerQuery
XLabelsSource = ‘ITEM_TYPE’
XValues.Order = loAscending
YValues.Name = ‘Pie’
YValues.Order = loNone
YValues.ValueSource = ‘SUM’
Frame.InnerBrush.BackColor = clRed
Frame.InnerBrush.Gradient.EndColor = clGray
Frame.InnerBrush.Gradient.MidColor = clWhite
Frame.InnerBrush.Gradient.StartColor = 4210752
Frame.InnerBrush.Gradient.Visible = True
Frame.MiddleBrush.BackColor = clYellow
Frame.MiddleBrush.Gradient.EndColor = 8553090
Frame.MiddleBrush.Gradient.MidColor = clWhite
Frame.MiddleBrush.Gradient.StartColor = clGray
Frame.MiddleBrush.Gradient.Visible = True
Frame.OuterBrush.BackColor = clGreen
Frame.OuterBrush.Gradient.EndColor = 4210752
Frame.OuterBrush.Gradient.MidColor = clWhite
Frame.OuterBrush.Gradient.StartColor = clSilver
Frame.OuterBrush.Gradient.Visible = True
Frame.Width = 4
OtherSlice.Legend.Visible = False
end
end
end
object DatabaseConnection: TFDConnection
Params.Strings = (
‘Database=C:\Users\Public\Documents\Embarcadero\Studio\21.0\Sampl’ +
‘es\Data\EMPLOYEE.GDB’
‘ConnectionDef=EMPLOYEE’)
Connected = True
LoginPrompt = False
Left = 104
Top = 64
end
object CustomerQuery: TFDQuery
AfterScroll = CustomerQueryAfterScroll
Connection = DatabaseConnection
SQL.Strings = (
‘select * from customer’)
Left = 240
Top = 72
object CustomerQueryCUST_NO: TFDAutoIncField
FieldName = ‘CUST_NO’
Origin = ‘CUST_NO’
ProviderFlags = [pfInUpdate, pfInWhere, pfInKey]
IdentityInsert = True
end
object CustomerQueryCUSTOMER: TStringField
FieldName = ‘CUSTOMER’
Origin = ‘CUSTOMER’
Required = True
Size = 25
end
object CustomerQueryCITY: TStringField
FieldName = ‘CITY’
Origin = ‘CITY’
Size = 25
end
object CustomerQuerySTATE_PROVINCE: TStringField
FieldName = ‘STATE_PROVINCE’
Origin = ‘STATE_PROVINCE’
Size = 15
end
object CustomerQueryCOUNTRY: TStringField
FieldName = ‘COUNTRY’
Origin = ‘COUNTRY’
Size = 15
end
object CustomerQueryPOSTAL_CODE: TStringField
FieldName = ‘POSTAL_CODE’
Origin = ‘POSTAL_CODE’
Size = 12
end
object CustomerQueryON_HOLD: TStringField
AutoGenerateValue = arDefault
FieldName = ‘ON_HOLD’
Origin = ‘ON_HOLD’
FixedChar = True
Size = 1
end
end
object CustomerDataSource: TDataSource
DataSet = CustomerQuery
Left = 341
Top = 72
end
object SalesQuery: TFDQuery
MasterSource = CustomerDataSource
MasterFields = ‘CUST_NO’
DetailFields = ‘CUST_NO’
Connection = DatabaseConnection
FetchOptions.AssignedValues = [evCache]
FetchOptions.Cache = [fiBlobs, fiMeta]
UpdateOptions.AssignedValues = [uvRefreshMode]
SQL.Strings = (
‘select * from sales’
‘where :Cust_NO = Cust_No’)
Left = 79
Top = 240
ParamData = <
item
Name = ‘CUST_NO’
DataType = ftInteger
ParamType = ptInput
Value = 1001
end>
object SalesQueryCUST_NO: TIntegerField
DisplayLabel = ‘CUST#’
FieldName = ‘CUST_NO’
Origin = ‘CUST_NO’
Required = True
end
object SalesQueryORDER_DATE: TSQLTimeStampField
AutoGenerateValue = arDefault
DisplayLabel = ‘ORD_DATE’
DisplayWidth = 10
FieldName = ‘ORDER_DATE’
Origin = ‘ORDER_DATE’
end
object SalesQueryTOTAL_VALUE: TCurrencyField
FieldName = ‘TOTAL_VALUE’
Origin = ‘TOTAL_VALUE’
Required = True
end
object SalesQueryITEM_TYPE: TStringField
FieldName = ‘ITEM_TYPE’
Origin = ‘ITEM_TYPE’
Required = True
Size = 12
end
end
object SalesDataSource: TDataSource
DataSet = SalesQuery
Left = 184
Top = 240
end
object BindingsList1: TBindingsList
Methods = <>
OutputConverters = <>
Left = 628
Top = 69
object LinkControlToPropertyActive: TLinkControlToProperty
Category = ‘Quick Bindings’
Control = DatabaseActiveCheckBox
Track = True
Component = CustomerQuery
ComponentProperty = ‘Active’
end
object LinkControlToPropertyActive2: TLinkControlToProperty
Category = ‘Quick Bindings’
Control = DatabaseActiveCheckBox
Track = True
Component = SalesQuery
ComponentProperty = ‘Active’
InitializeControlValue = False
end
object LinkControlToPropertyActive3: TLinkControlToProperty
Category = ‘Quick Bindings’
Control = DatabaseActiveCheckBox
Track = True
Component = SalesByItemTypeForCustomerQuery
ComponentProperty = ‘Active’
InitializeControlValue = False
end
end
object SalesByItemTypeForCustomerQuery: TFDQuery
MasterSource = CustomerDataSource
MasterFields = ‘CUST_NO’
Connection = DatabaseConnection
UpdateOptions.AssignedValues = [uvRefreshMode]
SQL.Strings = (
‘select Item_Type,sum(Total_Value) from Sales’
‘where Cust_NO = :Cust_No’
‘Group by Item_type’)
Left = 128
Top = 320
ParamData = <
item
Name = ‘CUST_NO’
DataType = ftInteger
ParamType = ptInput
Value = Null
end>
object SalesByItemTypeForCustomerQueryITEM_TYPE: TStringField
AutoGenerateValue = arDefault
FieldName = ‘ITEM_TYPE’
Origin = ‘ITEM_TYPE’
ProviderFlags = []
ReadOnly = True
Size = 12
end
object SalesByItemTypeForCustomerQuerySUM: TFMTBCDField
AutoGenerateValue = arDefault
FieldName = ‘SUM’
Origin = ‘”SUM”‘
ProviderFlags = []
ReadOnly = True
Precision = 18
Size = 2
end
end
end
|
cs |
단 한 줄의 코드로 프로젝트 완성하기
프로젝트를 한 번 저장해줍시다.
고객을 선택할 때마다 TeeChart 파이 차트를 자동 새로고침 해줘야겠죠? CustomerQuery AfterScroll 이벤트 핸들러에 딱 한 줄의 코드를 작성해보겠습니다.
1
2
3
4
5
|
void __fastcall TMasterDetailForm::CustomerQueryAfterScroll(TDataSet *DataSet)
{
// refresh the chart data when customer row scroll happens
DBChart1->RefreshData();
}
|
cs |
이 단 한 줄의 코드만으로 SalesByItemTypeForCustomerQuery 값이 업데이트 될 때마다 파이 차트 데이터가 자동 새로고침됩니다.
MasterDetailUnit.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
//—————————————————————————
#ifndef MasterDetailUnitH
#define MasterDetailUnitH
//—————————————————————————
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Data.DB.hpp>
#include <FireDAC.Comp.Client.hpp>
#include <FireDAC.Comp.DataSet.hpp>
#include <FireDAC.DApt.hpp>
#include <FireDAC.DApt.Intf.hpp>
#include <FireDAC.DatS.hpp>
#include <FireDAC.Phys.hpp>
#include <FireDAC.Phys.IB.hpp>
#include <FireDAC.Phys.IBDef.hpp>
#include <FireDAC.Phys.Intf.hpp>
#include <FireDAC.Stan.Async.hpp>
#include <FireDAC.Stan.Def.hpp>
#include <FireDAC.Stan.Error.hpp>
#include <FireDAC.Stan.Intf.hpp>
#include <FireDAC.Stan.Option.hpp>
#include <FireDAC.Stan.Param.hpp>
#include <FireDAC.Stan.Pool.hpp>
#include <FireDAC.UI.Intf.hpp>
#include <FireDAC.VCLUI.Wait.hpp>
#include <Vcl.DBCtrls.hpp>
#include <Vcl.DBGrids.hpp>
#include <Vcl.ExtCtrls.hpp>
#include <Vcl.Grids.hpp>
#include <Data.Bind.Components.hpp>
#include <Data.Bind.DBScope.hpp>
#include <Data.Bind.EngExt.hpp>
#include <Data.Bind.Grid.hpp>
#include <System.Bindings.Outputs.hpp>
#include <System.Rtti.hpp>
#include <Vcl.Bind.DBEngExt.hpp>
#include <Vcl.Bind.Editors.hpp>
#include <Vcl.Bind.Grid.hpp>
#include <Vcl.WinXCtrls.hpp>
#include <VCLTee.Chart.hpp>
#include <VCLTee.Series.hpp>
#include <VclTee.TeeGDIPlus.hpp>
#include <VCLTee.TeEngine.hpp>
#include <VCLTee.TeeProcs.hpp>
#include <VCLTee.DBChart.hpp>
#include <Datasnap.DBClient.hpp>
#include <Datasnap.Provider.hpp>
//—————————————————————————
class TMasterDetailForm : public TForm
{
__published: // IDE-managed Components
TFDConnection *DatabaseConnection;
TFDQuery *CustomerQuery;
TDataSource *CustomerDataSource;
TFDQuery *SalesQuery;
TDBNavigator *DBNavigator1;
TPanel *Panel1;
TSplitter *Splitter1;
TCheckBox *DatabaseActiveCheckBox;
TDBGrid *CustomerDBGrid;
TDBGrid *SalesDBGrid;
TDataSource *SalesDataSource;
TBindingsList *BindingsList1;
TLinkControlToProperty *LinkControlToPropertyActive;
TLinkControlToProperty *LinkControlToPropertyActive2;
TPanel *Panel2;
TIntegerField *SalesQueryCUST_NO;
TSQLTimeStampField *SalesQueryORDER_DATE;
TCurrencyField *SalesQueryTOTAL_VALUE;
TStringField *SalesQueryITEM_TYPE;
TSplitter *Splitter2;
TFDAutoIncField *CustomerQueryCUST_NO;
TStringField *CustomerQueryCUSTOMER;
TStringField *CustomerQueryCITY;
TStringField *CustomerQuerySTATE_PROVINCE;
TStringField *CustomerQueryCOUNTRY;
TDBChart *DBChart1;
TPieSeries *Series1;
TFDQuery *SalesByItemTypeForCustomerQuery;
TLinkControlToProperty *LinkControlToPropertyActive3;
TStringField *CustomerQueryPOSTAL_CODE;
TStringField *CustomerQueryON_HOLD;
TStringField *SalesByItemTypeForCustomerQueryITEM_TYPE;
TFMTBCDField *SalesByItemTypeForCustomerQuerySUM;
void __fastcall CustomerQueryAfterScroll(TDataSet *DataSet);
private: // User declarations
public: // User declarations
__fastcall TMasterDetailForm(TComponent* Owner);
};
//—————————————————————————
extern PACKAGE TMasterDetailForm *MasterDetailForm;
//—————————————————————————
#endif
|
cs |
MasterDetailUnit.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
//—————————————————————————
#include <vcl.h>
#pragma hdrstop
#include “MasterDetailUnit.h”
//—————————————————————————
#pragma package(smart_init)
#pragma resource “*.dfm”
TMasterDetailForm *MasterDetailForm;
//—————————————————————————
__fastcall TMasterDetailForm::TMasterDetailForm(TComponent* Owner)
: TForm(Owner)
{
}
//—————————————————————————
void __fastcall TMasterDetailForm::CustomerQueryAfterScroll(TDataSet *DataSet)
{
// refresh the chart data when customer row scroll happens
DBChart1–>RefreshData();
}
//—————————————————————————
|
cs |
프로그램 실행하기
완성한 프로그램을 실행해볼까요? 제가 만든 프로그램은 아래와 같이 실행이 됩니다. 데이터 첫 부분의 두 고객에 대한 정보를 클릭했을 때의 화면입니다. customer sales 그리드와 파이 차트가 각 고객을 선택했을 때 다르게 보이는 걸 확인하실 수 있겠죠?