Cách duyệt các phần tử của một xâu(chuỗi) ký tự trong VBA. (1 người xem)

  • Thread starter Thread starter seikoqn
  • Ngày gửi Ngày gửi
Liên hệ QC

Người dùng đang xem chủ đề này

seikoqn

Thành viên hoạt động
Tham gia
19/1/15
Bài viết
161
Được thích
58
Tôi muốn duyệt qua các phần tử của một xâu kí tự trong VBA nhưng không biết phải viết code ra sao(Không biết trong VBA có thể làm được không? Ngày xưa tôi học Pascal thì có) mong các anh(chị) giúp đỡ với ạ! Ví dụ tôi có File đính kèm. Trong File tôi có 2 chuỗi giờ tôi muốn viết câu lệnh để duyệt từ phần tử đầu tới phần tử cuối thì phải viết thế nào ạ? Ví dụ với xâu "Tôi yêu giaiphapexcel" nếu tôi muốn lấy các phần tử "Tôi yêu" thì code phải viết sao ạ?
 

File đính kèm

Tôi muốn duyệt qua các phần tử của một xâu kí tự trong VBA nhưng không biết phải viết code ra sao(Không biết trong VBA có thể làm được không? Ngày xưa tôi học Pascal thì có) mong các anh(chị) giúp đỡ với ạ! Ví dụ tôi có File đính kèm. Trong File tôi có 2 chuỗi giờ tôi muốn viết câu lệnh để duyệt từ phần tử đầu tới phần tử cuối thì phải viết thế nào ạ? Ví dụ với xâu "Tôi yêu giaiphapexcel" nếu tôi muốn lấy các phần tử "Tôi yêu" thì code phải viết sao ạ?


Có thể dùng hàm mid để duyệt từng ký tự trong 1 string, khi xét đến khoảng trắng thứ 2 thì dừng lại chẳng hạn.
 
Upvote 0
Tôi muốn duyệt qua các phần tử của một xâu kí tự trong VBA nhưng không biết phải viết code ra sao(Không biết trong VBA có thể làm được không? Ngày xưa tôi học Pascal thì có) mong các anh(chị) giúp đỡ với ạ! Ví dụ tôi có File đính kèm. Trong File tôi có 2 chuỗi giờ tôi muốn viết câu lệnh để duyệt từ phần tử đầu tới phần tử cuối thì phải viết thế nào ạ? Ví dụ với xâu "Tôi yêu giaiphapexcel" nếu tôi muốn lấy các phần tử "Tôi yêu" thì code phải viết sao ạ?


duyệt từng ký tự đây

Mã:
for i=1 to len(vString)

     'xet tung ky tu theo Mid(vString,i,1)

next i
 
Upvote 0
Tôi muốn duyệt qua các phần tử của một xâu kí tự trong VBA nhưng không biết phải viết code ra sao(Không biết trong VBA có thể làm được không? Ngày xưa tôi học Pascal thì có) mong các anh(chị) giúp đỡ với ạ! Ví dụ tôi có File đính kèm. Trong File tôi có 2 chuỗi giờ tôi muốn viết câu lệnh để duyệt từ phần tử đầu tới phần tử cuối thì phải viết thế nào ạ? Ví dụ với xâu "Tôi yêu giaiphapexcel" nếu tôi muốn lấy các phần tử "Tôi yêu" thì code phải viết sao ạ?

Bạn đã từng học qua lập trình (Pascal?) rồi mà lại đặt một câu hỏi như thế này sao?

"duyệt qua các phần tử của một xâu kí tự trong VBA" không phải là giải đáp của
'xâu "Tôi yêu giaiphapexcel" nếu tôi muốn lấy các phần tử "Tôi yêu" thì code phải viết sao'

duyệt qua các ký tự thì dùng code bài số #3
còn tách "Tôi yêu" ra khỏi "Tôi yêu giaiphapexcel" thì trong VBA có cách khác. Tuỳ theo bạn xác định tách như thế nào (lấy 2 từ đầu, bỏ từ cuối, hay loại bỏ từ giaiphapexcel bất kỳ chỗ nào, hay lấy từ lý tự u trở về trước,... có cả trăm cách xác định tách)

