VBA - Vlookup với VBA không ra kết quả. Mong anh chị hướng dẫn gỡ rối

Trạng thái
Không mở trả lời sau này.

songcham

Yêu THVBA
Chào anh chị
Mình mới tập tành viết code vba, không biết viết sai chỗ nào. Mong anh chị chỉ giúp
Mình có 1 sheet solieutho, từ cột I1:AE1 là các tiêu chí mình muốn tạo sheet : Tổng doanh thu hoạt động kinh doanh,……lãi suy giảm trên cổ phiếu. Tổng cộng có 24 tiêu chí như vậy. Và mình tạo ra 1 sheet TIEUCHI bên cạnh.
Trong sheet TIEUCHI, cột A là theo tên tiêu chí ( 24 tiêu chí bên sheet solieutho), cột B là tên viết tắt các tiêu chí. Mình muốn tạo ra 24 sheet theo tên viết tắt như cột B của sheet tieuchi.
sheet TDT1 ( Tổng doanh thu từ hoạt động kinh doanh ) màu xanh là sheet mẫu, mình dùng hàm vlookup trong excel để tìm kiếm bình thường. ( Mình tạo 2 sheet: data, sheetphu ..để xử lý dữ liệu tạo ra sheet TDT).
Bây giờ mình viết viết vba tự chèn 24 sheet, theo 24 tiêu chí như cột B sheet Tieuchi.
Hàm mình viết module 4, chạy sai không ra kết quả. Mong anh chị coi giúp. Mình cám ơn
 

tuhocvba

Administrator
Thành viên BQT
Chào bạn.
Hiện tại trong code của bạn đang không được thực thi ở đây:
Mã:
Set vungdulieu = Sheets("DATA").Range("vdl")
Bạn có thể nói cho mọi người biết vdl là gì không ạ?
 

songcham

Yêu THVBA
Mình đặt name cho vùng $D$1:$AC$30000 trong sheet data đó anh. Sheets("Data").Range("D1:AC30000").
Cụ thể là mình có sheet solieutho, và 24 sheet là sheet mình cần tạo. Mình không rành hàm nên tạo 2 sheet phụ để dò tìm đó anh.
 

tuhocvba

