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

vanthinh3101

Thành viên tích cực
Tham gia ngày
24 Tháng một 2015
Bài viết
897
Được thích
1,024
Điểm
560
Tuổi
32
Nơi ở
Hà Nội
Em chỉ muốn ô đó là ô trống, em tự điền. Nhưng khi em chạy code thì dữ liệu em đã điền bị xóa luôn. Ý là cột 1,2,3 là fill dữ liệu từ code, bỏ cột 4 ( tự điền ), fill cột 5 fill dữ liệu từ code
Bạn xem đúng ý không.
Mã:
Public Sub GPE()
    Dim sArr(), dArr1(), dArr2(), I As Long, J As Long, K As Long, C As Long, R As Long
    With Sheets("Roster")
        C = .Range("F2") - .Range("C2") + 6
        sArr = .Range("B5", .Range("B50000").End(xlUp)).Resize(, C).Value
        R = UBound(sArr, 1)
        ReDim dArr1(1 To R * C, 1 To 3): ReDim dArr2(1 To R * C, 1 To 1)
    End With
    For I = 5 To R Step 5
        If sArr(I, 1) <> Empty Then
            For J = 6 To C
                K = K + 1
                dArr1(K, 1) = sArr(I, 1)
                dArr1(K, 2) = sArr(1, J)
                dArr1(K, 3) = sArr(1, J)
                dArr2(K, 1) = sArr(I, J)
            Next J
        End If
    Next I
    With Sheets("IT2003")
        Range("A2").Resize(100000, 3).ClearContents
        Range("E2").Resize(100000).ClearContents
        If K Then .Range("A2").Resize(K, 3) = dArr1: .Range("E2").Resize(K, 1) = dArr2
    End With
End Sub
 

bigbabol89

Thành viên hoạt động
Tham gia ngày
15 Tháng mười 2012
Bài viết
192
Được thích
20
Điểm
370
Bạn xem đúng ý không.
Mã:
Public Sub GPE()
    Dim sArr(), dArr1(), dArr2(), I As Long, J As Long, K As Long, C As Long, R As Long
    With Sheets("Roster")
        C = .Range("F2") - .Range("C2") + 6
        sArr = .Range("B5", .Range("B50000").End(xlUp)).Resize(, C).Value
        R = UBound(sArr, 1)
        ReDim dArr1(1 To R * C, 1 To 3): ReDim dArr2(1 To R * C, 1 To 1)
    End With
    For I = 5 To R Step 5
        If sArr(I, 1) <> Empty Then
            For J = 6 To C
                K = K + 1
                dArr1(K, 1) = sArr(I, 1)
                dArr1(K, 2) = sArr(1, J)
                dArr1(K, 3) = sArr(1, J)
                dArr2(K, 1) = sArr(I, J)
            Next J
        End If
    Next I
    With Sheets("IT2003")
        Range("A2").Resize(100000, 3).ClearContents
        Range("E2").Resize(100000).ClearContents
        If K Then .Range("A2").Resize(K, 3) = dArr1: .Range("E2").Resize(K, 1) = dArr2
    End With
End Sub
Thành công mỹ mãn. Em cám ơn anh rất nhiều
 

Bui Van hieu

Thành viên mới
Tham gia ngày
26 Tháng ba 2018
Bài viết
23
Được thích
0
Điểm
163
Tuổi
32
Hi cả nhà ạ
Mình có viết đoạn code về tìm kiếm trong Combobox như sau:

Dim i As Long
For i = 1 To Application.WorksheetFunction.CountA(Main.Range("F:F"))
If LCase(Left(Main.Cells(i, 1), 1)) = Me.ComboBox1 And Me.ComboBox1 <> "" Then
Me.ComboBox1.AddItem Main.Cells(i, 1)
End If
Next i
Me.ComboBox1.DropDown
With Me
.txtdi.Value = .ComboBox1.List(.ComboBox1.ListIndex, 1)
End With
End Sub

nhưng khi bấm seach thì không hiện ra như mong muốn, chỉ viết tìm kiếm được có một chữ đến 2 chữ cái chứ không viết nhiều được ạ, và viết xong không bấm nút xoá được.
Trong Combobox mình để có 2 cột
Mong cả nhà giúp đỡ ạ
 

cuong.vp.nuce

