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:
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
Í, 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
"mời" viết code chi vậy? Code tôi viết thì có gì đặc biệt?
Cũng như chuyện văn chương, tôi bàn thơ mới đáng kể chứ thơ tôi làm nó lạt như nước ốc.
 
Upvote 0
Sub haskl()
Dim a, b As Long
Dim rng As Range
Dim hm As WorksheetFunction
Set hm = Application.WorksheetFunction
a = hm.RandBetween(1, 25)
b = hm.RandBetween(1, 25)

With Worksheets(1)
.Range(.Cells(a, b), .Cells(a + 8, b + 8)) _
.Borders.LineStyle = xlThick

End With
End Sub
Dạ moij nguoi giup minh viet them Code dat ten cho Range do dc hok\
 
Upvote 0
"mời" viết code chi vậy? Code tôi viết thì có gì đặc biệt?
Cũng như chuyện văn chương, tôi bàn thơ mới đáng kể chứ thơ tôi làm nó lạt như nước ốc.
Hu hu hu.......Trời oi là trời
Bác
VetMini
chỉ biết luật thơ thui
Còn không biết làm thơ đâu bà con ui.
 
Upvote 0
Mình có đoạn code muốn mọi người chỉ cho cách để hoàn thiện đoạn code này với ạ .( phần chữ màu đỏ mình chưa biết cách viết như thế nào)

Sub tinh_tong()
Dim KTcancat As Range, rVung As Range, LastCell, stt, lan
Dim ChuaCat As Range, KT As Range, rKtra As Range
Dim KTchuacat As Long, Chieudai1cay As Long
Dim Sothanhdacat As Long, Sothanhcancat As Long, Tongsothanhdacat As Long
Dim Tongsothanhcancat As Long, Socay As Long


On Error Resume Next
Application.DisplayAlerts = False
Set rVung = Application.InputBox(Prompt:="Chon vung", Title:="GPE", Type:=8)
On Error GoTo 0
Application.DisplayAlerts = True
If rVung Is Nothing Then Exit Sub
If rVung.Columns.Count <> 2 Then Exit Sub

LastCell = rVung.Item(rVung.Count).Address
Socay = 10
rVung.Select
Selection.Copy
Set rVung = rVung.Columns.Item(1)
rVung.Columns.Item(2).Offset(0, 1).FormulaR1C1 = "=RC[-2]*RC[-1]"


Range(LastCell).Select
ActiveCell.Offset(0, 3).FormulaR1C1 = Socay
ActiveCell.Offset(0, 4).FormulaR1C1 = " bằng tổng của cột vừa được nhân ra(phần code chữ màu xanh), rồi chia cho 6. kết quả nếu nhỏ hơn "socay" thì trả kết quả là đúng và lơn hơn"socay" thì trả kết quả là sai"
End Sub
 
Upvote 0
Em chào anh chị, em có mã code này mong anh chị giúp đỡ.
Mục đích: em muốn code chạy đến dò điểm từ cột G3:G14. Sau đó trả về kết quả từ cột H3:H14.
Vì em tự viết code nên khi run nó chỉ chạy ra kết quả ở cột H3.
Mong mọi người hỗ trợ em ạ
Code của em đây:
Sub hocluc()
Sheets("sheet1").Select
Range("G3:G14").Select
If ActiveCell >= 8 Then
Range("H3").Value = " Gioi"
ElseIf ActiveCell >= 6.5 Then
Range("H3").Value = " Kha"
ElseIf ActiveCell >= 6.5 Then
Range("H3").Value = " Trung Binh"
Else
Range("H3").Value = " Kem"
End If
End Sub
 
Upvote 0
Em chào anh chị, em có mã code này mong anh chị giúp đỡ.
Mục đích: em muốn code chạy đến dò điểm từ cột G3:G14. Sau đó trả về kết quả từ cột H3:H14.
Vì em tự viết code nên khi run nó chỉ chạy ra kết quả ở cột H3.
Mong mọi người hỗ trợ em ạ
Code của em đây:
Sub hocluc()
Sheets("sheet1").Select
Range("G3:G14").Select
If ActiveCell >= 8 Then
Range("H3").Value = " Gioi"
ElseIf ActiveCell >= 6.5 Then
Range("H3").Value = " Kha"
ElseIf ActiveCell >= 6.5 Then
Range("H3").Value = " Trung Binh"
Else
Range("H3").Value = " Kem"
End If
End Sub
Sub HocLuc()
Dim r As Long, sh As Worksheet
Set sh = Sheets("sheet1")
For r = 3 To 14
If sh.Cells(r, "G").Value >= 8 Then
sh.Cells(r, "H").Value = "Gioi"
ElseIf sh.Cells(r, "G").Value >= 6.5 Then
sh.Cells(r, "H").Value = "Kha"
ElseIf sh.Cells(r, "G").Value >= 5 Then
sh.Cells(r, "H").Value = "Trung Binh"
ElseIf sh.Cells(r, "G").Value >= 3.5 Then
sh.Cells(r, "H").Value = "Kem"
Else
sh.Cells(r, "H").Value = "Yeu"
End If
Next
End Sub
 
Upvote 0
Web KT

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

Back
Top Bottom