Tự động tạo mã khách hàng

Liên hệ QC

gnurtel

Thành viên mới
Tham gia
19/12/06
Bài viết
14
Được thích
11
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
 
Lần chỉnh sửa cuối:
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é! :)
 
Upvote 0
Thanks bác hai2hai

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
 
Upvote 0
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
Mã:
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 nháy vào mấy chữ quảng cáo của google cho mình cái

File đính kèm nè
 

File đính kèm

Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Bạn thử dùng hàm này xem sao (riêng mình nghĩ nó rất hay):
Mã:
Option Explicit
Dim Matran()
[B][COLOR=red]'Thu tuc nay se tao so ngau nhien khong trung nhau[/COLOR][/B]
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....
[B][COLOR=red]Public Function Split_1(strtext As String) As String[/COLOR][/B]
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)
 
Lần chỉnh sửa cuối:
Upvote 0
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
 
Lần chỉnh sửa cuối:
Upvote 0
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
 
Upvote 0
gnurtel đã viết:
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é:
Mã:
Option Explicit
Dim Matran()
'Thu tuc nay se tao so ngau nhien khong trung nhau
[B][COLOR=red]Sub Creat_Random(min_i As Integer)
[/COLOR][/B]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
'
[B][COLOR=red]Public Function SuperTrim(TheStr As String)
[/COLOR][/B]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
'
[B][COLOR=red]Public Function Split_1(strText As String) As String
[/COLOR][/B]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
 
Upvote 0
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
 
Lần chỉnh sửa cuối:
Upvote 0
gnurtel đã viết:
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....
 
Upvote 0
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
 
Upvote 0
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
 
Lần chỉnh sửa cuối:
Upvote 0
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ã.
 
Upvote 0
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)
 
Upvote 0
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!
 
Upvote 0
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: "/?<>;[]{}()&*^%$#@!`. . . "
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
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
 
Lần chỉnh sửa cuối:
Upvote 0
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!
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
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.
 
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom