0905744404
Thành viên thường trực




- Tham gia
- 26/10/10
- Bài viết
- 333
- Được thích
- 107
- Nghề nghiệp
- Trước là : Thủ Kho - còn giờ thì :"Tài Xế"
Em nhờ mọi cả nhà giúp em viết code chuyển từ hàm Vlookup() sang Code VBA
Sub MyVlookup()
Dim arr1(), arr2(), i&, j&
j = Range("B65000").End(xlUp).Row
Range("C2") = 1
Range("C2").AutoFill Range("C2:C" & j), xlFillSeries
Range("A2:C" & j).Sort Range("A2")
arr1 = Range("A2:B" & j)
Range("A2:C" & j).Sort Range("C2")
Range("C2:C" & j).Clear
j = Range("F65000").End(xlUp).Row
Range("E2") = 1
Range("E2").AutoFill Range("E2:E" & j), xlFillSeries
Range("E2:F" & j).Sort Range("F2")
arr2 = Range("F2:G" & Range("F65000").End(xlUp).Row)
For j = 1 To UBound(arr2)
If i > UBound(arr1) - 1 Then
arr2(j, 2) = ""
Else
Do While i <= UBound(arr1) - 1
i = i + 1
If arr1(i, 1) = arr2(j, 1) Then
arr2(j, 2) = arr1(i, 2)
Exit Do
ElseIf arr1(i, 1) > arr2(j, 1) Then
arr2(j, 2) = ""
i = i - 1
Exit Do
End If
Loop
End If
Next
Range("F2:G" & j) = arr2
Range("E2:G" & j).Sort Range("E2")
Range("E2:E" & j).Clear
End Sub
Sub NoneDic()
Dim Vung, Tim, Tm, I, J
Vung = Range([A2], [A50000].End(xlUp)).Resize(, 2)
Tim = Range([F2], [F50000].End(xlUp)).Resize(, 2)
Tm = Range([A2], [A50000].End(xlUp))
On Error Resume Next
For I = 1 To UBound(Tim, 1)
J = WorksheetFunction.Match(Tim(I, 1), Tm, 0)
If J > 0 Then Tim(I, 2) = Vung(J, 2): Tm(J, 1) = "": J = ""
Next
Range([F2], [F50000].End(xlUp)).Resize(, 2) = Tim
End Sub
Code của bác Sealand không khác gì vlookup thông thường cả, tức là chỉ tìm giá trị đầu tiên. Ở đây đề bài mà bác Let Gâu là sau khi tìm được "Nguyễn Văn 12" lần 1 ở hàng 2 (kết quả 20) rồi thì lần 2 sẽ tìm từ hàng sau trở đi (kết quả ở hàng 5 là 28). Nếu không tìm thấy thì để trống.
Sub NoneDic()
Dim Vung, Tim, Tm, i, j
Vung = Range([A2], [A50000].End(xlUp)).Resize(, 2)
Tim = Range([F2], [F50000].End(xlUp)).Resize(, 2)
Tm = Range([A2], [A50000].End(xlUp))
On Error Resume Next
For i = 1 To UBound(Tim, 1)
j = WorksheetFunction.Match(Tim(i, 1), Tm, 0)
If Err.Number > 0 Then
Tim(i, 2) = ""
Err.Clear
Else
Tim(i, 2) = Vung(j, 2)
[COLOR=#ff0000]Vung(j, 1) = ""[/COLOR]
End If
Next
Range([F2], [F50000].End(xlUp)).Resize(, 2) = Tim
End Sub
Tôi hiểu giải thuật của anh Sealand
Mấu chốt nằm ở chỗ màu đỏ ấyMã:Sub NoneDic() Dim Vung, Tim, Tm, i, j Vung = Range([A2], [A50000].End(xlUp)).Resize(, 2) Tim = Range([F2], [F50000].End(xlUp)).Resize(, 2) Tm = Range([A2], [A50000].End(xlUp)) On Error Resume Next For i = 1 To UBound(Tim, 1) j = WorksheetFunction.Match(Tim(i, 1), Tm, 0) If Err.Number > 0 Then Tim(i, 2) = "" Err.Clear Else Tim(i, 2) = Vung(j, 2) [COLOR=#ff0000]Vung(j, 1) = ""[/COLOR] End If Next Range([F2], [F50000].End(xlUp)).Resize(, 2) = Tim End Sub
Có thể anh Sealand viết nhầm, lý ra phải là Tm(j, 1) = "" mới đúng
Nếu gọi nó trong ngữ cảnh Application thì đối tượng Application sẽ kềm hiện tượng lỗi lại và đưa luôn cái Object lỗi này cho Match. Vì vậy ta không cần bẫy lỗi. Trong trường hợp này ta xét thẳng tính chất của đối tượng do hàm Match trả về, nếu nó không phải là một con số thì kết luận là tìm không được.
TypeName(Application.Match("a",Range("A1:A10"),0))
Vừa thử xong:
Nếu kết quả trả về là "Error" thì có nghĩa là không tìm thấyMã:TypeName(Application.Match("a",Range("A1:A10"),0))
-------------------
Sao chưa thấy ai dùng Find Method nhỉ?
{=IF(ISERROR(MATCH(F2,$A$2:$A$12,0)),"not found in tb",IF(COUNTIF($F$2:F2,F2)>COUNTIF($A$2:$A$12,F2),"out side",INDEX($A$2:$B$12,SMALL(IF($A$2:$A$12=F2,ROW($A$2:$A$12)),COUNTIF($F$2:F2,F2))[B][SIZE=4]-1[/SIZE][/B],2)))}
Góp vui thêm công thức có thông báo:bới lên cái nữa
đã muộn nhưng có vẫn vui
xin được góp vui 1 cách dùng hàm excel
công thức tại ô H2
với số -1 còn tùy vào việc đặt bảng dò ở đâu . ví dụ bảng dò bắt đầu từ dòng số 10 thì phải -9Mã:{=IF(ISERROR(MATCH(F2,$A$2:$A$12,0)),"not found in tb",IF(COUNTIF($F$2:F2,F2)>COUNTIF($A$2:$A$12,F2),"out side",INDEX($A$2:$B$12,SMALL(IF($A$2:$A$12=F2,ROW($A$2:$A$12)),COUNTIF($F$2:F2,F2))[B][SIZE=4]-1[/SIZE][/B],2)))}
{=IF(COUNTIF($A$2:$A$12,F2)=0,"not found in tb",IFERROR(INDEX($B$2:$B$12,SMALL(IF($A$2:$A$12=F2,ROW($A$2:$A$12)-1,""),COUNTIF($F$2:F2,F2))),"out side"))}
{=IFERROR(INDEX($B$2:$B$12,SMALL(IF($A$2:$A$12=F2,ROW($A$2:$A$12)-1,""),COUNTIF($F$2:F2,F2))),"")}
Vẫn áp dụng bài này:
http://www.giaiphapexcel.com/forum/...ết-dùng-mã-vba-thay-thế-cho-hàm-vlookup/page3
Ta làm như sau:
1> Code trong module
2> Code trong sheet2Mã:Public 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("Sheet2") Set SrcRng = wks.Range("A2:C10000") 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) End If End If Next End Sub
3> Code cho sheet 3Mã:Private Sub Worksheet_Change(ByVal Target As Range) Chk = True End Sub Private Sub Worksheet_Deactivate() If Chk Then Auto_Open Chk = False End If End Sub
Mã:Private Sub Worksheet_Change(ByVal Target As Range) Dim rTarget As Range, aTarget, i As Long Dim arr(), tmp On Error Resume Next If Dic Is Nothing Then Auto_Open If Not Intersect(Range("B3:B1000"), Target) Is Nothing Then Set rTarget = Intersect(Range("B3:B1000"), 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 arr(1 To UBound(aTarget, 1), 1 To 2) For i = 1 To UBound(aTarget, 1) If aTarget(i, 1) <> "" Then tmp = aTarget(i, 1) If Dic.Exists(tmp) Then arr(i, 1) = aResult(Dic.Item(tmp), 2) arr(i, 2) = aResult(Dic.Item(tmp), 3) End If End If Next rTarget.Offset(, 1).Resize(, 2).Value = arr End If End Sub
Tốt nhất bạn nên mở topic mới kèm file + kết quả mong muốn lên.các bác cho hỏi luôn làm cách nào để tự động them code cho sheet3, vì sheet3 của mình do PM xuất, không có code sẵn, chỉ có giá trị ở cột B, còn lại phải vlookup từ 1 sheet danh mục như sheet 2
1. Click ButtonKính nhờ các cao nhân trợ giúp. Mong muốn của em là thay vì dùng hàm Vlookup không thể Ctrl [ để đến cell đang liên kết trực tiếp giá trị và hàm Vlookup cũng làm nặng file rất nhiều. Em làm bên xây dựng, việc lập giá dự toán, dự thầu sẽ dùng rất nhiều đến tính năng này. Cụ thể em đã có 1 file tổng hợp các vật tư cần dùng bao gồm có cột mã vật tư, tên vật tư, đơn vị tính và giá vật tư hiện tại. 1 file đích thì đang cần nối giá vật tư hiện tại vào cũng có các cột tương tự là MSVT, tên vật tư, đơn vị tính và cột giá cần nối đến.
Trân trọng cảm ơn mọi người đã quan tâm.
Em cảm ơn Anh nhiều. Nếu có giữ được link = trực tiếp từ file nguồn để bấm Ctrl [ sẽ đến được địa chỉ đang link thì tròn bài Anh ạ. Việc đổ ra giá trị (số chết) này nhanh hơn dùng hàm Vlookup nhưng click vào hàm Vlookup ít ra vẫn biết được giá trị lấy từ đâu. Em được voi đòi luôn cả bà tưng nữa Anh thông cảm nhé. Trân trọng.1. Click Button
2. Chọn đến File nguồn "0. Gia vat tu.xlsx"
Có rủi ro là chọn không đúng file thì sẽ không ra kết quả gì.
Theo tôi, bạn nên copy các code mã vật tư và 1 sheet, từ đó tìm kiếm bằng phương thức Find là nhanh nhất. Thực chất thì code của tôi cũng là copy bảng MSVT vào file gốc, rồi tìm kiếm trên đó thôi.
[gpecode=vb]
Sub FindMethod()
Dim FileName As String, sArr(), i&, MSVT(), KQ1(), KQ2(), Rng As Range
If Not Application.FindFile Then Exit Sub
With ActiveWorkbook
FileName = .Name
With .ActiveSheet
sArr = .Range(.[B4], .[E65000].End(3)).Value
End With
.Close False
End With
Sheets("TH vat tu XD").[AA1].Resize(UBound(sArr), 4) = sArr
MSVT = Range(Sheets("TH vat tu XD").[B8], Sheets("TH vat tu XD").[B65000].End(3))
ReDim KQ1(1 To UBound(MSVT), 1 To 2)
ReDim KQ2(1 To UBound(MSVT), 1 To 1)
For i = 1 To UBound(MSVT)
Set Rng = Sheets("TH vat tu XD").[AA1:AA50000].Find(MSVT(i, 1), , , 1)
If Not Rng Is Nothing Then
KQ1(i, 1) = Rng(, 2)
KQ1(i, 2) = Rng(, 3)
KQ2(i, 1) = Rng(, 4)
End If
Next
Sheets("TH vat tu XD").[C8].Resize(i - 1, 2) = KQ1
Sheets("TH vat tu XD").[G8].Resize(i - 1, 1) = KQ2
Sheets("TH vat tu XD").[AA1].Resize(UBound(sArr), 4).Clear
Erase sArr
End Sub[/gpecode]
[note]Lần sau bạn nên mở 1 Topic mới để đặt câu hỏi, đừng chèn câu hỏi vào topic của người khác[/note]
Tôi cũng chưa hiểu thao tác ctrl [ là để làm j nữa.Em cảm ơn Anh nhiều. Nếu có giữ được link = trực tiếp từ file nguồn để bấm Ctrl [ sẽ đến được địa chỉ đang link thì tròn bài Anh ạ. Việc đổ ra giá trị (số chết) này nhanh hơn dùng hàm Vlookup nhưng click vào hàm Vlookup ít ra vẫn biết được giá trị lấy từ đâu. Em được voi đòi luôn cả bà tưng nữa Anh thông cảm nhé. Trân trọng.
Tôi cũng chưa hiểu thao tác ctrl [ là để làm j nữa.
Những để lấy tên file và đường dẫn của file nguồn dán kết quả vào 1 ô nào đó để biết đó là file nào thì có đúng ý bạn không?
Sao không ném luôn cái file giá vật tư vào file Nha de xe đi bạn!!! Làm như thế có phải đỡ tốn công hơn không. Muốn link trực tiếp viết code cũng được, mà chả cần code kiếc gì, viết hàm kết hợp thủ thuật là có liên kết trực tiếp thôi. Còn cái sheet vật tư trong Nhà để xe thì liên kết với File giá vật tư, trong trường hợp nhiều file dự toán cùng liên kết đến 1 giá vật tư gốc thì thay đổi file gốc là các file khác updata theo, nhưng không ảnh hưởng đến liên kết nội bộ file.Ví dự như giá trị ô C1 sheet1 đang được lấy từ ô A1 sheet 3. Tại ô C1 sheet bấm Ctrl [ thì lập tức đến được ô A1 sheet3.
Thao tác này để kiểm tra các file excel quá tiện anh ạ.
https://www.fshare.vn/file/79G69GASSEAW Anh tải về file nén, giải nén, sau đó bấm mở file 2. Nha de xe, tại ô G8 sheet TH vat tu bấm Ctrl [ là hiểu ý đồ của em ngay anh ạ.
Việc biết lấy dữ liệu ở đâu đơn giản thôi mà bạn.Nếu làm như video thì không ổn lắm, file 0. Gia vat tu là 1 file em tổng hợp tất cả các vật tư sẽ dùng trên công trình, sau đó đi tìm giá nhập vào. Trong 1 công trình có khoảng 30 hạng mục như nhà để xe đó. Thủ công thì đứt điện ngay.
Nếu là chỉ để em làm ra giá trị thì không vấn đề, hàm Vlookup thì chỉ vài nốt nhạc là xong, nhưng quan trọng là giúp cho người kiểm tra dễ kiểm tra. Cách của anh Cá ngừ ở trên nhanh hơn hàm Vlookup rồi nhưng không biết lấy từ đâu thì chưa tròn bài.
Xin cảm ơn ACE đã quan tâm.
Thế nào là thủ công nhỉ?? File ví dụ của tôi có vài dòng thì tôi F2 Enter cho nó tiện. Chứ file có hàng nghìn dòng làm thế sao được. Dùng chức năng Find an Replace tùy chọn Formula, 1 nháy xong ngay.Nếu làm như video thì không ổn lắm, file 0. Gia vat tu là 1 file em tổng hợp tất cả các vật tư sẽ dùng trên công trình, sau đó đi tìm giá nhập vào. Trong 1 công trình có khoảng 30 hạng mục như nhà để xe đó. Thủ công thì đứt điện ngay.
Nếu là chỉ để em làm ra giá trị thì không vấn đề, hàm Vlookup thì chỉ vài nốt nhạc là xong, nhưng quan trọng là giúp cho người kiểm tra dễ kiểm tra. Cách của anh Cá ngừ ở trên nhanh hơn hàm Vlookup rồi nhưng không biết lấy từ đâu thì chưa tròn bài.
Xin cảm ơn ACE đã quan tâm.