Cách chuyển chuỗi thành mảng

Liên hệ QC

Lucky070765

Thành viên mới
Tham gia
25/11/11
Bài viết
3
Được thích
0
Tôi mới học VBA nên cũng chưa biết nhiều. Tôi có một vấn đề nhờ các anh chị em trong diễn đàn giúp.
Giả sử tôi có chuỗi s="Diễn đàn Giải Pháp Excel", bây giờ tôi muốn tạo một mảng chuỗi mà mỗi phần tử là một ký tự của chuỗi s thì phải code làm sao. Mục đích của tôi là để duyệt qua từng ký tự của chuỗi mà không cần dùng hàm Mid(s, i, j)
 
Tôi mới học VBA nên cũng chưa biết nhiều. Tôi có một vấn đề nhờ các anh chị em trong diễn đàn giúp.
Giả sử tôi có chuỗi s="Diễn đàn Giải Pháp Excel", bây giờ tôi muốn tạo một mảng chuỗi mà mỗi phần tử là một ký tự của chuỗi s thì phải code làm sao. Mục đích của tôi là để duyệt qua từng ký tự của chuỗi mà không cần dùng hàm Mid(s, i, j)
Dùng hàm này:
PHP:
Function StringToArray(ByVal Text As String)
  Dim Tmp As String
  If Trim(Text) = "" Then StringToArray = "": Exit Function
  With CreateObject("VBScript.RegExp")
    .Global = True: .Pattern = ""
    Tmp = Replace(Trim(.Replace(Text, " ")), "  ", " ")
  End With
  StringToArray = Split(Tmp, " ")
End Function
Áp dụng:
=StringToArray("Diễn đàn Giải Pháp Excel") sẽ cho kết quả là 1 mảng với các phần tử là những ký tự của chuổi trên
-----------------
Mà tôi thắc mắc: Bạn quét từng ký tự, dùng hàm MID cũng có vấn đề gì đâu chứ
 
Upvote 0
Dùng hàm này:
PHP:
Function StringToArray(ByVal Text As String)
  Dim Tmp As String
  If Trim(Text) = "" Then StringToArray = "": Exit Function
  With CreateObject("VBScript.RegExp")
    .Global = True: .Pattern = ""
    Tmp = Replace(Trim(.Replace(Text, " ")), "  ", " ")
  End With
  StringToArray = Split(Tmp, " ")
End Function
Áp dụng:
=StringToArray("Diễn đàn Giải Pháp Excel") sẽ cho kết quả là 1 mảng với các phần tử là những ký tự của chuổi trên
-----------------
Mà tôi thắc mắc: Bạn quét từng ký tự, dùng hàm MID cũng có vấn đề gì đâu chứ
Xin cám ơn bạn. Chỉ là tôi tìm tòi và học tập.
 
Upvote 0
Dùng hàm này:
PHP:
Function StringToArray(ByVal Text As String)
  Dim Tmp As String
  If Trim(Text) = "" Then StringToArray = "": Exit Function
  With CreateObject("VBScript.RegExp")
    .Global = True: .Pattern = ""
    Tmp = Replace(Trim(.Replace(Text, " ")), "  ", " ")
  End With
  StringToArray = Split(Tmp, " ")
End Function
Áp dụng:
=StringToArray("Diễn đàn Giải Pháp Excel") sẽ cho kết quả là 1 mảng với các phần tử là những ký tự của chuổi trên
-----------------
Mà tôi thắc mắc: Bạn quét từng ký tự, dùng hàm MID cũng có vấn đề gì đâu chứ
Ví dụ em có mảng sau

Arr(1,2)=789
Arr(2,2)=789
Arr(3,2)=8,9,10,11,12

Cho em hỏi ứng dụng hàm của thầy thì sẽ viết thế nào để ra kết quả mảng như sau trong VBA:

Result(1,1)=7
Result(1,2)=8
Result(1,3)=9

Result(2,1)=7
Result(2,2)=8
Result(2,3)=9

Result(3,1)=8
Result(3,2)=9
Result(3,3)=10
Result(3,4)=11
Result(3,5)=12
 
Upvote 0
Ví dụ em có mảng sau

Arr(1,2)=789
Arr(2,2)=789
Arr(3,2)=8,9,10,11,12

Cho em hỏi ứng dụng hàm của thầy thì sẽ viết thế nào để ra kết quả mảng như sau trong VBA:

