Code lấy dữ liệu từ 3 file con.

Liên hệ QC
Tôi tuân thủ nội quy khi đăng bài

LuuAnh980

Thành viên tiêu biểu
Tham gia
28/9/22
Bài viết
453
Được thích
104
Giới tính
Nữ
Chào các anh trong GPE!!!!
Em có bắt chước code của anh @Hoàng Tuấn 868 làm cho em để lấy dữ liệu, nhưng không biết sai chổ nào mà báo lỗi ngay dòng này:
Mã:
md(k, 11) = "VTF" & Mid(wn.Name, InStr(wn.Name, "WF") - 1, 1)
lỗi Subscript out of range ạ.
Code đây ạ:
Mã:
Option Explicit

Sub LayDuLieuSheetTonDau_TuCacFile()
Application.ScreenUpdating = False
Dim wd As Workbook, wn As Workbook
Dim sd As Worksheet, sn As Worksheet, sn1 As Worksheet, sn2 As Worksheet
Dim lrd As Long, lrn As Long, lrn1 As Long, lrn2 As Long
Dim i As Long, j As Long, k As Long, p As Long, q As Long
Dim md() As String, md1, md2, mn, mn1, mn2

Set wd = ThisWorkbook
Set sd = wd.Sheets("TonDau")
Set sn1 = wd.Sheets("DanhMuc")

lrn1 = sn1.Cells(Rows.Count, 2).End(xlUp).Row
mn1 = sn1.Range("B6:j" & lrn1)


ReDim md(1 To 2000, 1 To 11)
ReDim md1(1 To 2000, 1 To 6)

With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = True
.Show
If .SelectedItems.Count = 0 Then Exit Sub
    For i = 1 To .SelectedItems.Count
        Set wn = Workbooks.Open(.SelectedItems(i), False)
        Set sn = wn.Sheets("BaoCao")
        
        If sn.AutoFilterMode = True Then sn.AutoFilterMode = False
        lrn = sn.Cells(Rows.Count, 2).End(xlUp).Row
        mn = sn.Range("B8:E" & lrn)
        For j = 1 To UBound(mn, 1)
            If Trim(mn(j, 2)) <> "" And Left(mn(j, 2), 11) <> "Steel Plate" Or Trim(mn(j, 2)) <> "" And Left(mn(j, 2), 11) <> "Chequered" Then

                If InStr(mn(j, 2), "Steel Plate") = 0 Then
                    If InStr(mn(j, 2), "Chequered") = 0 Then
            On Error GoTo thoat
            
                    k = k + 1
                    md(k, 4) = mn(j, 1)
                    md1(k, 1) = mn(j, 3)
                    End If
                End If
md(k, 11) = "VTF" & Mid(wn.Name, InStr(wn.Name, "WF") - 1, 1)
End If
thoat:
        Next j
    k = k + 1
    wn.Close False
    Next i
    
    If k > 0 Then
    
    
        For p = 1 To UBound(mn1, 1)
            For q = 1 To k
                If mn1(p, 2) = md(q, 4) Then
                    md(q, 5) = mn1(p, 8)
                    md1(q, 9) = mn1(p, 7)
                End If
            Next q
        Next p
        
 
        sd.Range("A3:M10000").Clear
        sd.Range("A3").Resize(k, 11) = md
        sd.Range("J3").Resize(k - 1, 1) = md1
        lrd = sd.Cells(Rows.Count, 8).End(xlUp).Row
        sd.Range("A3:M" & lrd).Borders.LineStyle = True
  End If
End With

        For i = 6 To lrd - 1
        If sd.Cells(i, 1) = "" Then
            sd.Range("A" & i).Resize(1, 11) = ""
            sd.Range("A" & i).Resize(1, 11).Interior.ColorIndex = 37
        End If
    Next i
    
Application.ScreenUpdating = True
End Sub
 
Nghe nói hàm InStr() trả về kết quả là kiểu "số", lấy "số" đi so sánh với "" có lẽ hình như không ổn.
 
