You are on page 1of 24

GHI CHÚ/HƯỚNG DẪN TẠO DANH MỤC

1. Tạo Table (Database name)


Vị trí tạo: Database Data

 Thiết lập giá trị mặc định cho các thuộc tính:
 ParentId: Giá trị mặc định là -1 (Chưa có)
 IsGroup: Giá trị mặc định là 0 (Không phải là nhóm dữ liệu)
 IsActive: Giá trị mặc định là 1 (Dữ liệu không bị đình chỉ). Trạng thái dữ liệu
có hai loại gồm: Đình chỉ (0), Không đình chỉ (1). Dữ liệu vừa tạo ra mặc định
là dữ liệu không đình chỉ.
 CreatedAt, ModifiedAt: Giá trị mặc định được lấy từ hàm GETUTCDATE()
 Sử dụng GETUTCDATE() cho giá trị Default của CreatedAt và ModifiedAt.
 Giải thích: Được sử dụng để trả về thời gian và ngày hiện tại theo múi giờ UTC.
Khi sử dụng thì thời gian lưu không phụ thuộc vào máy Local/Client mà chỉ lấy
giờ theo múi giờ UTC.
=> Đồng bộ dữ liệu khi lưu trữ nếu có nhiều máy chủ con/Client thuộc nhiều múi
giờ khác nhau
Múi giờ UTC là gì?
Giờ UTC hay còn gọi là giờ phối hợp quốc tế, được viết tắt từ một cụm từ tiếng
Anh “Coordinated Universal Time” và một cụm từ tiếng Pháp “Temps Universel
Coordonné”. Đây là tiêu chuẩn giờ để định vị thời gian chuẩn quốc tế, được cơ
quan đo lường quốc tế (BIPM) công nhận và chọn làm mốc thời gian về pháp lý
trên toàn cầu.
 Nguyên tắc đặt tên Constraint: DF_Tên bảng_Tên thuộc tính

Ví dụ:
 Lưu ý: Thiết lập các thuộc tính là NOT NULL nếu muốn Default giá trị cho thuộc
tính. Nếu ta để NULL hoặc không thiết lập NOT NULL thì khi INSERT dữ liệu từ
chương trình dữ liệu sẽ bị NULL.
 Mẫu tạo bảng:

Lưu ý: Ở thuộc tính Id luôn thiết lập IDENTITY(1,1) để thuộc tính luôn có giá trị khi tạo
mới là tự động tăng

 Mẫu thiết lập giá trị mặc định


2. Tạo View (Database name_Data) Exploxer , Editor, Lookup
Lưu ý: View phải tạo ở Database hệ thống (Không có Data và Log ở cuối)

3. Insert vào B00FileList và B00FieldList


 Lưu ý: Các giải thích về các giá trị thường thấy chỉ là các quan sát về dữ liệu có
trong bảng B00FileList và B00FieldList của tác giả. Không phải tiêu chuẩn phải
tuân theo
 B00FileList: Khai báo các thông tin nhằm phục vụ việc lưu log của các bảng.

Thuộc tính Chú thích

TableName Tên bảng, view cần tạo log

CreateLogName Bảng được chọn để lưu Log/Chọn bảng lưu log

Câu hỏi: Có bảng có giá trị NULL, có bảng giá trị là


B20ChangeLog.

 Ở các bảng có đuôi là Detail thường có giá trị là


NULL

CreatelogNum Gắn thêm vào $ và giá trị vào CreateLogName trong Data
Log

Câu hỏi: Giá trị thường dùng là 0, có bảng có giá trị NULL.
Vậy lúc nào dùng 0 lúc nào dùng NULL

CreateLogColList Khai báo các field/thuộc tính tạo log được thể hiện ở phần
đầu phiếu khi vào nhật ký sử dụng

XmlLogColList Danh sách các cột cần lưu log. Để * nếu cần lưu log tất cả
các cột (trừ image, binary, timestamp)

Thường có giá trị là * và NULL

LogByPass Bỏ qua không tạo log


Thường có giá trị là MergeCode và NULL

