Lọc dữ liệu tự động từ Insert Comment ... (2 người xem)

Liên hệ QC

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

Bro SA_DQ ơi, giúp mình thêm phát nữa nhé.
1*/ Bạn đừng nên viết thế này; Mà nên dùng là đại từ ngôi thứ hai số nhiều
Tại sao thì bạn tự tìm hiểu & trả lời, nha!

2*/ Bạn chạy Color2 độc lập sau cái macro hôm trước, hay thêm dòng
Color2 vô trước dòng lệnh cuối để gọi macro2 này
Tuy nhiên Macro1 không thể không cùng song hành với người anh em kết nghĩa của nó
3*/ Trong 2 macro mình chỉ cho rằng có 5 nhóm số trùng nhau là tối đa giữa 2 dòng; Trong thực tế nhiều hơn, bạn nên tăng biến mảng này lên cho phù hợp.

PHP:
Option Explicit:            Option Base 1

Sub Color2()
 Dim cRng As Range, sRng As Range, Clls As Range
 Dim StrC0 As String, StrC1 As String
 Dim bDD As Byte, bJ As Byte, bVTr As Byte, bDem As Byte
 
 Set cRng = Cells.SpecialCells(xlCellTypeComments)
 Set sRng = cRng.Cells(1, 1).Offset(, -1).Resize(cRng.Rows.Count, 1)
 Application.ScreenUpdating = False
 
 For Each Clls In sRng
    If Clls.Row = 1 Then
        GoTo 35
    Else
        Set cRng = Clls.Offset(-1)
        StrC0 = cRng.Value:                     StrC1 = Clls.Value
        bDD = Len(StrC0):                       ReDim MVTr(5) As Byte
        For bJ = 1 To bDD Step 3
            bVTr = InStr(1, StrC1, Mid(StrC0, bJ + 1, 2))
            If bVTr > 0 Then
                bDem = 1 + bDem:                MVTr(bDem) = bJ + 1
            End If
        Next bJ
        Color1 cRng, MVTr:                      bDem = 0
    End If
35 Next Clls
End Sub
Mã:
[B]Sub Color1[/B](Rng As Range, MMM As Variant)
 Dim bZ As Byte
 
    Rng.Select
    With ActiveCell.Characters(Start:=1, Length:=MMM(1) - 1).Font
        .ColorIndex = 11
    End With
For bZ = 1 To 5
    If MMM(bZ) = 0 Then Exit For
    With ActiveCell.Characters(Start:=MMM(bZ), Length:=2).Font
        .ColorIndex = 3
    End With
    With ActiveCell.Characters(Start:=MMM(bZ) + 2, Length:=12).Font
        .ColorIndex = 11
    End With
 Next bZ
[B]End Sub[/B]
 
@SA_DQ ơi, xem lại file demo mình gửi kèm theo nhé, mình đã chạy macro rồi mà sao kết quả không như mong muốn theo hình minh họa ở dưới. Thanks !!!

compare_row_fix.jpg
 

File đính kèm

Lần chỉnh sửa cuối:
Ai cha... bài này nhìn vào code của các cao thủ như anh SA mà hiểu dc e rằng hơi bị lâu...
Nếu là tôi thì tôi sẽ dùng phương pháp củ chuối như sau:
1> Đầu tiên dùng code để Export Comment ra cell
PHP:
Sub Com_Exp()
Set RngCom = Cells.SpecialCells(xlCellTypeComments)
For Each Clls In RngCom
  CM1 = Clls.Comment.Text
  CM = Application.WorksheetFunction.Substitute(CM1, Chr(10), "-")
  Clls.Offset(, -1).Value = CM
Next
End Sub
Ta dc chuổi số có dạng: xxx-yyy-zzz-........
2> Dùng công cụ Text to Column để tách ra từng số 1
3> Cuối cùng dùng các hàm IF, MOD.. vân vân để lấy ra số cần tìm
Dể như ăn cháo!
Cách của anh SA cho kết quả trong vòng.. nháy mắt thì cách củ chuối này tuy ko nhanh nhưng cũng ko chậm gì lắm... Cùng lắm trong vòng 5 phút là ra... Quan trọng nhất là hiểu dc cái mình đang làm là giống gì ... He... he...
ANH TUẤN
 
Xong câu I rồi đây, Xem xét & cho í kiến nha!

PHP:
Option Explicit:            Option Base 1

