Nhờ viết hàm tìm kiếm trong VBA (1 người xem)

Liên hệ QC

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

LuongVanHieu

Thành viên mới
Tham gia
24/8/17
Bài viết
18
Được thích
2
Giới tính
Nam
Lần trước đã nhờ các bác giúp đỡ nhưng giờ nảy sinh vấn đề mới là:
Hiện tại mình có file dự liệu
Bình thường mình dùng hàm Vlookup để tìm kiếm dự liệu ở sheets du lieu
Nhưng đợt này do tính chất công việc thay đổi nên mình buộc phải làm giá trị bằng link trực tiếp
Mong các bác giúp đỡ viết hộ mình cái đoạn code này được không
 

File đính kèm

Lần chỉnh sửa cuối:
Xin lỗi các bác em đã có sai sót trong up file
Cảm ơn @chisinhvnn nhắc nhở
Nội dung em muốn làm là như sau:
Viết 1 VBA để link dự liệu từ cột bên Sheet DuLieu vào Sheet DG
Nó là link trực tiếp
Hồi trước em dùng Vlookup để làm công việc này. Nhưng giờ do công việc cần nên mới chuyển sang link trực tiếp dự liệu
Mong các bác giúp đỡ
 

File đính kèm

Upvote 0
Tạm thời là macro cái đã; Hàm thì tính tiếp:
PHP:
Sub GPE()
 Dim WF As Object, Cls As Range, Rg0 As Range

 Set Rg0 = Range([c2], [c65500].End(xlUp).Offset(1)).SpecialCells(xlCellTypeBlanks)
 Set WF = Application.WorksheetFunction
 For Each Cls In Rg0
    With Cls.Offset(, 1)
        .Value = WF.Sum(Range(.Offset(0), .End(xlDown)))
    End With
 Next Cls
End Sub
 
Upvote 0
Tạm thời là macro cái đã; Hàm thì tính tiếp:
PHP:
Sub GPE()
 Dim WF As Object, Cls As Range, Rg0 As Range

 Set Rg0 = Range([c2], [c65500].End(xlUp).Offset(1)).SpecialCells(xlCellTypeBlanks)
 Set WF = Application.WorksheetFunction
 For Each Cls In Rg0
    With Cls.Offset(, 1)
        .Value = WF.Sum(Range(.Offset(0), .End(xlDown)))
    End With
 Next Cls
End Sub

Thực sự buổi sáng dậy thấy có câu trả lời rất chi là vui mừng rồi bác ah!
Nhưng khi chạy nó thật sự không được hiệu quả như mong muốn
Cái mình thực sự là: mình có vùng dự liệu (Dulieu) cần link trực tiếp bên DG sang dữ liệu
Dù sao cùng cảm ơn @Hoang2013 và mong bác và các bác giúp thêm
 
Upvote 0
Thực sự buổi sáng dậy thấy có câu trả lời rất chi là vui mừng rồi bác ah!
Nhưng khi chạy nó thật sự không được hiệu quả như mong muốn
Cái mình thực sự là: mình có vùng dự liệu (Dulieu) cần link trực tiếp bên DG sang dữ liệu
Dù sao cùng cảm ơn @Hoang2013 và mong bác và các bác giúp thêm
Bạn thử:
PHP:
Sub abc()
    Dim Rng1 As Range, Rng2 As Range, LR&, i&, sum1
    Dim GT As Range, Cll As Range
    LR = Sheets("dulieu").Rows.Count
    Set Rng1 = Sheets("Dulieu").Range("B2", Sheets("Dulieu").Range("B" & LR).End(3))
    Set Rng2 = Sheets("DG").Range("B3", Sheets("DG").Range("B" & LR).End(3))
    With Rng1
        For Each Cll In Rng2
            Set GT = .Find(Cll, , xlValues, xlWhole, , , True)
            If Not GT Is Nothing Then
                Range(GT.Offset(0, 1), GT.Offset(0, 1)).Copy
                Cll.Offset(0, 1).PasteSpecial (xlPasteValues)
                Application.CutCopyMode = False
            End If
        Next
    End With
    For i = Cells(Rows.Count, 2).End(3).Row To 2 Step -1
        If Cells(i, 1) = "" Then
            sum1 = sum1 + Cells(i, 3).Value
        Else
            Cells(i, 4) = sum1 + Cells(i, 3)
            sum1 = 0
        End If
    Next
