VBA và Vlookup (1 người xem)

Liên hệ QC

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

Cá ngừ F1

( ͡° ͜ʖ ͡°)
Thành viên BQT
Moderator
Tham gia
1/1/08
Bài viết
2,579
Được thích
3,723
Donate (Momo)
Donate
Giới tính
Nam
Nghề nghiệp
Quan hệ.. và quan hệ..
E có một file dữ liệu (các code copy của thầy NDU) - có 2 sheet là Data và P22
Code trong Module
Option ExplicitPublic Chk As Boolean, Dic As Object, aResult()
Sub Auto_Open()
Dim wks As Worksheet, SrcRng As Range, sArray
Dim lR As Long, i As Long, n As Long, tmp
On Error Resume Next
Set wks = Sheets("P22")
Set SrcRng = wks.Range("A1:K10000")
sArray = SrcRng.Value
ReDim aResult(1 To UBound(sArray, 1), 1 To UBound(sArray, 2))
Set Dic = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(sArray, 1)
If CStr(sArray(i, 1)) <> "" Then
tmp = sArray(i, 1)
If Not Dic.Exists(tmp) Then
lR = lR + 1
Dic.Add tmp, lR
aResult(lR, 1) = tmp
aResult(lR, 2) = sArray(i, 2)
aResult(lR, 3) = sArray(i, 3)
aResult(lR, 5) = sArray(i, 5)
aResult(lR, 6) = sArray(i, 6)
aResult(lR, 14) = sArray(i, 14)
aResult(lR, 13) = sArray(i, 13)
End If
End If
Next
End Sub
Code trong sheet Data
Private Sub Worksheet_Change(ByVal Target As Range) Dim rTarget As Range, aTarget, i As Long, n As Long
Dim Arr1(), Arr2(), Arr3(), tmp
On Error Resume Next
If Dic Is Nothing Then Auto_Open
If Not Intersect(Range("F2:F10000"), Target) Is Nothing Then
Set rTarget = Intersect(Range("F2:F10000"), Target)
If IsArray(rTarget.Value) Then
aTarget = rTarget.Value
Else
ReDim aTarget(1 To 1, 1 To 1)
aTarget(1, 1) = rTarget.Value
End If
ReDim Arr1(1 To UBound(aTarget, 1), 1 To 2)
ReDim Arr2(1 To UBound(aTarget, 1), 1 To 3)
ReDim Arr3(1 To UBound(aTarget, 1), 1 To 1)
For i = 1 To UBound(aTarget, 1)
If aTarget(i, 1) <> "" Then
tmp = aTarget(i, 1)
If Dic.Exists(tmp) Then
Arr1(i, 1) = aResult(Dic.Item(tmp), 2)
Arr1(i, 2) = aResult(Dic.Item(tmp), 3)
Arr2(i, 1) = aResult(Dic.Item(tmp), 5)
Arr2(i, 2) = aResult(Dic.Item(tmp), 6)
Arr2(i, 3) = aResult(Dic.Item(tmp), 14)
Arr3(i, 1) = aResult(Dic.Item(tmp), 13)
End If
End If
Next
rTarget.Offset(, 1).Resize(, 2).Value = Arr1
rTarget.Offset(, 4).Resize(, 3).Value = Arr2
rTarget.Offset(, 11).Resize(, 1).Value = Arr3
End If
End Sub
E có loay hoay để sửa nhưng mà quay quay cái đầu, chả ra đâu vào đâu :=\+ (chưa hiểu bản chất vấn đề)
Lookup_value e để ở Range("F2:F10000") của sheet Data
Giờ muốn tìm kiếm 6 cột bên sheet P22 để đưa vào sheet Data (thay cho hàm vlookup nặng nề) thì code cần thêm/sửa những j

P/S: quả thật file này bảo mật nên ko thể úp lên đây, mong các thầy/anh/chị thông cảm giúp đỡ
 
E xin gửi file ạh
Thêm 1 trường Ma1 và D1.. thầy xem giúp e ạh
 

File đính kèm

Upvote 0
E xin gửi file ạh
Thêm 1 trường Ma1 và D1.. thầy xem giúp e ạh

