Code lấy dữ liệu từ 3 file con. (1 người xem)

Liên hệ QC

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

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
463
Được thích
106
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
 
lỗi Subscript out of range ạ.
Bạn từng đăng bài rất nhiều. Cái tối thiểu là đính kèm file để có thể test giúp bạn xem nó như nào thì lại không làm. Việc trên nó như kiểu đem ảnh đi khám bệnh ấy. Xin lỗi vì nếu nói làm bạn thấy tự ái.
 
  • Thích
Reactions: th7
Upvote 0
Sao câu hỏi của bạn với bạn này giống nhau không?
 
Upvote 0
Đúng ạ, code này là em chế lại của anh @Hoàng Tuấn 868 làm cho em, em có nhờ ảnh giúp, nhưng ảnh nói ảnh bận công tác chưa giúp được, hôm nay em nôn quá đưa lên đây nhờ anh nào coi thử giúp em ạ.
 
Upvote 0
Bạn không bẫy lỗi thì chỗ này sẽ trả về 0 khi WF nằm ở ngay vị trí đầu tiên hoặc -1 nếu kg tìm thấy, thì hàm MID báo sai thôi.
Mã:
InStr(wn.Name, "WF") - 1
 
Upvote 0
Tôi thấy chỗ sai nhưng không hiểu bài nên không biết sửa. Chỗ này ReDim md(1 To 2000, 1 To 11) nhưng biến k chỗ này md(k, 11) = "VTF" & Mid(wn.Name, InStr(wn.Name, "WF") - 1, 1) nó bằng 0 nên lỗi.
 
Upvote 0
Đúng ạ, code này là em chế lại của anh @Hoàng Tuấn 868 làm cho em, em có nhờ ảnh giúp, nhưng ảnh nói ảnh bận công tác chưa giúp được, hôm nay em nôn quá đưa lên đây nhờ anh nào coi thử giúp em ạ.
Tôi nhớ không lầm thì bài này có điều kiện là dòng nào của cột Item của các sh BaoCao/ file nguồn không có "Steel Plate" hoặc "Chequered" thì mới lấy. do vậy 1 dòng không đồng thời có cả Steel plate và Chequered được. Vậy nên
Thử thay chỗ này
Mã:
            If InStr(mn(j, 2), "Steel Plate") = 0  Then
                     If InStr(mn(j, 2), "Chequered") = 0 Then
thành
Mã:
 If InStr(mn(j, 2), "Steel Plate") = 0 Or InStr(mn(j, 2), "Chequered") = 0 Then
và xóa đi 1 end if xem sao.
Chỗ này
Mã:
ReDim md(1 To 2000, 1 To 11)
ReDim md1(1 To 2000, 1 To 6)
và chỗ này
Mã:
       md(q, 5) = mn1(p, 8)
       md1(q, 9) = mn1(p, 7)
nó có phù hợp với nhau không?
 
Upvote 0
Cám ơn các anh đã quan tâm, mong các anh giúp đỡ.
 
Upvote 0
Định thử nhưng thấy UnProtect sheet, thôi bỏ cuộc...
vgf là gì vậy bạn?
 
Upvote 0
À, bây giờ lại lỗi ngay dòng này ạ :
Mã:
    wn.Close False
 
Upvote 0
Lỗi ở chỗ k = 0 chứ không phải instr = 0

1714275827007.png
 
Upvote 0
Dòng code kia không có gì sai cả. Thuộc tính False là không lưu thôi mà chú
Tôi hiểu là giữa wn.Close False và wn.Close chả có khác gì nhau.

Tôi chỉ nói theo kiểu quăng chài thôi, chứ thực ra trên máy tôi thì bỏ hay không bỏ chạy ok. Còn trên máy bạn ấy thì không biết. Bạn có thể giúp bạn ấy và giúp tôi cho tôi được mở rộng tầm mắt được không?
À mà trên máy tôi, tôi bỏ luôn cả dòng "Goto thoát" và dòng "thoát:". Bạn @LuuAnh980 thử bỏ cả 2 dòng này xem sao.
 