End Sub
 
Upvote 0
Bạn thử:
PHP:
Sub abc()
    Dim Rng1 As Range, Rng2 As Range, LR&, i&, sum1
    Dim GT As Range, Cll As Range
    LR = Sheets("dulieu").Rows.Count
    Set Rng1 = Sheets("Dulieu").Range("B2", Sheets("Dulieu").Range("B" & LR).End(3))
    Set Rng2 = Sheets("DG").Range("B3", Sheets("DG").Range("B" & LR).End(3))
    With Rng1
        For Each Cll In Rng2
            Set GT = .Find(Cll, , xlValues, xlWhole, , , True)
            If Not GT Is Nothing Then
                Range(GT.Offset(0, 1), GT.Offset(0, 1)).Copy
                Cll.Offset(0, 1).PasteSpecial (xlPasteValues)
                Application.CutCopyMode = False
            End If
        Next
    End With
    For i = Cells(Rows.Count, 2).End(3).Row To 2 Step -1
        If Cells(i, 1) = "" Then
            sum1 = sum1 + Cells(i, 3).Value
        Else
            Cells(i, 4) = sum1 + Cells(i, 3)
            sum1 = 0
        End If
    Next
End Sub
Nhờ bác kiểm tra hộ em cái
Khi chạy nó chưa link được file
Nó mới cho giá trị về đùng ô cần tìm
 
Upvote 0
Lần trước đã nhờ các bác giúp đỡ nhưng giờ nảy sinh vấn đề mới là:
Hiện tại mình có file dự liệu
Bình thường mình dùng hàm Vlookup để tìm kiếm dự liệu ở sheets du lieu
Nhưng đợt này do tính chất công việc thay đổi nên mình buộc phải làm giá trị bằng link trực tiếp
Mong các bác giúp đỡ viết hộ mình cái đoạn code này được không
Tôi không biết VBA nhưng có cách khác có được không?
Tôi thấy dạo này diễn đàn lạm dụng VBA nhiều quá, từ những trường hợp có thể giải quyết bằng công thức đên những trường hợp có thể dùng công cụ có sẵn của Excel đều là VBA hết. Kiểu như bấm phát có kết quả sướng hơn ngồi xem và làm theo hướng dẫn.
 
Upvote 0
Tôi không biết VBA nhưng có cách khác có được không?
Tôi thấy dạo này diễn đàn lạm dụng VBA nhiều quá, từ những trường hợp có thể giải quyết bằng công thức đên những trường hợp có thể dùng công cụ có sẵn của Excel đều là VBA hết. Kiểu như bấm phát có kết quả sướng hơn ngồi xem và làm theo hướng dẫn.
Cám ơn bác!
Đúng thật là có lạm dụng VBA vì có 2 nguyên nhân bác ah:
+ Thứ 1: Em muốn học thêm tý VBA vì em quá kém
+ Thứ 2: Do tính chất công việc
Nhưng nếu thật bác có cách thủ công nào hay hãy chỉ cho em với
Hiện tại em đang link bằng cách chọn filter để link nhưng quá lâu ( vì bảng quá nhiều)
 