Sub ColorInRow()
 Dim cRng As Range, sRng As Range, Clls As Range
 Dim StrC As String, StrC1 As String, StrC9 As String
 Dim bDD As Byte, bJ As Byte, bVTr As Byte, bVTri As Byte
 
 Set cRng = Cells.SpecialCells(xlCellTypeComments)
 Set sRng = cRng.Cells(1, 1).Offset(, -1).Resize(cRng.Rows.Count, 1)
 Application.ScreenUpdating = False:            Set cRng = Nothing
 For Each Clls In sRng
    ReDim MVTr(9) As Byte:                      Dim bDem As Byte
    If Clls = sRng.Cells(1, 1) Or Clls = sRng.Cells(sRng.Rows.Count, 1) Then
        StrC = Clls.Value:                      bDD = Len(StrC)
        If Clls = sRng.Cells(1, 1) Then
            StrC1 = Clls.Offset(1)
        ElseIf Clls.Address = sRng.Cells(sRng.Rows.Count, 1).Address Then
            StrC1 = Clls.Offset(-1)
        End If
        For bJ = 1 To bDD Step 3
            bVTr = InStr(1, StrC1, Mid(StrC, bJ + 1, 2))
            If bVTr > 0 Then
                bDem = 1 + bDem:                MVTr(bDem) = bJ + 1
            End If
        Next bJ
        Color1 Clls, MVTr:                      bDem = 0
    Else
        StrC1 = Clls.Offset(-1).Value:          StrC = Clls.Value
        StrC9 = Clls.Offset(1).Value:           bDD = Len(StrC)
        For bJ = 1 To bDD Step 3
            bVTr = InStr(1, StrC1, Mid(StrC, bJ + 1, 2))
            bVTri = InStr(1, StrC9, Mid(StrC, bJ + 1, 2))
            If bVTr > 0 Or bVTri > 0 Or (bVTr > 0 And bVTri > 0) Then
                bDem = 1 + bDem:                MVTr(bDem) = bJ + 1
            End If
        Next bJ
        Color1 Clls, MVTr:                      bDem = 0
    End If
 Next Clls
End Sub

Mã:
[B]Sub Color1(Rng As Range, MMM As Variant)[/B]
 Dim bZ As Byte
 
    Rng.Select
    With ActiveCell.Characters(Start:=1, Length:=MMM(1) - 1).Font
        .ColorIndex = 11
    End With
 For bZ = 1 To 9
    If MMM(bZ) = 0 Then Exit For
    With ActiveCell.Characters(Start:=MMM(bZ), Length:=2).Font
        .ColorIndex = 3
    End With
    With ActiveCell.Characters(Start:=MMM(bZ) + 2, Length:=12).Font
        .ColorIndex = 11
    End With
 Next bZ
[B]End Sub[/B]
 
Lần chỉnh sửa cuối:
-Những yêu cầu của bạn Anti-Plusđược bác SA_DQgiải quyết hoàn toàn. Những đoạn code của bác SA_DQ đã cho mình rất nhiều bài học. Tuy nhiên trong quá trình mày mò tìm lời giải, mình cũng viết được một vài đoạn, nếu bỏ đi cũng tiếc nên post lên để các bạn đọc cho vui và để trao đổi học tập. Mong các bạn cho ý kiến.
Mã:
Option Explicit
Sub color()
Dim StrC1 As Variant, StrC2 As Variant
Dim C1 As Integer, C2 As Integer, i As Integer, j As Integer
Dim MyCell As Range
Range("vungchon").Select
Selection.Font.ColorIndex = 11
For Each MyCell In Selection
StrC1 = Split(MyCell, " ")
   C1 = 1: C2 = 1
     For i = 1 To UBound(StrC1)
        StrC2 = Split(MyCell.Offset(1, 0), " ")
            For j = 1 To UBound(StrC2)
               If StrC1(i) = StrC2(j) Then
                 MyCell.Characters(Start:=C1, Length:=3).Font.ColorIndex = 3
                 MyCell.Offset(1, 0).Characters(Start:=C2, Length:=3).Font.ColorIndex = 3
               End If
               C2 = C2 + 3
            Next
         C2 = 1
        C1 = C1 + 3
     Next
Next
End Sub
 

File đính kèm

Quá dễ hiểu & rất chi rõ ràng & mạch lạc!