Upvote 0
Tôi hiểu là giữa wn.Close False và wn.Close chả có khác gì nhau.

Tôi chỉ nói theo kiểu quăng chài thôi, chứ thực ra trên máy tôi thì bỏ hay không bỏ chạy ok. Còn trên máy bạn ấy thì không biết. Bạn có thể giúp bạn ấy và giúp tôi cho tôi được mở rộng tầm mắt được không?
À mà trên máy tôi, tôi bỏ luôn cả dòng "Goto thoát" và dòng "thoát:".
Cháu về quê nghỉ lễ mất rồi bài này cho anh tuấn anh ấy không hỗ trợ nốt phần dở dang
 
Upvote 0
Em bỏ False thì hiện vầy anh @HUONGHCKT ơi
AA9.png
đòi lưu hay không lưu anh ơi.
 
Upvote 0
On Error Goto thoat
mà trong thoat có câu lệnh close bà nó file rồi, code vẫn chạy vì chạy trên mảng.
Trong vòng lặp gặp thêm Error thứ 2 lại goto thoat lần 2, có còn file đâu mà close?
 
Upvote 0
Cháu về quê nghỉ lễ mất rồi bài này cho anh tuấn anh ấy không hỗ trợ nốt phần dở dang
Chúc bạn và gia đình có kỳ nghỉ lễ vui vẻ nhé.
Tôi chợt nhận thấy bạn đã tiếp thu được tinh thần của anh Vet rất nhiều rồi đấy.
Tôi nói thế nếu không đúng mong bạn hãy xem như chưa đọc, chưa thấy dòng trên này nhé.
Bài đã được tự động gộp:

Em bỏ False thì hiện vầy anh @HUONGHCKT ơi
View attachment 300538
đòi lưu hay không lưu anh ơi.
Thử bỏ "Goto thoat" và "thoat" xem sao.
Như bài #26 đã nêu ra lý do.
 
Upvote 0
Biết cách test thì chỉ 5 phút ra hàng đống chỗ sai, chứ làm gì mà loay hoay cả tuần lễ rồi đoán chỗ này chỗ kia.
 
Upvote 0
Thử bỏ "Goto thoat" và "thoat" xem sao.
Như bài #26 đã nêu ra lý do.
Goto là 1 kiểu bắt lỗi (lỗi bất kỳ, lỗi gì cũng bắt) và xử lý lỗi. Nếu bỏ thì phải biết lỗi gì và xử lý bằng cách khác, chứ không xử lý lỗi là lại sinh chuyện.
Mong Thầy @ptm0412 giúp đỡ ạ. Code này do em bắt chước code của Anh @Hoàng Tuấn 868 làm cho em ạ.
Tôi chỉ gợi ý đến mức đó thôi.
 
Upvote 0
Thầy @ptm0412 biết trình độ VBA của em mà .
Tôi biết cả cách học như không học của bạn nữa. Và tôi không chiều.
Cách của tôi tìm và sửa như sau: Chẳng hạn tôi nói: "Lỗi ở k = 0 chứ không phải instr = 0"
1. Tìm cách nào:
Khi bi lỗi và tô vàng dòng lệnh, thì trong tình trạng tô vàng tôi kiểm tra giá trị các biến và các giá trị khác có tham gia câu lệnh đó. Nếu các giá trị trong câu lệnh lỗi đều phù hợp thì còn phải tìm thêm các giá trị ở các dòng lệnh bên trên. Thí dụ tên sheet, tên file, kích thước mảng, ...
Cụ thể là k = 0 thì không gán gía trị cho mảng ở vị trí 0 được.
Hoặc file đã đóng thì không đóng nữa được. Cái này ngó xuống task bar là thấy, khỏi đọc code.

2. Sửa làm sao: Phải tự đặt ra câu hỏi.
Lỗi k=0
Tại sao k = 0? tại sao đã gán k = k + 1 rồi mà cứ bằng 0 hoài? Tìm ra là sửa được.
Lỗi đóng file
Tại sao chưa xong đã đóng rồi bây giờ không đóng được? Tại sao lại đóng ngang xương? Tìm ra là sửa được.

Ghi chú:
On Error Goto <label> là 1 cấu trúc khó mà bản thân tôi còn chưa dám xài. Các câu lệnh bên dưới label rất khó kiểm soát, và rất nhiều trường hợp phải thêm câu lệnh Resume để quay về chỗ nào đó chạy tiếp, chứ không phải chạy tuồn tuột đến cuối. (Nếu không resume thì nó chạy xong 1 vài câu lệnh mong muốn để xử lý lỗi, nó chạy tiếp xuống dưới một cách không mong muốn)

Nếu cách học của bạn thay đổi, chịu đọc, chịu tư duy và làm, thì chỉ cần giải thích như trên là tự làm được.
 
Upvote 0
Em đọc lời thầy Mỹ chỉ, mà như "vịt nghe sấm" vậy.
 
Upvote 0
Em đọc lời thầy Mỹ chỉ, mà như "vịt nghe sấm" vậy.
Trả lời nhanh như vậy tức là chỉ đọc lướt qua bài viết mà không đọc lại code đã viết. Nghĩa là cái nết của bạn vẫn vậy, không muốn tư duy mà chỉ muốn ai đó làm sẵn.
Những bài trả lời bên trên không sửa được lỗi chỉ là do không biết cách tìm, chỉ đọc rồi đoán. Instr có thể bằng 0, trừ 1 cũng có thể bằng 0, nhưng trong tình huống tên file có sẵn, tên file có WF rõ ràng, và WF nằm ở vị trí không phải 1, thì không thể bằng 0. Rà chuột vào nó còn hiện ra giá trị 14, 15 gì đó mà lại đoán bằng 0 được!
Thứ 2: Đóng file không được chẳng liên quan gì đến True hay False. True là có lưu trước khi đóng, False là không lưu. Bỏ trống có 2 trường hợp tùy theo file đó có bị đụng chạm gì không:
- không bị đụng chạm gì: mặc định không lưu
- Có chỉnh sửa: Bị hỏi như hình bài 25
Trường hợp không đụng chạm gì nhưng file có dùng hàm volatile, coi như có thay đổi và vẫn hỏi. Đang filter bị bỏ filter ra cũng là 1 thay đổi.
 
Lần chỉnh sửa cuối:
Upvote 0
Căn bản VBA em có biết gì đâu mà em không trả lời nhanh thầy Mỹ, em chỉ biết đổi các tham chiếu trong code thôi, ví dụ md(k, 11) là em biết cộtL vậy thôi, mà cột L em muốn nó là VTF + số cuối của tên file con.
 
Upvote 0
Em đọc những chỉ dạy của Thầy Mỹ mà chả hiểu gì hết các anh ạ.
Mong các anh giúp.
 
Upvote 0
File của bạn có phải làm theo yêu cầu này không, bạn tham khảo thử cách mình làm có đúng không nhé
Do file của bạn có chưa lọc và khoá sheet và có nhiều mục mình không hiểu nên mình tạo file khác giữ dữ liệu cũ.
Trước khi thực hiện bạn cần mở 4 file lên cùng lúc.
Thanks.
 

File đính kèm

