Danh Sách Duy Nhất !! (2 người xem)

Liên hệ QC

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

Mr Okebab

Ngon Ngất Ngây
Thành viên đã mất
Tham gia
6/8/06
Bài viết
3,260
Được thích
3,790
Có rất nhiều bạn vất vả khi phải trích lọc một danh sách duy nhất từ một mớ hỗn lộn mọi thứ.
Có người dùng cột phụ, có người dùng Filter. . . .

Mình xin trình bày với các bạn một hàm mới có tác dụng trích lọc lấy danh sách duy nhất từ một vùng khác :
PHP:
Function DanhSach(MangDL As Range, Optional MangMa As Range)
    On Error Resume Next
    Dim i As Long
    If MangDL.Rows.Count < 1 Then Exit Function
    If MangMa.Rows.Count = 0 Then DanhSach = MangDL(1): Exit Function
    For i = 1 To MangDL.Rows.Count
        If WorksheetFunction.CountIf(MangMa, MangDL(i)) = 0 Then
            DanhSach = MangDL(i)
            Exit For
    End If: Next
End Function
Em đã thử tạo một hàm mảng về vấn đề này nhưng không thành công.
Bác nào có nhã ý thì có thể giúp em được không ạ ??
Thanks!!

Thân!
 

File đính kèm

Sau một hồi gõ gõ, tự nhiên lại được.--=0--=0
Các bác tham khảo hàm mảng nhé :

PHP:
Function DanhSachM(MangDL As Range)
    Dim i As Long, i1 As Long, m As Integer, Tim As Boolean, Ma As Range
    Dim MangTemp(1 To 1000, 0) As Variant
    If MangDL.Rows.Count = 0 Then Exit Function
    For Each Ma In MangDL
        i = i + 1
        If i = 1 Then
            m = m + 1
            MangTemp(m, 0) = Ma.Value
        Else
            For i1 = 1 To m
                If UCase(MangTemp(i1, 0)) = UCase(Ma) Then
                    Tim = True
                    Exit For
                End If
            Next i1
            If Tim = False Then
                m = m + 1
                MangTemp(m, 0) = Ma.Value
            End If
        End If
        Tim = False
    Next
    DanhSachM = MangTemp
End Function

Các bác cho em hỏi là như hàm trên em khai báo là tối đa có 1000 phần tử được lọc. Nếu có số phần tử lớn hơn thì nó sẽ báo lỗi.
Vậy có cách nào để nó tự động co giãn theo số phần tử tìm được không vậy ?? Chẳng lẽ lại khai báo lại ???


Thân!

P/S : Nếu muốn thông báo là Dư thiếu bao nhiêu hàng thì bạn chèn hàng này trước DanhSachM = MangTemp

PHP:
.
.
If Selection.Rows.Count <> m Then MsgBox IIf(Selection.Rows.Count - m > 0, "Du : ", " Thieu : ") & Selection.Rows.Count - m & " hang"
.
.
 

File đính kèm

Upvote 0
Mr Okebab đã viết:
Sau một hồi gõ gõ, tự nhiên lại được.--=0--=0
Các bác tham khảo hàm mảng nhé :

PHP:
Function DanhSachM(MangDL As Range)
Dim i As Long, i1 As Long, m As Integer, Tim As Boolean, Ma As Range
Dim MangTemp(1 To 1000, 0) As Variant
If MangDL.Rows.Count = 0 Then Exit Function
For Each Ma In MangDL
i = i + 1
If i = 1 Then
m = m + 1
MangTemp(m, 0) = Ma.Value
Else
For i1 = 1 To m
If UCase(MangTemp(i1, 0)) = UCase(Ma) Then
Tim = True
Exit For
End If
Next i1
If Tim = False Then
m = m + 1
MangTemp(m, 0) = Ma.Value
End If
End If
Tim = False
Next
DanhSachM = MangTemp
End Function