Administrator
Thành viên BQT
Bạn sử dụng code sau đây nhé:
Mã:
Sub tuhocvba()
    Dim i As Integer
    Dim sosheet As Integer
    
    sosheet = Sheets("TIEUCHI").Range("E1").Value
    Call Focus(true) ' tang tốc VBA
    For i = 1 To sosheet Step 1
        'Tao sheet moi
        Sheets("MAUTRINHBAY").COPY After:=Sheets("MAUTRINHBAY")
        'Gan ten cho sheet
        ActiveSheet.Name = Sheets("TIEUCHI").Range("B1").Offset(i - 1, 0)
        'Thuc hien gan cong thuc cho B2
        ActiveSheet.Cells(2, 2).FormulaR1C1 = _
        "=IFERROR(VLOOKUP('SHEET PHU'!RC,DATA!R[-1]C4:R[29998]C29,TIEUCHI!R1C3,0),"""")"
        Range("B2").Select
    Selection.AutoFill Destination:=Range("B2:B454")
    Range("B2:B454").Select
    Selection.AutoFill Destination:=Range("B2:BP454"), Type:=xlFillDefault
    Range("B2:BP454").Select
        
        
    Next i
call Focus(False)
End Sub
Sub Focus(ByVal Flag As Boolean)
    With Application
        .EnableEvents = Not Flag
        .ScreenUpdating = Not Flag
        .Calculation = IIf(Flag, xlCalculationManual, xlCalculationAutomatic)
    End With
End Sub
 

songcham

Yêu THVBA
Bạn sử dụng code sau đây nhé:
[/Code]
Đầu tiên xin cám ơn anh đã chỉnh sửa code giúp mình.
Có một điều nhỏ là kết quả các sheet đều giống nhau, cột tham chiếu trả về hình như thiếu offset phải không anh. Do mình mới viết tập viết nên kiểu viết RC mình không biết chỉnh sửa thế nào.
Không biết mình có thể tối ưu code hơn để cho nó chạy nhanh hơn được không anh. Mình chạy code ra kết quả hơi lâu anh à.
Xin cảm phiền anh.
Bạn cần đăng nhập để thấy hình ảnh

Bạn cần đăng nhập để thấy hình ảnh
 

tuhocvba

Administrator
Thành viên BQT
Thì bạn cho có một sheet làm mẫu, nên mình cứ theo cái mẫu ấy thôi. Giờ bạn cho hai sheet mẫu để mình xem quy luật như nào.
Muốn nhanh thì không dùng công thức, điền trực tiếp giá trị vào thôi. Mà giờ chúng nó đi ngủ hết rồi :D
Bạn gửi hai sheet kết quả mẫu để mình xem nó khác nhau như nào nhé.
 

songcham

Yêu THVBA
Mình xin gửi file kết quả sau khi chạy code VBA trên của anh.

Đây là 2 sheet mẫu ( mình viết hàm vlookup thủ công ) trong tổng số 24 sheet mình muốn tạo.
Bạn cần đăng nhập để thấy đa phương tiện
Nếu mà điền trực tiếp được giá trị thay vì dùng công thức thì quá tốt anh. Do mình mới mò mẫm nên viết theo kiểu viết hàm bên excel thôi. Xin phiền a coi giúp.
 

vbano1

SMod
Thành viên BQT
Công thức nhìn hoa hết cả mắt, dựa vào code của tác giả thì sửa lại như sau:
Mã:
Sub tuhocvba()
    Dim i As Integer
    Dim sosheet As Integer
   
    sosheet = Sheets("TIEUCHI").Range("E1").Value
    Call Focus(true) ' tang tốc VBA
    For i = 1 To sosheet Step 1
        'Tao sheet moi
        Sheets("MAUTRINHBAY").COPY After:=Sheets("MAUTRINHBAY")
        'Gan ten cho sheet
        ActiveSheet.Name = Sheets("TIEUCHI").Range("B1").Offset(i - 1, 0)
        'Thuc hien gan cong thuc cho B2
        ActiveSheet.Cells(2, 2).FormulaR1C1 = _
        "=IFERROR(VLOOKUP('SHEET PHU'!RC,DATA!R[-1]C4:R[29998]C29,TIEUCHI!R"& i &"C3,0),"""")"
        Range("B2").Select
    Selection.AutoFill Destination:=Range("B2:B454")
    Range("B2:B454").Select
    Selection.AutoFill Destination:=Range("B2:BP454"), Type:=xlFillDefault
    Range("B2:BP454").Select
       
       
    Next i
call Focus(False)
End Sub
Sub Focus(ByVal Flag As Boolean)
    With Application
        .EnableEvents = Not Flag
        .ScreenUpdating = Not Flag
        .Calculation = IIf(Flag, xlCalculationManual, xlCalculationAutomatic)
    End With
End Sub
 

tuhocvba

Administrator
Thành viên BQT
@songcham Mình hiểu rồi. Cái tiêu chí phải tăng lên. Đầu tiên là C1. tiếp theo là C2. Tiếp theo là C3.
Vậy bạn sử dụng code của @vbano1 xem sao. Thú thực là mình nhìn file không hiểu logic mô tê gì đâu, toàn dùng hàm tự bản thân tạo ra thôi, cho nên nhìn bảng tính như này mình chỉ biết copy thôi, hoa hết cả mắt. Bản thân cũng thấy là code chưa tốt, nên cũng đã nhắn cho @Snow24 có thời gian thì xem cho bạn.
 

songcham