Result(1,1)=7
Result(1,2)=8
Result(1,3)=9

Result(2,1)=7
Result(2,2)=8
Result(2,3)=9

Result(3,1)=8
Result(3,2)=9
Result(3,3)=10
Result(3,4)=11
Result(3,5)=12
Bạn nên dùng Collection, kiểu nó thế này
1583307180144.png
 
Upvote 0
Bài này đã hơn 8 năm rồi. Lúc đó người viết code chắc muốn biểu diễn regex nên mới làm phức tạp vậy.
Bài này làm cho giản dị là dùng hàm StrConv và Split.
 
Upvote 0
À bác nhắc em mới để ý tại thấy bạn hỏi tiếp, nên em cũng đào mộ theo.
Ở bài #4 bạn ấy hỏi về mảng 2 chiều. Lý do cần thiết là ở diễn đàn này có lệ code dữ liệu theo mảng 2 chiều để tiện việc copy thẳng cả mảng vào worksheet range.
Collection có làm được thao tác "copy thẳng" như thế không?
 
Upvote 0
Cho em hỏi ứng dụng hàm của thầy thì sẽ viết thế nào để ra kết quả mảng như sau trong VBA:
---------------------------


Hàm của Thầy ndu sẽ chậm vì mất thời gian CreateObject.

Năm nay 2020 rồi thì dùng hàm này này.

-------------------
PHP:
Public Function SplitString(ByVal Expression As String, Optional ByVal delimeter As String = " ", Optional ByVal Limit As Long = -1, Optional ByVal Compare As VbCompareMethod = vbBinaryCompare) As String()
  If delimeter = VBA.vbNullChar Or delimeter = VBA.vbNullString Then
    Expression = VBA.StrConv(Expression, VBA.vbUnicode)
    Expression = VBA.Left(Expression, Len(Expression) - 1)
  End If
  SplitString = VBA.Split(Expression, delimeter, Limit, Compare)
End Function
--------------------


Muốn ra mảng như vậy thì vận dụng Redim Preserve


-------------------

PHP:
Public Function SplitStringToNewArray(ByVal InputArray, Optional ByVal delimeter As String = ",", Optional ByVal Limit As Long = -1)
  On Error Resume Next
  Dim SP$(), K As Long, I As Long, J As Long, Max As Long, cSP As Long
  Dim Result(), Arr As Variant
  Arr = InputArray
  For I = 1 To UBound(Arr) - LBound(Arr) + 1
    SP = SplitString(Arr(I - 1), VBA.IIf(Arr(I - 1) Like "*" & delimeter & "*", delimeter, ""), Limit)
    cSP = UBound(SP) + 1
    If VBA.err.Number = 0 Then
      If cSP > Max Then
        ReDim Preserve Result(1 To UBound(Arr) - LBound(Arr) + 1, 1 To cSP)
        Max = cSP
      End If
      For J = 1 To cSP
        Result(I, J) = SP(J - 1)
      Next
    Else
      VBA.err.Clear
    End If
  Next
  SplitStringToNewArray = Result
  On Error GoTo 0
End Function
 
Lần chỉnh sửa cuối:
Upvote 0
---------------------------


Hàm của Thầy ndu sẽ chậm vì mất thời gian CreateObject.

Năm nay 2020 rồi thì dùng hàm này này.

-------------------
PHP:
Public Function SplitString(ByVal Expression As String, Optional ByVal delimeter As String = " ", Optional ByVal Limit As Long = -1, Optional ByVal Compare As VbCompareMethod = vbBinaryCompare) As String()
  If delimeter = VBA.vbNullChar Or delimeter = VBA.vbNullString Then
    Expression = VBA.StrConv(Expression, VBA.vbUnicode)
    Expression = VBA.Left(Expression, Len(Expression) - 1)
  End If
  SplitString = VBA.Split(Expression, delimeter, Limit, Compare)
End Function
--------------------


Muốn ra mảng như vậy thì vận dụng Redim Preserve


-------------------