Các bác cho em hỏi là như hàm trên em khai báo là tối đa có 1000 phần tử được lọc. Nếu có số phần tử lớn hơn thì nó sẽ báo lỗi.
Vậy có cách nào để nó tự động co giãn theo số phần tử tìm được không vậy ?? Chẳng lẽ lại khai báo lại ???


Thân!

P/S : Nếu muốn thông báo là Dư thiếu bao nhiêu hàng thì bạn chèn hàng này trước DanhSachM = MangTemp

PHP:
.
.
If Selection.Rows.Count <> m Then MsgBox IIf(Selection.Rows.Count - m > 0, "Du : ", " Thieu : ") & Selection.Rows.Count - m & " hang"
.
.

Cái này hay đấy, đang cần cho một số ứng dụng.
Cảm ơn MrOkebab nhé !
Chúc khỏe !
 
Upvote 0
vungoc đã viết:
Cái này hay đấy, đang cần cho một số ứng dụng.
Cảm ơn MrOkebab nhé !
Chúc khỏe !

Cảm ơn bác, làm mấy cái hàm, chỉ thấy người tải mà không thấy THANKS nên hơi . . nản.-\\/.-\\/.-\\/.

May quá có mấy bác!!--=0--=0--=0

Thân!
 
Upvote 0
Mr Okebab đã viết:
Cảm ơn bác, làm mấy cái hàm, chỉ thấy người tải mà không thấy THANKS nên hơi . . nản.-\\/.-\\/.-\\/.

May quá có mấy bác!!--=0--=0--=0

Thân!

Hôm trước bác có làm cho mình đoạn code dùng để loại bỏ những dòng phụ tùng giống nhau - cũng giống chức năng của danh mục duy nhất này(lúc mình làm file đặt mã phụ tùng), nhưng dạo này cái ổ cứng nó hư mất tiêu rồi - mà mình lại đang muốn kiếm nó.

Bác làm ơn tìm dùm mình và post lại lên đây dùm với nhé.

Cảm ơn và chúc mọi điều tốt đẹp đối với bác.

Hơn tuần nay không gặp được bác (vì bận túi bụi) - nhớ bác quá.

Hẹn sớm gặp lại (CF) !

Thân mến !
 
Upvote 0
Mr Okebab đã viết:
Các bác cho em hỏi là như hàm trên em khai báo là tối đa có 1000 phần tử được lọc. Nếu có số phần tử lớn hơn thì nó sẽ báo lỗi.
Vậy có cách nào để nó tự động co giãn theo số phần tử tìm được không vậy ?? Chẳng lẽ lại khai báo lại ???

Nếu Không xác định được số phần tử cụ thể của mảng, em khai báo:
Function DanhSachM(MangDL As Range)
Dim i As Long, i1 As Long, m As Integer, Tim As Boolean, Ma As Range
Dim MangTemp() As Variant

...........
Sau khi xác định được số phần tử (ví dụ n phần tử), khai báo lại:
Redim MangTemp(1 to n)
 
Upvote 0
phamduylong đã viết:
Nếu Không xác định được số phần tử cụ thể của mảng, em khai báo:
Function DanhSachM(MangDL As Range)
Dim i As Long, i1 As Long, m As Integer, Tim As Boolean, Ma As Range
Dim MangTemp() As Variant

...........
Sau khi xác định được số phần tử (ví dụ n phần tử), khai báo lại:
Redim MangTemp(1 to n)

Vâng, cảm ơn bác nhiều.
Tuy nhiên áp dụng vào thì nó chạy búa xua.

bác có thể ráp luôn vào code trên được không ạ ???

Cảm ơn bác!!

Thân!
 
Upvote 0
Sao ko dùng A-Tools của Tuân rồi làm câu query: SELECT DISTINCT ... gì đó có phải hay không?

SELECT DISTINCT ID FROM tb_InventoryItem

Khi đó tb_InventoryItem là 1 Sheet trong file Excel.