Thành viên mới
Tham gia ngày
21 Tháng sáu 2016
Bài viết
10
Được thích
0
Điểm
163
Tuổi
29
Cho mình hỏi code:
Mã:
Range("$C$3:$C$1734").AutoFilter Field:=1, Criteria1:="*" & Range("C1").Value & "*", Operator:=xlFilterValues
Nghĩ là gì vậy
 

FPT_online

Thành viên hoạt động
Tham gia ngày
27 Tháng mười 2013
Bài viết
133
Được thích
16
Điểm
370
Tuổi
37
Cho em hỏi đoạn code em viết này sao nó chậm thế, có cách nào cho nhanh hơn không ạ
 

File đính kèm

FPT_online

Thành viên hoạt động
Tham gia ngày
27 Tháng mười 2013
Bài viết
133
Được thích
16
Điểm
370
Tuổi
37
Cho em hỏi nếu viết dưới dạng Application.WorsheetFunction để có thể dùng với nhiều dạng hàm khác thì không được ạ?
 

♫ђöล♥ßล†♥†µ♫

Thành viên tiêu biểu
Tham gia ngày
10 Tháng ba 2018
Bài viết
684
Được thích
1,441
Điểm
360
Nơi ở
Cái Bang
Cho em hỏi nếu viết dưới dạng Application.WorsheetFunction để có thể dùng với nhiều dạng hàm khác thì không được ạ?
Em đọc ở đâu đó không nhớ rõ nhưng nếu mà sử dụng Application.WorsheetFunction thì phải thêm gỡ lỗi nữa thì phải..Cái Áp pờ li ca ti on khác với cái Áp pờ li ca ti on guốc sít phăn thì phải.Ôi khó đi ..
 
Lần chỉnh sửa cuối:

truongvu317

Thành viên tiêu biểu
Tham gia ngày
15 Tháng mười một 2010
Bài viết
575
Được thích
395
Điểm
435
Em đọc ở đâu đó không nhớ rõ nhưng nếu mà sử dụng Application.WorsheetFunction thì phải thêm gỡ lỗi nữa thì phải..Cái Áp pờ li ca ti on khác với cái Áp pờ li ca ti on guốc sít phăn thì phải.Ôi khó đi ..
Dùng cái nào đi nữa đều phải chủ động bẫy lỗi, ví dụ với cái vlookup chẳng hạn, Application.WorsheetFunction khi không dò được thì phát sinh lỗi. Với application tuy không phát sinh lỗi thực thi, nhưng kết quả của nó là Na, vẫn phải bẫy trường hợp này, nếu không code cũng teo.
 

♫ђöล♥ßล†♥†µ♫

Thành viên tiêu biểu
Tham gia ngày
10 Tháng ba 2018
Bài viết
684
Được thích
1,441
Điểm
360
Nơi ở
Cái Bang
Dùng cái nào đi nữa đều phải chủ động bẫy lỗi, ví dụ với cái vlookup chẳng hạn, Application.WorsheetFunction khi không dò được thì phát sinh lỗi. Với application tuy không phát sinh lỗi thực thi, nhưng kết quả của nó là Na, vẫn phải bẫy trường hợp này, nếu không code cũng teo.
Em không biết 1 tẹo tiếng anh nào. Nhưng google họ dịch như thế này
Mã:
Thí dụ