Trong Pascal, ký tự là một kiểu dữ liệu căn bản, và chuỗi là một mảng ký tự.
Trong VBA, chuỗi là một kiểu dữ liệu có tính chất là một dãy ký tự. VBA có một đống hàm và phương thức để làm việc với loại dữ liệu này. Vì VBA không có kiểu dữ liệu ký tự cho nên chỉ có thể tạm xem chuỗi là một mảng ký tự, nhưng không thể coi như tương đương. Nói thẳng ra là chuỗi của VBA không có phần tử. Đối với mảng thì có thể dùng toán tử () để truy cập phần tử. Đối với chuỗi thì phải dùng hàm Mid để truy cập một nhóm chuỗi con.
 
Upvote 0
Bạn đã từng học qua lập trình (Pascal?) rồi mà lại đặt một câu hỏi như thế này sao?

"duyệt qua các phần tử của một xâu kí tự trong VBA" không phải là giải đáp của
'xâu "Tôi yêu giaiphapexcel" nếu tôi muốn lấy các phần tử "Tôi yêu" thì code phải viết sao'

duyệt qua các ký tự thì dùng code bài số #3
còn tách "Tôi yêu" ra khỏi "Tôi yêu giaiphapexcel" thì trong VBA có cách khác. Tuỳ theo bạn xác định tách như thế nào (lấy 2 từ đầu, bỏ từ cuối, hay loại bỏ từ giaiphapexcel bất kỳ chỗ nào, hay lấy từ lý tự u trở về trước,... có cả trăm cách xác định tách)

Trong Pascal, ký tự là một kiểu dữ liệu căn bản, và chuỗi là một mảng ký tự.
Trong VBA, chuỗi là một kiểu dữ liệu có tính chất là một dãy ký tự. VBA có một đống hàm và phương thức để làm việc với loại dữ liệu này. Vì VBA không có kiểu dữ liệu ký tự cho nên chỉ có thể tạm xem chuỗi là một mảng ký tự, nhưng không thể coi như tương đương. Nói thẳng ra là chuỗi của VBA không có phần tử. Đối với mảng thì có thể dùng toán tử () để truy cập phần tử. Đối với chuỗi thì phải dùng hàm Mid để truy cập một nhóm chuỗi con.
Cảm ơn bạn VietMini rất nhiều vì đã giải thích rất cặn kẽ! Thực ra tôi đang muốn làm bài tập về tách tên và tách số trong các cell ra khỏi chuỗi (tuy nhiên ở mỗi 1 cell các số ở các vị trí khác nhau, tuy nhiên các số tôi định tách có chiều dài bằng nhau là 10 ) ý tưởng của tôi là duyệt qua từng phần tử sau đó dùng hàm valhàm isnumber để kiểm tra nếu là số thì tôi sẽ gán chúng vào 1 chuỗi mới sau đó sẽ chuyển chuỗi mới này thành số? Không biết ý tưởng của tôi có thực hiện được không? Mong bạn giúp đỡ!
Ví dụ bạn xem File đính kèm!
Nếu không được mong nhận được ý tưởng khác từ bạn! Cảm ơn!
 

File đính kèm

Upvote 0
Cảm ơn bạn VietMini rất nhiều vì đã giải thích rất cặn kẽ! Thực ra tôi đang muốn làm bài tập về tách tên và tách số trong các cell ra khỏi chuỗi (tuy nhiên ở mỗi 1 cell các số ở các vị trí khác nhau, tuy nhiên các số tôi định tách có chiều dài bằng nhau là 10 ) ý tưởng của tôi là duyệt qua từng phần tử sau đó dùng hàm valhàm isnumber để kiểm tra nếu là số thì tôi sẽ gán chúng vào 1 chuỗi mới sau đó sẽ chuyển chuỗi mới này thành số? Không biết ý tưởng của tôi có thực hiện được không? Mong bạn giúp đỡ!
Ví dụ bạn xem File đính kèm!
Nếu không được mong nhận được ý tưởng khác từ bạn! Cảm ơn!
Thử cách không dùng Mid()
Cú pháp:
- Lấy tên : Tach( ô nào đó, 1)
- Lấy số : Tach( ô nào đó, số khác 1)
Mã:
Public Function Tach(DL, K)