SuggestCodeMethod Cái này viết riêng để tạo mã của danh mục: Sử dụng trong
usp_sys_AutoNewCode.

SuggestCodeMethod = 1 thì Mã mới sẽ tự tạo dựa theo Họ


Tên (Ví dụ: Nguyễn Văn Dũng -> DUNGNV).
SuggestCodeMethod <> 1: Tự động tăng

 Thường có giá trị là 0 và 2. Giá trị 1 chỉ xuất hiện ở


bảng B20Employee

VerticallyPartitioned Thường có giá trị là 0 và 1. Giá trị 1 chỉ xuất hiện ở một vài
bảng B30

VerticallyPartitioned =1: Đánh dấu các table/view (sổ cái,


thẻ kho, giá thành) được tách theo dvcs/năm

LastUpdated Thời điểm thay đổi giá trị cuối cùng của bảng đó, được thực
hiện qua các trigger ChangeLog. Mục đích để quyết định lấy
dữ liệu từ bảng hay cache cho các widget.

Lưu ý: Bản Bravo8R3 không sử dụng phương án này

nDeplaytime Dành riêng cho Delay của bảng dữ liệu so với cache (Giây -
Second) phải có quyền VIEW SERVER STATE

Có/Thường giá trị là NULL

DataCopy Khai báo giá trị = 1 đối với các bảng dữ liệu của CSDL Data
cần copy vào CSDL hệ thống (các bảng B10 và một số bảng
khai báo tham số B20Class...)

Lưu ý: Riêng bảng B30 sẽ bỏ qua trong thủ tục lấy dữ liệu

 Mẫu SQL:
 B00FieldList: Dùng cho trường hợp sửa mã, gộp mã trong danh mục sẽ đổi ở các
bảng liên quan

Thuộc tính Chú thích

MasterTable Bảng chính khi thay đổi ở bảng chỉnh sẽ điều chỉnh ở các
bảng thuộc Table_Name

MasterField Các field khi thay đổi ở bảng chính cần phải thay đổi ở bảng
liên quan

Table_Name Các bảng bị tác động khi field MasterTable thay đổi

Field_Name Các field thay đổi khi tác động của Field của bảng
MasterTable

Ví dụ: Ở B20Dept có giá trị ở cột MasterField: Id, Code,


Name. Ý nghĩa là khi các thuộc tính Id, Code, Name ở bảng
B20Dept thay đổi thì các bảng liên quan chứa các thuộc tính
này giá trị cũng thay đổi

Comma_Separated Dùng tìm trong danh sách các filed và ngăn cách nhau bằng
dấu phẩy.

Comma_Separated = 1: Tìm các mã trong danh sách thường


dùng trong bảng khai báo công thức

Comma_Separated = 0: Không có dấu phẩn trong phần mã


cần đổi
ParentTable Khi thay đổi ở bảng con và bảng con có field liên quan cần
đổi ở bảng cha và khai báo thêm ở ParentKey và ChildKey.

Giá trị thường là một số bảng thuộc nhóm B30

ParentKey Tên Field của bảng cha

ChildKey Tên Field của bảng con

Id Primay key/Khóa chính

 Mẫu SQL:

4. Tạo CommandKey ở B00Command và lookup (Nếu có)


 B00Command: Khai báo chức năng của chương trình

Thuộc tính Chú thích

ParentId Khai báo = Id của bảng mẹ nếu truyền dữ liệu dạng dữ liệu
bảng mẹ bảng con (Cần hỏi thêm)

IsGroup IsGroup=1: Bảng mẹ hoặc bảng đơn

IsGroup=0: Các bảng con

Câu hỏi: Bảng mẹ, bảng đơn, bảng con là gì?

CommandKey Trường khóa

Câu hỏi: Vai trò, Chức năng là gì?

DLLName Tên file DLL chứa Class

Câu hỏi: File DLL là gì?


Các loại DLL Name:

 LayoutEditor
 Survey
 Backup
 DataEditor
 Permission
 Reporter
 DataExplorer
 TaskMan
 TaskSchedule
 Bravo.Diagram
 LogViewer
 DataTransfer
 Wizard
 MainWindow