Upvote 0
Cám ơn bác!
Đúng thật là có lạm dụng VBA vì có 2 nguyên nhân bác ah:
+ Thứ 1: Em muốn học thêm tý VBA vì em quá kém
+ Thứ 2: Do tính chất công việc
Nhưng nếu thật bác có cách thủ công nào hay hãy chỉ cho em với
Hiện tại em đang link bằng cách chọn filter để link nhưng quá lâu ( vì bảng quá nhiều)
Bạn nhập công thức này:
Mã:
="="&CELL("address",INDEX(Dulieu!$C$2:$C$5,MATCH(B3,Dulieu!$B$2:$B$5,)))
Nếu muốn tham chiếu tương đối thì dùng thêm hàm SUBSTITUTE
Mã:
="="&SUBSTITUTE(CELL("address",INDEX(Dulieu!$C$2:$C$5,MATCH(B3,Dulieu!$B$2:$B$5,))),"$","")
Sau khi copy công thức cho cả cột thì Copy - Paste value, Dùng Find and replace chuyển chuỗi công thức thành công thức (Thay = thành =)
 
Upvote 0
Bạn nhập công thức này:
Mã:
="="&CELL("address",INDEX(Dulieu!$C$2:$C$5,MATCH(B3,Dulieu!$B$2:$B$5,)))
Nếu muốn tham chiếu tương đối thì dùng thêm hàm SUBSTITUTE
Mã:
="="&SUBSTITUTE(CELL("address",INDEX(Dulieu!$C$2:$C$5,MATCH(B3,Dulieu!$B$2:$B$5,))),"$","")
Sau khi copy công thức cho cả cột thì Copy - Paste value, Dùng Find and replace chuyển chuỗi công thức thành công thức (Thay = thành =)

Vâng cám ơn bác đây là 1 cách rất hay, và em đã dùng nó
Nhưng có 1 nhược điểm ko hiểu sau khi em Thay = thành = nó ko cho ấy. Em phải click trực tiếp vào nó mới nhảy
 
Upvote 0
Cám ơn bác!
Đúng thật là có lạm dụng VBA vì có 2 nguyên nhân bác ah:
+ Thứ 1: Em muốn học thêm tý VBA vì em quá kém
+ Thứ 2: Do tính chất công việc
Nhưng nếu thật bác có cách thủ công nào hay hãy chỉ cho em với
Hiện tại em đang link bằng cách chọn filter để link nhưng quá lâu ( vì bảng quá nhiều)
Bạn đang nghiên cứu VBA thì cho mình góp vui 1 Code nha:
Mã:
Sub TimDonGia()
    Dim sArr, tArr, dArr, I As Long, K As Long, R As Long, Er As Long, Et As Long
    Dim Dic As Object
Application.ScreenUpdating = False
Const Nguon = "'Dulieu'!"
Set Dic = CreateObject("Scripting.Dictionary")
With Sheets("Dulieu")
    tArr = .Range("B1", .Range("B65535").End(3)).Resize(, 2).Value
End With
For I = 2 To UBound(tArr)
    Dic.Item(tArr(I, 1)) = I
Next I
With Sheets("DG")
    Er = .Range("B65535").End(3).Row
    sArr = .Range("A1:A" & Er).Resize(, 3).Value
    ReDim dArr(1 To UBound(sArr), 1 To 1)
    For I = 2 To UBound(sArr)
        K = K + 1
        If sArr(I, 1) = Empty Then
            R = Dic.Item(sArr(I, 2))
            If R Then dArr(K, 1) = "=" & Nguon & "C" & R
        End If
    Next I
   If K Then .Range("C2").Resize(K, 1) = dArr
    Et = Er
    For I = Er To 2 Step -1
        If .Range("A" & I) <> Empty Then
            .Range("D" & I) = "=Sum(C" & I + 1 & ":C" & Et & ")"
            Et = I - 1
        End If
    Next I
End With
Application.ScreenUpdating = True
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
@PacificPR
Nhờ bác giúp em nếu mình thêm cột thêm hàng cần chỉnh chộ nào trong code
Được bác giúp em giải thích ít về đoạn code này với