With CreateObject("VBScript.RegExp")
If K = 1 Then
.Pattern = "\s[a-z].+"
Tach = Replace(DL, .Execute(DL)(0), "")
Else
.Pattern = ".+:\s*(\d+).+"
Tach = .Replace(DL & " ", "$1")
End If
End With

End Function
 
Upvote 0
Ý của bạn:
Phần tách số thì được. Vì bạn có xác định là chuỗi 10 ký tự số liên tiếp.
Phần tách tên thì không được. Vì bạn không có luật nào để xác định giới hạn của tên. Ví dụ chuỗi bắt đầu là "Trần Văn Lớp..." thì tên dừng ở Văn hay ở Lớp?

Tôi là chuyên viên về dữ liệu. Bất cứ cái gì không khả thi là tôi nhìn ra ngay.
 
Upvote 0
Thử cách không dùng Mid()
Cú pháp:
- Lấy tên : Tach( ô nào đó, 1)
- Lấy số : Tach( ô nào đó, số khác 1)
Mã:
Public Function Tach(DL, K)

With CreateObject("VBScript.RegExp")
If K = 1 Then
.Pattern = "\s[a-z].+"
Tach = Replace(DL, .Execute(DL)(0), "")
Else
.Pattern = ".+:\s*(\d+).+"
Tach = .Replace(DL & " ", "$1")
End If
End With

End Function
Rất tuyệt vời, cảm ơn bạn nhiều lắm!
 
Upvote 0
Ý của bạn:
Phần tách số thì được. Vì bạn có xác định là chuỗi 10 ký tự số liên tiếp.
Phần tách tên thì không được. Vì bạn không có luật nào để xác định giới hạn của tên. Ví dụ chuỗi bắt đầu là "Trần Văn Lớp..." thì tên dừng ở Văn hay ở Lớp?

Tôi là chuyên viên về dữ liệu. Bất cứ cái gì không khả thi là tôi nhìn ra ngay.
Phần tách số thế là được, còn phần tách tên tôi nghĩ nếu tên chỉ có 3 từ thì được, tôi sẽ đếm số khoảng trắng giữa các từ. Bởi vì đa số tên trong danh sách của tôi chỉ có 3 từ nếu có ít hoặc nhiều hơn 3 thì đúng là bó tay? Ở bài trên bạn gtri đã đưa ra 1 cách và đã giải quyết được nhưng cách này tôi không hiểu vì từ pascal chuyển sang vba vẫn chưa nắm hết được cú pháp cũng như những cái mới trong VBA. Nếu bạn VietMini có cách giải quyết nào bằng cách duyệt phần tử của xâu như của tôi thì giúp đỡ tôi với! Tạm thời dùng cách của bạn gtri rồi từ từ học để hiểu sau.
 
Upvote 0
Phần tách số thế là được, còn phần tách tên tôi nghĩ nếu tên chỉ có 3 từ thì được, tôi sẽ đếm số khoảng trắng giữa các từ. Bởi vì đa số tên trong danh sách của tôi chỉ có 3 từ nếu có ít hoặc nhiều hơn 3 thì đúng là bó tay? Ở bài trên bạn gtri đã đưa ra 1 cách và đã giải quyết được nhưng cách này tôi không hiểu vì từ pascal chuyển sang vba vẫn chưa nắm hết được cú pháp cũng như những cái mới trong VBA. Nếu bạn VietMini có cách giải quyết nào bằng cách duyệt phần tử của xâu như của tôi thì giúp đỡ tôi với! Tạm thời dùng cách của bạn gtri rồi từ từ học để hiểu sau.

Code trên nếu bạn nói là giải quyết được vấn đề của bạn thì bạn không cách nào hiểu nổi nó đâu. Vì nó không dựa vào điều kiện của bạn đã ra:

1. Tên: điều kiện của bạn là 3 từ đầu tiên. Code tìm mọi từ viết hoa để làm tên cho đến lúc gặp một từ bắt đầu bằng ký tự thường, không hoa.
Tức là bạn có 3 từ viết hoa thì nó lấy 3; 2 hay 4 thì nó lấy 2 hay 4.

2. Số: điều kiện của bạn là 10 ký tự số liên tiếp. Code lấy các ký tự số liên tiếp kể từ sau dâu ":", và nếu xuất hiện trên 1 lần thì lấy lần sau cùng. Tức là nếu bạn thêm ":" vào trước số 2 cuối cùng trong ô A3 thì sẽ thấy kết quả là 2

