Chuyên đề giải đáp những thắc mắc về code VBA

Liên hệ QC

maytinhvp01

Thành viên thường trực
Tham gia
27/7/13
Bài viết
390
Được thích
179
Mình muốn nhờ giải thich câu lệnh " If Ran.Cells(d, c) > max Then max = Ran.Cells(d, c) "
trong ví du:
Public Function LonNhat(Ran As Range)
Dim max As Double, v As Integer, d As Integer, c As Integer
max = Ran.Cells(1, 1)
For d = 1 To Ran.Rows.Count
For c = 1 To Ran.Columns.Count
If Ran.Cells(d, c) > max Then max = Ran.Cells(d, c)
Next c
Next d
v = Tim(max, Ran)
LonNhat = max
End Function
-------------------------------------------------------
[INFO1]Thông báo:
Vì topic này:
http://www.giaiphapexcel.com/forum/...ải-thích-các-code-đề-nghị-các-bạn-gửi-vào-đây
đã quá dài nên BQT đóng lại.
Nay tôi mở topic mới với cùng chủ đề: GIẢI THÍCH NHỮNG THẮC MẮC VỀ CODE
Các bạn nếu có nhu cầu giải thích code, vui lòng post tại đây nhé
NDU96081631

[/INFO1]
 
Chỉnh sửa lần cuối bởi điều hành viên:
Thì đưa theo cách... bình thương đi. Có vấn đề gì chứ?
Tại vì nhiều lúc em muốn đoạn text dài và sử dụng text đó nhiều lần ạ.
Thực sự là chuyên gia trong diễn đàn GPE đã nói vậy tức là em hết cách rồi. Em cám ơn bác rất nhiều ạ
Bài đã được tự động gộp:

Thì đưa theo cách... bình thương đi. Có vấn đề gì chứ?
Em đã giải quyết được vẫn đề, tại mới tiếp xúc với VBA nên còn chưa thuận. Cám ơn bác rất nhiều em đã đọc rất nhiều hướng dẫn của bác trên diễn đàn GPE, rất hữu ích và dễ hiểu. Chúc bác luôn khỏe và tiếp tục hướng dẫn mọi người
 
Lần chỉnh sửa cuối:
Upvote 0
Các anh/chị cho em hỏi chút: lúc em copy 1 sheet tạo thành file mới hoặc trong Vba em để code : sheet1.copy thì lại báo lỗi. Cách sửa là như thế nào ạ
 
Upvote 0
Các anh/chị cho em hỏi chút: lúc em copy 1 sheet tạo thành file mới hoặc trong Vba em để code : sheet1.copy thì lại báo lỗi. Cách sửa là như thế nào ạ
Vấn đề là trong file của bạn có cái sheet nào là sheet1 hay không? Cái chổ màu đỏ là NameCode nhé.
 
Upvote 0
Vấn đề là trong file của bạn có cái sheet nào là sheet1 hay không? Cái chổ màu đỏ là NameCode nhé.
Có bạn ạ. Code vba của mình lấy đúng sheet cần copy rồi. Và mình thực hiện bằng chuột đơn thuần cũng ko copy được sheet cần copy thành file mới
 
Upvote 0
Với dữ liệu excel hơn 45.000 dòng, khi em sử dụng code sau thời gian chờ code chạy xong lâu quá! Mong các sư phụ chỉ giúp cách xử lý sao cho thời gian nhanh sớm hơn ah! Em cũng đã search rồi nhưng vẫn chưa thấy code nào tối ưu hơn ah.
Sub Code_TonThoiGian()
Dim tg As Double
tg = Timer

'Voi hon 45.000 dong, thoi gian lau qua
Sheets("DuLieu").Select
SoDongDuLieu = Range("A1").End(xlDown).Row

Dim j As Long
For j = 1 To SoDongDuLieu
If Range("A" & j).Value Like "05" Then
Range("B" & j).Value = "PGD05"
End If
If Range("A" & j).Value Like "00" Then
Range("B" & j).Value = "HoiSo"
End If
If Range("A" & j).Value Like "03" Then
Range("B" & j).Value = "PGD03"
End If
If Range("A" & j).Value Like "04" Then
Range("B" & j).Value = "PGD04"
End If
If Range("A" & j).Value Like "07" Then
Range("B" & j).Value = "PGD07"
End If
If Range("A" & j).Value Like "09" Then
Range("B" & j).Value = "PGD09"
End If
If Range("A" & j).Value Like "10" Then
Range("B" & j).Value = "PGD10"
End If
If Range("A" & j).Value Like " " Then
Range("A" & j).Value = "KoPhongBan"
Range("B" & j).Value = "KoPhongBan"
End If
If Range("C" & j).Value = "" Then
Range("C" & j).Value = "KoMaNhanSu"
End If
If Range("D" & j).Value = "" Then
Range("D" & j).Value = "KoTenTuoi"
End If
Next