Upvote 0
Em chỉnh lại là :
Mã:
  If mn(j, 3) <> "" And InStr(mn(j, 3), "Steel Plate") = 0 Then
    If mn(j, 3) <> "" And InStr(mn(j, 3), "Chequered") = 0 Then
Chỗ này có thể viết gọn hơn được chứ. thử xem
Mã:
If mn(j, 3) <> "" And (InStr(mn(j, 3), "Steel Plate") = 0 Or InStr(mn(j, 3), "Chequered") = 0 ) Then
 
Upvote 0
Chỗ này có thể viết gọn hơn được chứ. thử xem
Mã:
If mn(j, 3) <> "" And (InStr(mn(j, 3), "Steel Plate") = 0 Or InStr(mn(j, 3), "Chequered") = 0 ) Then
Theo lô gic này thì nếu mn(j, 3) không chứa "Steel Plate" thì đã thỏa mãn. Việc chứa "Chequered" không thành vấn đề.

Vì vậy nó không giống:
If mn(j, 3) <> "" And InStr(mn(j, 3), "Steel Plate") = 0 Then
If mn(j, 3) <> "" And InStr(mn(j, 3), "Chequered") = 0 Then

Như vầy mới giống:
If mn(j, 3) <> "" And InStr(mn(j, 3), "Steel Plate") = 0 And InStr(mn(j, 3), "Chequered") = 0 Then
 
Upvote 0
Theo lô gic này thì nếu mn(j, 3) không chứa "Steel Plate" thì đã thỏa mãn. Việc chứa "Chequered" không thành vấn đề.

Vì vậy nó không giống:
If mn(j, 3) <> "" And InStr(mn(j, 3), "Steel Plate") = 0 Then
If mn(j, 3) <> "" And InStr(mn(j, 3), "Chequered") = 0 Then

Như vầy mới giống:
If mn(j, 3) <> "" And InStr(mn(j, 3), "Steel Plate") = 0 And InStr(mn(j, 3), "Chequered") = 0 Then
Cảm ơn anh đã xem bài. Tôi cũng chỉ là nhìn cấu trúc code của chủ thớt trên điện thoại thì cho rằng nếu mn(j,3) <> Rỗng và không chứa "Steel Plate" thì lại xét lại mn(j,3) và lại xét xem trong mn(j,3) có chứa "Chequered" hay không. Như vậy là thừa 1 lần xét mn(j,3)<> rỗng và cho rằng không thể mn(j,3) cùng chứa cả Steel Plate và "Chequered", nhưng tôi đã sai. Lý giải và cách giải quyết của anh mới là đúng và đã làm tôi nhận thức ra vấn đề. Một lần nữa trân trọng cảm ơn anh
 
Upvote 0
Upvote 0
Cũng có thể dùng

If Not mn(j, 3) Like "Steel Plate*" And Not mn(j, 3) Like "Chequered*" Then

Chỉ 2 điều kiện và 1 And
Hỏng dám đâu bạn vàng ơi:
1714662641088.png
Điều kiện <> "" không thể bỏ không test.
1714662771384.png

Chú thích: đem Not làm thừa số chung thì And đổi thành Or
Not a And Not b <==> Not (a Or b)
 
Upvote 0
Hỏng dám đâu bạn vàng ơi:

Điều kiện <> "" không thể bỏ không test.
Coi như có giả định rằng vùng dữ liệu của mảng không bỏ trống. Nguyên tắc là cột mã và tên không bỏ trống. Nhưng đó là nói chung chứ đối với tác giả chủ đề này thì nó vô nghĩa.
Bảng kết quả không trống còn cố tình chèn 1 dòng trống vào và tô màu nữa kia. Xì tai này nó có sẵn trong máu rồi, không có không chịu được (từ khi bắt đầu hỏi GPE đến giờ)

1714745596870.png
 