Upvote 0
Em đọc những chỉ dạy của Thầy Mỹ mà chả hiểu gì hết các anh ạ.
Mong các anh giúp.
Vấn đề nằm ở việc bạn tiếp nhận góp ý và xử lý vấn đề.
Bạn đưa lên 1 đoạn code và hỏi mọi người vì sao lỗi, mọi người có góp ý tư vấn cho bạn tìm ra một số điểm.
Bạn cũng cần tự xử lý vấn đề của mình nếu muốn tiến bộ thay vì "chả hiểu gì hết" :D
Trong mảng md mà bạn tạo không thể truy vấn về địa chỉ 0 được ? k khởi tạo dĩ nhiên là bằng 0; k = k + 1 nằm trong tận 2 dấu if, khi if không thỏa mãn thì k= 0 thôi.
Tiếp theo ảnh cũng có nói đến là dòng On Error GoTo thoat, và chỉ dẫn rằng nếu không hiểu rõ thì bỏ ra, bạn cũng phải cố gắng thử đã chứ :D
p/s:
1. Trừ khi là bạn code để học hoặc để chơi, còn để áp dụng vào công việc của bạn thì bản phải hiểu rõ, lỡ sai xót thì không thể nói do code "ở trên trển" em lấy về xài.
2. Nếu thực sự "chả hiểu gì hết các anh ạ." thì bạn nên đưa đầu bài, rõ ràng yêu cầu thì diễn đàn sẽ có người giúp đỡ thôi;
 
Lần chỉnh sửa cuối:
Upvote 0
2. Nếu thực sự "chả hiểu gì hết các anh ạ." thì bạn nên đưa đầu bài, rõ ràng yêu cầu thì diễn đàn sẽ có người giúp đỡ thôi;
Đầu bài của em ạ:
Lấy dữ liệu từ sheet!BaoCao của 3 file con: 04-2024 HoiGPE-WF1, 04-2024 HoiGPE-WF3, 04-2024 HoiGPE-WF6. gán vào sheet!TonDau file ThepHinh, theo nguyên tắc sau:
1/ chỉ lấy những tên vật tư khác tên "Steel Plate" và "Chequered" như code hiện tại:
Mã:
If InStr(Arr(i, 3), "Steel Plate") = 0 Or InStr(Arr(i, 3), "Steel Plate") = 0 Then
                        If InStr(Arr(i, 3), "Chequered") = 0 Or InStr(Arr(i, 3), "Chequered") = 0 Then
2/Lấy dữ liệu cột B sheet!BaoCao của 3 file con gán vào cột D sheet!TonDau file ThepHinh.
3/Lấy dữ liệu cột E sheet!BaoCao của 3 file con gán vào cột J sheet!TonDau file ThepHinh.
4/Giá trị cột L sheet!TonDau bằng "VTF" cộng số cuối cùng của tên 3 file con (1,3,6), theo dữ liệu của file con, ví dụ dữ liệu của file con tên 04-2024-HoiGPE-WF1 thì cột L là VTF1.v..vv., code trong file đang là
Mã:
md(k, 11) = "VTF" & Mid(wn.Name, InStr(wn.Name, "WF") - 1, 1)
5/ sau dữ liệu của mỗi xưởng thì có dòng trống phân cách với xưởng khác, và bôi màu từ cột A-> cột M, code trong file:
Mã:
sd.Range("A" & i).Resize(1, 11).Interior.ColorIndex = 37
Mong các anh xem giúp.
Nhưng các anh ơi, đã có Thầy Mỹ chỉ cách sai của code, mà sao các anh, hoặc Thầy Mỹ chỉnh dùm code trên luôn dùm em vậy.???
 
Upvote 0
Đang hỏi, vì thầy Mỹ đã chỉ thì các anh biết các anh chỉnh dùm trên code đó luôn đi, còn hỏi đề bài làm gì nữa.
Bài đã được tự động gộp:

Code đang lỗi ở cột L, mục số 4, biến k =0, các anh biết các anh chỉnh có tí là xong thôi.
Bài đã được tự động gộp:

Cười gì hoài anh @BuiQuangThuan , anh biết anh chỉnh code trên dùm đi, Chúc anh nghỉ lễ vui vẻ.
 