tg = Timer - tg
MsgBox tg & " done."
End Sub
 
Upvote 0
Thử xem:
Mã:
Sub Code_TonThoiGian_sua()
    Dim tg As Double, arr()
    tg = Timer

    Sheets("DuLieu").Select
    SoDongDuLieu = Range("A1").End(xlDown).Row
    Dim j As Long

    arr = Range("A1:D" & SoDongDuLieu)
    For j = 1 To UBound(arr, 1)
        If InStr(1, arr(j, 1), "05", vbTextCompare) > 0 Then arr(j, 2) = "PGD05"
        If InStr(1, arr(j, 1), "00", vbTextCompare) > 0 Then arr(j, 2) = "HoiSo"
        If InStr(1, arr(j, 1), "03", vbTextCompare) > 0 Then arr(j, 2) = "PGD03"
        If InStr(1, arr(j, 1), "04", vbTextCompare) > 0 Then arr(j, 2) = "PGD04"
        If InStr(1, arr(j, 1), "07", vbTextCompare) > 0 Then arr(j, 2) = "PGD07"
        If InStr(1, arr(j, 1), "09", vbTextCompare) > 0 Then arr(j, 2) = "PGD09"
        If InStr(1, arr(j, 1), "10", vbTextCompare) > 0 Then arr(j, 2) = "PGD10"
        If Trim(arr(j, 1)) = "" Then
            arr(j, 1) = "KoPhongBan"
            arr(j, 2) = arr(j, 1)
        End If
        If Trim(arr(j, 3)) = "" Then arr(j, 3) = "KoMaNhanSu"
        If Trim(arr(j, 4)) = "" Then arr(j, 4) = "KoTenTuoi"
    Next
    Range("A1:D" & SoDongDuLieu).Value = arr

    tg = Timer - tg
    MsgBox tg & " done."
End Sub
 
Upvote 0
Thử xem:
Mã:
Sub Code_TonThoiGian_sua()
    Dim tg As Double, arr()
    tg = Timer

    Sheets("DuLieu").Select
    SoDongDuLieu = Range("A1").End(xlDown).Row
    Dim j As Long

    arr = Range("A1:D" & SoDongDuLieu)
    For j = 1 To UBound(arr, 1)
        If InStr(1, arr(j, 1), "05", vbTextCompare) > 0 Then arr(j, 2) = "PGD05"
        If InStr(1, arr(j, 1), "00", vbTextCompare) > 0 Then arr(j, 2) = "HoiSo"
        If InStr(1, arr(j, 1), "03", vbTextCompare) > 0 Then arr(j, 2) = "PGD03"
        If InStr(1, arr(j, 1), "04", vbTextCompare) > 0 Then arr(j, 2) = "PGD04"
        If InStr(1, arr(j, 1), "07", vbTextCompare) > 0 Then arr(j, 2) = "PGD07"
        If InStr(1, arr(j, 1), "09", vbTextCompare) > 0 Then arr(j, 2) = "PGD09"
        If InStr(1, arr(j, 1), "10", vbTextCompare) > 0 Then arr(j, 2) = "PGD10"
        If Trim(arr(j, 1)) = "" Then
            arr(j, 1) = "KoPhongBan"
            arr(j, 2) = arr(j, 1)
        End If
        If Trim(arr(j, 3)) = "" Then arr(j, 3) = "KoMaNhanSu"
        If Trim(arr(j, 4)) = "" Then arr(j, 4) = "KoTenTuoi"
    Next
    Range("A1:D" & SoDongDuLieu).Value = arr

    tg = Timer - tg
    MsgBox tg & " done."
End Sub
Code này chưa chắc đúng. Vì nó chỉ tăng tốc chứ mức độ chính xác thì thua cả code ban đầu.
 