Chỉ cần thêm 1 câu lệnh Left join với tb_InventoryItem nữa là lấy đủ tất cả các thông tin về InventoryItem. A-Tool của Tuân cho phép làm việc đó mà.

Ví dụ:

SELECT tb_InventoryItem.* FROM (SELECT DISTINCT ID FROM tb_InventoryItem) AS NO_DUPLICATE_ITEMS
LEFT JOIN tb_InventoryItem ON NO_DUPLICATE_ITEMS.ID = tb_InventoryItem.ID

Nếu dùng vòng for thì giả sử cái sheet InventoryItem có 65,000 rows thì chả cần xử lý gì, chỉ cần vòng lặp với 65,000 lần thôi cũng khá tốn time rồi.
 
Lần chỉnh sửa cuối:
Upvote 0
smbsolutions đã viết:
Sao ko dùng A-Tools của Tuân rồi làm câu query: SELECT DISTINCT ... gì đó có phải hay không?

SELECT DISTINCT ID FROM tb_InventoryItem

Khi đó tb_InventoryItem là 1 Sheet trong file Excel.

Chỉ cần thêm 1 câu lệnh Left join với tb_InventoryItem nữa là lấy đủ tất cả các thông tin về InventoryItem. A-Tool của Tuân cho phép làm việc đó mà.

Ví dụ:

SELECT tb_InventoryItem.* FROM (SELECT DISTINCT ID FROM tb_InventoryItem) AS NO_DUPLICATE_ITEMS
LEFT JOIN tb_InventoryItem ON NO_DUPLICATE_ITEMS.ID = tb_InventoryItem.ID

Nếu dùng vòng for thì giả sử cái sheet InventoryItem có 65,000 rows thì chả cần xử lý gì, chỉ cần vòng lặp với 65,000 lần thôi cũng khá tốn time rồi.
Chắc chắn không nhanh hơn advance filter, unique record.
 
Upvote 0
Đây là hàm trả về Danh Sách đã được sắp xếp tăng dần :
PHP:
Function DanhSachMSX(MangDL As Range)
    Application.ScreenUpdating = False
    Dim i As Long, i2, i1 As Long, m As Integer, Tim As Boolean, Ma As Range
    Dim MangTemp(1 To 1000, 0) As Variant
    Dim Mang(1 To 1000, 0)
    If MangDL.Rows.Count = 0 Then Exit Function
    For Each Ma In MangDL
        i = i + 1
        If i = 1 Then
            m = m + 1
            MangTemp(m, 0) = Ma.Value
        Else
            For i1 = 1 To m
                If UCase(MangTemp(i1, 0)) = UCase(Ma) Then
                    Tim = True
                    Exit For
                End If
            Next i1
            If Tim = False Then
                m = m + 1
                MangTemp(m, 0) = Ma.Value
            End If
        End If
        Tim = False
    Next
    'Loc Danh Sach
    For i = 1 To m
        If i = 1 Then ' Gan PT dau tien
            Mang(1, 0) = MangTemp(1, 0)
        Else
            For i1 = 1 To i - 1 ' Xem co nho hon GT nao trong Mang khong ??
                If LCase(MangTemp(i, 0)) < LCase(Mang(i1, 0)) Then Tim = True: Exit For
            Next i1
            
            If Tim = False Then ' Khong co : Cho xuong duoi Danh Sach
                Mang(i, 0) = MangTemp(i, 0)
            Else ' Neu co :
                For i2 = i To i1 + 1 Step -1
                    Mang(i2, 0) = Mang(i2 - 1, 0) 'Dich chuyen danh sach xuong 1 nac
                Next i2
                Mang(i1, 0) = MangTemp(i, 0)  Cho phan tu vao DS
            End If
        End If
        Tim = False
    Next
    DanhSachMSX = Mang()
    Set Ma = Nothing
    Application.ScreenUpdating = True
End Function