PHP:
Public Function SplitStringToNewArray(ByVal InputArray, Optional ByVal delimeter As String = ",", Optional ByVal Limit As Long = -1)
  On Error Resume Next
  Dim SP$(), K As Long, I As Long, J As Long, Max As Long, cSP As Long
  Dim Result(), Arr As Variant
  Arr = InputArray
  For I = 1 To UBound(Arr) - LBound(Arr) + 1
    SP = SplitString(Arr(I - 1), VBA.IIf(Arr(I - 1) Like "*" & delimeter & "*", delimeter, ""), Limit)
    cSP = UBound(SP) + 1
    If VBA.err.Number = 0 Then
      If cSP > Max Then
        ReDim Preserve Result(1 To UBound(Arr) - LBound(Arr) + 1, 1 To cSP)
        Max = cSP
      End If
      For J = 1 To cSP
        Result(I, J) = SP(J - 1)
      Next
    Else
      VBA.err.Clear
    End If
  Next
  SplitStringToNewArray = Result
  On Error GoTo 0
End Function
Cảm ơn bạn, để mình thử.

Phiền bạn thử vận dụng với file đính kèm giúp mình nhé. Mình đã thêm hai Function trên và viết code vận dụng Function mà không xong.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Phiền bạn thử vận dụng với file đính kèm giúp mình nhé. Mình đã thêm hai Function trên và viết code vận dụng Function mà không xong.
------------------

Mảng nhập vào hàm phải là Array một chiều nhé bạn.

Arr(1 to 3, 1 to 1) thì chuyển sang mảng một chiều bằng cách vận dụng:

Arr1D = Application.Index(Application.Transpose(Arr), 1, 0)
 
Upvote 0
------------------

Mảng nhập vào hàm phải là Array một chiều nhé bạn.

Arr(1 to 3, 1 to 1) thì chuyển sang mảng một chiều bằng cách vận dụng:

Arr1D = Application.Index(Application.Transpose(Arr), 1, 0)
Mình không hiểu về vận dụng những Function dạng cao này, bạn có thể chỉ giúp mình code hoàn chỉnh được không?

Mã:
Sub Test()
Dim Arr(), Arr1D(), i As Long
Arr = Sheet1.Range("B3:B6").Value
For i = 1 To 3
    Arr1D = Application.Index(Application.Transpose(Arr(i,1)), 1, 0)
    SplitStringToNewArray (Arr1D)
Next i
End Sub
 
Upvote 0
Mình không hiểu về vận dụng những Function dạng cao này, bạn có thể chỉ giúp mình code hoàn chỉnh được không?
-------------


Không có hàm dạng cao nào cả. Do bạn không biết nhiều về VBA căn bản.


-------------
PHP:
Sub Test()

''Application.Index Lấy ra mảng theo chiều ngang của mảng đa chiều
''Application.Transpose chuyển đổi chiều của mảng 1 và 2 chiều
   
Dim Arr As Variant
''Array 2 chiều - dọc thành ngang
Arr = Sheet1.Range("B3:B6").Value
Arr = Application.Index(Application.Transpose(Arr), 1, 0)
Arr = SplitStringToNewArray (Arr)
   
''Array 2 chiều - ngang
Arr = Sheet1.Range("A1:C1").Value
Arr = Application.Index(Arr, 1, 0)
Arr = SplitStringToNewArray (Arr)
   
''Array 1 chiều - ngang
Arr = Array(789,789, "7,8,9,10,11,12")
Arr = SplitStringToNewArray (Arr)  
   
''Array 1 chiều - ngang
Arr = [{789,789, "7,8,9,10,11,12"}]
Arr = SplitStringToNewArray (Arr)  
End Sub
 
Upvote 0
PHP:
Sub Test()

''Application.Index Lấy ra mảng theo chiều ngang của mảng đa chiều
''Application.Transpose chuyển đổi chiều của mảng 1 và 2 chiều

Dim Arr As Variant
''Array 2 chiều - dọc thành ngang
Arr = Sheet1.Range("B3:B6").Value
Arr = Application.Index(Application.Transpose(Arr), 1, 0)
Arr = SplitStringToNewArray (Arr)

End Sub
Cảm ơn bạn rất nhiều! Đúng là mình không biết nhiều về căn bản, trước nay mình chỉ vận dụng code mẫu mình hiểu vào bài toán thực tế của mình. Đôi khi thấy cũng thật chật vật khi thuốc có rồi mà không biết cách sử dụng.

