PDA

View Full Version : Tự động tạo mã khách hàng



gnurtel
21-12-06, 05:24 PM
Chào các bác,
Em là thành viên mới, hiện đang có vấn đề này muốn nhờ các bác giúp.
Em có 1 danh mục tên khách hàng, em muốn dùng excel tự động tạo mã khách hàng theo nguyên tắc:
- Mã khách hàng bao gồm tất cả các chữ cái đầu tiên của tất cả các từ trong tên khách hàng
- Các ký tự đầu tiên của từ mà là nguyên âm có dấu hoặc ă, â, đ, ê, ô, ơ, ư ... thì sẽ chuyển về ký tự không dấu tương ứng
- Yêu cầu mã tối đa 12 ký tự, nếu dài quá cắt bớt đi, nếu ngắn quá thì thêm vào ký tự bất kỳ cho đủ
Ví dụ: Tên "Công ty TNHH tin học và Giải pháp ích xeo" thì mã là "CTTTHVGPIC01"
Mong các bác cao thủ chỉ cho cách giải quyết vấn đề trên.
Xin cảm ơn

hai2hai
21-12-06, 06:06 PM
Viết 2 hàm nhỏ:
- 1 là hàm bỏ dấu tiếng Việt (chú ý các loại bảng mã như Unicode, TCVN3, v.v..)
- 2 là hàm lấy ký tự đầu của các từ trong 1 chuỗi (cái này chắc các bạn tự làm được chứ?), sau đó thì thêm kỹ tự cho đủ độ dài hoặc cắt ngắn bớt đi cho đúng với yêu cầu của codelength).

Các bạn làm bài tập này giúp gnurtel nhé! :)

gnurtel
22-12-06, 11:12 PM
Có bác nào rành lập trình VBA giúp tôi với, tôi hiện đang rất cần
Cảm ơn trước