Vấn đề còn lại là nhỏ vô cùng; đó là thời lượng hoàn tất chương trinh;
Đối với những CSDL dưới 1.000 dòng thì sẽ chẵng hề hấn gì; nhưng hơn thì có khi của bác sẽ chậm hơn của tôi.
Nếu như CSDL có n dòng thì vòng lặp của bác là 2*n lần; của tôi có thể chỉ là 1.5*n lần mà thôi; Bác thấy tôi dùng hàm InStr() sẽ nhanh hơn vòng lặp thứ 2 của bác (?)

Còn một câu hỏi cuối nữa: tô màu các chữ số cuối trong các Comments; Mình mới thấy lóe đóm lữa nhỏ ở cuối đường hầm mà thôi; Rất mong Bác & các bạn, chúng ta cùng giải quyết rốt ráo vấn đề này

To MOD phụ trách: Có lẽ chuyển Topic này sang macro thôi;
Ngay ÂnhTuân1066 cũng phải dùng macro để tách các chữ số kia từ Comments kia mà! Mình cho rằng nếu muốn giải bằng công thức, chỉ có ý nghĩa học thuật mà thôi; Đối với khả năng về công thức hạn hẹp của mình, giải công thức vấn đề này là không tưởng!
Chờ kết quả & ý kiến của các 'Siêu nhân Công thức' để được chiêm nghiệm sự đẹp đẽ của excel nói chung!
 
Các bro ơi, cái macro thì đã chạy chính xác rồi. Nhưng mình muốn mở rộng thêm vùng chọn để cho macro tự động làm thêm nữa thì phải làm thế nào ?

Mình có kèm theo file demo cho các bro đó ... Xin cám ơn sự giúp đỡ tận tình !

(file mình gửi kèm theo để demo cũng chính xác là file mình đang sử dụng cho nhu cầu riêng của mình luôn đó)
 

File đính kèm

Cái macro thì đã chạy chính xác rồi. Nhưng mình muốn mở rộng thêm vùng chọn để cho macro tự động làm thêm nữa thì phải làm thế nào ? Mình có kèm theo file demo cho các bro đó . . . cũng chính xác là file mình đang sử dụng cho nhu cầu riêng của mình luôn đó)[/I][/B]
Với macro LocKQ thì không có vấn đề gì, phải không; Cứ bấm chạy & được kết quả;
Với macro ColorInRow Bạn ghi thêm dòng lệnh này:
Mã:
 Set cRng = Application.InputBox("Hay Dung Chuot Chon Vung:", Type:=8)
vô sau dòng:
Set cRng = Cells.SpecialCells(xlCellTypeComments);
Khi chạy macro, sẽ xuất hiện hộp thoại bảo bạn chọn vùng cần (tô màu);
Khi đó bạn dùng chuột quét chọn vùng chưa tô màu; Mình ví dụ bạn chọn mỗi lần chạy macro 1 trong các vùng sau:
'E3:E9'
'E13:E19'
'E23:E29'
'E32:E39'
Chịu khó chọn cho đến hết; tại chúng ta chưa lường hết thực tiển của bạn mà!
 
Thank you bro !!! Kết quả thành công mỹ mãn ... Mình rất mong bro sớm hoàn thành câu hỏi 2 càng sớm càng tốt ... Chúc bro 1 ngày vui vẻ & gặt hái được nhiều thành công !
 
Nguyên văn bởi SA_DQ
Quá dễ hiểu & rất chi rõ ràng & mạch lạc!
-Cám ơn lời động viên của bác.
Vấn đề còn lại là nhỏ vô cùng; đó là thời lượng hoàn tất chương trinh;
-Mình nghĩ vấn đề này không nhỏ. Nhiều khi phải xử lý một CSDL lớn, vài nghìn dòng chẳng hạn, mình gặp rất nhiều khó khăn. Lúc bấy giờ có thể phải thay đổi toàn bộ phương án. Cũng có khi không tìm được cách giải quyết nào. Vẫn phải chấp nhận cho người dùng chờ đợi. Mình đồng ý với bác là nên hạn chế vòng lặp. Nhất là vòng lặp lồng nếu có một cách làm khác.
-Cám ơn bác đã chỉ ra chỗ này.
 
Sao đoạn code này bỏ sót