Set Dic = CreateObject("Scripting.Dictionary")
With Sheets("Dulieu")
tArr = .Range("B1", .Range("B65535").End(3)).Resize(, 2).Value
End With
For I = 2 To UBound(tArr)
Dic.Item(tArr(I, 1)) = I
Next I
With Sheets("DG")
Er = .Range("B65535").End(3).Row
sArr = .Range("A1:A" & Er).Resize(, 3).Value
ReDim dArr(1 To UBound(sArr), 1 To 1)
For I = 2 To UBound(sArr)
K = K + 1
If sArr(I, 1) = Empty Then
R = Dic.Item(sArr(I, 2))
If R Then dArr(K, 1) = "=" & Nguon & "C" & R
End If
Next I
 

File đính kèm

Upvote 0
@PacificPR
Nhờ bác giúp em nếu mình thêm cột thêm hàng cần chỉnh chộ nào trong code
Được bác giúp em giải thích ít về đoạn code này với
Bạn thử xem sao nha
Mã:
Sub TimDonGia()
    Dim sArr, tArr, dArr, I As Long, K As Long, R As Long, Er As Long, Et As Long
    Dim Dic As Object
Application.ScreenUpdating = False
Const Nguon = "'Dulieu'!"
Set Dic = CreateObject("Scripting.Dictionary")
With Sheets("Dulieu")
    tArr = .Range("B1", .Range("B65535").End(3)).Resize(, 2).Value
End With
For I = 2 To UBound(tArr)
    Dic.Item(tArr(I, 1)) = I
Next I
With Sheets("DG")
    Er = .Range("F65535").End(3).Row
    sArr = .Range("A4:A" & Er).Resize(, 7).Value
    ReDim dArr(1 To UBound(sArr), 1 To 1)
    For I = 1 To UBound(sArr)
        K = K + 1
        If sArr(I, 1) = Empty Then
            R = Dic.Item(sArr(I, 6))
            If R Then dArr(K, 1) = "=" & Nguon & "C" & R
        End If
    Next I
    If K Then .Range("G4").Resize(K, 1) = dArr
    Et = Er
    For I = Er To 4 Step -1
        If .Range("A" & I) <> Empty Then
            .Range("H" & I) = "=Sum(G" & I + 1 & ":G" & Et & ")"
            Et = I - 1
        End If
    Next I
End With
Application.ScreenUpdating = True
End Sub
 
Upvote 0
Mình đang tập áp dụng VBA vào công việc, mày mò hỏi mọi người viết được cái form nhập liệu như này nhưng giờ mình muốn nhập đơn giá trên cơ sở dữ liệu bên "sheet!data" theo loại hàng và phân loại khách hàng vào biểu tổng hợp và tính ra thành tiền mà mò mãi không tìm được code viết tham chiếu và ghi ra giá trị theo 2 điều kiện sau khi nhập dữ liệu từ form vào. Nhờ các cao thủ giúp với. Ngoài ra đoạn code: If Application.WorksheetFunction.CountIf(.Range("f2", .Range("f65000").End(xlUp)), cbkh.Text) = 0 Then là vùng điều kiện của mình nếu mình muốn sửa thành name mình đặt sẵn là ma_khach_hang để mỗi lần nếu có chèn thêm cột không phải sửa lại code thì sửa thế nào.
 

File đính kèm

Upvote 0
Mình thấy Pacific rất hay sử dụng cú pháp Set Dic = CreateObject("Scripting.Dictionary")
....
Rồi sau đó
Dic.Item = I
Bạn có thể giải thích chỗ này rõ 1 chút được không?
 
Upvote 0
Mình thấy Pacific rất hay sử dụng cú pháp Set Dic = CreateObject("Scripting.Dictionary")
....
Rồi sau đó
Dic.Item = I
Bạn có thể giải thích chỗ này rõ 1 chút được không?
Vậy anh chưa tìm hiểu về Dictionary rồi. Giải thích cũng khó. Trong diễn đàn có bài Tổng quan về Dictionary anh tìm hiểu rồi sẽ rõ ( Cái anh đang hỏi ở mục Thuộc tính Item)
 