Ở đoạn code này khi mình sử dụng và gán giá trị từ ô E2 nhưng tại sao dòng 2 lại là dữ liệu rỗng nhỉ bạn?
Bài này mục đích của mình là mình có dữ liệu tại cột B muốn chuyển đổi thành mảng, sau đó mảng này kết hợp với dữ liệu tại cột A bắt đầu từ dòng 3. Nhưng khi sử dụng vòng lặp for bắt đầu từ 1 thì dữ liệu không như mong muốn. Đúng của nó thì dữ liệu A3 sẽ được kết hợp với B3 nhưng vì dữ liệu Arr tại dòng 1 là rỗng dẫn đến hai dữ liệu không ăn khớp nhau mặc dù có chỉ số dòng bắt đầu như nhau, giống như đôi đũa cùng chiều dài cùng đặt tại một điểm nhưng khi chạy code thì thành đôi đũa lệch.
 
Lần chỉnh sửa cuối:
Upvote 0
Không phải do căn bản đâu. Tôi còn không hiểu huống hồ gì bạn.
Về việc sử dụng một hàm thì thường người viết hàm sẽ có dòng chỉ dẫn, giải thích cách nạp tham số, trừ phi chúng rất đơn giản.
Tên hàm là SplitStringTo... mà tham số là array thì chỉ thánh mới hiểu.
 
Upvote 0
Không phải do căn bản đâu. Tôi còn không hiểu huống hồ gì bạn.
Về việc sử dụng một hàm thì thường người viết hàm sẽ có dòng chỉ dẫn, giải thích cách nạp tham số, trừ phi chúng rất đơn giản.
Tên hàm là SplitStringTo... mà tham số là array thì chỉ thánh mới hiểu.
Trong bài toán thực tế thì em viết code như này là xử lý xong vấn đề (Tạo mảng Data sao cho dư ra 1 dòng đầu để hết lệch), nhưng em đang không hiểu tại sao mảng Arr chỉ số đầu tiên lại là rỗng

Mã:
    With Sheets("MAIN")
        R = .Range("AO6500").End(xlUp).Row - 3
        Arr = .Range("AP5").Resize(R, 1).Value
        Arr = Application.Index(Application.Transpose(Arr), 1, 0)
        Arr = SplitStringToNewArray(Arr)
        Data = .Range("AO4").Resize(R, 1).Value
        For i = 1 To UBound(Data, 1)
            For j = 1 To UBound(Arr, 2)
                If Arr(i, j) > 0 Then
                    Tem = Data(i, 1) & Arr(i, j)
                    If Not Dic.Exists(Tem) Then
                        k = k + 1
                        Dic.Add Tem, k
                    End If
                End If
            Next j
        Next i
    End With
 
Upvote 0
Tôi có nói là tôi không hiểu mà. Không hiểu lấy gì giải thích.
Không phải do căn bản đâu. Tôi còn không hiểu ...

Lưu ý là tôi không hề nói code đúng sai. Tôi chỉ nói là với người bình thường thì code khó dùng. Túm lại, phần chỉ dẫn cách sử dụng không theo kịp độ cao siêu của code.
 
Upvote 0
Vì sao đặt "NewArray" mà ko phải là "Array"?

Có những con người không đủ hiểu biết mới dư lời "phò phán".

"Xem lại con người mình có đủ trình phán không đã"
 
Upvote 0
SplitStringTo... thì hiểu cái túc tự (Input) của hành động Split là String. VBA chứ có phải là C đâu mà bắt người ta phải tự hiểu String là Array.
To... cái gì thì nói sau.

Trình độ tiếng Anh như vậy chỉ đủ để đọc mấy cái tài liệu gú gồ được thôi. Muốn dùng tên tiếng Anh thì cần trình độ viết Anh ngữ, cách sử dụng trạng từ, tĩnh từ, và phần khó nhất là giới từ.
 
Upvote 0
Trong bài toán thực tế thì em viết code như này là xử lý xong vấn đề (Tạo mảng Data sao cho dư ra 1 dòng đầu để hết lệch), nhưng em đang không hiểu tại sao mảng Arr chỉ số đầu tiên lại là rỗng

------------

Arr = .Range("AP5").Resize(R, 1).Value
Data = .Range("AO4").Resize(R, 1).Value

Để tránh không gặp lỗi này nên viết là:

Const START_ROW = 5
If R < START_ROW Then Exit Sub
Arr = .Range("AP" & START_ROW ).Resize(R, 1).Value
Data = .Range("AO" & START_ROW).Resize(R, 1).Value
 
Upvote 0
Web KT

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

Back
Top Bottom