Trong khi tìm lời giải cho câu cuối còn lại, tôi đã tạo ra macro;
Nội dung nó như dưới đây, Nhưng nó chưa làm đúng í:
* Các số cuối đạt điều kiện cần tô màu trong Comments, thì chưa tô được
* Cái này mới khó hiểu hơn, macro bỏ sót một vài số trong dãy số cần tô màu
(Trong hình đính kèm số 85 & 65 chưa được tô màu.)
Mong các bạn xem xét & chỉ ra cách khắc phục giúp
PHP:
Sub CommentsFontColorS()
 Dim cRng As Range, sRng As Range, Clls As Range
 Dim StrC As String, sComm As String
 Dim bLen As Byte, bW As Byte, bVTr As Byte

 Set cRng = Cells.SpecialCells(xlCellTypeComments)
 Set sRng = cRng.Cells(1, 1).Offset(, -1).Resize(cRng.Rows.Count, 1)
 For Each Clls In cRng
    StrC = Clls.Offset(, -1):               bLen = Len(StrC)
    sComm = Clls.Comment.Text & " "
    With Clls.Comment.Shape.TextFrame
        For bW = 1 To bLen Step 3
            bVTr = InStr(1, sComm, Mid(StrC, bW + 1, 2))
            If bVTr > 0 And (Mid(sComm, bVTr + 2, 1) = "-" _
                Or Mid(sComm, bVTr + 2, 1) = " ") Then _
                .Characters(Start:=bVTr, Length:=2).Font.ColorIndex = 3
        Next bW

    End With
 Next Clls
Exit Sub:           End Sub


Comment.jpg
 
Đúng là macro của bro đã có phát huy tác dụng, nhưng vẫn còn bỏ sót 1 số thỏa điều kiện mà vẫn chưa được thi hành. Rất mong các bro cùng nhau khắc phục lỗi này nhé .... Thanks !!!
 
Cứ tưởng việc trích xuất chuổi từ trong Comment là độc quyền của VBA, nhưng tôi phát hiện thì ra công thức vẫn có thể làm dc điều này...
Quy trinh thực hiện như sau:



A> Giã thiết rằng trong bảng tính chỉ có comment mà ko có bất cứ object nào khác:
Bước 1: Đặt con trỏ chuột tại cell đầu tiên, nơi mà bạn muốn xuất dử liệu ra.. Tiếp theo vào Define name và đặt các name sau đây:​
Mã:
Ob_Label =GET.DOCUMENT(42+NOW()*0)
[/INDENT]

[INDENT]Get_Com =GET.OBJECT(12,INDEX(Ob_Label,1,ROWS($1:1)))
Bước 2: Ngay tại vị trí cell ấy, gõ vào công thức:​
Mã:
=SUBSTITUTE(Get_Com,CHAR(10),"-")
Kéo fill công thức xuống​

B> Trong trường hợp trên bảng tính ngoài comment còn có các object khác thì công việc khó hơn 1 chút:
Bước 1: Đặt con trỏ tại cell đầu tiên mà bạn muốn xuất dử liệu rồi vào Define name và đặt 3 name:​
Mã:
Ob_Label =GET.DOCUMENT(42+NOW()*0)
[/INDENT][INDENT]Get_Com =GET.OBJECT(12,INDEX(Ob_Label,1,SMALL(VT,ROWS($1:1))))[/INDENT][INDENT]VT =IF(ISERR(SEARCH("Comment",Ob_Label,1)),"",TRANSPOSE(ROW(INDIRECT("1:"&COUNTA(Ob_Label)))))
Bước 2: Gõ vào cell ấy công thức:​
Mã:
=SUBSTITUTE(Get_Com,CHAR(10),"-")
Kéo fill công thức xuống​
Thế là xong!
Bây giờ phần việc khó nhất đã xong, việc còn lại của các cao thủ là dùng cách gì đó để lấy ra giá trị mình cần... Chuyện này nhỏ như con thỏ nhỉ
He... he...
Xem file nhé!
ANH TUẤN
 

File đính kèm

Lần chỉnh sửa cuối:
Đúng là Bác Tuấn có nhiều cách làm cho công thức trở nên linh hoạt không ngờ
 
Tôi xin nói thêm 1 tí về hàm =GET.DOCUMENT(42)
Hàm này tạo ra 1 mãng ngang với các phần tử là tên của tất cả các object đang tồn tại trong sheet.. Việc sắp xếp các phần tử trong mãng dựa trên tiêu chí object dc vẽ ra trước sẽ sắp trước, object vẽ sau sẽ sắp sau (chứ ko nhóm từng loại vào chung)... Chính vì lẽ đó đã gây khó khăn ko ít cho việc xử lý mãng, tách phần Comment ra riêng!
------------------------
Chúng ta có thể áp dụng hàm này để tìm ra các Object trong sheet 1 cách dể dàng đấy (bất kể object đang ẩn hay hiện)
Mến
ANH TUẤN
 