Lần chỉnh sửa cuối:
Upvote 0
Mình đang tập áp dụng VBA vào công việc, mày mò hỏi mọi người viết được cái form nhập liệu như này nhưng giờ mình muốn nhập đơn giá trên cơ sở dữ liệu bên "sheet!data" theo loại hàng và phân loại khách hàng vào biểu tổng hợp và tính ra thành tiền mà mò mãi không tìm được code viết tham chiếu và ghi ra giá trị theo 2 điều kiện sau khi nhập dữ liệu từ form vào. Nhờ các cao thủ giúp với. Ngoài ra đoạn code: If Application.WorksheetFunction.CountIf(.Range("f2", .Range("f65000").End(xlUp)), cbkh.Text) = 0 Then là vùng điều kiện của mình nếu mình muốn sửa thành name mình đặt sẵn là ma_khach_hang để mỗi lần nếu có chèn thêm cột không phải sửa lại code thì sửa thế nào.
Bạn tiết kiệm dấy fẩy, dấu chấm câu hay xuống dòng quá.
Nên đọc hết câu thì quên đầu câu bạn viết gì luôn á!

Gốp í với bạn ngoài lề:
Mã khách hàng (KH) sao không là 101 là lại là 001; Mấy con số không trước số có trị làm ta dễ sai sót & Excel thì tài lanh sẽ làm bạn không kiểm soát được kết quả lúc nào đó cho mà xem.

Vì chưa thể hiểu í của bạn nên chỉ góp đến vậy.
 
Upvote 0
Bạn tiết kiệm dấy fẩy, dấu chấm câu hay xuống dòng quá.
Nên đọc hết câu thì quên đầu câu bạn viết gì luôn á!

Gốp í với bạn ngoài lề:
Mã khách hàng (KH) sao không là 101 là lại là 001; Mấy con số không trước số có trị làm ta dễ sai sót & Excel thì tài lanh sẽ làm bạn không kiểm soát được kết quả lúc nào đó cho mà xem.

Vì chưa thể hiểu í của bạn nên chỉ góp đến vậy.
Mình xin tóm tắt và gửi lại file của mình như sau:
Bên trong sheet tonghop tại cột I đơn giá mình đang dùng công thức của excel để tham chiếu ra đơn giá. Mình muốn dùng code VBA thay cho công thức đó vì công việc của mình tham chiếu rất nhiều nên nếu cứ dùng công thức excel thì bị chậm lắm.
Ngoài ra nhiều lúc mình còn phải tham chiếu nhiều điều kiện hơn nữa nên mới mày mò áp dụng VBA.
Còn việc mã khách hàng cám ơn bạn góp ý nhưng đấy là quy ước chung của Công ty nhiều phòng ban dùng, mình sửa thì bộ phận khác không làm được.
Trong file mình gửi lại mình đã bôi đỏ ô mình đang dùng công thức, bạn xem có giúp mình dùng VBA được không.
Bạn Hoang2013 và bạn PacificPR xem hộ mình với
 

File đính kèm