ClassName Tên class thực hiện command

Câu hỏi: Class là gì?

CtorArgs Các tham số truyền thêm. Với khai báo Editor thì khai báo giá
trị ngầm định của các trường khi thêm mới. (Cần hỏi thêm)

MethodName Tên method

Câu hỏi: Method là gì?

InvokeArgs Không dùng

CommandType Phiên bản Bravo7 sử dụng, hiện tại không rõ

DefaultEnabledState 1: Có thể gọi trực tiếp từ menu hoặc phân hệ


0: Không được gọi trực tiếp từ menu hoặc phân hệ. Chỉ có thể
được gọi qua Evaluator

ShortKeyText Mô tả phím tắt được gọi. Thường chỉ sử dụng cho các
CommandKey liên quan đến phím tắt

ShortKeyValue Giá trị cho phím tắt

Image Hình ảnh Command

CommandClass Khai báo các tham số trong phần mềm

AlterCommandClass Khai báo các tham số trong phần mềm sau thay đổi

CustomFlags Nhận các giá trị là bội số của 2 để xử lý thêm với


CommandKey đó (Cần hỏi thêm)

CategoryFlags Chưa dùng

 Mẫu SQL:

5. Tạo Trigger
Lưu ý: Khi tạo Trigger MergeCode thì phải Insert dữ liệu của bảng cần tạo vào
B00FieldList.

6. Thiết kế Layout
 Explorer
Tổng quan:
Ở trong Bravo các layout được thiết kế theo dòng (Rows) và cột (Cols). Trước khi
thiết kế một layout nào ta cần xác định trước số cột và dòng cần có để thuận tiện thiết
kế.
Ví dụ: Trong layout Explorer của Danh mục bộ phận có 1 Cột (Col) và 2 dòng

Bước 1: Thêm Danh mục đã tạo trong CommandKey vào Hệ thống Menu và Panel Cây
phân hệ

Hinh 1: Danh mục đã được khai báo CommandKey

Hinh 2:Tùy chọn danh sách lệnh ở thanh công cụ


Hinh 3: Thêm Danh mục vào Hệ thống menu

Hinh 4: Tùy chỉnh danh sách lệnh ở Panel Phân hệ


Hinh 5: Thêm Danh mục vào Panel Phân hệ

Bước 2: Khai báo Datasource

Thành phần Datasource:

<root> Khai báo đầu tiên khi bắt đầu chương trình. Có chức năng khai
báo thủ tục chạy của chương trình
<Tables> Khai báo bảng chứa dữ liệu của chương trình. Trong Layout,
khai báo để kết nối dữ liệu với bảng trong SQL
<ParentTable> Khai báo bảng dữ liệu chính, nơi lưu dữ liệu gốc của
chương trình.
<Name>Tên bảng</Name> Khai báo bảng dữ liệu nguồn của Danh mục.
Các bảng này đã được tạo trong SQL (Với Danh mục là các bảng B20 còn
Chứng từ là B30).
<Evaluators> Thẻ khai báo các Event/Chức năng. Các Event được
khai báo trong Datasource, khi muốn sử dụng phải gọi trong layout.
<Eval_EditCar> Thẻ khai báo Eval (khai báo Event) do người
dùng tự định nghĩa để phân biệt giữa các Eval.
<ClassName>BravoCommandKey</ClassName> ClassName là loại xử
lý dữ liệu cho mỗi loại control tương ứng. Nó tương tự như kiểu dữ
liệu của thẻ được khai báo.
<CommandKey>Tên CommandKey</CommandKey> Tên CommandKey được
khai báo trong bảng B00Command.
</Eval_EditCar>
</Evaluators>
</ParentTable>
</Tables>
</root>

Bước 3: Khai báo và tùy chỉnh Layout