Yêu THVBA
Do dữ liệu lớn, nhiều lúc cả 100 sheet mà phải thường xuyên update . Mình viết hàm thủ công cực quá nên mò mẫm VBA để nó nhanh hơn. Do mới tập tành viết nên chưa hiểu cấu trúc code nên viết chưa được tốt.
Cám ơn anh @vbano1 đã hỗ trợ, song code nó báo lỗi đỏ anh à.
Bạn cần đăng nhập để thấy hình ảnh

Xin phiền mấy anh.
 

tuhocvba

Administrator
Thành viên BQT
Nếu mà điền trực tiếp được giá trị thay vì dùng công thức thì quá tốt anh. Do mình mới mò mẫm nên viết theo kiểu viết hàm bên excel thôi. Xin phiền a coi giúp.
Tốt rồi. Có cơ hội cống hiến cho diễn đàn rồi.
@thanhphuongvip đâu, có cái file toàn Vlookup đây này, xử lý cho bạn này càng nhanh càng tốt, trong thứ 2 này. Bạn ấy bảo muốn ghi trực tiếp giá trị của Vlookup, khỏi cần để công thức làm gì cho lôi thôi này :D
 
S

Snow24

Guest
@songcham Bạn thử code này xem đúng không nhé.Code vẫn chưa tối ưu lắm do vẫn phải dùng đến sheets "data".
Mã:
Sub xoasheets()
Application.DisplayAlerts = False
Const tenshet As String = "TIEUCHI#DATA#MAUTRINHBAY#SOLIEUTHO"
    Dim sh As Worksheet
        For Each sh In ThisWorkbook.Worksheets
            If InStr(1, tenshet, sh.Name) = 0 Then
               sh.Delete
            End If
        Next
End Sub

Sub taothemsheet()
    Dim arr, i As Long, lr As Long, dk As String, dks As String, dic As Object, data, kq, sh As Worksheet, a As Long, b As Long, k As Integer
    Dim j As Long
    Set dic = CreateObject("scripting.dictionary")
    With Sheets("tieuchi")
         arr = .Range("A1:B24").Value
    End With
    With Sheets("DATA")
         lr = .Range("D" & Rows.Count).End(xlUp).Row
         data = .Range("D1:AC" & lr).Value
         For i = 2 To UBound(data)
            dk = data(i, 1)
            dic.Item(dk) = i
         Next i
         For j = 2 To UBound(data, 2)
            dk = data(1, j)
            dic.Item(dk) = j
         Next j
    End With
    For k = 1 To UBound(arr)
        With Sheets("mautrinhbay")
             kq = .Range("A1:BP454").Value
        End With
        Set sh = Worksheets.Add
            sh.Name = arr(k, 2)
            b = dic.Item(arr(k, 1))
            If b Then
               For i = 2 To UBound(kq)
                   For j = 2 To UBound(kq, 2)
                       dk = kq(i, 1) & " " & kq(1, j)
                       a = dic.Item(dk)
                       If a Then
                       If data(a, b) Then kq(i, j) = data(a, b)
                       End If
                   Next j
               Next i
            End If
            sh.Range("a1:bp454").Value = kq
    Next k
End Sub
 
S

Snow24

Guest
Thực ra bài trên không cần các sheets phụ data,Mẫu,....Vẫn chạy được.Đỡ phải có công thức.
 

Euler

Administrator
Thành viên BQT
Chưa hiểu ý tác giả, có nhất thiết phải để tất cả các kết quả vào các sheet khác nhau trên một file hay không. Vì số lượng data lớn, số lượng sheet nhiều. Không hẳn là code chậm, mà ngay việc mở file lên cũng rất chậm rồi. Nếu như ý đồ được làm rõ hơn, các kết quả được thể hiện ở trên các file khác nhau thì có được không. Chứ mở cái file 100 sheet, lượng data lên tới cả vài vạn dòng, đơ cả máy, thật đáng sợ.
 

giaiphapvba

