Vấn đề sắp xếp hàng trong mảng

Liên hệ QC

Hoàng Trọng Nghĩa

Chuyên gia GPE
Thành viên BQT
Moderator
Tham gia
17/8/08
Bài viết
8,662
Được thích
16,720
Giới tính
Nam
Tôi có 1 thủ tục lọc hàng có điều kiện trong mảng:

Mã:
Private Sub CommandButton1_Click()
    Dim MyArr1, MyArr2, MyItem As Long, MyRow As Long
        LocKhachHang.[A:I].ClearContents
        MyArr1 = KhachHang.Range("B5", KhachHang.[B65536].End(xlUp)).Resize(, 15).Value
        MyRow = UBound(MyArr1, 1)
        ReDim MyArr2(1 To MyRow, 1 To 9)
            [COLOR=#006400]'Giữ tiêu đề ở hàng đầu tiên:[/COLOR]
            MyArr2(1, 1) = MyArr1(1, 1)
            MyArr2(1, 2) = MyArr1(1, 2)
            MyArr2(1, 3) = MyArr1(1, 4)
            MyArr2(1, 4) = MyArr1(1, 5)
            MyArr2(1, 5) = MyArr1(1, 6)
            MyArr2(1, 6) = MyArr1(1, 11)
            MyArr2(1, 7) = MyArr1(1, 8)
            MyArr2(1, 8) = MyArr1(1, 9)
            MyArr2(1, 9) = MyArr1(1, 10)
    For MyItem = 2 To MyRow - 1
       [COLOR=#006400] 'Chuyển dữ liệu từ dưới lên trên:[/COLOR]
        If MyArr1(MyRow + 1 - MyItem, 1) <> "" And MyArr1(MyRow + 1 - MyItem, 15) <> "Thanh Lý" Then
            MyArr2(MyItem, 1) = MyArr1(MyRow + 1 - MyItem, 1)
            MyArr2(MyItem, 2) = MyArr1(MyRow + 1 - MyItem, 2)
            MyArr2(MyItem, 3) = MyArr1(MyRow + 1 - MyItem, 4)
            MyArr2(MyItem, 4) = MyArr1(MyRow + 1 - MyItem, 5)
            MyArr2(MyItem, 5) = MyArr1(MyRow + 1 - MyItem, 6)
            MyArr2(MyItem, 6) = MyArr1(MyRow + 1 - MyItem, 11)
            MyArr2(MyItem, 7) = MyArr1(MyRow + 1 - MyItem, 8)
            MyArr2(MyItem, 8) = MyArr1(MyRow + 1 - MyItem, 9)
            MyArr2(MyItem, 9) = MyArr1(MyRow + 1 - MyItem, 10)
        End If
    Next
    If IsArray(MyArr2) Then LocKhachHang.[A1].Resize(UBound(MyArr2, 1), 9).Value = MyArr2
End Sub

Xin vui lòng cho hỏi các vấn đề sau:

1) Sau khi chạy thủ tục, tại sheet LOC_KH có bị trống 1 số hàng (màu vàng) do lọc theo điều kiện, Vậy làm sao để nó dồn lên trên để không bị trống nữa?

2) Code có thể rút gọn được không?

Xin cám ơn rất nhiều!
 

File đính kèm

Tôi có 1 thủ tục lọc hàng có điều kiện trong mảng:

Mã:
Private Sub CommandButton1_Click()
    Dim MyArr1, MyArr2, MyItem As Long, MyRow As Long
        LocKhachHang.[A:I].ClearContents
        MyArr1 = KhachHang.Range("B5", KhachHang.[B65536].End(xlUp)).Resize(, 15).Value
        MyRow = UBound(MyArr1, 1)
        ReDim MyArr2(1 To MyRow, 1 To 9)
            [COLOR=#006400]'Giữ tiêu đề ở hàng đầu tiên:[/COLOR]
            MyArr2(1, 1) = MyArr1(1, 1)
            MyArr2(1, 2) = MyArr1(1, 2)
            MyArr2(1, 3) = MyArr1(1, 4)
            MyArr2(1, 4) = MyArr1(1, 5)
            MyArr2(1, 5) = MyArr1(1, 6)
            MyArr2(1, 6) = MyArr1(1, 11)
            MyArr2(1, 7) = MyArr1(1, 8)
            MyArr2(1, 8) = MyArr1(1, 9)
            MyArr2(1, 9) = MyArr1(1, 10)
    For MyItem = 2 To MyRow - 1
       [COLOR=#006400]'Chuyển dữ liệu từ dưới lên trên:[/COLOR]
        If MyArr1(MyRow + 1 - MyItem, 1) <> "" And MyArr1(MyRow + 1 - MyItem, 15) <> "Thanh Lý" Then
            MyArr2(MyItem, 1) = MyArr1(MyRow + 1 - MyItem, 1)
            MyArr2(MyItem, 2) = MyArr1(MyRow + 1 - MyItem, 2)
            MyArr2(MyItem, 3) = MyArr1(MyRow + 1 - MyItem, 4)
            MyArr2(MyItem, 4) = MyArr1(MyRow + 1 - MyItem, 5)
            MyArr2(MyItem, 5) = MyArr1(MyRow + 1 - MyItem, 6)
            MyArr2(MyItem, 6) = MyArr1(MyRow + 1 - MyItem, 11)
            MyArr2(MyItem, 7) = MyArr1(MyRow + 1 - MyItem, 8)
            MyArr2(MyItem, 8) = MyArr1(MyRow + 1 - MyItem, 9)
            MyArr2(MyItem, 9) = MyArr1(MyRow + 1 - MyItem, 10)
        End If
    Next
    If IsArray(MyArr2) Then LocKhachHang.[A1].Resize(UBound(MyArr2, 1), 9).Value = MyArr2
End Sub

Xin vui lòng cho hỏi các vấn đề sau:

1) Sau khi chạy thủ tục, tại sheet LOC_KH có bị trống 1 số hàng (màu vàng) do lọc theo điều kiện, Vậy làm sao để nó dồn lên trên để không bị trống nữa?

2) Code có thể rút gọn được không?

Xin cám ơn rất nhiều!
- Thêm 1 biến K, khi nào thỏa lấy biến K làm thứ tự của mảng kết quả
- Lấy từ dưới lên thì cứ cho biến chạy từ .....dưới lên, khai báo chi "dzắc dzối" quá
Chạy thử code này:
Mã:
Public Sub RacRoi()
Dim Vung, Mg(), I, K
        LocKhachHang.[A:I].ClearContents: K = 1
        Vung = KhachHang.Range("B5", KhachHang.[B65536].End(xlUp)).Resize(, 15).Value
        ReDim Mg(1 To UBound(Vung), 1 To 9)
            'Giu tieu de o hang dau tien:
            Mg(1, 1) = Vung(1, 1)
            Mg(1, 2) = Vung(1, 2)
            Mg(1, 3) = Vung(1, 4)
            Mg(1, 4) = Vung(1, 5)
            Mg(1, 5) = Vung(1, 6)
            Mg(1, 6) = Vung(1, 11)
            Mg(1, 7) = Vung(1, 8)
            Mg(1, 8) = Vung(1, 9)
            Mg(1, 9) = Vung(1, 10)
    For I = UBound(Vung) To 2 Step -1
        'Chuyen du lieu tu duoi len tren (moi o tren cu o duoi):
        If Vung(I, 1) <> "" And Vung(I, 15) <> "Thanh Lý" Then
          K = K + 1
            Mg(K, 1) = Vung(I, 1)
            Mg(K, 2) = Vung(I, 2)
            Mg(K, 3) = Vung(I, 4)
            Mg(K, 4) = Vung(I, 5)
            Mg(K, 5) = Vung(I, 6)
            Mg(K, 6) = Vung(I, 11)
            Mg(K, 7) = Vung(I, 8)
            Mg(K, 8) = Vung(I, 9)
            Mg(K, 9) = Vung(I, 10)
        End If
    Next
    LocKhachHang.[A1].Resize(UBound(Mg), 9).Value = Mg
End Sub
Mình không biết cách rút gọn nữa
Híc
 
Upvote 0
- Thêm 1 biến K, khi nào thỏa lấy biến K làm thứ tự của mảng kết quả
- Lấy từ dưới lên thì cứ cho biến chạy từ .....dưới lên, khai báo chi "dzắc dzối" quá
Chạy thử code này:
Mã:
[SIZE=3][COLOR=#ff0000][B]Public Sub RacRoi[/B][/COLOR][/SIZE]()
..........................................
Mình không biết cách rút gọn nữa
Híc

Kakaka, đúng là trả lời kiểu CÒ! Trời ơi, tại không chịu suy nghĩ nè! Cám ơn bác concogia nhiều nhé!
 
Upvote 0
Thử cái này để rút gọn xem, chỉ rút gọn code, không nói gì đến thuật toán:


PHP:
Sub RacRoi() 
Dim Vung, Mg(), I, K
         LocKhachHang.[A:I].ClearContents: K = 1
         Vung = KhachHang.Range("B5", KhachHang.[B65536].End(xlUp)).Resize(, 15).Value
         ReDim Mg(1 To UBound(Vung), 1 To 9)
        List1 = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
        List2 = Array(1, 2, 4, 5, 6, 11, 8, 9, 10)
        For i = 1 to 9
             Mg(1, List1(i)) = Vung(1, List2(i))
        Next
    For I = UBound(Vung) To 2 Step -1
         'Chuyen du lieu tu duoi len tren (moi o tren cu o duoi):
         If Vung(I, 1) <> "" And Vung(I, 15) <> "Thanh Lý" Then
           K = K + 1
           For j = 1 to 9
             Mg(K, List1(j)) = Vung(I, List2(j))
          Next
         End If
     Next     
LocKhachHang.[A1].Resize(UBound(Mg), 9).Value = Mg 
End Sub
 
Upvote 0
Thử cái này để rút gọn xem, chỉ rút gọn code, không nói gì đến thuật toán:


PHP:
Sub RacRoi() 
Dim Vung, Mg(), I, K
         LocKhachHang.[A:I].ClearContents: K = 1
         Vung = KhachHang.Range("B5", KhachHang.[B65536].End(xlUp)).Resize(, 15).Value
         ReDim Mg(1 To UBound(Vung), 1 To 9)
        List1 = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
        List2 = Array(1, 2, 4, 5, 6, 11, 8, 9, 10)
        For i = 1 to 9
             Mg(1, List1(i)) = Vung(1, List2(i))
        Next
    For I = UBound(Vung) To 2 Step -1
         'Chuyen du lieu tu duoi len tren (moi o tren cu o duoi):
         If Vung(I, 1) <> "" And Vung(I, 15) <> "Thanh Lý" Then
           K = K + 1
           For j = 1 to 9
             Mg(K, List1(j)) = Vung(I, List2(j))
          Next
         End If
     Next     
LocKhachHang.[A1].Resize(UBound(Mg), 9).Value = Mg 
End Sub

Cách này của Sư phụ "ngộ" thiệt! Nhưng em thử chạy nó báo lỗi số 9 (Supscript out of range). Vì cách này quá mới mẽ nên chưa thể biết sai điểm nào, mong Sư phụ chỉ dạy!
 
Upvote 0
quên, mảng tự đặt thì bắt đầu bằng 0
Sửa
For i = 1 to 9
thành
For i = 0 to 8
là được.

Ở dưới là j nha, vì sợ trùng với I của Cò
 
Upvote 0
Upvote 0
Thử cái này để rút gọn xem, chỉ rút gọn code, không nói gì đến thuật toán:


PHP:
Sub RacRoi() 
Dim Vung, Mg(), I, K
         LocKhachHang.[A:I].ClearContents: K = 1
         Vung = KhachHang.Range("B5", KhachHang.[B65536].End(xlUp)).Resize(, 15).Value
         ReDim Mg(1 To UBound(Vung), 1 To 9)
        List1 = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
        List2 = Array(1, 2, 4, 5, 6, 11, 8, 9, 10)
        For i = 1 to 9
             Mg(1, List1(i)) = Vung(1, List2(i))
        Next
    For I = UBound(Vung) To 2 Step -1
         'Chuyen du lieu tu duoi len tren (moi o tren cu o duoi):
         If Vung(I, 1) <> "" And Vung(I, 15) <> "Thanh Lý" Then
           K = K + 1
           For j = 1 to 9
             Mg(K, List1(j)) = Vung(I, List2(j))
          Next
         End If
     Next     
LocKhachHang.[A1].Resize(UBound(Mg), 9).Value = Mg 
End Sub
Híc. Xách xe đi nhậu mới nghĩ ra cách rút gọn code, gọi cho Minh Thiện gợi ý cách làm. Bi giờ về mở máy thấy Lão Chít Tiệt làm chứ hổng phải Minh Thiện. Ngộ
Híc, chắc lúc mình gọi cho Minh Thiện sóng di động thế quái nào gọi luôn cho Lão í nên Lão làm đúng như cái mình gợi ý cho Minh Thiện.
Ủa, mà cái thằng List1 làm cái quái gì nhỉ ?????. Ngộ quá ta
Híc
 
Lần chỉnh sửa cuối:
Upvote 0
Híc. Xách xe đi nhậu mới nghĩ ra cách rút gọn code, gọi cho Minh Thiện gợi ý cách làm. Bi giờ về mở máy thấy Lão Chít Tiệt làm chứ hổng phải Minh Thiện. Ngộ
Híc, chắc lúc mình gọi cho Minh Thiện sóng di động thế quái nào gọi luôn cho Lão í nên Lão làm đúng như cái mình gợi ý cho Minh Thiện.
Ủa, mà cái thằng List1 làm cái quái gì nhỉ ?????. Ngộ quá ta
Híc
Hic kí rì mà hic! Thiên tài không cần ai gợi ý. Còn cái vụ List1 hả? Phòng xa sau này ai đó làm List1 lộn tùng phèo giống List2, chứ thiên tài dư biết chỉ cần thế này:
PHP:
For i = 0 to 8
    Mg(1, i + 1) = Vung(1, List2(i))
Next
 
Upvote 0
Ếch Xanh cho hỏi ké cái nha, thông cảm đi nà!

Ta có thể áp dụng fương thức tìm kiếm để tìm thành fần nào trong mảng chứa trị cụ thể nào đó cần tìm không ta?​
 
Upvote 0
- Thêm 1 biến K, khi nào thỏa lấy biến K làm thứ tự của mảng kết quả
- Lấy từ dưới lên thì cứ cho biến chạy từ .....dưới lên, khai báo chi "dzắc dzối" quá
Chạy thử code này:
Mã:
Public Sub RacRoi()

            Mg(1, 1) = Vung(1, 1)
            Mg(1, 2) = Vung(1, 2)
            Mg(1, 3) = Vung(1, 4)
            Mg(1, 4) = Vung(1, 5)
            Mg(1, 5) = Vung(1, 6)
            Mg(1, 6) = Vung(1, 11)
            Mg(1, 7) = Vung(1, 8)
            Mg(1, 8) = Vung(1, 9)
            Mg(1, 9) = Vung(1, 10)
  
End Sub
Em nghĩ nếu thay đoạn này băng đoạn này thì tốt độ cũng không thay đổi nhiêu, còn nếu muốn sài trên mảng thì làm trực tiếp trên sheet CSDL khổi qua sheet Loc_KH làm chi cho khoe
PHP:
KhachHang.Range("B5:C5,E5:K5").Copy LocKhachHang.Range("a1")
 
Upvote 0
Tôi có 1 thủ tục lọc hàng có điều kiện trong mảng:



Xin vui lòng cho hỏi các vấn đề sau:

1) Sau khi chạy thủ tục, tại sheet LOC_KH có bị trống 1 số hàng (màu vàng) do lọc theo điều kiện, Vậy làm sao để nó dồn lên trên để không bị trống nữa?