<root>
<panelExplorer> Khai báo toàn bộ các nhóm đối tượng trên màn hình
Eplorer
<Controls>
<Control_Explorer> Thẻ người dùng tự định nghĩa để phân biệt các
Controls với nhau
<Assembly>Bravo.DataExplorer</Assembly> Khai báo các DLL chứa
các ClassName có sẵn. Như trong Form Explorer thì DLL là DataExplorer
<ClassName>BravoExplorerControl</ClassName>
<Dock>Fill</Dock>
<Execute> Thực thi các Event (Eval)đã được khai báo ở
Datasource
<Eval_EditCar /> Event trỏ tới Form Edit có CommandKey tương
ứng đã được khai báo trong B00Command
</Execute>
<Row>
<Row_0>
<Height>80</Height>
</Row_0>
</Row>
<Cols>
<Thuộc_tính>
<Width>250</Width> Khai báo chiều dài của cột
<Style>Font:Arial;TextAlign:LeftTop;</Style> Khai báo các
định dạng của nội dung được chứa trong cột
<Rows>
<Row_0>
<Text> Khai báo nội dung của tiêu đề (Header) cột
<Vietnamese>Tên tiếng việt</Vietnamese>
<English>Tên tiếng Anh</English>
</Text>
</Row_0>
</Rows>
</ Thuộc_tính >
……
</Cols>
<DataMember>Tên bảng</DataMember> Khai báo bảng dữ liệu mà
Form sử dụng. (Đã được khai báo ở DataSource)
</Control_Explorer>
</Controls>
</panelExplorer>
</root>
 Editor

Bước 1: Khai báo CommandKey tương ứng trong B00Command

Hinh 6: Khai báo CommandKey Edit_Tên bảng vào B00Command

Bước 2: Khai báo Datasource

<root>
<Tables>
<ParentTable>
<Name>B20Car</Name>
<ServerLoading> Khai báo các cột bổ sung vào câu lệnh query lấy
dữ liệu từ server về client. Thường sử dụng để thêm một số trường được
tính toán bằng hàm hoặc thêm bằng cách khai báo
<CodeCopied>Code</CodeCopied>
<CodeTmp>Code</CodeTmp>
</ServerLoading>
<RowAdded>
<Eval_AutoNewCode />
</RowAdded>
<RowCopied>
<Eval_CodeTmp_DefaultValueIfCopy>
<DataMember>CodeTmp</DataMember>
<Value>CodeCopied</Value>
</Eval_CodeTmp_DefaultValueIfCopy>
<Eval_AutoNewCode />
</RowCopied>
<ColumnChanged>
<Code>
<Eval_AutoNewCode>EMPTY(Code)</Eval_AutoNewCode>
</Code>
</ColumnChanged>
<Evaluators>
<Eval_AutoNewCode>
<ClassName>BravoServerConstraint</ClassName>
<Command>usp_sys_AutoNewCode</Command>
<DataMember>Code</DataMember>
<Parameters>
<Code>CodeTmp</Code>
<TableName>TableName</TableName>
<ColumnName>ColumnName</ColumnName>
</Parameters>
<Text />
</Eval_AutoNewCode>
<NewGroupCommand>
<ClassName>BravoCommandKey</ClassName>
<CommandKey>New</CommandKey>
<zCtorArgs>IsGroup=True;</zCtorArgs>
</NewGroupCommand>
<NewCommand>
<ClassName>BravoCommandKey</ClassName>
<CommandKey>New</CommandKey>
<zCtorArgs>IsGroup=False;</zCtorArgs>
</NewCommand>
</Evaluators>
<Validators> Thẻ Validators chứa toàn bộ các khai báo kiểm tra
dữ liệu hợp lệ
<NotNull> Khai báo rang buộc không cho phép NULL
<SourceColumn>Tên_thuộc_tính</SourceColumn>Khai báo thuộc
tính không cho phép NULL
<bEmptyAsNull>True</bEmptyAsNull>Khai báo
</NotNull>
<Code>
<ClassName>BravoUniqueKeyValidator</ClassName>
<SourceColumn>Code</SourceColumn>
</Code>
</Validators>
<Expressions>
<TableName>'B20Car'</TableName>
<ColumnName>'Code'</ColumnName>
</Expressions>
<DefaultValues> Khai báo giá trị mặc định của thuộc tính khi mở
Form Editor
<Thuộc_Tính>Giá_trị</Thuộc_Tính>
</DefaultValues>
</ParentTable>
Lưu ý: Nếu người dùng thêm một ChildTable thì Datamember là một view
thì không được đặt có tên ParentTable trước dấu _.
Đúng: ParentTable: vB20Car Childrenttable: vB20CarComponent_Explorer
Sai: ParentTable: vB20Car ChildrentTable: vB20Car_Component
</Tables>
</root>