@gtri: hàm Replace của RegEx không bẫy lỗi cho nên nếu chuỗi không có ":" thì code của bạn sẽ trả về nguyên chuỗi.
 
Upvote 0
Code trên nếu bạn nói là giải quyết được vấn đề của bạn thì bạn không cách nào hiểu nổi nó đâu. Vì nó không dựa vào điều kiện của bạn đã ra:

1. Tên: điều kiện của bạn là 3 từ đầu tiên. Code tìm mọi từ viết hoa để làm tên cho đến lúc gặp một từ bắt đầu bằng ký tự thường, không hoa.
Tức là bạn có 3 từ viết hoa thì nó lấy 3; 2 hay 4 thì nó lấy 2 hay 4.

2. Số: điều kiện của bạn là 10 ký tự số liên tiếp. Code lấy các ký tự số liên tiếp kể từ sau dâu ":", và nếu xuất hiện trên 1 lần thì lấy lần sau cùng. Tức là nếu bạn thêm ":" vào trước số 2 cuối cùng trong ô A3 thì sẽ thấy kết quả là 2

@gtri: hàm Replace của RegEx không bẫy lỗi cho nên nếu chuỗi không có ":" thì code của bạn sẽ trả về nguyên chuỗi.
Tức là không thể giải quyết bài toán này bằng xâu đúng không bạn?
 
Upvote 0
Tức là không thể giải quyết bài toán này bằng xâu đúng không bạn?
Thêm một hàm tự tạo
Mã:
Public Function Tim(DL, K)
Dim Tam, c As Long, cl As Long

Tam = Split(DL, " ")

If K = 1 Then
For c = 0 To UBound(Tam)
If UCase(Mid(Tam(c), 1, 1)) = Mid(Tam(c), 1, 1) Then
Tim = Trim(Tim & " " & Tam(c))
Else
Exit For
End If
Next c

Else
For c = 1 To Len(DL) - 9
Tam = ""

For cl = c To c + 9
If IsNumeric(Mid(DL, cl, 1)) = True Then
Tam = Tam & Mid(DL, cl, 1)
End If
Next cl

If Len(Tam) = 10 Then
Tim = Tam
Exit For
End If

Next c
End If

End Function

- Cách tìm tên của bài 6 và bài này là giống như ý 1 của bài 10
- Dãy số tìm kiếm có chiều dài là 10 phần tử
 
Lần chỉnh sửa cuối:
Upvote 0
Thêm một hàm tự tạo
Mã:
Public Function Tim(DL, K)
Dim Tam, c As Long, cl As Long

Tam = Split(DL, " ")

If K = 1 Then
For c = 0 To UBound(Tam)
If UCase(Mid(Tam(c), 1, 1)) = Mid(Tam(c), 1, 1) Then
Tim = Trim(Tim & " " & Tam(c))
Else
Exit For
End If
Next c

Else
For c = 1 To Len(DL) - 9
Tam = ""

For cl = c To c + 9
If IsNumeric(Mid(DL, cl, 1)) = True Then
Tam = Tam & Mid(DL, cl, 1)
End If
Next cl

If Len(Tam) = 10 Then
Tim = Tam
Exit For
End If

Next c
End If

End Function

- Cách tìm tên của bài 6 và bài này là giống như ý 1 của bài 10
- Dãy số tìm kiếm có chiều dài là 10 phần tử
Thật tuyệt vời! Cảm ơn gtri nhiều lắm!
 
Upvote 0
@gtri:

Trong code trên, hai công đoạn tìm tên và tìm số hầu như biệt lập nhau. Vậy bạn tách nó ra thành 2 hàm có phải khoẻ, không phải thêm tham số thứ 2 !

Bạn chì gộp chung khi hai công đoạn có dính líu với nhau, hoặc dùng chung một đoạn code nào đó. Trong trường hợp này, chúng có thể dính líu với nhau ở chỗ bạn phải luôn luôn tìm tên, và bắt đầu tìm số sau tên.

@seikoqn:

Code thuần tuý duyệt chuỗi, như thế này:

Mã:
[COLOR=#008000]' lưu ý: bên trong code thay đổi trị tham số, cho nên phải dùng byVal
[/COLOR]Public Function TenVaSo(ByVal chuoi As String) As Variant
Const DODAI = 10 [COLOR=#008000]' độ dài bắt buộc của chuỗi số[/COLOR]
Dim tvs(1 To 2) As String
Dim i As Integer, j As Integer
Dim c1 As String, c2 As String [COLOR=#008000]' hai ký tự liên tiếp nhau[/COLOR]
[COLOR=#008000]' đầu tiên là tìm tên
[/COLOR]c1 = " " [COLOR=#008000]' ký tự đi trước[/COLOR]
For i = 1 To Len(chuoi) [COLOR=#008000]' vòng lặp tìm tên[/COLOR]
    c2 = Mid(chuoi, i, 1)
    If c1 = " " Then [COLOR=#008000]' c2 là ký tự đầu từ[/COLOR]
        If UCase(c2) <> c2 Then Exit For[COLOR=#008000] ' ký tự đầu từ không hoa, chấm dứt duyệt tên[/COLOR]
    End If
    c1 = c2
Next i
[COLOR=#008000]' khi dứt vòng lặp, i là chỉ số của ký tự đầu tiên không thuộc về tên
' như vậy i-1 là ký tự cuói cùng thuộc về tên (thực ra nó là một dấu cách)
[/COLOR]tvs(1) = Trim(Left(chuoi, i - 1))
[COLOR=#008000]' đoạn code sau đây tìm chuỗi số
[/COLOR]chuoi = Replace(chuoi, " ", "x") [COLOR=#008000]' vì dùng hàm isnumeric cho nên phải đổi dấu cách thành x để tránh nhầm lẫn[/COLOR]
Do While i <= Len(chuoi) - DODAI + 1
    j = i + DODAI - 1[COLOR=#008000] ' chỉ số của ký tự thứ 10[/COLOR]
    If IsNumeric(Mid(chuoi, j, 1)) Then [COLOR=#008000]' nếu ký tự thứ 10 là số thì mới xét tiếp[/COLOR]
        If IsNumeric(Mid(chuoi, i, j - i + 1)) Then
            tvs(2) = Mid(chuoi, i, j - i + 1) [COLOR=#008000]' đã tìm được một chuỗi[/COLOR]
            Exit Do [COLOR=#008000]' thoát ra luôn[/COLOR]
        End If
    Else[COLOR=#008000] ' nếu ký tự thứ 10 không phải là số thì nhảy vọt qua nó luôn cho nhanh[/COLOR]
        i = j
    End If
    i = i + 1
Loop
TenVaSo = tvs
End Function

Functiion trên có 2 cách sử dụng:

1. Để nguyên xi vây
Muốn lấy tên thì =TenVaSo(A2); muốn lấy số thì =INDEX(TenVaSo(A2),2)
Hoặc dùing nhập kết quả mảng, bôi đen cả B2:C2, gõ =TenVaSo(A2), và Ctrl+Shift+Enter

2. viết thêm 2 hàm phụ
function ten(byval chuoi) as string
ten = tenvaso(chuoi)(1)
end function
function so(byval chuoi) as string
so = tenvaso(chuoi)(2)
end function
 
Upvote 0
@gtri:

Trong code trên, hai công đoạn tìm tên và tìm số hầu như biệt lập nhau. Vậy bạn tách nó ra thành 2 hàm có phải khoẻ, không phải thêm tham số thứ 2 !

Bạn chì gộp chung khi hai công đoạn có dính líu với nhau, hoặc dùng chung một đoạn code nào đó. Trong trường hợp này, chúng có thể dính líu với nhau ở chỗ bạn phải luôn luôn tìm tên, và bắt đầu tìm số sau tên.

@seikoqn:

Code thuần tuý duyệt chuỗi, như thế này:

Mã:
[COLOR=#008000]' lưu ý: bên trong code thay đổi trị tham số, cho nên phải dùng byVal
[/COLOR]Public Function TenVaSo(ByVal chuoi As String) As Variant
Const DODAI = 10 [COLOR=#008000]' độ dài bắt buộc của chuỗi số[/COLOR]
Dim tvs(1 To 2) As String
Dim i As Integer, j As Integer
Dim c1 As String, c2 As String [COLOR=#008000]' hai ký tự liên tiếp nhau[/COLOR]
[COLOR=#008000]' đầu tiên là tìm tên
[/COLOR]c1 = " " [COLOR=#008000]' ký tự đi trước[/COLOR]
For i = 1 To Len(chuoi) [COLOR=#008000]' vòng lặp tìm tên[/COLOR]
    c2 = Mid(chuoi, i, 1)
    If c1 = " " Then [COLOR=#008000]' c2 là ký tự đầu từ[/COLOR]
        If UCase(c2) <> c2 Then Exit For[COLOR=#008000] ' ký tự đầu từ không hoa, chấm dứt duyệt tên[/COLOR]
    End If
    c1 = c2
Next i
[COLOR=#008000]' khi dứt vòng lặp, i là chỉ số của ký tự đầu tiên không thuộc về tên
' như vậy i-1 là ký tự cuói cùng thuộc về tên (thực ra nó là một dấu cách)
[/COLOR]tvs(1) = Trim(Left(chuoi, i - 1))
[COLOR=#008000]' đoạn code sau đây tìm chuỗi số
[/COLOR]chuoi = Replace(chuoi, " ", "x") [COLOR=#008000]' vì dùng hàm isnumeric cho nên phải đổi dấu cách thành x để tránh nhầm lẫn[/COLOR]
Do While i <= Len(chuoi) - DODAI + 1
    j = i + DODAI - 1[COLOR=#008000] ' chỉ số của ký tự thứ 10[/COLOR]
    If IsNumeric(Mid(chuoi, j, 1)) Then [COLOR=#008000]' nếu ký tự thứ 10 là số thì mới xét tiếp[/COLOR]
        If IsNumeric(Mid(chuoi, i, j - i + 1)) Then
            tvs(2) = Mid(chuoi, i, j - i + 1) [COLOR=#008000]' đã tìm được một chuỗi[/COLOR]
            Exit Do [COLOR=#008000]' thoát ra luôn[/COLOR]
        End If
    Else[COLOR=#008000] ' nếu ký tự thứ 10 không phải là số thì nhảy vọt qua nó luôn cho nhanh[/COLOR]
        i = j
    End If
    i = i + 1
Loop
TenVaSo = tvs
End Function

Functiion trên có 2 cách sử dụng:

1. Để nguyên xi vây
Muốn lấy tên thì =TenVaSo(A2); muốn lấy số thì =INDEX(TenVaSo(A2),2)
Hoặc dùing nhập kết quả mảng, bôi đen cả B2:C2, gõ =TenVaSo(A2), và Ctrl+Shift+Enter

2. viết thêm 2 hàm phụ
function ten(byval chuoi) as string
ten = tenvaso(chuoi)(1)
end function
function so(byval chuoi) as string
so = tenvaso(chuoi)(2)
end function
Cảm ơn bạn VetMiNi nhiều lắm. Rất tuyệt vời. Bài toán đã được giải quyết mà thuật toán này tôi cũng đã hiểu vì chú thích rất rõ ràng.
 
Upvote 0
@gtri:

Trong code trên, hai công đoạn tìm tên và tìm số hầu như biệt lập nhau. Vậy bạn tách nó ra thành 2 hàm có phải khoẻ, không phải thêm tham số thứ 2 !

Bạn chì gộp chung khi hai công đoạn có dính líu với nhau, hoặc dùng chung một đoạn code nào đó. Trong trường hợp này, chúng có thể dính líu với nhau ở chỗ bạn phải luôn luôn tìm tên, và bắt đầu tìm số sau tên.

@seikoqn:

Code thuần tuý duyệt chuỗi, như thế này:

Mã:
[COLOR=#008000]' lưu ý: bên trong code thay đổi trị tham số, cho nên phải dùng byVal
[/COLOR]Public Function TenVaSo(ByVal chuoi As String) As Variant
Const DODAI = 10 [COLOR=#008000]' độ dài bắt buộc của chuỗi số[/COLOR]
Dim tvs(1 To 2) As String
Dim i As Integer, j As Integer
Dim c1 As String, c2 As String [COLOR=#008000]' hai ký tự liên tiếp nhau[/COLOR]
[COLOR=#008000]' đầu tiên là tìm tên
[/COLOR]c1 = " " [COLOR=#008000]' ký tự đi trước[/COLOR]
For i = 1 To Len(chuoi) [COLOR=#008000]' vòng lặp tìm tên[/COLOR]
    c2 = Mid(chuoi, i, 1)
    If c1 = " " Then [COLOR=#008000]' c2 là ký tự đầu từ[/COLOR]
        If UCase(c2) <> c2 Then Exit For[COLOR=#008000] ' ký tự đầu từ không hoa, chấm dứt duyệt tên[/COLOR]
    End If
    c1 = c2
Next i
[COLOR=#008000]' khi dứt vòng lặp, i là chỉ số của ký tự đầu tiên không thuộc về tên
' như vậy i-1 là ký tự cuói cùng thuộc về tên (thực ra nó là một dấu cách)
[/COLOR]tvs(1) = Trim(Left(chuoi, i - 1))
[COLOR=#008000]' đoạn code sau đây tìm chuỗi số
[/COLOR]chuoi = Replace(chuoi, " ", "x") [COLOR=#008000]' vì dùng hàm isnumeric cho nên phải đổi dấu cách thành x để tránh nhầm lẫn[/COLOR]
Do While i <= Len(chuoi) - DODAI + 1
    j = i + DODAI - 1[COLOR=#008000] ' chỉ số của ký tự thứ 10[/COLOR]
    If IsNumeric(Mid(chuoi, j, 1)) Then [COLOR=#008000]' nếu ký tự thứ 10 là số thì mới xét tiếp[/COLOR]
        If IsNumeric(Mid(chuoi, i, j - i + 1)) Then
            tvs(2) = Mid(chuoi, i, j - i + 1) [COLOR=#008000]' đã tìm được một chuỗi[/COLOR]
            Exit Do [COLOR=#008000]' thoát ra luôn[/COLOR]
        End If
    Else[COLOR=#008000] ' nếu ký tự thứ 10 không phải là số thì nhảy vọt qua nó luôn cho nhanh[/COLOR]
        i = j
    End If
    i = i + 1
Loop
TenVaSo = tvs
End Function

Functiion trên có 2 cách sử dụng:

1. Để nguyên xi vây
Muốn lấy tên thì =TenVaSo(A2); muốn lấy số thì =INDEX(TenVaSo(A2),2)
Hoặc dùing nhập kết quả mảng, bôi đen cả B2:C2, gõ =TenVaSo(A2), và Ctrl+Shift+Enter

2. viết thêm 2 hàm phụ
function ten(byval chuoi) as string
ten = tenvaso(chuoi)(1)
end function
function so(byval chuoi) as string
so = tenvaso(chuoi)(2)
end function


Chào bạn, cho mình hỏi vấn đề này giả như mình có chuỗi tên như là: Duy & Đức & Hùng có cách nào để lấy từng tên ra đc ko ạ?
 
Upvote 0
Chào bạn, cho mình hỏi vấn đề này giả như mình có chuỗi tên như là: Duy & Đức & Hùng có cách nào để lấy từng tên ra đc ko ạ?

Chào dungnvps,

Bạn thử 2 cách sau:
Cách 1: Dùng chức năng Text to Columns.
Cách 2: Dùng hàm sau.
Mã:
Function ten(strg As String) As Variant
ten = Split(strg, "&")
End Function
Giả sử A2="Duy & Đức & Hùng"
Công thức:
Mã:
B2=TRIM(INDEX(ten(A2),1))
C2=TRIM(INDEX(ten(A2),2))
D2=TRIM(INDEX(ten(A2),3))
Hoặc chọn B2:D2 rồi gõ =TRIM(ten(A2)) rồi ctrl + shift + enter.
 
Upvote 0
Chào dungnvps,

Bạn thử 2 cách sau:
Cách 1: Dùng chức năng Text to Columns.
Cách 2: Dùng hàm sau.
Mã:
Function ten(strg As String) As Variant
ten = Split(strg, "&")
End Function
Giả sử A2="Duy & Đức & Hùng"
Công thức:
Mã:
B2=TRIM(INDEX(ten(A2),1))
C2=TRIM(INDEX(ten(A2),2))
D2=TRIM(INDEX(ten(A2),3))
Hoặc chọn B2:D2 rồi gõ =TRIM(ten(A2)) rồi ctrl + shift + enter.

Vâng, cám ơn bạn rất nhiều!!
 
Upvote 0
Web KT

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

Back
Top Bottom