2) Code có thể rút gọn được không?

Xin cám ơn rất nhiều!
tôi không hiểu code nhiều lắm nhưng với code của minhthien321 mà chạy trên excel 2007--trở lên thì chỉ cần sửa đoạn này là tạm ổn
PHP:
If IsArray(MyArr2) Then LocKhachHang.[A2].Resize(UBound(MyArr2, 1), 9).Value = MyArr2
     Sheets("loc_kh").Range("A1:I" & [a60000].End(3).Row() + 1).RemoveDuplicates Columns:=Array(1, 2, 3, 4, 5, 6,  7, 8, 9), Header:=xlNo
 
Lần chỉnh sửa cuối:
Upvote 0
Mình thấy làm như anh em thì lại đẻ ra 2 cái List phiền thêm. Mục đích chỉ để đảo vị trí của cột 7.
Y kiến mình nên làm thế này gọn gàng hơn:

Mã:
Sub RacRoi()
Dim Vung, Mg(), I, K
         LocKhachHang.[A:I].ClearContents: K = 1
         Vung = KhachHang.Range("B5", KhachHang.[B65536].End(xlUp)).Resize(, 15).Value
         ReDim Mg(1 To UBound(Vung), 1 To 9)
        For I = 1 To 9
             Mg(1, I) = Vung(1, I)
        Next
    For I = UBound(Vung) To 2 Step -1
         'Chuyen du lieu tu duoi len tren (moi o tren cu o duoi):
         If Vung(I, 1) <> "" And Vung(I, 15) <> "Thanh Lý" Then
           K = K + 1
           For j = 1 To 9
             Mg(K, j) = Vung(I, j + IIf(j = 7, 3, 0))
          Next
         End If
     Next
LocKhachHang.[A1].Resize(UBound(Mg), 9).Value = Mg
End Sub
 