Lần chỉnh sửa cuối:
Các bạn xem dùm đoạn code đã đạt yêu cầu chưa?
Mã:
Option Explicit
Sub colorC()
Dim StrC1 As Variant, StrC3 As Variant
Dim C3 As Integer, i As Integer, t As Integer, m As Integer
Dim StrChuoilon As String
Dim MyCell As Range
Range("vungchon").Select
For Each MyCell In Selection
StrChuoilon = MyCell.Offset(0, 1).Comment.Text
StrChuoilon = Replace(StrChuoilon, Chr(10), "-")
MyCell.Offset(0, 1).Comment.Shape.TextFrame.Characters.Font.ColorIndex = 11
     C3 = 1
     StrC1 = Split(MyCell, " ")
     For i = 1 To UBound(StrC1)
             StrC3 = Split(StrChuoilon, "-")
              For t = 0 To UBound(StrC3)
                  m = Len(StrC3(t))
                  StrC3(t) = RTrim(StrC3(t))
                  If StrC1(i) = Right(StrC3(t), 2) Then
                 MyCell.Offset(0, 1).Comment.Shape.TextFrame.Characters(Start:=C3 + Len(StrC3(t)) - 2, Length:=2).Font.ColorIndex = 3
                  End If
               C3 = C3 + m + 1
             Next
            C3 = 1
    Next
Next
End Sub
 

File đính kèm

Cám ơn Voda rất nhiều, kết qua đạt yêu cầu 100% ... Vậy là Voda đã giải quyết xong tất cả các câu hỏi đã đạt ra rồi !

P/S: bro ơi, còn 1 sự cố nhỏ nhờ các bro giải quyết giúp luôn là trường hợp của Voda thì rất OK nhưng chỉ sử dụng được trên 1 Sheet thôi, nếu nhảy qua Sheet khác cũng trường hợp như vậy thì không thực hiện việc thay đổi màu mà chỉ thực hiện được lọc kết quả thôi.

Thanks !
 
Lần chỉnh sửa cuối:
Cứ tưởng việc trích xuất chuổi từ trong Comment là độc quyền của VBA, nhưng tôi phát hiện thì ra công thức vẫn có thể làm dc điều này...
Quy trinh thực hiện như sau:

thực ra a làm như vậy là công thức k thuần túy

vì đó là dạng của macro 4 _> đều có thể làm được mọi điều mà VBA - dĩ nhiên là đồng mục đích nhưngchưa chắc đã mạnh bằng

-> khẳng định một điều rằng còn nhiều công thức chưa khám phá

hy vọng GPE có nhìu ng như a tuan sẽ khám phá hết, hi iiiiiiiii
 
- Các bro giải quyết xong vấn đề trên & tiếp tục tìm thêm 1 giải pháp giúp mình nữa nhé các bro,

- Theo hình minh họa dưới & có đính kèm theo file demo thì công việc cần giải quyết như sau :

+ Trong Sheet1, mình có những ô Comment [E2:E39] đã được Insert Comment sẵn sẵng nhưng trong những ô Comment này sẽ được rỗng (không chứa bất kì dữ liệu nào).
+ Trong Sheet2, mình có ô B2:B10 được chứa sẵn dữ liệu.
+ Vậy Y/C đặt ra là từ trong Sheet1 & con trỏ ở bất kì ô Comment nào, các bro dùng giải pháp sao cho tại ngay con trỏ có chứa Comment rỗng sẽ tự động lấy dữ liệu từ ô B2:B10 trong Sheet2 vào ngay Comment rỗng này & chỉ vào duy nhất 1 ô Comment mà vị trí con trỏ đang đứng tại Comment đó.

Thanks !!!

FillCommentSheet1.jpg

FillCommentSheet2.jpg
 

File đính kèm

Lần chỉnh sửa cuối:
Nguyên văn bởi SA_DQ
Sao đoạn code này bỏ sót
Theo mình nguyên nhân như sau:
1.Các số trong ô tương ứng với Comment:
17 59 37
2. Các số trong Comment:
Mã:
                                 76 
                                8[COLOR="Red"]17 [/COLOR]
                            [B]37[/B]72-0054-57[COLOR="red"]59[/COLOR] 
                              2646 
           29892-51358-45642-81744-20084-85237-71366 
                       69140-83216 
                            03994 
                            26532 
                             65434
Nhìn vào ta có thể thấy ngay chính số 37 trong 3772 đã làm cho số 37 trong 85237 bị bỏ qua...
 
Web KT

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

Back
Top Bottom