Lần chỉnh sửa cuối:
Upvote 0
Đang hỏi, vì thầy Mỹ đã chỉ thì các anh biết các anh chỉnh dùm trên code đó luôn đi, còn hỏi đề bài làm gì nữa.
Bài đã được tự động gộp:

Code đang lỗi ở cột L, mục số 4, biến k =0, các anh biết các anh chỉnh có tí là xong thôi.
Bài đã được tự động gộp:

Cười gì hoài anh @BuiQuangThuan , anh biết anh chỉnh code trên dùm đi, Chúc anh nghỉ lễ vui vẻ.
Đặt lệnh md(k, 11) = "VTF" & Mid(wn.Name, InStr(wn.Name, "WF") - 1, 1)
sau dòng k= k+1
Có 2 dòng k= k+1, đặt ở đâu là tùy bạn

Chỉ chữa cháy tạm, còn lại tự xử
 
Upvote 0
Trời, anh Hiếu đã ra tay cứu vớt em, dạ để em thử ạ.
Cám ơn anh Hiếu nhiều.
Bài đã được tự động gộp:

vẫn lỗi anh Hiếu ơi, mình bỏ đi 1 dòng k=k+1 hả anh.????
 
Lần chỉnh sửa cuối:
Upvote 0
Code đang lỗi ở cột L, mục số 4, biến k =0, các anh biết các anh chỉnh có tí là xong thôi.
Bài 38 nói: " k khởi tạo dĩ nhiên là bằng 0; k = k + 1 nằm trong tận 2 dấu if End if, khi if không thỏa mãn thì k= 0 thôi."
Thì khi thỏa điều kiện câu lệnh gán giá trị md(k, 11) phải nằm ở chỗ thỏa điều kiện tức là chỗ k đã + 1. Tức là nằm trong If-End If, như bài 42 chỉ dẫn. Chứ nằm ngoài tức là không thỏa điều kiện, k = 0 chứ sao. Bạn thật tình là không muốn động não 1 chút nào. y như tôi nhận xét từ đầu.

Còn việc xóa On Error Goto và xóa thoat
khi xóa thoat phải xóa luôn câu lệnh bên dưới thoat (k = k +1), nếu không kết quả sẽ sinh ra các dòng trống. Khi có quá nhiều dòng trống thì lại vượt kích thước mảng kết quả.
 
Upvote 0
Trời, anh Hiếu đã ra tay cứu vớt em, dạ để em thử ạ.
Cám ơn anh Hiếu nhiều.
Bài đã được tự động gộp:

vẫn lỗi anh Hiếu ơi, mình bỏ đi 1 dòng k=k+1 hả anh.????
Code bạn bị vướng tùm lum tùm la sửa mệt hơn viết mới, nói rỏ cần làm gì các bạn trên diễn đàn sẽ giúp viết lại code.
 
Upvote 0
Có "Động não" chứ Thày Mỹ, nhưng có biết tí gì đâu mà chỉnh thầy Mỹ.
Bạn thật tình là không muốn động não 1 chút nào. y như tôi nhận xét từ đầu.
Bài đã được tự động gộp:

Code bạn bị vướng tùm lum tùm la sửa mệt hơn viết mới, nói rỏ cần làm gì các bạn trên diễn đàn sẽ giúp viết lại code.
Thì em có nói rồi đó anh Hiếu. Bài #39
 
Upvote 0
Em đã làm theo, nhưng code chạy vẫn lỗi thầy Mỹ:
Mã:
                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, 11) = "VTF" & Mid(wn.Name, InStr(wn.Name, "WF") - 1, 1)
                    md(k, 4) = mn(j, 1)
                    md1(k, 1) = mn(j, 3)
                    End If
                End If
Phải vầy không thầy Mỹ.
 