Upvote 0
Mình thấy làm như anh em thì lại đẻ ra 2 cái List phiền thêm. Mục đích chỉ để đảo vị trí của cột 7.
Y kiến mình nên làm thế này gọn gàng hơn:
Code mình viết dùng 2 cái List1 và List2 là trường hợp tổng quát. List1 có thể bỏ vì ít khi đảo lộn, nhưng cái List2 đâu phải lúc nào cũng cộng 3 hoặc không cộng. Tất nhiên là tuỳ từng bài cụ thể để viết, nhưng có 1 cách tổng quát vẫn hơn.
 
Upvote 0
Đấy là trường hợp thay đổi ít, để tổng quát thì em thay hàm choose vào là được thôi mà
Mã:
Sub RacRoi()
Dim Vung, Mg(), I, K
         LocKhachHang.[A:I].ClearContents: K = 1
         Vung = KhachHang.Range("B5", KhachHang.[B65536].End(xlUp)).Resize(, 15).Value
         ReDim Mg(1 To UBound(Vung), 1 To 9)
        For I = 1 To 9
             Mg(1, I) = Vung(1, I)
        Next
    For I = UBound(Vung) To 2 Step -1
         'Chuyen du lieu tu duoi len tren (moi o tren cu o duoi):
         If Vung(I, 1) <> "" And Vung(I, 15) <> "Thanh Lý" Then
           K = K + 1
           For j = 1 To 9
             Mg(K, j) = Vung(I, Choose(j, 1, 2, 3, 4, 5, 6, 11, 8, 9, 10))
          Next
         End If
     Next
LocKhachHang.[A1].Resize(UBound(Mg), 9).Value = Mg
End Sub
 
Upvote 0
Ta có thể áp dụng fương thức tìm kiếm để tìm thành fần nào trong mảng chứa trị cụ thể nào đó cần tìm không ta?​

Em nghĩ là được, viết hàm dưới đây, Bác SA có thể kiểm chứng:

PHP:
Function FindString(ByVal MyArray, MyString As String) As Boolean
    Dim MyTmp(), iRow As Long, iCol As Long
    On Error Resume Next
    MyTmp = MyArray
    FindString = False
    For iRow = 1 To UBound(MyTmp, 1)
        For iCol = 1 To UBound(MyTmp, 2)
            If MyTmp(iRow, iCol) = MyString Then
                FindString = True
                Exit For
            End If
        Next
    Next
End Function

Kiểm tra:

PHP:
Sub test()
    Dim MyArr
    MyArr = [A1:C5].Value
    MsgBox FindString(MyArr, "Sa_DQ")
End Sub
 

File đính kèm

Upvote 0
Không được Minh Thien ơi, Bác Sa hỏi về phương thức Find cơ mà. Trong khi phương thức Find chỉ áp dụng cho Range Object. Còn ví dụ của Minh Thien là sử dụng Hàm UDF trong hàm không sử dụng Find.
 
Upvote 0
Sau khi loại bỏ hàng rỗng từ mảng cũ sang mảng mới, vậy tại sao Ubound(NewArray) vẫn bằng Ubound(OldArray)?

Vậy có cách nào để điều chỉnh cho đúng với số hàng đã loại bỏ khoảng trắng không?

PHP:
Sub MangQuaRacRoi()
    Dim Vung(), Mg(), i As Long, j As Long, K As Long
    [F:G].ClearContents: K = 0
    Vung = Range([A1], [A65536].End(xlUp)).Resize(, 2).Value
    ReDim Mg(1 To UBound(Vung), 1 To 2)
    For i = 1 To UBound(Vung)
        If Vung(i, 2) <> "" Then
            K = K + 1
            For j = 1 To 2
                Mg(K, j) = Vung(i, j)
            Next
        End If
    Next
    MsgBox UBound(Mg, 1)
    [F1].Resize(UBound(Mg, 1), 2).Value = Mg
End Sub
 

File đính kèm

Upvote 0
Cách giải quyết:

PHP:
[F1].Resize(K, 2).Value = Mg

Mg đã redim từ đầu bằng vung, nếu không redim lần 2 thì có thay đổi kích thước gì đâu.
 
Upvote 0
Cách giải quyết:

PHP:
[F1].Resize(K, 2).Value = Mg

Mg đã redim từ đầu bằng vung, nếu không redim lần 2 thì có thay đổi kích thước gì đâu.

Dạ, cám ơn Sư phụ, nhưng chủ yếu em hỏi mình có thể RESIZE ngay tại cái mảng mới được không ạ? Bởi nếu mình gán lên Combobox thì khoảng trắng vẫn hiển thị trong List của nó.
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT

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

Back
Top Bottom