Administrator
Thành viên BQT
Cảm ơn anh @Snow24
Chương trình của anh @Snow24 chạy khá giật. Và code thiếu comment. Nếu sheet cần tạo ra mà đang tồn tại thì bị lỗi.
Ngoài ra, nó chỉ đúng với file này, cố định BP454. Có lẽ vì anh thiếu thời gian.
Vì vậy, cho phép em hoàn thiện lại code của anh.
Đã cập nhật lại code lúc 13h18p giờ Việt Nam. cảm ơn anh @Snow24 đã feedback.
Mã:
'Code nay de xoa het cac sheet khong Can thiet. Ban co the su dung no cho nut bam xoa het cac sheet.
'Cac sheet: TIEUCHI, DATA, MAUTRINHBAY, SOLIEUTHO se khong bi xoa
Sub xoasheets()

    Const tenshet As String = "TIEUCHI#DATA#MAUTRINHBAY#SOLIEUTHO"
    Dim sh As Worksheet
    Call Focus(True)
            For Each sh In ThisWorkbook.Worksheets
                If InStr(1, tenshet, sh.Name) = 0 Then
                   sh.Delete
                End If
            Next
    Call Focus(False)
End Sub
'Muc dich:Tao ra cac sheet ket qua va ghi ket qua tinh toan vao
Sub taothemsheet_tuhocvba()
    Dim arr As Variant, i As Long, lr As Long, dk As String, dks As String
    Dim dic As Object, data As Variant, kq, sh As Worksheet, a As Long, b As Long, k As Integer
    Dim j As Long
    Dim rend As Long
    Dim cend As Integer
    Set dic = CreateObject("scripting.dictionary")
    Call Focus(True) 'Tang toc VBA
    ThisWorkbook.Sheets("TIEUCHI").Activate 'Lam viec voi sheet TIEUCHI
    With Sheets("TIEUCHI")
            rend = .Cells(Rows.Count, 2).End(xlUp).Row
            arr = .Range(Cells(1, 1), Cells(rend, 2)).Value 'Lay du lieu cot A,B tren sheet TIEUCHI
    End With
    ThisWorkbook.Sheets("DATA").Activate 'Lam viec voi sheet DATA
    With Sheets("DATA")
         lr = .Range("D" & Rows.Count).End(xlUp).Row 'Lay dong cuoi cua sheet DATA
         cend = .Cells(1, Columns.Count).End(xlToLeft).Column 'Cot cuoi tren sheet DATA
         data = .Range(Cells(1, 4), Cells(lr, cend)).Value  'Lay du lieu D1:AC30000
         For i = 2 To UBound(data, 1) 'Duyet qua tung dong cua sheet DATA-thuc te la mang data()
            dk = data(i, 1)  'NAP CAC KEYWORD TREN COT D CUA SHEET DATA
            dic.Item(dk) = i  'GHI LAI VI TRI DONG i VAO TU DIEN
         Next i
         For j = 2 To UBound(data, 2)   'Duyet qua tung cot cua sheet Data
            dk = data(1, j) 'Ten cot. Ex: TONG DOANH THU HOAT DONG KINH DOANH
            dic.Item(dk) = j 'Ghi lai vi tri cot vao tu dien
         Next j
    End With
   
  
    '==============TINH TOAN KET QUA
    For k = 1 To UBound(arr)
        If kiemtrasheet(CStr(arr(k, 2))) = True Then
                MsgBox "Hay xoa het cac sheet khong can thiet truoc khi chay chuong trinh"
                Exit Sub
        End If
   ThisWorkbook.Sheets("MAUTRINHBAY").Activate
    With Sheets("MAUTRINHBAY")
            'Lay dong cuoi va cot cuoi tren sheet MAU TRINH BAY
             rend = .Cells(Rows.Count, 1).End(xlUp).Row
             cend = .Cells(1, Columns.Count).End(xlToLeft).Column
             kq = .Range(Cells(1, 1), Cells(rend, cend)).Value 'A1:BP454
    End With
        Set sh = Worksheets.Add(After:=Worksheets(Worksheets.Count)) 'Them sheet moi vao phia ben phai
            sh.Name = CStr(arr(k, 2)) 'Gan ten sheet theo cot B sheet TIEU CHI
            b = dic.Item(arr(k, 1)) 'Tim xem arr(k, 1) =TONG DOANH THU HOAT DONG tren shet DATA la cot thu bao nhieu tinh tu cot D,
            'tra ket qua vao b. b = 2.
            If b Then 'Neu tim thay, tuc la b>0 thi thuc hien:
               For i = 2 To UBound(kq)
                   For j = 2 To UBound(kq, 2)
                       dk = kq(i, 1) & " " & kq(1, j) 'Key word de tim kiem. Ex: AAV 2018
                       a = dic.Item(dk) 'Tim xem dong chua key word ay la dong nao tren sheet data. Ex = 14
                       If a Then
                                If data(a, b) Then kq(i, j) = data(a, b) 'lay ket qua sheet data o cot a dong b. Chu y vi tri cot tinh tu cot D.
                       Else
                                kq(i, j) = "0" 'Khong tim thay
                       End If
                   Next j
               Next i
            End If
            sh.Range(Cells(1, 1), Cells(rend, cend)).Value = kq
    Next k
    Call Focus(False)