Upvote 0
Em đã làm theo, nhưng code chạy vẫn lỗi thầy Mỹ:
Mã:
                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, 11) = "VTF" & Mid(wn.Name, InStr(wn.Name, "WF") - 1, 1)
                    md(k, 4) = mn(j, 1)
                    md1(k, 1) = mn(j, 3)
                    End If
                End If
Phải vầy không thầy Mỹ.
Còn câu "xóa On Error Goto và xóa thoat: khi xóa thoat phải xóa luôn câu lệnh bên dưới thoat (k = k +1)"
sao không đọc, không làm theo?

Việc xóa này đã nói từ bài 28

1714453904066.png
 
Upvote 0
Em làm thì thấy nó lấy dữ liệu sai, đúng ra là cột L là số 12, mà code cũ là 11
Mã:
md(k, 11) = "VTF" & Mid(wn.Name, InStr(wn.Name, "WF") - 1, 1)
em thay là 12 thì lỗi ngay dòng
Mã:
md(k, 12) = "VTF" & Mid(wn.Name, InStr(wn.Name, "WF") - 1, 1)
Mong thầy Mỹ giúp.
 
Upvote 0
Dạ tới cột M, là 13 cột thầy, em đã chỉnh Redim md(1 to 2000, 1 to 13) sao nó chạy lấy dữ liệu không đúng, thôi thiệt tình em xin lỗi các anh và thầy Mỹ. Mong các anh và thầy viết cho em code mới luôn ạ, chứ giờ chỉnh sửa hư hoài. Mong mọi người giúp em.
 
Upvote 0
Cái thằng cha già chết tiệt ấy nói sai. Thớt không hẳn mắc bệnh lười động não.
Theo tôi thì thớt mắc bệnh chủ quan (subjective) và thành kiến (prejudice)
Thớt chỉ đọc thôi chứ gần như bỏ ngoài tai những lời nói không hợp ý mình.

Điển hình: cha già chết tiệt đã mách khi gặp lỗi "subscript out of range" thì phải bảo khung immediate in ra đủ dimensions của mảng.
Khi lão ta hỏi lại lần nữa về độ lớn của md thì thớt chỉ nói vỏn vẹn là 13, tức cột M.
Nếu là tôi thì tôi gõ vào immediate như sau:
? LBound(md), UBound(md), LBound(md), UBound(md,2)
? Mid(wn.Name, InStr(wn.Name, "WF") - 1, 1)
 
Upvote 0
Cái thằng cha già chết tiệt ấy nói sai. Thớt không hẳn mắc bệnh lười động não.
Theo tôi thì thớt mắc bệnh chủ quan (subjective) và thành kiến (prejudice)
Thớt chỉ đọc thôi chứ gần như bỏ ngoài tai những lời nói không hợp ý mình.
Tôi đọc code từ bài 1, và đọc code trong file có chạy kiểm tra lỗi, và nhớ rằng chỉ Redim 11 cột. Lỗi tôi phát hiện và hướng dẫn sửa thì sau bài 50 không phản hồi chạy được hay chưa; lại sinh ra lỗi do gán vào cột 12. Từ chỗ này sinh ra 2 nguyên nhân có thể sinh ra lỗi:
- Lỗi cũ, sửa chưa hết
- Không biết Redim 12 cột chưa mà gán vào cột 12

Cho nên tôi định hỏi từng lần, mỗi lần 1 nguyên nhân để loại trừ. Hỏi 2 câu 1 lúc thì tôi quá biết là sẽ chỉ trả lời 1 (giống như bài 44 hướng dẫn 2 chuyện cũng không làm, sau đó chỉ làm 1 chuyện).

Nếu lỗi cũ sau khi sửa 2 chuyện đó đã chạy tốt rồi (tôi đã test), thì lỗi cột 12 là 1 lỗi mới, lẽ ra nên đưa code mới lên lại xem thử đã phá thêm những gì.