Mã số:
Phạm vi ("A1") .Giá trị = Ứng dụng.WorksheetFunction.Vlookup (.....)
Nếu Vlookup không tìm thấy một kết quả phù hợp (# N / A khi được viết trong một ô)
Sau đó, mã của bạn ngừng chạy và bạn nhận được cửa sổ gỡ lỗi.

nếu bạn làm như thế này
Mã số:
x = Application.Vlookup (.....)
Nó không còn dừng lại với gỡ lỗi.
Thay vào đó, biến x được gán giá trị lỗi và mã tiếp tục chạy.
 

truongvu317

Thành viên tiêu biểu
Tham gia ngày
15 Tháng mười một 2010
Bài viết
575
Được thích
395
Điểm
435
Em không biết 1 tẹo tiếng anh nào. Nhưng google họ dịch như thế này
Mã:
Thí dụ

Mã số:
Phạm vi ("A1") .Giá trị = Ứng dụng.WorksheetFunction.Vlookup (.....)
Nếu Vlookup không tìm thấy một kết quả phù hợp (# N / A khi được viết trong một ô)
Sau đó, mã của bạn ngừng chạy và bạn nhận được cửa sổ gỡ lỗi.

nếu bạn làm như thế này
Mã số:
x = Application.Vlookup (.....)
Nó không còn dừng lại với gỡ lỗi.
Thay vào đó, biến x được gán giá trị lỗi và mã tiếp tục chạy.
Bạn cứ thử đi, biết liền, những điều tớ nói hoàn toàn tương đồng với google dịch.
 

FPT_online

Thành viên hoạt động
Tham gia ngày
27 Tháng mười 2013
Bài viết
133
Được thích
16
Điểm
370
Tuổi
37
Nói chung mình muốn hỏi làm sao vẫn dùng Application.WorksheetFunction thì có cách nào cho nhanh không đó, nếu bẫy lỗi thì bẫy thế nào mọi người góp ý giúp
 

♫ђöล♥ßล†♥†µ♫

Thành viên tiêu biểu
Tham gia ngày
10 Tháng ba 2018
Bài viết
684
Được thích
1,441
Điểm
360
Nơi ở
Cái Bang

File đính kèm

VetMini

Chuyên gia GPE
Tham gia ngày
21 Tháng mười hai 2012
Bài viết
9,519
Được thích
11,402
Điểm
1,560
Em đọc ở đâu đó không nhớ rõ nhưng nếu mà sử dụng Application.WorsheetFunction thì phải thêm gỡ lỗi nữa thì phải..Cái Áp pờ li ca ti on khác với cái Áp pờ li ca ti on guốc sít phăn thì phải.Ôi khó đi ..
Tôi đã từng viết bài nói về cái này rồi. Nhưng nếu bạn vẫn mù mờ về lỗi thì có lẽ là chưa đọc bài đó.

WorksheetFunction sẽ lăn cù nếu gặp lỗi. Đó là điều kiện của nó. Nếu muốn tránh ngủm thì cái nơi gọi nó phải bẫy lỗi. Code bẫy lỗi thường là "On Error...". Loại code này thì hầu hết mọi người học qua bậc trung VBA đều biết viết.

Khi gọi hàm thẳng qua Application thì bạn có thể coi như là bạn gọi qua lớp bao gián tiếp (wrapper function). Lớp bao này cũng gọi hàm WorksheetFunction nhưng nó thêm cái code bẫy lỗi cho bạn. Nếu hàm bị lỗi thì nó sẽ không tỏi mà trả về một trị Error. Trong trường hợp này, người ta xét trị trả về để biết nó thành công hay error, và nếu error thì là gì.
Ví dụ điển hình:
myVariant = Application.Match(tim, mangDo, 0)
If Not IsError(myVariant) Then ' đây là hàm match cho nên dùng IsNumeric cũng được
' myVariant là kết quả
Else
' sử lý error ở đây
' nhưng 99,99% trường hợp hàm match thì là do tìm không có cho nên cũng dễ biết
' 0,01% còn lại là do dữ liệu dỏm, ví dụ mảng chẳng phải là mảng
End If

Chú: thực ra giữa cách gọi trực tiếp và gián tiếp còn khác nhau ở một vài tính chất mặc định của tham số truyền vào. Nhưng cấp độ này rất cao, thú nhận rằng tôi cũng chỉ biết 1 vài trường hợp chứ chưa nắm hết.
 

♫ђöล♥ßล†♥†µ♫

Thành viên tiêu biểu
Tham gia ngày
10 Tháng ba 2018
Bài viết
684
Được thích
1,441
Điểm
360
Nơi ở
Cái Bang
Tôi đã từng viết bài nói về cái này rồi. Nhưng nếu bạn vẫn mù mờ về lỗi thì có lẽ là chưa đọc bài đó.

WorksheetFunction sẽ lăn cù nếu gặp lỗi. Đó là điều kiện của nó. Nếu muốn tránh ngủm thì cái nơi gọi nó phải bẫy lỗi. Code bẫy lỗi thường là "On Error...". Loại code này thì hầu hết mọi người học qua bậc trung VBA đều biết viết.

Khi gọi hàm thẳng qua Application thì bạn có thể coi như là bạn gọi qua lớp bao gián tiếp (wrapper function). Lớp bao này cũng gọi hàm WorksheetFunction nhưng nó thêm cái code bẫy lỗi cho bạn. Nếu hàm bị lỗi thì nó sẽ không tỏi mà trả về một trị Error. Trong trường hợp này, người ta xét trị trả về để biết nó thành công hay error, và nếu error thì là gì.
Ví dụ điển hình:
myVariant = Application.Match(tim, mangDo, 0)
If Not IsError(myVariant) Then ' đây là hàm match cho nên dùng IsNumeric cũng được
' myVariant là kết quả
Else
' sử lý error ở đây
' nhưng 99,99% trường hợp hàm match thì là do tìm không có cho nên cũng dễ biết
' 0,01% còn lại là do dữ liệu dỏm, ví dụ mảng chẳng phải là mảng
End If

Chú: thực ra giữa cách gọi trực tiếp và gián tiếp còn khác nhau ở một vài tính chất mặc định của tham số truyền vào. Nhưng cấp độ này rất cao, thú nhận rằng tôi cũng chỉ biết 1 vài trường hợp chứ chưa nắm hết.
Dạ Cám ơn Thầy. Em cũng mới biết đến cái này ạ. Hôm trước em có đọc qua bài "Viết các UDF hiệu quả của VBA (Phần 2) - sử dụng các hàm Excel bên trong một UDF" họ nói WorksheetFunction tốc đọ nhanh hơn Thầy ạ
 

VetMini

Chuyên gia GPE
Tham gia ngày
21 Tháng mười hai 2012
Bài viết
9,519
Được thích
11,402
Điểm
1,560
Wrapper function nó có cái giá phải trả của nó. Chương trình phải kết nối wrapper và chạy 1 vài dòng code phụ - điển hình là code bẫy lỗi.

Tuy nhiên, nếu tôi không lầm thì trong mẫu code so sánh của bài trên, người ta không có bẫy lỗi. Vì vậy, sự so sánh chỉ trên lý thuyết.
Trên thực tế, code bẫy lỗi của worksheetfunction sẽ tăng nó lên 1 chút. Và bên application thì dùng variant cho nên cũng bị tăng lên một chút. (variant chậm hơn Long).
 

truongvu317

Thành viên tiêu biểu
Tham gia ngày
15 Tháng mười một 2010
Bài viết
575
Được thích
395
Điểm
435
Tôi đã từng viết bài nói về cái này rồi. Nhưng nếu bạn vẫn mù mờ về lỗi thì có lẽ là chưa đọc bài đó.

WorksheetFunction sẽ lăn cù nếu gặp lỗi. Đó là điều kiện của nó. Nếu muốn tránh ngủm thì cái nơi gọi nó phải bẫy lỗi. Code bẫy lỗi thường là "On Error...". Loại code này thì hầu hết mọi người học qua bậc trung VBA đều biết viết.

Khi gọi hàm thẳng qua Application thì bạn có thể coi như là bạn gọi qua lớp bao gián tiếp (wrapper function). Lớp bao này cũng gọi hàm WorksheetFunction nhưng nó thêm cái code bẫy lỗi cho bạn. Nếu hàm bị lỗi thì nó sẽ không tỏi mà trả về một trị Error. Trong trường hợp này, người ta xét trị trả về để biết nó thành công hay error, và nếu error thì là gì.
Ví dụ điển hình:
myVariant = Application.Match(tim, mangDo, 0)
If Not IsError(myVariant) Then ' đây là hàm match cho nên dùng IsNumeric cũng được
' myVariant là kết quả
Else
' sử lý error ở đây
' nhưng 99,99% trường hợp hàm match thì là do tìm không có cho nên cũng dễ biết
' 0,01% còn lại là do dữ liệu dỏm, ví dụ mảng chẳng phải là mảng
End If

Chú: thực ra giữa cách gọi trực tiếp và gián tiếp còn khác nhau ở một vài tính chất mặc định của tham số truyền vào. Nhưng cấp độ này rất cao, thú nhận rằng tôi cũng chỉ biết 1 vài trường hợp chứ chưa nắm hết.
Thì em mới nói là dùng cái nào cũng phải bẫy lỗi, dùng application thì biến gán phải là variant, nếu không có thể gây ra lỗi.
 
Top Bottom