File VD



To bác smbsolution : Em mà biết về SQL thì . . . còn gì bằng nữa.:=\+:=\+
Thân!
 
Upvote 0
ThuNghi đã viết:
Chắc chắn không nhanh hơn advance filter, unique record.

Bạn cho tớ 1 file ví dụ đi. Tớ chả rõ cái "advance filter, unique record" nó hoạt động thế nào vì tớ ko biết tý gì về Excel cả. Cho tớ ví dụ 1 cái Sheet khoảng ~100,000 records thôi nhé để tớ biết "advance filter" nó làm như thế nào. Sau khi có cái file ~100,000 rows đó, gửi cho tớ để tớ cũng thử tạo 1 ví dụ nho nhỏ để có được cái Recordset của ADO sau khi đã remove hết các duplicate rows (tớ sẽ thực hiện save cái kết quả của "no duplicate" recordset đó ra file XML). OK?

Ví dụ cái Sheet của bạn chỉ có 3 cột thôi: ID (Long), Code (Text 20 ký tự), Name

Trong đó cột ID và cột Code đang bị trùng lắp rất nhiều. Test thử với giá trị là 100,000 dòng nhé (hoặc max row của Excel gì đó thì tùy, tớ ko rõ max row của Excel là bao nhiêu đâu).
 
Upvote 0
Mr Okebab đã viết:
To bác smbsolution : Em mà biết về SQL thì . . . còn gì bằng nữa.:=\+:=\+
Thân!
Vấn đề là Bab ko thích thôi. Có mỗi SELECT [Tên cột],... FROM [Tên sheet] thôi mà. Mấy cái loằng ngoằng liên quan tới SELECT FROM đó chỉ mất 30 phút lên mạng của Bab là có thể tìm hiểu được. Nếu nó khó thật thì mình ko dám nói, ở đây mình thấy nó còn đơn giản hơn học cái "Advance Filter" và chắc chắn dễ hơn cái mà Bab post dài loằng ngoằng ở trên.

Dĩ nhiên, SQL ở dạng advance hơn thì chưa nói ở đây vội làm gì.

Căn bản là thấy trên GPE cũng có rất nhiều người đang sài A-Tool đấy chứ, nếu ko có kiểu A-Tool thì cũng chả bàn đến vấn đề này ở đây.

Với lại, nếu như ThuNghi nói là dùng "Advance Filter" với "Unique record" đã có sẵn trong Excel được thì tại sao lại phải viết code như Bab đã viết ở trên (chắc phải có lý do chứ Bab nhỉ :)). Sao ko dùng cái sẵn có? Cái "Advance Filter" kia có điểm yếu gì mà phải Re-Invent lại? (Nên đặt tính hiệu quả lên hàng đầu nhé). Bab thử nói lý do tại sao Advance Filter như ThuNghi đề cập lại ko đáp ứng được mà phải viết thành code như Bab đã viết nhé.
 
Lần chỉnh sửa cuối:
Upvote 0
LearnMore đã viết:
Data cho các bác test đây, giả sử lọc duy nhất 5 cột đầu thôi nhé. CSDL này tới trên 10 triệu dòng lận mình trích ra maxrow của Excel 2003 trở về trước.

Download:
http://www.zshare.net/download/4592951f0f1e21/

LM
Hay quá, bây giờ mình mới biết Excel 2003 có trên 65,536 rows đấy. Thế mà cái Excel 2003 của mình nó lại ko lên tới 65,537 rows mới a kay chứ. LearnMore có bản Excel nào hỗ trợ 1 Sheet có dòng thứ 65,537 (ko cần tới 10tr dòng đâu) thì send cho mình nhé. Thanks alot!

PS: Cái ZShare này cứ down được nửa chừng thì lại chết (Do mạng chậm quá). Nếu dùng ngắn hạn thì dùng mytempdir.com đi.
 