End Sub
'Thu tuc con duoc su dung de tang toc chuong trinh
Sub Focus(ByVal Flag As Boolean)
    With Application
        .EnableEvents = Not Flag
        .ScreenUpdating = Not Flag
        .DisplayAlerts = Not Flag
        .Calculation = IIf(Flag, xlCalculationManual, xlCalculationAutomatic)
    End With
End Sub
'Kiem tra ten sheet (Ex sheet name = tuhocvba) da ton tai trong workbook hay chua. Neu dang ton tai, ket qua tra ve la True
Function kiemtrasheet(ByVal tensheet As String) As Boolean
    Dim n As Integer
    Dim i As Integer
    n = ThisWorkbook.Sheets.Count
    For i = 1 To n Step 1
        If ThisWorkbook.Sheets(i).Name = tensheet Then
            kiemtrasheet = True
            Exit Function
        End If
    Next i
    kiemtrasheet = False 'mac dinh khong tim thay
End Function
Đã chạy thử và so sánh kết quả với file của @songcham đưa lên, kết quả là khớp nhau.

Bạn chạy thủ tục taothemsheet_tuhocvba để tạo ra kết quả.
Chạy thủ tục xoasheets để xóa hết các sheet.
 
S

Snow24

Guest
giaiphapvba Cái mảng Kq bắt buộc phải để trong vong lạp for không thì sẽ bị lỗi kết quả.Nó sẽ không xóa được dữ liệu ở các sheets.Ở cái mà kiểm tra ten sheets đó dùng bẫy lỗi có vẻ nhanh hơn.Tại mình viết chưa bẫy lỗi.Nếu muốn tối ưu thì phải bỏ cả sheets mẫu với data đi nữa chỉ dùng mỗi solieutho thôi.Bạn thử viết theo kiểu đó xem.sheet mẫu cũng được tạo khi duyệt qua các dữ liệu ở solieutho.
 

songcham

Yêu THVBA
Xin cám ơn các anh trong diễn đàn đã hỗ trợ nhiệt tình. Do bận công việc nên giờ mình mới phản hồi được.
Mình đã copy code anh @Snow24 chạy và cho kết quả đúng như mong muốn ạ. Mình chân thành cám ơn anh đã hỗ trợ.
Cám ơn anh @giaiphapvba đã hỗ trợ code, mình chạy thì nó nó lỗi như hình dưới. Không biết sữa lỗi ntn nên mong anh coi giúp.
Bạn cần đăng nhập để thấy đa phương tiện
Xin cám ơn!
 
Trạng thái
Không mở trả lời sau này.
Top