Upvote 0
Nói chung code trong chủ đề này, nói là của bạn @Hoàng Tuấn 868 nhưng không biết nguyên thủy được bao nhiêu, mà rất thô thiển.
1. Cách đặt tên biến: Chẳng thà lấy tên người yêu cũ làm tên biến, người yêu đầu làm mảng data nguồn, người yêu kế làm mảng tạm, người yêu hiện thời làm mảng kết quả còn có ý nghĩa hơn là mn, md, wd, sd, sn, ... rồi lại còn md1.
2. Chỉ gán kết quả 2 cột đầu và cuối, mà lại tạo mảng 13 cột.
Gán mảng 13 cột xuống từ A đến M xong, gán chèn cột J ở giữa bằng mảng 1 cột thứ 2.
Mảng 13 cột gán k dòng, mảng 1 cột gán k - 1 dòng, mà kết quả trên sheet vẫn bằng nhau!
3. Ba cái If lồng nhau 1 cách không cần thiết
4. Không kiểm soát được biến k, gán giá trị cho mảng ở vị trí 0
5. Câu lệnh nằm sai vị trí
6. Sử dụng On Error Goto <label> mà không kiểm soát được label và vị trí label.
7. Gán công thức Vlookup mà tự cho số vào vùng dò tìm, sinh ra lỗi N/A mà không biết tại sao.
 
Lần chỉnh sửa cuối:
Upvote 0
Nói chung code trong chủ đề này, nói là của bạn @Hoàng Tuấn 868 nhưng không biết nguyên thủy được bao nhiêu, mà rất thô thiển.
...
Nói chung thì cô chủ thớt này cũng có cái hay.
Nhờ cô ta mà tôi biết được nhiều điều mà trước đây mình không tưởng là có thể xảy ra.
Điển hinh: code nát bét mà cũng còn có người muốn vá víu. Nếu vá xong học được cái gì thì cũng đáng. Đằng này chủ yếu chỉ là vá cho nên loogic giữa vấn đề và code trở nên rất lòng vòng.
 
Upvote 0
Vậy Bác @VetMini và thầy Mỹ viết dùm em code hoàn chỉnh dùm được không ạ.!!!!
Tôi viết code hoàn chỉnh xong, lại thắc mắc không có mấy dòng trống chen giữa, cũng không tô màu rồi sẽ lại không dùng thôi.
Hoặc là lại phá code theo ý mình lần nữa
 
Upvote 0
Trước em thử bỏ thì ô đó trống nó cũng lấy dữ liệu.
Bài 70 là tôi nói chung chung, còn code của bạn không cần kiểm tra điều kiện ô "tên" không trống mn(j, 3) <> ""
Vì bên trên bạn đã có điều kiện
If mn(j, 5) > 0 Then

mn(j, 5) là số lượng, kiểm tra số lượng > 0
Mặt hàng trống là không có mặt hàng. Không có mặt hàng lấy đâu ra số lượng. Nên SL >0 đồng nghĩa mặt hàng <> "" mất rồi. Kiểm tra thêm là dư.
 
Upvote 0
Thì thầy Mỹ cứ viết có dòng trống ngăn cách các xưởng và bôi màu là được rồi.
 
Upvote 0
Upvote 0
ha ha. Đời tôi viết code không bao giờ viết cho chuyện vô bổ. Và tôi cũng không chiều chuyện vô bổ của người khác.
Tôi thì không ngại viết code vô bổ.
Nhưng tôi có nguyên tắc về phân tích lô gic. Rất tiếc là nguyên tắc này không thích hợp với cách làm việc của thớt cho nên tôi không làm nữa. Đối với tôi chỉ lô gic mới quan trọng. Code chỉ là dịch từng bước của lô gic thôi.

Thắc mắc: tôi cũng chả hiểu thớt làm công việc gì, cấp bậc gì mà nói chuyện thì không khác kỹ sư vận hành chuyên nghiệp (operation engineer). Chức vụ này chỉ báo cáo cho kỹ sư trưởng (chief engineer) hoặc trưởng phòng kỹ thuật (Technical and Operattion Department) thôi.
 
Upvote 0
Web KT

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

Back
Top Bottom