Nói thêm:
LBound, Ubound có thể xem lại chỗ Redim, chưa cần Immediate
InStr(wn.Name, "WF") - 1 theo như tôi phân tích ở bài 34 thì tên file luôn luôn có sẵn "WF" và nằm tít đằng sau, Instr dù trừ 1 cũng không thể bằng 0
 
Upvote 0
Cám ơn các anh và thầy Mỹ đã hướng dẫn, sau gần 1 tháng em đã làm được code chạy rồi, nhưng sao em thấy nó vẫn giựt màn hình.
Mặc dù code dòng đầu có:
Mã:
    Application.ScreenUpdating = False
    Application.DisplayAlerts = False
và cuối có:
Mã:
Application.ScreenUpdating = True
Application.DisplayAlerts = True
và code mới đây ạ:
Mã:
Sub LayDuLieuSheetIssue_TuCacFile()
Application.ScreenUpdating = False
Dim wd As Workbook, wn As Workbook
Dim sd As Worksheet, sn As Worksheet
Dim Lrd As Long, lrn As Long, lrn1 As Long
Dim i As Long, j As Long, k As Long, p As Long, q As Long
Dim md() As String, md1, mn
    Application.ScreenUpdating = False
    Application.DisplayAlerts = False

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


ReDim md(1 To 2000, 1 To 13)
ReDim md1(1 To 2000, 1 To 5)

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("A8:E" & lrn)
        For j = 1 To UBound(mn, 1)
                If mn(j, 5) > 0 Then
                    If InStr(mn(j, 3), "Steel Plate") = 0 Or InStr(mn(j, 3), "Steel Plate") = 0 Then
                        If InStr(mn(j, 3), "Chequered") = 0 Or InStr(mn(j, 3), "Chequered") = 0 Then
                        On Error GoTo thoat
            
                        k = k + 1
                        md(k, 4) = mn(j, 2)
                        md(k, 5) = mn(j, 3)
                        md1(k, 1) = mn(j, 5)
                        md(k, 12) = "VTF" & Left(Right(wn.Name, 6), 1)
                    End If
                End If
            End If
thoat:
        Next j
    k = k + 1
    wn.Close False
    Next i
    
    If k > 0 Then
    
        
 
        sd.Range("A3:M2000").Clear
        sd.Range("A3").Resize(k, 13) = md
        sd.Range("J3").Resize(k - 1, 1) = md1
        Lrd = sd.Cells(Rows.Count, 4).End(xlUp).Row
        sd.Range("A3:M" & Lrd).Borders.LineStyle = True
  End If