ruadangyeu
23-12-06, 01:58 AM
Bạn dùng 2 cột của một sheet 1 cột đánh những chữ như â, ấ ô, ê..
một cột bạn đánh từ thanh thế như a,a,o,e...(phải đầy đủ tất cả đấy nhé
giả sử sheet đó là sheet 1
Ta viết code như sau


Function rua(chuoi As String) As String
Dim i As Integer
Dim kq As String
n = 1
kq = Left$(chuoi, 1)
kq = kttt(kq)
Do While i <= Len(chuoi)
i = InStr(n, chuoi, " ")
chuoi = Mid$(chuoi, i + 1)
If i < 1 Then
Exit Do
End If
i = i + 1
kq = kq & kttt(Left(chuoi, 1))
Loop
i = Asc("A")
Do While Len(kq) < 12
kq = kq & Chr(i)
i = i + 1
Loop
rua = kq
End Function

Function kttt(a As String) As String
Dim vung As Range
Dim b As Range
Dim c As String
Set vung = Worksheets(1).Range("a1:a33")
'//thay đổi cho đúng vùng điều kiện thay thế
For Each b In vung
If a = b.Cells(1, 1) Then
a = b.Cells(1, 1).Offset(0, 1)
End If
Next
kttt = a
End Function

Mình đã thử với chuỗi
"Rùa Đang Yêu ai ải ài ai đấy"
kết quả là chuỗi
RDYAAAADABCD

Nếu chạy bon thì thanks cho mình phát nhé
Còn nếu tốt bụng hơn thì vào trang http://ruadangyeu.info (http://ruadangyeu.info) nháy vào mấy chữ quảng cáo của google cho mình cái

File đính kèm nè

nvson
23-12-06, 07:35 AM
Bạn thử dùng hàm này xem sao (riêng mình nghĩ nó rất hay):


Option Explicit
Dim Matran()
'Thu tuc nay se tao so ngau nhien khong trung nhau
Sub Creat_Random(min_i As Integer)
Dim i As Integer, j As Integer
Dim gtri
Dim max_i As Integer
max_i = 9
ReDim Matran(1 To min_i)
For i = 1 To min_i
Do
gtri = Round(Rnd() * max_i, 0)
For j = 1 To i - 1
If gtri = Matran(j) Then GoTo tieptuc
Next j
Matran(i) = gtri
Exit Do
tieptuc:
Loop While True
Next i
End Sub

'Ban su dung ham nay de tach cac ky tu....
Public Function Split_1(strtext As String) As String
Dim strText_1 As String, strText_2 As String
Dim subText() As String
Dim i As Integer
subText = Split(strtext, " ")
For i = 0 To UBound(subText)
Select Case Asc(Left(subText(i), 1))
Case Is = 184, Is = 181, Is = 182, Is = 183, Is = 185, Is = 168, Is = 190, _
Is = 187, Is = 188, Is = 189, Is = 198, Is = 169, Is = 202, Is = 199, Is = 200, Is = 201, Is = 203
strText_2 = Chr(97)
Case Is = 208, Is = 204, Is = 206, Is = 207, Is = 209, Is = 170, _
Is = 213, Is = 210, Is = 211, Is = 212, Is = 214
strText_2 = Chr(101)
Case Is = 221, Is = 215, Is = 216, Is = 220, Is = 222
strText_2 = Chr(105)
Case Is = 227, Is = 223, Is = 225, Is = 226, Is = 228, Is = 171, Is = 232, _
Is = 229, Is = 230, Is = 231, Is = 233, Is = 172, Is = 237, Is = 234, Is = 235, Is = 236, Is = 238
strText_2 = Chr(111)
Case Is = 243, Is = 239, Is = 241, Is = 242, Is = 244, Is = 173, _
Is = 248, Is = 245, Is = 246, Is = 247, Is = 249
strText_2 = Chr(117)
Case Is = 253, Is = 250, Is = 251, Is = 252, Is = 254
strText_2 = Chr(121)
Case Is = 174
strText_2 = Chr(100)
Case Is = 193, Is = 192, Is = 195, Is = 161, Is = 162
strText_2 = Chr(65)
Case Is = 164, Is = 165
strText_2 = Chr(79)
Case Is = 166
strText_2 = Chr(85)
Case Is = 167
strText_2 = Chr(68)
Case Else
strText_2 = Left(subText(i), 1)
End Select
strText_1 = strText_1 & strText_2
Next i
strText_1 = Mid(strText_1, 1, 12)
If Len(strText_1) < 3 Then Exit Function
Call Creat_Random(12 - Len(strText_1))
For i = 1 To 12 - Len(strText_1)
strText_1 = strText_1 & Matran(i)
Next i
Split_1 = strText_1
End Function

(P/S: Các bạn có thể tham khảo luôn cách tạo số ngẫu nhiên không trùng lặp)

gnurtel
23-12-06, 08:51 AM
Cảm ơn các bác,
Cách giải quyết của bác nvson rất hay, cảm ơn bác lần nữa.
Tuy nhiên cái này mới áp dụng được cho font TCVN3 và mới chỉ dùng được với tên khách hàng mà có số từ nhỏ hơn 12, nếu lớn hơn sẽ báo lỗi #VALUE!
Ngoài ra em muốn bác giúp bỏ qua các ký tự không phải là chữ và số ra khỏi mã khách hàng, chẳng hạn trường hợp sau:
* "Công ty TNHH LG Electronic (Việt Nam)" bỏ "(" đi
* "Ngân hàng TMCP Sài Gòn Thương Tín - Chi nhánh Đống Đa" bỏ "-" đi
* v.v...
Mong bác giải quyết giúp

ruadangyeu
23-12-06, 09:43 AM
Trời sao bạn không nói sớm cái đó thì có cái gì đâu
chỉ cần cho câu lệnh kiểm tra điều kiện khi ghép chuỗi hay thay thế khi chuỗi đã hoàn thành là ok ngay.
Bạn xem mã của mình xem nó chạy trên unicode đấy chứ
Mình chạy thử rồi mày

nvson
23-12-06, 11:57 AM
Cảm ơn các bác,
Cách giải quyết của bác nvson rất hay, cảm ơn bác lần nữa.
Tuy nhiên cái này mới áp dụng được cho font TCVN3 và mới chỉ dùng được với tên khách hàng mà có số từ nhỏ hơn 12, nếu lớn hơn sẽ báo lỗi #VALUE!
Ngoài ra em muốn bác giúp bỏ qua các ký tự không phải là chữ và số ra khỏi mã khách hàng, chẳng hạn trường hợp sau:
* "Công ty TNHH LG Electronic (Việt Nam)" bỏ "(" đi
* "Ngân hàng TMCP Sài Gòn Thương Tín - Chi nhánh Đống Đa" bỏ "-" đi
* v.v...
Mong bác giải quyết giúp
Bạn thử code sau nhé:


Option Explicit
Dim Matran()
'Thu tuc nay se tao so ngau nhien khong trung nhau
Sub Creat_Random(min_i As Integer)
Dim i As Integer, j As Integer
Dim gtri
Dim max_i As Integer
max_i = 9
ReDim Matran(1 To min_i)
For i = 1 To min_i
Do
gtri = Round(Rnd() * max_i, 0)
For j = 1 To i - 1
If gtri = Matran(j) Then GoTo tieptuc
Next j
Matran(i) = gtri
Exit Do
tieptuc:
Loop While True
Next i
End Sub
'
Public Function SuperTrim(TheStr As String)
Dim Temp As String, DoubleSpase As String
DoubleSpase = Chr(32) & Chr(32)
Temp = Trim(TheStr)
Temp = Replace(Temp, DoubleSpase, Chr(32))
Do Until InStr(Temp, DoubleSpase) = 0
Temp = Replace(Temp, DoubleSpase, Chr(32))
Loop
SuperTrim = Temp
End Function
'
Public Function Split_1(strText As String) As String
Dim strText_1 As String, strText_2 As String
Dim subText() As String
Dim i As Integer
For i = 33 To 47
strText = Replace(strText, Chr(i), "")
Next i
strText = SuperTrim(strText)
subText = Split(strText, " ")
For i = 0 To UBound(subText)
Select Case Asc(Left(Trim(subText(i)), 1))
Case Is = 184, Is = 181, Is = 182, Is = 183, Is = 185, Is = 168, Is = 190, _
Is = 187, Is = 188, Is = 189, Is = 198, Is = 169, Is = 202, Is = 199, Is = 200, Is = 201, Is = 203
strText_2 = Chr(97)
Case Is = 208, Is = 204, Is = 206, Is = 207, Is = 209, Is = 170, Is = 213, _
Is = 210, Is = 211, Is = 212, Is = 214
strText_2 = Chr(101)
Case Is = 221, Is = 215, Is = 216, Is = 220, Is = 222
strText_2 = Chr(105)
Case Is = 227, Is = 223, Is = 225, Is = 226, Is = 228, Is = 171, Is = 232, _
Is = 229, Is = 230, Is = 231, Is = 233, Is = 172, Is = 237, Is = 234, Is = 235, Is = 236, Is = 238
strText_2 = Chr(111)
Case Is = 243, Is = 239, Is = 241, Is = 242, Is = 244, Is = 173, Is = 248, Is = 245, Is = 246, Is = 247, Is = 249
strText_2 = Chr(117)
Case Is = 253, Is = 250, Is = 251, Is = 252, Is = 254
strText_2 = Chr(121)
Case Is = 174
strText_2 = Chr(100)
Case Is = 193, Is = 192, Is = 195, Is = 161, Is = 162
strText_2 = Chr(65)
Case Is = 164, Is = 165
strText_2 = Chr(79)
Case Is = 166
strText_2 = Chr(85)
Case Is = 167
strText_2 = Chr(68)
Case Is = 163
strText_2 = Chr(69)
Case Else
strText_2 = Left(subText(i), 1)
End Select
strText_1 = strText_1 & strText_2
Next i
strText_1 = Mid(strText_1, 1, 12)
If Len(strText_1) < 12 And Len(strText_1) > 3 Then
Call Creat_Random(12 - Len(strText_1))
For i = 1 To 12 - Len(strText_1)
strText_1 = strText_1 & Matran(i)
Next i
End If
Split_1 = strText_1
End Function

gnurtel
23-12-06, 12:45 PM
Thanks bác nvson,
Bác giúp tôi rất nhiều, tôi cũng đã hiểu được cách làm, tôi sẽ sửa thêm theo ý mình.
=> Nhân đây bác cho hỏi luôn tại sao bác lại giới hạn tên khách hàng > 3, ví dụ: "Công ty Muối" hoặc "Cty Trần Anh" hoặc "Công ty CMC" thì lại bị bác loại ra

nvson
23-12-06, 01:26 PM
Thanks bác nvson,
Bác giúp tôi rất nhiều, tôi cũng đã hiểu được cách làm, tôi sẽ sửa thêm theo ý mình.
=> Nhân đây bác cho hỏi luôn tại sao bác lại giới hạn tên khách hàng > 3, ví dụ: "Công ty Muối" hoặc "Cty Trần Anh" hoặc "Công ty CMC" thì lại bị bác loại ra
Vì nó phụ thuộc vào hàm lấy số ngẫu nhiên.
Từ 0 đến 9 sẽ lấy được ngẫu nhiên 10 số, mà hàm của bạn bắt buộc phải có 12 số nên nếu tên chỉ có dưới 2 thì không thể tạo được 12 ký tự.
Nếu bạn lấy số ngẫu nhiên có lặp lại thì không cần phải có điều kiện này....

quanghuy2412
04-02-09, 10:06 PM
Nhân dịp đọc bài của Bác, mình cũng có 1 nhu cầu sau, nhờ bác giúp, rất cám ơn.
Viết hàm mã hóa tổ hợp (tên nhân viên + ngày sinh) thành 01 mã số nhân viên bao gồm mã số SCII+số của ngày tháng
ví dụ Nguyễn Văn Tèo sinh 01/01/1975 sẽ được mã hóa NGUYENVANTEO0101975=78718589697886657884697927395
Nguoc lai tu day so tren co the suy nguoc ra ten va ngay sinh

cadafi
04-02-09, 10:29 PM
Nhân dịp đọc bài của Bác, mình cũng có 1 nhu cầu sau, nhờ bác giúp, rất cám ơn.
Viết hàm mã hóa tổ hợp (tên nhân viên + ngày sinh) thành 01 mã số nhân viên bao gồm mã số SCII+số của ngày tháng
ví dụ Nguyễn Văn Tèo sinh 01/01/1975 sẽ được mã hóa NGUYENVANTEO0101975=78718589697886657884697927395
Nguoc lai tu day so tren co the suy nguoc ra ten va ngay sinh

Việc chuyển từ NGUYENVANTEO01011975 <----> 78718589697886657884697927395 và chuyển ngược lại không khó!

Cái khó và cũng là cái vướng mắc: là chuyển từ Nguyễn Văn Tèo --> NGUYENVANTEO

Và vấn đề đặt ra là:

1. Nếu có ông nào đó tên Nguyên Vân Tẹo cũng sinh ngày 01/01/1975 thì mã số nhân viên này theo cách mã hóa trên sẽ bị trùng!
2. Từ dãy số mã hóa đó [78718589697886657884697927395] ----> dịch ra là NGUYENVANTEO01011975 sẽ cho ra NGUYENVANTEO 01/01/1075 ---> làm sao biết NGUYENVANTEO là: NGUYỄN VĂN TÈO hay NGUYÊN VÂN TẸO, hay NGUYỄN VĂN TẺO

smbsolutions
04-02-09, 11:04 PM
Tại sao ko phải là mã số dạng này nhỉ?

1000001 Nguyễn Văn A
1000002 Nguyễn Văn B

Mã như thế này có tác dụng gì? NGUYENVANTEO01011975
Trong khi đã có thêm các thông tin là Họ và tên: Nguyễn Văn Tèo, Ngày sinh: 01/01/1975, vậy tại sao lại thêm cột mã là ghép 2 cái đó vào?

Đối với máy tính, khi 1 bảng dữ liệu dạng
ID
Name
v.v...

thì chỉ cần ID là ko trùng lặp. Thế là đủ. Không nhất thiết phải ghép này ghép nọ với nhau để tạo lên 1 cái mã. Khi tìm kiếm, ta có thể tìm toàn bộ các thông tin của đối tượng chứ ko nhất thiết tìm theo mã.

HYen17
26-03-09, 10:48 AM
Tại sao ko phải là mã số dạng này nhỉ?
1000001 Nguyễn Văn A
1000002 Nguyễn Văn B
Đối với máy tính, khi 1 bảng dữ liệu dạng
ID
Name
v.v...
thì chỉ cần ID là ko trùng lặp. Thế là đủ. Khi tìm kiếm, ta có thể tìm toàn bộ các thông tin của đối tượng chứ ko nhất thiết tìm theo mã.

Theo mình mã không nên là số, mà nên có ký tự, dù chỉ là 1; Lí do:
Tại mỗi vị trí ta có thể dùng đến 35 ký tự khác để thay thế; Và như vậy chỉ cần 2 ký tự là ta có thể ấn định mã cho hơn ngàn người rồi còn gì! (35*36)

TrungChinhs
27-03-09, 06:50 AM
Theo mình mã không nên là số, mà nên có ký tự, dù chỉ là 1; Lí do:
Tại mỗi vị trí ta có thể dùng đến 35 ký tự khác để thay thế; Và như vậy chỉ cần 2 ký tự là ta có thể ấn định mã cho hơn ngàn người rồi còn gì! (35*36)

Xin Bác một file ví dụ để nghiên cứu cách làm này. Thank!

HYen17
27-03-09, 07:37 AM
Xin Bác một file ví dụ để nghiên cứu cách làm này. Thank!
Hãy chiêm nghiệm từ bảng sau:
Num|
A0|1
. .|
AZ|36
ZZ|936 = 26*36
|
0A|1
0Z|26
9Z|260 =10 * 26
|
Sum:| 1.196
Chúc|vui!

longnh
14-07-09, 12:54 AM
Hãy chiêm nghiệm từ bảng sau:
Num|
A0|1
. .|
AZ|36
ZZ|936 = 26*36
|
0A|1
0Z|26
9Z|260 =10 * 26
|
Sum:| 1.196
Chúc|vui!


để hiểu đc cách nào hiệu quả hơn trong lưu trữ thì bạn phải nhìn ở cấp độ BIT chứ không chỉ là dộ dài chuỗi nhìn thấy. ( 1 ký tự = 1 byte ASCIIII ) biểu diễn đc 256 số bạn ạ.

From Sa_DQ:
(*) Bạn hãy lấy ví dụ về khía cạnh góc nhìn cấp độ BIT thêm, để mọi người đều hiểu ấy mà!
Xin cảm ơn bạn trước;
(*) Đúng là khả năng là vậy (biểu diễn được 256 ký tự khác nhau) Nhưng mấy ai lấy ký tự
từ cái chuỗi sau làm mã đâu: "/?<>;[]{}()&*^%$#@!`. . . "

hai2hai
14-07-09, 11:35 AM
Theo mình mã không nên là số, mà nên có ký tự, dù chỉ là 1; Lí do:
Tại mỗi vị trí ta có thể dùng đến 35 ký tự khác để thay thế; Và như vậy chỉ cần 2 ký tự là ta có thể ấn định mã cho hơn ngàn người rồi còn gì! (35*36)

Trong CSDL người ta hay dùng: (Thực ra đây là thiết kế chuẩn của thế giới rồi, các bạn khỏi cần thắc mắc) --=0

ID (PK) Kiểu Long Hoặc GUID
---------------------------
Code Varchar(25), UniqueIndex (Ko trùng lặp)
Name
...

Và để xác định 1 bản ghi, người ta dùng ID (PK) chứ ko dùng các trường khác, Code chỉ là tham chiếu đặc biệt mà thôi, nó chả các gì cái số CMT đó.

Khi tra cứu trên máy tính, người ta có thể Find hoặc Filter theo mọi thông tin của bản ghi. Trong đó, trường Code chỉ là 1 trong các thông tin đặc biệt mà thôi (vì nó cũng là UniqueIndex)

Tôi cũng chưa hiểu chữ AA-->ZZ có gì hay mà ko phải là 11-->99 làm Prefix. Code ko nhất thiết là chữ, mà có thể là số. Người ta hay dùng số cho mã, cũng có thể dùng chữ cho mã, hoặc ghép cả chữ & số, nhưng chung quy lại vẫn là UniqueIndex (No Duplicate)

Ví dụ:

Giả sử quy định AA là 1 nhóm nào đó

AA0001
AA0002
...

Thì có hơn gì: Nếu ta cũng quy định 11 là nhóm đó?

110001
110002

HYen17
14-07-09, 11:55 AM
Trong CSDL người ta hay dùng: (Thực ra đây là thiết kế chuẩn của thế giới rồi, các bạn khỏi cần thắc mắc) --=0

ID (PK) Kiểu Long Hoặc GUID
---------------------------
Code Varchar(25), UniqueIndex (Ko trùng lặp)
Name
...
Giả sử quy định AA là 1 nhóm nào đó
AA0001
AA0002 ..
Thì có hơn gì: Nếu ta cũng quy định 11 là nhóm đó?
110001
110002

Đúng vậy; Chỉ có điều trong excel ta không dùng được
00000159, hay 01234567. chẳng hạn. Vì các ID này luôn nên cùng độ dài (Đây là ý cá nhân thôi, nhằm thu gọn tối đa chuỗi ID ấy thôi)

Sẽ tiếp thu ý kiến các bạn thêm.

Nhưng theo mình, chúng ta có trăm triệu dân thì số chứng minh ND là 10 chữ số chẳng hạn; Nếu dùng Vài chữ cái vô đó thì chỉ cần độ dài 5 hay 6 ký tự & ký số, chúng ta có thể phát chứng minh NDcho tỉ người cũng xong.

Nhưng thôi, vậy có khi bị chê vì không giống ai!

sealand
14-07-09, 12:05 PM
Mình tham gia chút dưới giác độ người sử dụng. Nếu nhà lập trình nào khuyên mình đặt mã vật tư trong phần mềm Kế toán mình vẫn dùng theo cách 00001, 00002... thì mình xin vái cả nón. Kiểu này, nhiều lúc ngồi trước máy mà không sao tìm được thứ mình cần. Lúc nào cũng cần có cuốn từ điển mã để tra. Mình cũng tạo cho mình 1 nguyên tắc đặt mã (Một khi đã sử dụng phần mềm quản lý thì bắt buộc phải lo điều này).
1-Mã phải gọn gàng nhất có thể.
2-Mã phải là duy nhất và không lồng nhau (Ví dụ: HOAN lồng trong HOANG)
3-Mã phải có tính gợi ý: Nhìn vào mã đã có 1 số thông tin nhất định. Khi quên dễ dàng tìm thấy nó.
Ví dụ:
2K/tự nhom-2ktự hàng-3ky tu chung loại
-GO75001: Sắt góc 75 loại 001
-GA14002: Sắt gai phi 14 loại 002

Có vấn đề gì, nhân thể các bạn cũng tham gia giùm.

ChanhTQ@
14-07-09, 12:25 PM
Mình có nguyên tắc đặt mã
1-Mã phải gọn gàng nhất có thể.
2-Mã phải là duy nhất và không lồng nhau (Ví dụ: HOAN lồng trong HOANG)
3-Mã phải có tính gợi ý: Nhìn vào mã đã có 1 số thông tin nhất định. Khi quên dễ dàng tìm thấy nó.
Ví dụ:
2K/tự nhom-2ktự hàng-3ky tu chung loại
Có vấn đề gì, nhân thể các bạn cũng tham gia giùm.

Xin hỏi thêm Đất Cảng:

1*/ Mã có cần độ dài như nhau không?

2*/ 'HOAN1' & 'HOANG' có bị coi là lồng vô nhau không?

3*/ Trong mã có tất cả những ký tự trên bàn phím hay chỉ nên 26+10 (=36) ký tự thôi?

Xin cảm ơn trước.

hai2hai
14-07-09, 01:25 PM
2K/tự nhom-2ktự hàng-3ky tu chung loại
-GO75001: Sắt góc 75 loại 001
-GA14002: Sắt gai phi 14 loại 002

Có vấn đề gì, nhân thể các bạn cũng tham gia giùm.

Khi nào phần mềm hỗ trợ tra cứu khi gõ:

GO 75 01 thì nó nhảy đúng tới dòng đó mà ko cần có mã như vậy, chỉ cần hàng có các thuộc tính như: Sắt góc 75 loại 001
Đó là cách mà hiện có nhiều người làm PM đã nghĩ đến (Cách thức tìm kiếm thông minh dạng Google, gõ dấu hoặc ko dấu đều hiện ra)

Nói vậy thôi, chắc mọi người đang nói tơi Excel, còn tôi lại nói tới thiết kế CSDL và trường ID là khóa có kiểu Long dùng để liên kết với các bảng khác, trường Code là UniqueIndex có kiểu Varchar. Thông thường trước kia (và ngày nay) rất nhiều người dùng luôn trường Code làm khóa chính (chính tôi cũng bị dính đòn chuyện này rồi mà bây giờ gỡ ko nổi). Trường Code là 1 trường độc lập trong bảng, ko phải là khóa, không dùng để làm relationship với nhiều bảng khác. Làm thế có lợi như sau:

- Cascade Update là ko dùng tới (Vì ko ai sửa cái ID làm gì cả, họ chỉ sửa Code thôi, mà sửa code thì ko cascade với các bảng khác nên CSDL sẽ chạy rất nhanh, khi nào tới triệu bản ghi các bạn sẽ thấy vấn đề này)
- Nếu dùng Code để làm PK và cascade update sang nhiều bảng khác, chỉ cần quan hệ bố con tới 3 mức thôi là bất kể CSDL nào cũng chịu cứng ko cho phép cascade update. Đó chính là lý do ko sửa code được nếu code làm khóa chính. Ví dụ: Employee có Training History, mỗi 1 training có 1 Cerfiticate. Như vậy là có quan hệ 3 cấp xảy ra. Nếu bạn sửa Employee Code thì đáng ra phải cascade update tới cả bảng Training History và bảng Cerfiticate. Tiếc thay ko có hệ quản trị CSDL nào cho phép làm điều đó. Vì thế các bạn sẽ ko sửa được Code ở chương trình một khi dùng nó làm khóa chính. Còn nếu các bạn dùng ID làm khóa chính, còn trường code chỉ là phụ thôi thì các bạn đang sở hữu 1 CSDL cực ngon rồi đó (vì 70% số lập trình viên ko biết tới những điều này).
- Khi dùng ID (Long) làm khóa chính thì CSDL sẽ chạy nhanh hơn rất nhiều vì relationship sẽ faster nếu thông qua trường số (numeric) chứ ko phải varchar.

Đây là cái đoạn mà các bạn đang bàn tới:
Còn trường code, bạn muốn ghép thuộc tính nào của bản ghi đều được, ghép 1 ký tự, ghép 2 ký tự, độ dài là 10, là 20, là 100 ký tự, thích đặt prefix là ký tự nào (ví dụ: PN001, PX001, PT001, PC001...), subfix là ký tự nào cũng được v.v... Dân coder, ko, chỉ cần những ai trên GPE đều có thể làm được với mấy hàm Left$(), v.v.. gì đó, biết dăm ba lệnh xử lý và ghép string đều có thể làm được những điều đó. Còn chuyện ghép dài hay ghép ngắn, ghép khó hiểu hay dễ hiểu,... đều phụ thuộc vào yêu cầu quản lý của các bạn (quản lý thuốc khác, quản lý phụ tùng khác, quản lý nhân viên khác, quản lý tài sản khác, quản lý xa máy, ô to, bệnh nhân, tài khoản, chứng từ, v.v.... Có rất nhiều loại đối tượng mà ko thể cứ khăng khăng ép cách thức tạo mã của đối tượng nào cũng giống đối tượng nào cả. Nhưng nếu bạn làm công cụ cho người khác, bạn cần cung cấp cái tool, cái option để cho người ta muốn ghép gì thì ghép, ghép ngắn hay dài gì thì tùy họ. Và đó mới là cái đáng bàn!)

Nhưng, lại 1 lần nữa tôi nói, các thông tin dạng non-identify relationship đều thông qua ID (Long) chứ ko phải thông qua mã hay tên đối tượng.

Ví dụ:

tb_Item (Bảng hàng hóa)
===================
ID (Long - PK)
----------------------
Code
Name
....
CategoryID (Long FK) --> non-identify relationship với bảng tb_Category

tb_Category (Bảng nhóm hàng)
=======================
ID (Long - PK)
-------------------
Code
Name
ParentCategoryID (Long - FK, Self Referent relationship)
....

Không hiểu nói thế có phù hợp với GPE hay ko?

I am sorry, ko nói thêm về món này nữa. --=0

P/S: Hãy thử nghĩ tại sao họ lại sinh ra các chuẩn mã vạch như EVN13, EVN8,... hay Identification No toàn là số thôi?

Không ai ghép mã nước, mã tỉnh, mã huyện, STT (có dạng chữ) để tạo thành số CMT cả. Tất cả cái đó được mã hóa dạng số hết. Tương tự, mã số thuế, mã số....

sealand
14-07-09, 05:55 PM
Mình cho Hai2Hai đúng vì khi so sánh nó cực chuẩn xác. Không phải ngẫu nhiên mà khi tạo bảng trong Access nếu để acc tự tạo ID Key lập tức nó tao trường ID dạng Long ngay.
To ChanhTQ: Cái ví dụ của bạn chính là cách sử lý chống lồng mã đấy. Mã không bắt buộc đều nhau, còn nếu đều thì càng tiện sử lý và tìm kiếm về sau. Ví dụ tìm sắt gai từ 10 dến 20 ta gõ DK "GA2*" đại đa số phền mềm tìm được.

longnh
15-07-09, 02:16 AM
@ Sa_DQ

Ví dụ là thế này: A0 gồm 2 ký tụ A = 65 và 0 = 48 như vậy
để lưu trữ thực tế là: 01000001 00110000 (16 bit = 2 byte)
trong lúc nếu dùng 1 số (1byte) làm mã thì chỉ tốn 1 byte để lưu trữ.