File đính kèm

  • Sheet_MaxRows.jpg
    Sheet_MaxRows.jpg
    49.5 KB · Đọc: 108
Lần chỉnh sửa cuối:
Upvote 0
smbsolutions đã viết:
Vấn đề là Bab ko thích thôi. Có mỗi SELECT [Tên cột],... FROM [Tên sheet] thôi mà. Mấy cái loằng ngoằng liên quan tới SELECT FROM đó chỉ mất 30 phút lên mạng của Bab là có thể tìm hiểu được. Nếu nó khó thật thì mình ko dám nói, ở đây mình thấy nó còn đơn giản hơn học cái "Advance Filter" và chắc chắn dễ hơn cái mà Bab post dài loằng ngoằng ở trên.

Dĩ nhiên, SQL ở dạng advance hơn thì chưa nói ở đây vội làm gì.

Căn bản là thấy trên GPE cũng có rất nhiều người đang sài A-Tool đấy chứ, nếu ko có kiểu A-Tool thì cũng chả bàn đến vấn đề này ở đây.

Với lại, nếu như ThuNghi nói là dùng "Advance Filter" với "Unique record" đã có sẵn trong Excel được thì tại sao lại phải viết code như Bab đã viết ở trên (chắc phải có lý do chứ Bab nhỉ :)). Sao ko dùng cái sẵn có? Cái "Advance Filter" kia có điểm yếu gì mà phải Re-Invent lại? (Nên đặt tính hiệu quả lên hàng đầu nhé). Bab thử nói lý do tại sao Advance Filter như ThuNghi đề cập lại ko đáp ứng được mà phải viết thành code như Bab đã viết nhé.

Vâng, em sẽ cố học SQL vậy. Hy vọng dễ hơn học MetaStock !!--=0--=0

Advance Filter là một công cụ lọc rất mạnh của Excel. Có mấy lý do em làm mấy cái UFD này :
  1. Nâng cao trình độ thấp của em:-=
  2. Đa dạng hóa 1 vấn đề (excel đối với em chỉ là 1 cuộc dạo chơi)
  3. AF không linh hoạt = hàm (lý do phụ)
  4. AF không sắp xếp thứ tự được (lý do phụ)
Tất nhiên là AF nhanh hơn hàm nhiều rồi, mạnh hơn nữa.

Còn cái Excel2003 SP3 mà em thử cũng chỉ có 65,536 hàng. Còn 65,357 thì ở đâu nhỉ ???:=\+:=\+ Hay của bác dùng cái khác ???

Thân!
 
Upvote 0
CSDL này tới trên 10 triệu dòng lận, mình trích ra maxrow của Excel 2003 trở về trước.

À, mình hiểu rồi (do cậu thiếu dấu "," nên tớ cứ đọc liền tù tì, cứ tưởng là Excel có tới 10tr rows/sheet :D). Tức là CSDL gốc ̣ko phải là Excel lên tới 10tr dòng. Và LearnMore trích ra "maxrow của Excel 2003 trở về trước" để lưu vào file Excel. Phải đọc kỹ mới hiểu được ý tứ của đoạn văn :D.

Tớ down mãi ko được cái file data.zip của LearnMore (net buổi chiều chậm lắm).