Code của bạn là:
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
  Dim rTarget As Range, aTarget, lR As Long, n As Long
  Dim arr1(), arr2(), arr3()
  Dim tmp1 As String, tmp2 As String
  On Error Resume Next
  If dic1 Is Nothing Then Auto_Open
  If Not Intersect(Range("F2:F10000"), Target) Is Nothing Then
    Set rTarget = Intersect(Range("F2:F10000"), Target)
    aTarget = rTarget.Value
    If Not IsArray(rTarget.Value) Then
      ReDim aTarget(1 To 1, 1 To 1)
      aTarget(1, 1) = rTarget.Value
    End If
    ReDim arr1(1 To UBound(aTarget, 1), 1 To 1)
    ReDim arr2(1 To UBound(aTarget, 1), 1 To 2)
    ReDim arr3(1 To UBound(aTarget, 1), 1 To 2)
    For lR = 1 To UBound(aTarget, 1)
      If Len(aTarget(lR, 1)) Then
        [COLOR=#ff0000]tmp1 = "_" & aTarget(lR, 1)[/COLOR]
        If dic1.Exists(tmp1) Then
          tmp2 = aResult(dic1.Item(tmp1), 7)
          If dic2.Exists(tmp2) Then
            arr1(lR, 1) = dic2.Item(tmp2)
          Else
            arr1(lR, 1) = "Act"
          End If
          arr2(lR, 1) = aResult(dic1.Item(tmp1), 6)
          arr2(lR, 2) = aResult(dic1.Item(tmp1), 5)
          arr3(lR, 1) = aResult(dic1.Item(tmp1), 4)
          arr3(lR, 2) = aResult(dic1.Item(tmp1), 9)
        End If
      End If
    Next
    rTarget.Offset(, 1).Resize(, 1).Value = arr1
    rTarget.Offset(, 6).Resize(, 2).Value = arr2
    rTarget.Offset(, 9).Resize(, 2).Value = arr3
  ElseIf Not Intersect(Range("J2:J10000"), Target) Is Nothing Then
    Set rTarget = Intersect(Range("J2:J10000"), Target)
    aTarget = rTarget.Value
    If Not IsArray(rTarget.Value) Then
      ReDim aTarget(1 To 1, 1 To 1)
      aTarget(1, 1) = rTarget.Value
    End If
    ReDim arr1(1 To UBound(aTarget, 1), 1 To 1)
    ReDim arr2(1 To UBound(aTarget, 1), 1 To 1)
    For lR = 1 To UBound(aTarget, 1)
      If Len(aTarget(lR, 1)) Then
        [COLOR=#ff0000]tmp1 = "_" & aTarget(lR, 1)[/COLOR]
        If dic1.Exists(tmp1) Then
          tmp2 = aResult(dic1.Item(tmp1), 7)
          If dic2.Exists(tmp2) Then
            arr1(lR, 1) = dic2.Item(tmp2)
          Else
            arr1(lR, 1) = "Act"
          End If
          arr2(lR, 1) = aResult(dic1.Item(tmp1), 9)
        End If
      End If
    Next
    rTarget.Offset(, 1).Resize(, 1).Value = arr1
    rTarget.Offset(, 7).Resize(, 1).Value = arr2
  End If
End Sub
Để ý 2 đoạn màu đỏ tôi đánh dấu
- Đoạn màu đỏ ở trên: Do MÃ của ta không có dấu _ ở đâu nên biến Tmp ta phải tự thêm vào (tmp1 = "_" & aTarget(lR, 1))
- Đoạn màu đỏ ở dưới: Mã 1 tại cột J của bạn đã có dấu _ rồi, vậy thì thêm vào là THỪA và làm code chạy trật lật (do không tìm thấy
Vậy, đoạn màu đỏ ở dưới chỉ cần vầy: tmp1 = aTarget(lR, 1)
Hợp lý không?
 
Upvote 0
Dạ, e xin phép LÁI XE
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
  Dim rTarget As Range, aTarget, lR As Long, n As Long
  Dim arr1(), arr2()
  Dim tmp1 As String, tmp2 As String
  On Error Resume Next
  If dic1 Is Nothing Then Auto_Open
  If Not Intersect(Range([B]"F2:F10000"[/B]), Target) Is Nothing Then
    Set rTarget = Intersect(Range([B]"F2:F10000"[/B]), Target)
    aTarget = rTarget.Value
    If Not IsArray(rTarget.Value) Then
      ReDim aTarget(1 To 1, 1 To 1)
      aTarget(1, 1) = rTarget.Value
    End If
    ReDim arr1(1 To UBound(aTarget, 1), 1 To 1)
    ReDim arr2(1 To UBound(aTarget, 1), 1 To 4)
    For lR = 1 To UBound(aTarget, 1)
      If Len(aTarget(lR, 1)) Then
        tmp1 = "_" & aTarget(lR, 1)
        If dic1.Exists(tmp1) Then
          tmp2 = aResult(dic1.Item(tmp1), 7)
          If dic2.Exists(tmp2) Then
            arr1(lR, 1) = dic2.Item(tmp2)
          Else
            arr1(lR, 1) = "Act"
          End If
          arr2(lR, 1) = aResult(dic1.Item(tmp1), 4)
          arr2(lR, 2) = aResult(dic1.Item(tmp1), 5)
          arr2(lR, 3) = aResult(dic1.Item(tmp1), 6)
          arr2(lR, 4) = aResult(dic1.Item(tmp1), 9)
          End If
      End If
    Next
    rTarget.Offset(, 1).Resize(, 1).Value = arr1
    rTarget.Offset(, 36).Resize(, 4).Value = arr2
  ElseIf Not Intersect(Range([B]"AC2:AC10000"[/B]), Target) Is Nothing Then
    Set rTarget = Intersect(Range([B]"AC2:AC10000"[/B]), Target)
    aTarget = rTarget.Value
    If Not IsArray(rTarget.Value) Then
      ReDim aTarget(1 To 1, 1 To 1)
      aTarget(1, 1) = rTarget.Value
    End If
    ReDim arr1(1 To UBound(aTarget, 1), 1 To 1)
    ReDim arr2(1 To UBound(aTarget, 1), 1 To 1)
    For lR = 1 To UBound(aTarget, 1)
      If Len(aTarget(lR, 1)) Then
        tmp1 = "_" & aTarget(lR, 1)
        If dic1.Exists(tmp1) Then
          tmp2 = aResult(dic1.Item(tmp1), 7)
          If dic2.Exists(tmp2) Then
            arr1(lR, 1) = dic2.Item(tmp2)
          Else
            arr1(lR, 1) = "Act"
          End If
          arr2(lR, 1) = aResult(dic1.Item(tmp1), 9)
        End If
      End If
    Next
      rTarget.Offset(, 5).Resize(, 1).Value = arr1
      rTarget.Offset(, 17).Resize(, 1).Value = arr2
  ElseIf Not Intersect(Range([B]"AJ2:AJ10000"[/B]), Target) Is Nothing Then
    Set rTarget = Intersect(Range([B]"AJ2:AJ10000"[/B]), Target)
    aTarget = rTarget.Value
    If Not IsArray(rTarget.Value) Then
      ReDim aTarget(1 To 1, 1 To 1)
      aTarget(1, 1) = rTarget.Value
    End If
    ReDim arr1(1 To UBound(aTarget, 1), 1 To 1)
    ReDim arr2(1 To UBound(aTarget, 1), 1 To 1)
    For lR = 1 To UBound(aTarget, 1)
      If Len(aTarget(lR, 1)) Then
        tmp1 = "_" & aTarget(lR, 1)
        If dic1.Exists(tmp1) Then
          tmp2 = aResult(dic1.Item(tmp1), 7)
          If dic2.Exists(tmp2) Then
            arr1(lR, 1) = dic2.Item(tmp2)
          Else
            arr1(lR, 1) = "Act"
          End If
          arr2(lR, 1) = aResult(dic1.Item(tmp1), 9)
        End If
      End If
    Next
      rTarget.Offset(, 5).Resize(, 1).Value = arr1
      rTarget.Offset(, 11).Resize(, 1).Value = arr2
  End If
End Sub
Bảng tính của e có 3 mảng lookup_value. Sử dụng hàm theo kiểu truyền thống phải mất vài giây tính toán.
Những j thầy đã chỉ dậy, file chạy thực sự nhanh, mặc dù các mảng dữ liệu khá lơn...
Có thể nói câu này thành hơi sáo ngữ nhưng em vẫn nói "Cảm ơn thầy",
Mong đợi những bài học tiếp theo!!!
 
Upvote 0
E xin gửi file ạh
Thêm 1 trường Ma1 và D1.. thầy xem giúp e ạh
Cho e hỏi bổ đề thêm chút.. e xin phép pốt tiếp vào đây cho liền mạch.. file lấy ở bài #21
Câu hỏi như sau:
- Làm sao có thể triết xuất ra 1 báo cáo để lấy những Mã có trong sheets("BC").range(A:A) mà không có trong sheets("data").range("F:F") và sheets("data").range("J:J")
 

File đính kèm

Upvote 0
Cho e hỏi bổ đề thêm chút.. e xin phép pốt tiếp vào đây cho liền mạch.. file lấy ở bài #21
Câu hỏi như sau:
- Làm sao có thể triết xuất ra 1 báo cáo để lấy những Mã có trong sheets("BC").range(A:A) mà không có trong sheets("data").range("F:F") và sheets("data").range("J:J")

Đây là bài toán khác rồi (không thuộc chủ đề topic này)
Bài toán:
- Tìm kiếm dữ liệu tồn tại trong List1 và List2
- Tìm kiếm dữ liệu tồn tại trong List1 mà không tồn tại trong List2
- Tìm kiếm dữ liệu tồn tại trong List2 mà không tồn tại trong List1
3 bài toán tìm kiếm dạng trên đã post trên diễn đàn mấy chục lần rồi... có thể dùng phương pháp thủ công (advanced filter) hoặc viết code tùy ý
Bạn tìm đí
Nhớ rằng: Không được hỏi chen ngang 1 chủ đề không liên quan nha
 
Upvote 0
Sau khi LÁI XE khá tốt (#23) ..có một số vướng mắc sau ạh
sau khi sheet BC thay đổi số liệu..thì ko thấy bên sheet data thay đổi số liệu, vậy phải thêm động tác nào vào nữa ạh...
 
Upvote 0
Sau khi LÁI XE khá tốt (#23) ..có một số vướng mắc sau ạh
sau khi sheet BC thay đổi số liệu..thì ko thấy bên sheet data thay đổi số liệu, vậy phải thêm động tác nào vào nữa ạh...
E test thử bằng cách: cho sheet BC số liệu khác sau đó copy/paste lại mã ở Data thì mới thấy có tác dụng, nhưng mà nếu thêm đoạn code để copy/paste lại một loạt mã số thì e hơi CÙI BẮP ạh...
 
Upvote 0
E test thử bằng cách: cho sheet BC số liệu khác sau đó copy/paste lại mã ở Data thì mới thấy có tác dụng, nhưng mà nếu thêm đoạn code để copy/paste lại một loạt mã số thì e hơi CÙI BẮP ạh...
Các thầy/anh/chị giúp e với ạh, file thử nghiệm có thể lấy ở bài #24 ạh
 
Upvote 0
Mình đọc không nổi cái rừng của anh NDU nhưng nếu chỉ muốn thay mấy cái Vlookup đó thì bạn copy code này thử xem. Code mình viết thuộc dạng dưới cả căn bản nên dể chỉnh sửa. Tuy nhiên dữ liệu của bạn bị trùng thì Vookup chỉ tìm ra giá trị đầu thôi
PHP:
Sub VlookUp2()
Dim LookUpValue(), DesArr1(), DesArr2(), DesArr3(), i As Long, j As Long
Dim String1 As Range, String2 As String, String3 As Range
With Sheets("DATA")
   LookUpValue = .Range(.[F2], .[F65536].End(3)).Value
End With
ReDim DesArr1(1 To UBound(LookUpValue), 1 To 1)
ReDim DesArr2(1 To UBound(LookUpValue), 1 To 2)
ReDim DesArr3(1 To UBound(LookUpValue), 1 To 2)
For i = 1 To UBound(LookUpValue)
   Set String1 = Sheets("BC").[A:A].Find("_" & LookUpValue(i, 1), , , 1)
   If Not String1 Is Nothing Then
      Set String3 = Sheets("Status").[A:A].Find(String1.Offset(, 6), , , 1)
      If Not String3 Is Nothing Then
         DesArr1(i, 1) = String3.Offset(, 1)
      End If
      DesArr2(i, 1) = String1.Offset(, 5)
      DesArr2(i, 2) = String1.Offset(, 4)
      DesArr3(i, 1) = String1.Offset(, 3)
      DesArr3(i, 2) = String1.Offset(, 8)
   End If
Next
Sheets("DATA").[G2].Resize(i - 1) = DesArr1
Sheets("DATA").[L2].Resize(i - 1, 2) = DesArr2
Sheets("DATA").[O2].Resize(i - 1, 2) = DesArr3
End Sub
E có làm theo cách của a quanghai1969
Giả sử file có thêm mảng lookup value thì code cần thêm j ạh (ngoài mảng LookUpValue = .Range(.[F2], .[F65536].End(3)).Value), giả sử X2:X65536 chẳng hạn
E cảm ơn!
 
Upvote 0
E có làm theo cách của a quanghai1969
Giả sử file có thêm mảng lookup value thì code cần thêm j ạh (ngoài mảng LookUpValue = .Range(.[F2], .[F65536].End(3)).Value), giả sử X2:X65536 chẳng hạn
E cảm ơn!
Mình thuộc dạng người có IQ thấp nên thấy file có kèm công thức minh hoạ thì tìm cách, không có file thì hướng dẫn trật là cái chắc
 
Upvote 0
Mình thuộc dạng người có IQ thấp nên thấy file có kèm công thức minh hoạ thì tìm cách, không có file thì hướng dẫn trật là cái chắc
E xin pốt file ạh
- Giả sử file có thêm range lookup value ở cột Ma2 [D2:D65356]
- Thêm vào code để tìm kiếm kết quả ở status2, D2 (vẫn lấy từ sheet BC ạh)
Status2 vẫn lấy tham chiếu như status
D2 lấy tham chiếu như D1
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
E xin pốt file ạh
- Giả sử file có thêm range lookup value ở cột Ma2 [D2:D65356]
- Thêm vào code để tìm kiếm kết quả ở status2, D2 (vẫn lấy từ sheet BC ạh)
Status2 vẫn lấy tham chiếu như status
D2 lấy tham chiếu như D1
Thêm như thế này chắc là được nhưng đọc code thấy như cái rừng ớn thiệt
Mã:
Sub VlookUp2()
Dim LookUpValue(), LookupValue2(), DesArr1(), DesArr2(), DesArr3(), DesArr4()
Dim String1 As Range, String2 As Range, String3 As Range, i As Long, j As Long
With Sheets("DATA")
   LookUpValue = .Range(.[F2], .[F65536].End(3)).Value
   LookupValue2 = .Range(.[d2], .[D65536].End(3)).Value
   ReDim DesArr1(1 To UBound(LookUpValue), 1 To 1)
   ReDim DesArr2(1 To UBound(LookUpValue), 1 To 2)
   ReDim DesArr3(1 To UBound(LookUpValue), 1 To 2)
   ReDim DesArr4(1 To UBound(LookUpValue), 1 To 2)
   For i = 1 To UBound(LookUpValue)
      Set String1 = Sheets("BC").[A:A].Find("_" & LookUpValue(i, 1), , , 1)
      Set String2 = Sheets("BC").[A:A].Find("_" & LookupValue2(i, 1), , , 1)
      If Not String1 Is Nothing Then
         Set String3 = Sheets("Status").[A:A].Find(String1.Offset(, 6), , , 1)
         If Not String3 Is Nothing Then
            DesArr1(i, 1) = String3.Offset(, 1)
         End If
         DesArr2(i, 1) = String1.Offset(, 5)
         DesArr2(i, 2) = String1.Offset(, 4)
         DesArr3(i, 1) = String1.Offset(, 3)
         DesArr3(i, 2) = String1.Offset(, 8)
      End If
      If Not String2 Is Nothing Then
         Set String3 = Sheets("Status").[A:A].Find(String2.Offset(, 6), , , 1)
         If Not String3 Is Nothing Then
            DesArr4(i, 1) = String3.Offset(, 1)
         End If
         DesArr4(i, 2) = String2.Offset(, 8)
      End If
   Next
   .[G2].Resize(i - 1) = DesArr1
   .[L2].Resize(i - 1, 2) = DesArr2
   .[O2].Resize(i - 1, 2) = DesArr3
   .[Q2].Resize(i - 1, 2) = DesArr4
End With
End Sub
 
Upvote 0
Dạ..cảm ơn a..đi đường rừng mà nhanh hơn thì cũng phải triển thôi...
 
Upvote 0
Thêm như thế này chắc là được nhưng đọc code thấy như cái rừng ớn thiệt
Mã:
Sub VlookUp2()
Dim LookUpValue(), LookupValue2(), DesArr1(), DesArr2(), DesArr3(), DesArr4()
Dim String1 As Range, String2 As Range, String3 As Range, i As Long, j As Long
With Sheets("DATA")
   LookUpValue = .Range(.[F2], .[F65536].End(3)).Value
   LookupValue2 = .Range(.[d2], .[D65536].End(3)).Value
   ReDim DesArr1(1 To UBound(LookUpValue), 1 To 1)
   ReDim DesArr2(1 To UBound(LookUpValue), 1 To 2)
   ReDim DesArr3(1 To UBound(LookUpValue), 1 To 2)
   ReDim DesArr4(1 To UBound(LookUpValue), 1 To 2)
   For i = 1 To UBound(LookUpValue)
      Set String1 = Sheets("BC").[A:A].Find("_" & LookUpValue(i, 1), , , 1)
      Set String2 = Sheets("BC").[A:A].Find("_" & LookupValue2(i, 1), , , 1)
      If Not String1 Is Nothing Then
         Set String3 = Sheets("Status").[A:A].Find(String1.Offset(, 6), , , 1)
         If Not String3 Is Nothing Then
            DesArr1(i, 1) = String3.Offset(, 1)
         End If
         DesArr2(i, 1) = String1.Offset(, 5)
         DesArr2(i, 2) = String1.Offset(, 4)
         DesArr3(i, 1) = String1.Offset(, 3)
         DesArr3(i, 2) = String1.Offset(, 8)
      End If
      If Not String2 Is Nothing Then
         Set String3 = Sheets("Status").[A:A].Find(String2.Offset(, 6), , , 1)
         If Not String3 Is Nothing Then
            DesArr4(i, 1) = String3.Offset(, 1)
         End If
         DesArr4(i, 2) = String2.Offset(, 8)
      End If
   Next
   .[G2].Resize(i - 1) = DesArr1
   .[L2].Resize(i - 1, 2) = DesArr2
   .[O2].Resize(i - 1, 2) = DesArr3
   .[Q2].Resize(i - 1, 2) = DesArr4
End With
End Sub
code đang ko chạy ạh
New Picture (21).jpg
 
Upvote 0
Lúc này cước 3g đắt quá nên up file ngại lắm.
Sao anh không Xóa bớt dòng ở Sheet BC đi cho nhẹ.
Cái món Array khó nhai quá anh ạ, híc ...
Bạn Cá ngừ F1 gửi file cũng nên giảm bớt dung lượng file, dạo này 3G tăng cước, buổi tối mình online chút xíu hết 10k, chắc phải chuyển qua wifi thôi.
 
Upvote 0
Sao anh không Xóa bớt dòng ở Sheet BC đi cho nhẹ.
Cái món Array khó nhai quá anh ạ, híc ...
Bạn Cá ngừ F1 gửi file cũng nên giảm bớt dung lượng file, dạo này 3G tăng cước, buổi tối mình online chút xíu hết 10k, chắc phải chuyển qua wifi thôi.
Àh.. lúc đấy úp có wf free mà... chả mấy khi..hí hí
 
Upvote 0
Iq của anh to bự luôn !? Em copy được rất nhiều code của anh sử dụng tuyệt vời ...xúc tích ngắn gọn và những người chưa từng được học lấy một ngày về code như em vẫn đọc và hữu tí ti vận dụng được là một điều trên cả tuyệt vời... Sư phụ ...hic hic
 
Upvote 0
Web KT

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

Back
Top Bottom