Upvote 0
1.
Cho vào đây.
1538933880080.png
2.
SoDongDuLieu = Range("A1").End(xlDown).Row
Khi không có dữ liệu thì tụt tận gót chân.

3.
If Range("A" & j).Value Like " " Then
Range("A" & j).Value = "KoPhongBan"
Range("B" & j).Value = "KoPhongBan"
End If
Lần xử lý thứ 2 trở đi thì [Aj]= "KoPhongBan" thì xử lý sao?

4.
thì không đọc và ghi kết quả vào từng cell nữa.

PHP:
Option Explicit

Sub vidu()
    Const CodeMatch As String = "|||05||00||03||04||07||09||10||Ko|| "
    Const KMNS As String = "KhongMaNhanSu"
    Const KTT As String = "KhongTenTuoi"
    Dim PGD, lR As Long, arr(), i As Long, ws As Worksheet, N As Long, idx As Long, sCode As String
    PGD = Array("PGD05", "HoiSo", "PGD03", "PGD04", "PGD07", "PGD09", "PGD10", "KoPhongBan", "KoPhongBan")
    N = UBound(PGD)
    Set ws = ThisWorkbook.Worksheets("Dulieu")
    With ws
        lR = .Range("A" & Rows.Count).End(xlUp).Row
        arr = .Range("A1:D" & lR).Value2
        '//Côt A format: Text'
    End With
    For i = 1 To lR
        sCode = Left(arr(i, 1), 2)
        idx = 0
        If Len(sCode) > 0 Then idx = InStr(1, CodeMatch, sCode)
        If idx > 0 Then
            idx = idx / 4 - 1
            arr(i, 2) = PGD(idx)
            If idx = N Then arr(i, 1) = PGD(N)
        End If
        If Len(arr(i, 3)) = 0 Then arr(i, 3) = KMNS
        If Len(arr(i, 4)) = 0 Then arr(i, 4) = KTT
    Next i
    ws.Range("A1").Resize(lR, 4).Value = arr
End Sub
 
Upvote 0
Thử thôi rồi tính tiếp mà anh, có biết dữ liệu họ như thế nào, để họ tự phát triển thêm nữa. Ví dụ trong dữ liệu có công thức ...
Đã nói sai là sai.
Khi code có điều kiện ghi chồng dữ liệu là code luộm thuộm.
Code của bạn (và code ban đầu) phải thực hiện đủ 8 lần IF trong khi thực tế khong cần vậy, số lần duyệt trung bình ít hơn.
Trường hợp điều kiện 8 chồng lên điều kiện 7, 6, ... thì người ta dùng ELSE IF và xét ngược lại, 8 trước.

...
...
PGD = Array("PGD05", "HoiSo", "PGD03", "PGD04", "PGD07", "PGD09", "PGD10", "KoPhongBan", "KoPhongBan")
N = UBound(PGD)
...

Select Case trông dài hơn nhưng là cách sáng sủa nhất trong trường hợp này.
 
Lần chỉnh sửa cuối:
Upvote 0
Em thu gọn if lại thì lại ko ổn nên em để nhiều if, em biết là nhìn luộm thuộm. Mong VetMini chỉ giúp cho code nhanh ah.
Bài đã được tự động gộp:

Đúng vậy, thế mà em ko nhớ là dung select Case. Tuyệt. Gọn gàng code hơn. Hoàn toàn dữ liệu ko công thức ah.
 
Upvote 0
Đã nói sai là sai.
Khi code có điều kiện ghi chồng dữ liệu là code luộm thuộm.
Code của bạn (và code ban đầu) phải thực hiện đủ 8 lần IF trong khi thực tế khong cần vậy, số lần duyệt trung bình ít hơn.
Trường hợp điều kiện 8 chồng lên điều kiện 7, 6, ... thì người ta dùng ELSE IF và xét ngược lại, 8 trước.
Thuật toán và ý đồ là của tác giả, họ muốn nhanh thì mình dựa vào code của họ làm cho nhanh thôi. Tôi không cần biết và không thể biết ý của họ. Nhiều khi họ cố tình xét If như vậy thì sao?
Anh toàn đi bắt lỗi mà không đưa code ra.
Anh có thể viết code hoàn hảo trong khi chỉ dựa vào code của họ không?
 
Upvote 0
Thầy @VetMini nhà mình có tính rất xấu. Không bao giờ "Vở sạch chứ đẹp" được :p:p:p
 