@LearnMore: Trên cái file data đó có trùng dữ liệu nhiều ko? (Vì đã ở CSDL khác thì mình nghĩ là No Duplicate (FK as Unique Key hoặc PK) rồi vì khi người ta thiết kế CSDL thì ít khi lại đi thiết kế để có thể nhập trùng dữ liệu được.
 
Upvote 0
Download test ở link phía dưới (link chỉ tồn tại được trong 60 ngày). Tớ dùng cái MS FlexGrid để hiển thị kết quả nên hơi chuối (nếu dùng cái Grid khác thì bộp phát lên luôn nhưng đó là cái mà tớ ko thể gửi được).

Nhưng thời gian để có được cái Recordset dạng "no duplicate" từ lúc bấm Refresh tới thời điểm hiện ra cái Msgbox như vậy mình nghĩ là chấp nhận được.

http://www.mytempdir.com/2051788
 
Lần chỉnh sửa cuối:
Upvote 0
smbsolutions đã viết:
À, mình hiểu rồi (do cậu thiếu dấu &quot;,&quot; nên tớ cứ đọc liền tù tì, cứ tưởng là Excel có tới 10tr rows/sheet :D). Tức là CSDL gốc ̣ko phải là Excel lên tới 10tr dòng. Và LearnMore trích ra &quot;maxrow của Excel 2003 trở về trước&quot; để lưu vào file Excel. Phải đọc kỹ mới hiểu được ý tứ của đoạn văn :D.

Tớ down mãi ko được cái file data.zip của LearnMore (net buổi chiều chậm lắm).

@LearnMore: Trên cái file data đó có trùng dữ liệu nhiều ko? (Vì đã ở CSDL khác thì mình nghĩ là No Duplicate (FK as Unique Key hoặc PK) rồi vì khi người ta thiết kế CSDL thì ít khi lại đi thiết kế để có thể nhập trùng dữ liệu được.

Chạy làm sao vậy bác ???

Thông cảm nếu câu hỏi hơi . . . ngố.

Thân!
 
Upvote 0
Làm sao mà xóa bài không được.
 
Lần chỉnh sửa cuối:
Upvote 0
ThuNghi đã viết:
Còn project của Bác SMBSolutions thì phải Fox...chạy còn miệt mài hơn.

Thứ nhất, tớ trổ hết kỹ năng về ngữ pháp tiếng Việt, tiếng anh ra mà ko làm sao phân tích được câu nói trên sao cho đúng nghĩa. Vì thế tớ hiểu theo nghĩa bác nói cái tớ làm là viết bằng Fox.

Thứ 2: Cho tớ hỏi: Fox, Access, Query là những cái gì hả bác? Tớ ko biết món này :P (tớ chỉ làm Access 15 năm trước đây thôi, và cái từ Query cũng biến khỏi đầu tớ cũng ngần đấy thời gian. Tớ ko thích dùng những từ đó.)

Thứ 3: Group by, Import để làm gì hả bác? Chỉ cần hiển thị ra danh sách ko bị trùng lắp từ một danh sách trùng lắp thôi mà, sao lại phải Group với Import? Và cũng đâu nhất thiết phải làm mọi thứ trên Excel???

Thứ 4: Bác xem cái file Project1.exe mà phát biểu nó là Fox thì chả hiểu làm VBA để làm gì.

Thứ 5: AF nó chạy nhanh lắm, vậy "nhanh lắm" là như thế nào? Bao nhiêu giây?

Thứ 6: Giả sử cần phải sắp xếp sau khi trích lọc dữ liệu thì thế nào. Trong khi tớ chỉ ORDER BY 1 cái là xong. Ngôn ngữ SQL nó mạnh kinh khủng nếu bác học kỹ về nó. (Tỷ như có việc bác lọc trên nhiều Sheet rồi ghép các dữ liệu với nhau, trích ghép các cột với nhau, v.v....). Nếu AF mà thỏa mãn mấy cái đó thì cái A-Excel của Tuân cũng chả phải gắn thêm cái kiểu SQL vào Excel để làm gì. Tuân nhỉ? :D

Bình thêm:
- Không dở hơi thằng M$, Oracle, DB2, Infomix,... nó lại có cơ chế truy cập CSDL đâu bác :D.
- Bác mà chê thằng ADO thì M$ nó sập tiệm từ lâu rồi bác ạ. Chán nhỉ.

Thôi, tớ chả bỏ thời gian vào đây nữa đâu. Mệt lắm! Có lẽ tớ ko biết Excel thì ko nên vào nơi Excel thật. Đáng bị out lắm!
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT

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

Back
Top Bottom