End With

        sd.Range("E3").Formula = "=IF($D3<>"""",VLOOKUP($D3,'DanhMuc'!$B$6:$I$543,8,0),"""")"
        sd.Range("E3:E" & Lrd).FillDown
        sd.Range("F3").Formula = "=IF($D3<>0,VLOOKUP($D3,'DanhMuc'!$B$6:$I$1042,4,0),"""")"
        sd.Range("F3:F" & Lrd).FillDown
        sd.Range("G3").Formula = "=IF($D3<>0,VLOOKUP($D3,'DanhMuc'!$B$6:$I$1042,5,0),"""")"
        sd.Range("G3:G" & Lrd).FillDown
        sd.Range("H3").Formula = "=IF($D3<>0,VLOOKUP($D3,'DanhMuc'!$B$6:$I$1042,6,0),"""")"
        sd.Range("H3:H" & Lrd).FillDown
        sd.Range("I3").Formula = "=IF($D3<>0,VLOOKUP($D3,'DanhMuc'!$B$6:$I$1042,7,0),"""")"
        sd.Range("I3:I" & Lrd).FillDown
        sd.Range("K3").Formula = "=IFERROR(J3*I3,"""")"
        sd.Range("K3:K" & Lrd).FillDown

    For i = 3 To Lrd - 1
        If sd.Cells(i, 4) = "" Then
            sd.Range("A" & i).Resize(1, 13) = ""
            sd.Range("A" & i).Resize(1, 13).Interior.ColorIndex = 35
        End If
    Next i
    
Application.ScreenUpdating = True
Application.DisplayAlerts = True

End Sub
File đính kèm ạ.
Mong các anh và thầy Mỹ xem hộ code và chỉ ra chổ nào có vấn đề ạ.
 

File đính kèm

Upvote 0
Đọc 2 câu lệnh này:
Mã:
If InStr(mn(j, 3), "Steel Plate") = 0 Or InStr(mn(j, 3), "Steel Plate") = 0 Then
    If InStr(mn(j, 3), "Chequered") = 0 Or InStr(mn(j, 3), "Chequered") = 0 Then
Mỗi câu là 1 cái Or, nhưng 2 vế của Or nó như thế nào?

Các ô lỗi lại là lỗi của hàm Vlookup. Khi gán hàm Vlookup cho ô thì những con số 543, 1042 lấy từ đâu ra vậy?
 
Upvote 0
Cám ơn tác giả của code (Anh @Hoàng Tuấn 868 ), vì code này em sửa code của anh.
Và cám ơn anh @HUONGHCKT , anh @BuiQuangThuan và thầy @ptm0412 đã hướng dẫn cho em.
Vì em không rành căn bản code VBA, nên em chỉnh code tùm lum, nên mới xảy ra cơ sự.
Mong các anh thông cảm.
Mong nhận được sự giúp đỡ.
À, mà chổ thầy Mỹ chỉ, em chỉnh lại như sau(Theo anh @Hoàng Tuấn 868 chỉ ) là:
Mã:
If InStr(mn(j, 3), "Steel Plate") <> "" And InStr(mn(j, 3), "Steel Plate") = 0 Then
                 If InStr(mn(j, 3), "Chequered") <> "" And InStr(mn(j, 3), "Chequered") = 0 Then
Mong thầy Mỹ bỏ qua.
 
Upvote 0
Upvote 0
Vậy thì sao hả thầy??? Vậy bỏ đi hả thầy????
 
Upvote 0
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
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.
Thì tôi cũng đã nói: Tôi viết xong, bỏ qua việc thêm dòng tô màu vô bổ, code của tôi cũng sẽ bị phá nữa mà thôi.
 
Upvote 0
Thì tôi cũng đã nói: Tôi viết xong, bỏ qua việc thêm dòng tô màu vô bổ, code của tôi cũng sẽ bị phá nữa mà thôi.
Code bị phá nhằm nhòi gì.
Đằng này lời nói còn bị bẻ nghĩa, khả năng gây hiềm khích với thành viên khác nữa.
Tôi nói "lô gic (liên hệ) giữa vấn đề và code trở nên rất lòng vòng"
Người bảo tôi nói "code chạy lòng vòng". Như vậy có phải đem tôi ra khích tướng mấy người viết code không?
 
Upvote 0
Như vậy có phải đem tôi ra khích tướng mấy người viết code không?
Tôi chẳng lo. Bài trước tôi phân tích 8 điểm dở của code dù không biết của ai. Trước đó tôi còn phân tích cách tìm lỗi 5 phút mà không phải loay hoay cả tuần lễ. Lại còn phân tích việc chăm soi vào cái Instr "có thể bằng 0" mà không thấy nó tuyệt đối không thể bằng 0. Lại còn cố đóng (close) 1 file nhiều lần.
Tất cả những cái đó là động chạm kha khá người trong chủ đề này. Tuy vậy tôi tin rằng họ nhận ra rằng tôi nhận xét đúng, không dễ khích họ.
 
Upvote 0
Bài 37 có file có code mới, không phải code cũ sửa lại. Tôi có xem và thấy nó cũng chạy được. Nhưng chắc bị chê vì kết quả không chèn dòng trống và tô màu. Còn thuật toán hay hơn hay dở hơn thì chắc không cần biết.
 
Upvote 0

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

Back
Top Bottom