Lần chỉnh sửa cuối:
Upvote 0
Thuật toán và ý đồ là của tác giả, họ muốn nhanh thì mình dựa vào code của họ làm cho nhanh thôi. Tôi không cần biết và không thể biết ý của họ. Nhiều khi họ cố tình xét If như vậy thì sao?
Anh toàn đi bắt lỗi mà không đưa code ra.
Anh có thể viết code hoàn hảo trong khi chỉ dựa vào code của họ không?
Xét If như vậy là luộm thuộm.
Tuy nhiên, code ngừoi ta khác code của bạn ở chỗ là nó so sánh thẳng (tuy like có wildcard hì cũng như so sánh thẳng) nên không bị sai trường hợp chồng điều kiện. Code của bạn dùng hàm InStr cho nên có thể bị chồng điều kiện (chuỗi kia có thể chứa 030405 thì sao?). Và như vậy là không đúng.

Về sự luộm thuộm của dãy code này. Đáng lẽ cỡ bạn không khích nổi tôi phải viết code biểu diễn đâu. Nhưng tôi thấy có người "like" bài ấy cho nên tôi giải thích luôn cho các thành viên khác biết:

If InStr(1, arr(j, 1), "05", vbTextCompare) > 0 Then arr(j, 2) = "PGD05" ' xét chuỗi lần 1
If InStr(1, arr(j, 1), "00", vbTextCompare) > 0 Then arr(j, 2) = "HoiSo" ' lần thứ 2
If InStr(1, arr(j, 1), "03", vbTextCompare) > 0 Then arr(j, 2) = "PGD03"
If InStr(1, arr(j, 1), "04", vbTextCompare) > 0 Then arr(j, 2) = "PGD04"
If InStr(1, arr(j, 1), "07", vbTextCompare) > 0 Then arr(j, 2) = "PGD07"
If InStr(1, arr(j, 1), "09", vbTextCompare) > 0 Then arr(j, 2) = "PGD09"
If InStr(1, arr(j, 1), "10", vbTextCompare) > 0 Then arr(j, 2) = "PGD10" ' lần thứ 8
If Trim(arr(j, 1)) = "" Then ' lần thứ 9
arr(j, 1) = "KoPhongBan"
arr(j, 2) = arr(j, 1)
End If
Nếu arr(j, 1) = "05000304070910" thì arr(j,2) được gán tất cả 8 lần, xét 9 lần, và kết quả cuối cùng là "PGD10"
Tuy trường hợp này không có khả năng xảy ra, nhưng đó không thể là cái cớ để bảo rằng code không luộm thuộm
(chỗ tô đỏ ở phần quote trên là lời phê của tôi)

Code đúng đắn:
If Trim(arr(j, 1)) = "" Then ' lần thứ 1
arr(j, 1) = "KoPhongBan"
arr(j, 2) = arr(j, 1)
ElseIf InStr(1, arr(j, 1), "10", vbTextCompare) > 0 Then ' lần thứ 2, nhưng chỉ xảy ra khi lần thứ nhất khong đạt
arr(j, 2) = "PGD10"
ElseIf InStr(1, arr(j, 1), "09", vbTextCompare) > 0 Then ' lần thứ 3, nhưng chỉ xảy ra khi lần thứ 1 và 3 khong đạt
arr(j, 2) = "PGD09"
ElseIf...
...
ElseIf InStr(1, arr(j, 1), "05", vbTextCompare) > 0 Then
arr(j, 2) = "PGD05"
End If
Trung bình số lần xét là 4,5. Và số lần gán vào arr(j,2) tối đa là 1
Nếu arr(j, 1) = "05000304070910" thì arr(j,2) được gán chỉ 1 lần, xét 2 lần, và kết quả cuối cùng là "PGD10"

Chú thêm về select case:
Nếu dùng select case thì cái nhóm 03, 04, 05, 07, 09, 10 có thể gộp vào 1 case và kết qả là "PGD" & (trị của ô)
 
Upvote 0
Í, vậy là mình biết cách mời anh vetmini viết code rồi, hễ thấy ai mời anh vetmini viết code thì ta cứ bấm "lai" bài viết đó, anh vetmini nhìn thấy thì sẽ cho chúng ta được xem code, phải không anh vetmini ? Hihi
 
Upvote 0
Web KT
Back
Top Bottom