Bước 3: Khai báo/Tùy chỉnh Layout

<root>
<navigator>
<LinkCommand> Khai báo phần Công cụ nhập liệu

<Items> Khai báo các Thành phần/Đối tượng.


Trong phần Công cụ nhập liệu không chỉ có dạng Group
hay NotGroup mà có thể có các thao tác khác.
Ví dụ: Trong Danh mục vật tư có them phần Lấy nhà cung
cấp,…
<Item_0>
<Caption>
<Vietnamese>Tên_thành_phần</Vietnamese>
<English> Tên_thành_phần (Tiếng Anh)</English>
</Caption>
<Execute> Khai báo lệnh thực thi các Eval khi người dùng
Click vào
<NewGroupCommand /> Khai báo Eval người dùng tự định nghĩa
đã được khai báo từ Datasource
</Execute>
</Item_0>
</Items>
</LinkCommand>
</navigator>
<panelEditor> Khai báo toàn bộ các nhóm đối tượng trên màn hình
Editor (Parent, Grid, Summary)
<Cols>
<Column_0>
<Width>100</Width>
<SizeType>Percent</SizeType>
</Column_0>
</Cols>
<Controls>
<panelGeneral> Thẻ người dùng tự định nghĩa để nhóm/phân biệt
các nhóm với nhau.
Ví dụ: Trong Form Editor có 2 phần là: Ô
text box điền thông tin và lưới dữ liệu để
điền thông tin. Để dễ dàng phân biệt giữa 2
nhóm ta khai báo các đối tượng của nhóm đó
vào 2 thẻ: <panelGeneral> và <panelGrid>
(Tác giả tự định nghĩa)
<Text>
<Vietnamese>Xe</Vietnamese>
<English>Car</English>
</Text>
<Row />
<Column>0</Column>
<ClassName>BravoExpandingPanel</ClassName> Khai báo kiểu ‘dữ
liệu’ của thẻ (trong trường hợp này là thẻ panelGeneral).
<Controls>
<lblCode> Thẻ người dùng tự định nghĩa theo nguyên tắc:
lbl+Tên thuộc tính với lbl là viết tắt của Label.
<Text>
<Vietnamese>Mã xe</Vietnamese>
<English>Code</English>
</Text>
<Row />
<Column>1</Column>
<Dock>Fill</Dock>
</lblCode>
<txtCode> Thẻ người dùng tự định nghĩa theo nguyên tắc:
txt+Tên thuộc tính với txt là viết tắt của TextBox.
<DataMember>Code</DataMember> Khai báo Tên thuộc tính mà
thẻ đại diện.
<Column>2</Column>
<ColumnSpan>2</ColumnSpan>
<Dock>Top</Dock>
<ClassName>BravoKeyInputBox</ClassName> Khai báo ‘Kiểu dữ
liệu’ của thẻ
</txtCode>
</Controls>
</panelGeneral>
(Nếu có)
<panelGrid>
<Assembly>Bravo.DataEditor</Assembly>
<ClassName>BravoEditingGrid</ClassName>
<Row />
<Cols>
<ItemId> Khai báo tên thuộc tính
từ View xuất hiện trong Grid
<Editor>
<bindingMembers>
<Name>ItemName</Name>
</bindingMembers>
<ClassName>BravoLookupBox</ClassName>
<LookupKey>Item</LookupKey>
</Editor>
<Name>ItemId</Name>
<Style>TextAlign:LeftTop</Style>
<Width>200</Width>
<Rows>
<Row_0>
<Text>
<Vietnamese>Phụ kiện</Vietnamese>
</Text>
</Row_0>
</Rows>
</ItemId>
</Cols>
<DataMember>vB20CarComponent</DataMember>
</panelGrid>
</Controls>
</panelEditor>
</root>
Các xử lý với Form Editor
1. Hiển thị ô nhập liệu ở đầu phiếu và dưới lưới dữ liệu (Grid)
Giải thích bài toán: ở các Form chứng từ người dùng muốn thay đổi vị trí của ô
nhập liệu ở đầu phiếu và trong lưới dữ liệu tùy theo nghiệp vụ phát sinh.
Ví dụ dưới đây người dùng muốn thay đổi vị trí hiển thị của Lookup Bộ phận
xuống lưới dữ liệu. Và người dùng thực hiện trong Danh mục chứng từ bằng cách
chọn Hiển thị dưới lưới
Phương pháp thực hiện:
Bước 1: Làm rõ vấn đề
Người dùng thường lầm tưởng Lookup Bộ phận di chuyển từ đầu phiếu xuống
dưới lưới dữ liệu. Nhưng thật ra ngay lúc đầu Lookup Bộ phận đã nằm ở dưới lưới
dữ liệu và đầu phiếu chứng từ. Việc ta set Hiển thị đầu phiếu hay hiển thị dưới
lưới chỉ là cách bật hiển thị ở phần này và tắt hiển thị ở phần kia thông qua một
điều kiện nhất định.
Ta có thể thấy Lookup Bộ phận đã được khai báo ở đầu phiếu và dưới lưới dữ liệu
từ trước trong Phiếu nhập mua