Upvote 0
Tạm thời mình dùng Record macro và gán luôn giá trị vào cột đơn giá, thành tiền. Nếu mình dùng như này mà số liệu rất nhiều thì có vấn đề gì không. Ai biết tư vấn giúp mình với. Đoạn code mình sửa lại như sau:
Mã:
Private Sub cmdnhap_Click()
Dim Endr As Long
With Sheets("tonghop")
    Endr = .Range("A" & Rows.Count).End(xlUp).Row
    .Range("A" & Endr + 1) = txtngay.Text
    .Range("B" & Endr + 1) = txtthang.Text
    .Range("C" & Endr + 1) = cbkh.List(cbkh.ListIndex, 0)
    .Range("D" & Endr + 1) = cbkh.List(cbkh.ListIndex, 1)
    .Range("E" & Endr + 1) = cbkh.List(cbkh.ListIndex, 2)
    .Range("f" & Endr + 1) = cbmathang.List(cbmathang.ListIndex, 0)
    .Range("g" & Endr + 1) = cbmathang.List(cbmathang.ListIndex, 1)
    .Range("h" & Endr + 1) = txtluong.Text
     .Range("i" & Endr + 1).Select
    ActiveCell.FormulaR1C1 = _
      "=IFERROR(INDEX(data!R3C3:R26C5,MATCH(RC[-3],data!R3C1:R26C1,0),MATCH(RC[-4],data!R2C3:R2C5,0)),"""")"
Range("i" & Endr + 1).Value = Range("i" & Endr + 1).Value
 .Range("j" & Endr + 1).Select
    ActiveCell.FormulaR1C1 = "=RC[-2]*RC[-1]"
Range("j" & Endr + 1).Value = Range("j" & Endr + 1).Value
 End With
 txtngay.SetFocus
End Sub
 
Upvote 0
Tạm thời mình dùng Record macro và gán luôn giá trị vào cột đơn giá, thành tiền. Nếu mình dùng như này mà số liệu rất nhiều thì có vấn đề gì không. Ai biết tư vấn giúp mình với. Đoạn code mình sửa lại như sau:
Mã:
Private Sub cmdnhap_Click()
Dim Endr As Long
With Sheets("tonghop")
    Endr = .Range("A" & Rows.Count).End(xlUp).Row
    .Range("A" & Endr + 1) = txtngay.Text
    .Range("B" & Endr + 1) = txtthang.Text
    .Range("C" & Endr + 1) = cbkh.List(cbkh.ListIndex, 0)
    .Range("D" & Endr + 1) = cbkh.List(cbkh.ListIndex, 1)
    .Range("E" & Endr + 1) = cbkh.List(cbkh.ListIndex, 2)
    .Range("f" & Endr + 1) = cbmathang.List(cbmathang.ListIndex, 0)
    .Range("g" & Endr + 1) = cbmathang.List(cbmathang.ListIndex, 1)
    .Range("h" & Endr + 1) = txtluong.Text
     .Range("i" & Endr + 1).Select
    ActiveCell.FormulaR1C1 = _
      "=IFERROR(INDEX(data!R3C3:R26C5,MATCH(RC[-3],data!R3C1:R26C1,0),MATCH(RC[-4],data!R2C3:R2C5,0)),"""")"
Range("i" & Endr + 1).Value = Range("i" & Endr + 1).Value
 .Range("j" & Endr + 1).Select
    ActiveCell.FormulaR1C1 = "=RC[-2]*RC[-1]"
Range("j" & Endr + 1).Value = Range("j" & Endr + 1).Value
 End With
 txtngay.SetFocus
End Sub
Bạn thử như thế này xem
PHP:
Private Sub cmdnhap_Click()
    Dim Endr As Long, Rng As Range, Col As Long
    With Sheets("data")
        Set Rng = .Range("A3", .Range("A" & Rows.Count).End(3)).Resize(, 5)
        Col = Application.Match(cbkh.List(cbkh.ListIndex, 2), .Range("A2:E2"), 0)
    End With
    With Sheets("tonghop")
        Endr = .Range("A" & Rows.Count).End(xlUp).Row
        .Range("A" & Endr + 1) = txtngay.Text
        .Range("B" & Endr + 1) = txtthang.Text
        .Range("C" & Endr + 1) = cbkh.List(cbkh.ListIndex, 0)
        .Range("D" & Endr + 1) = cbkh.List(cbkh.ListIndex, 1)
        .Range("E" & Endr + 1) = cbkh.List(cbkh.ListIndex, 2)
        .Range("f" & Endr + 1) = cbmathang.List(cbmathang.ListIndex, 0)
        .Range("g" & Endr + 1) = cbmathang.List(cbmathang.ListIndex, 1)
        .Range("h" & Endr + 1) = txtluong.Text
        .Range("I" & Endr + 1) = Application.VLookup(cbmathang, Rng, Col, 0)
        .Range("J" & Endr + 1) = CLng(.Range("I" & Endr + 1)) * CLng(.Range("H" & Endr + 1))
    End With
    txtngay.SetFocus
End Sub
 
Upvote 0

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

Back
Top Bottom