Hinh 7: Lookup Bộ phận (lookupDeptId) đã được khai báo ở đầu phiếu


Hinh 8: Lookup Bộ phận (DeptId) đã được khai báo ở Grid

Bước 2: Khai báo cột/thuộc tính muốn thêm vào Datasource (Chứng từ cần them
thuộc tính (Tên cột muốn thêm) và Danh mục chứng từ (Using+Tên cột muốn
thêm))
Có 2 cách để thêm cột/thuộc tính vào Datasource:
 Cách 1: Cập nhật View trong Datasource
Ở cách này chúng ta áp dụng cho các Datasource sử dụng View là Table
(Đa số các Danh mục và Chứng từ có ParentTable và ChildTable là dạng
View). Tuy nhiên ở Danh mục chứng từ thì là một trường hợp đặc biệt
khi mà sử dụng thẳng bảng chính mà không qua View. Vậy nên để sử lý
trường hợp này ta có 2 cách:
+ Tạo View từ B00Dmct và khai báo trong DataSource
+ Sử dụng cột CustomField có sẵn trong B00Dmct
UsingCustomFiled1, UsingCustomFiled2, UsingCustomFiled3 được tạo
ra cho người dùng khai báo các côt/trường dữ liệu cần mở rộng
Lưu ý: Để có thể chọn lookup ta cần khai báo them lookup Class
Ở phần chứng từ ta có thể dùng cách cập nhật lại View
 Cách 2: Thêm cột tạm (Temp Col)

Ở cách này chỉ dùng trong các trường hợp ta cần xử lý tính toán và không lưu
vào Database. Vậy nên cách này không được sử dụng trong trường hợp này

Bước 3: Khai báo thẻ Expr để hiển thị đầu phiếu và dưới lưới

Sau khi người dùng khai báo Lookup ở Bước 1 và Bước 2, để cột/thuộc tính ở
đầu phiếu và dưới lưới hiển tị theo mong muốn ta sử dụng Thẻ Expr để lấy
điều kiện từ thuộc tính/trường dữ liệu Using+Tên cột ta đã khai báo ở Bước 2.

ở Using+Tên cột có 3 giá trị:

0: Không hiển thị

1: Hiển thị ở đầu phiếu


2: Hiển thị dưới lưới

Vậy nên ta sử dụng thẻ Expr như sau:

Hinh 9: Khai báo UsingCustomField1=1 khi muốn hiện đầu phiếu đã khai báo ở đầu phiếu

Hinh 10: Khai báo UsingCustomField1=2 khi muốn hiện ở lưới đã khai báo trong lưới

You might also like