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ứ nhất: Bạn xài phương thức FIND() như câu lệnh là không chắc chắn & nguy cơ sẽ dẫn bạn đến lỗi 1 khi không tìm ra ô có chứa dữ liệu cần tìn
Muốn phòng ngừa lỗi cần phải viết chân phương hơn.

Thứ hai: Khi tìm một trị kiểu Ngày-tháng-năm, vùng tìm & ngày cần tìm phải ở dạng "MM/DD/YYYY" trước khi FIND()

Bạn thử nghiền ngẫm hàm này 1 hồi xem sao:
PHP:
Function NgayKT(Rng As Range) As Date
Dim Dem As Integer, J As Integer, W As Integer, Dat As Date
Dim sRng As Range

If UCase$(Rng(1).Value) = "X" Then
    If UCase$(Rng(4).Value) = "NT" Then
        Dem = 5
    ElseIf UCase$(Rng(4).Value) = "NGT" Then
        Dem = 7
    End If  
    For J = 0 To 35
        Dat = Rng(5).Value + J
        Set sRng = Range("NgayLe").Find(Format(Rng(5), "MM/DD/yyyy"), , xlValues, xlWhole)
        If Weekday(Dat) > 1 Or sRng Is Nothing Then
            Dem = Dem - 1
            If Dem = 0 Then
                NgayKT = Dat:           Exit Function
            End If
        End If
    Next J
End If
End Function
Thanks bác,
Sau khi kiểm tra lại thì vấn đề nằm ở chỗ các dữ liệu Date là dữ liệu actual Date được Excel ghi nhận dưới dạng 1 con số nhất định tương ứng với từng thời điểm, trong khi dữ liệu Date của sheet Reference lại là dạng string. Sau khi convert dữ liệu Date về string, code đã hoạt động ổn định.
 
Upvote 0
Hi các bác,

Hiện tại em đang gặp phải lỗi Run time error 1004:
Picture 1.JPG
Phía dưới là dòng code lỗi:
Picture 2.JPG
Tại thời điểm xảy ra lỗi này là loop X = 3 và ActiveCell là "R5". Các bác giúp em lỗi này với ạ ?
 
Upvote 0
Nửa đêm mà chơi quả hình đau mắt quá.
SheetA.Range(Cells(1, 1), Cells(2, 2)) lỗi khi SheetA không phải là sheet hiện hành.
 
Upvote 0
Nửa đêm mà chơi quả hình đau mắt quá.
SheetA.Range(Cells(1, 1), Cells(2, 2)) lỗi khi SheetA không phải là sheet hiện hành.
Nếu muỗn trích xuất dữ liệu từ 1 sheet khác để tính toán cho ActiveCell của sheet hiện hành thì phải code thế nào hả bác ?
Như phía trên thì đang trích xuất theo loop cho hàm Sum từ Cells(4 * X - 3,16) cho đến Cells(4 * X,16) của sheet "Reference"
 
Lần chỉnh sửa cuối:
Upvote 0
Nếu muỗn trích xuất dữ liệu từ 1 sheet khác để tính toán cho ActiveCell của sheet hiện hành thì phải code thế nào hả bác ?
Như phía trên thì đang trích xuất theo loop cho hàm Sum từ Cells(4 * X - 3,16) cho đến Cells(4 * X,16) của sheet "Reference"
Nên viết rõ ràng, tường minh. Đặc biệt là khi code rối như tơ vò và khó nhận biết ở từng thời điểm thì sheet nào, cell nào đang active.
Trong vd. kiểu SheetA.Range(Cells(1, 1), Cells(2, 2)) thì dụng ý Cells(1, 1) và Cells(2, 2) thuộc sheet nào? Nếu dụng ý là thuộc sheetA mà sheetA ở thời điểm đó không active thi TEO rồi. Vì viết không tường minh kiểu đó thì Cells(1, 1) và Cells(2, 2) thuộc ActiveSheet. TEO có nghĩa là thậm chí nếu không có lỗi thì kết quả cũng là từ trên trời rớt xuống.

Nếu là lấy dữ liệu từ Reference thì
Mã:
Sheets("Reference").Range(Sheets("Reference").Cells(4 * X - 3, 16), Sheets("Reference").Cells(4 * X, 16))

hoặc

With Sheets("Reference")
    .Range(.Cells(4 * X - 3, 16), .Cells(4 * X, 16))
End With

Nên nhớ là với những vấn đề kiểu này thì không chỉ đính kèm ảnh. Ảnh chỉ để xem cho sướng mắt thôi. Mà ảnh kiểu này thì xem đau mắt chứ sướng gì.
 
Upvote 0
Nên viết rõ ràng, tường minh. Đặc biệt là khi code rối như tơ vò và khó nhận biết ở từng thời điểm thì sheet nào, cell nào đang active.
Trong vd. kiểu SheetA.Range(Cells(1, 1), Cells(2, 2)) thì dụng ý Cells(1, 1) và Cells(2, 2) thuộc sheet nào? Nếu dụng ý là thuộc sheetA mà sheetA ở thời điểm đó không active thi TEO rồi. Vì viết không tường minh kiểu đó thì Cells(1, 1) và Cells(2, 2) thuộc ActiveSheet. TEO có nghĩa là thậm chí nếu không có lỗi thì kết quả cũng là từ trên trời rớt xuống.

Nếu là lấy dữ liệu từ Reference thì
Mã:
Sheets("Reference").Range(Sheets("Reference").Cells(4 * X - 3, 16), Sheets("Reference").Cells(4 * X, 16))

hoặc

With Sheets("Reference")
    .Range(.Cells(4 * X - 3, 16), .Cells(4 * X, 16))
End With

Nên nhớ là với những vấn đề kiểu này thì không chỉ đính kèm ảnh. Ảnh chỉ để xem cho sướng mắt thôi. Mà ảnh kiểu này thì xem đau mắt chứ sướng gì.
Em đã thử viết như trên nhưng nó vẫn báo lỗi :(
range("J10").Value = Application.WorksheetFunction.Sum(Sheets("Reference").range(Sheets("Reference").Cells(4 * X - 3, 16), Sheets("Reference").Cells(4 * X, 16)))
Vẫn là Run time error 1004
 
Lần chỉnh sửa cuối:
Upvote 0
Em đã thử viết như trên nhưng nó vẫn báo lỗi :(
range("J10").Value = Application.WorksheetFunction.Sum(Sheets("Reference").range(Sheets("Reference").Cells(4 * X - 3, 16), Sheets("Reference").Cells(4 * X, 16)))
Vẫn là Run time error 1004
Bạn ạ, tôi chỉ viết về vấn đề mà huuthang_bd đoán thôi. Còn chuyện của bạn thì chịu. Bạn tung code lên không có một lời mô tả code đó làm gì. Và tung ảnh của một đoạn code. Tôi không chơi ảnh bạn ạ.
 
Upvote 0
Bạn ạ, tôi chỉ viết về vấn đề mà huuthang_bd đoán thôi. Còn chuyện của bạn thì chịu. Bạn tung code lên không có một lời mô tả code đó làm gì. Và tung ảnh của một đoạn code. Tôi không chơi ảnh bạn ạ.

Bạn đọc lại giúp mình phía trên nhé. Mình có ghi rõ là code để tính Sum từ Cells(4 * X - 3,16) cho đến Cells(4 * X,16) của sheet "Reference" - For X = 1 to 5; kết quả sẽ được thể hiện tại activeCell của sheet hiện tại. Code mình viết ra có thể ko đúng và mình hiện tại chưa biết cách sửa.

Ảnh mình post lên để coi như tính minh họa chứ ko có ý làm bất kỳ ai khó chịu.

Nếu như có thể nhận đc feedback hợp lý thì mình rất cảm ơn.
 
Upvote 0
Bạn đọc lại giúp mình phía trên nhé. Mình có ghi rõ là code để tính Sum từ Cells(4 * X - 3,16) cho đến Cells(4 * X,16) của sheet "Reference" - For X = 1 to 5; kết quả sẽ được thể hiện tại activeCell của sheet hiện tại. Code mình viết ra có thể ko đúng và mình hiện tại chưa biết cách sửa.

Ảnh mình post lên để coi như tính minh họa chứ ko có ý làm bất kỳ ai khó chịu.
Vấn đề không ở chỗ khó chịu. Nếu có code thì bao giờ cũng dò ra được chỗ sai, ít nhất là trong 99% trường hợp. Nhưng nhìn ảnh thì nhiều khi bó tay. Có những cái không "nhìn" được từ ảnh.
 
Upvote 0
Vấn đề không ở chỗ khó chịu. Nếu có code thì bao giờ cũng dò ra được chỗ sai, ít nhất là trong 99% trường hợp. Nhưng nhìn ảnh thì nhiều khi bó tay. Có những cái không "nhìn" được từ ảnh.
Cảm ơn batman1 huuthang_bd

Mình đã khắc phục được lỗi trên rồi. Hiện tại còn đoạn code này, mong bạn chỉ giáo:
Mã:
For X = 1 to 5
For Y = 1 to 5

ActiveCell.Value = Application.WorksheetFunction.Sum(Sheets("Reference").range(Sheets("Reference").Cells(5 * X + 10, 12).Offset(Y, 0).Resize(-Y + 6, 1)))
ActiveCell.Offset(1,0).Select

Next
Next

Mục đích của code này là như sau:
Nếu X = 1, Y = 1:
Giá trị của ActiveCell = Sum từ ô L16 đến L20
X = 1, Y = 2:
Giá trị của ActiveCell = Sum từ ô L17 đến L20
...
X = 1, Y = 5:
Giá trị của ActiveCell = giá trị của ô L20

Nếu X = 2, Y = 1:
Giá trị của ActiveCell = Sum từ ô L21 đến L25
Nếu X = 2, Y = 2:
Giá trị của ActiveCell = Sum từ ô L22 đến L25
...
Vòng lặp sẽ chạy theo logic trên đến khi X = 5 và Y =5:
Giá trị của activeCell = giá trị của ô L40

Các giá trị của ô L# nằm ở sheet "Reference". ActiveCell nằm ở sheet hiện tại.
Mình đã chaỵ thử và báo lỗi Run time error 1004.
 
Upvote 0
Mình đã khắc phục được lỗi trên rồi. Hiện tại còn đoạn code này, mong bạn chỉ giáo:
Mã:
For X = 1 to 5
For Y = 1 to 5
ActiveCell.Value = Application.WorksheetFunction.Sum(Sheets("Reference").range(Sheets("Reference").Cells(5 * X + 10, 12).Offset(Y, 0).Resize(-Y + 6, 1)))
ActiveCell.Offset(1,0).Select
Next
Next
ActiveCell.Value = Application.WorksheetFunction.Sum(Sheets("Reference").Range(Sheets("Reference").Cells(5 * X + 10, 12).Offset(Y, 0).Resize(-Y + 6, 1)))

là sai. Nếu muốn dùng Range(...) thì phải là

ActiveCell.Value = Application.WorksheetFunction.Sum(Sheets("Reference").Range(Sheets("Reference").Cells(5 * X + 10, 12).Offset(Y, 0).Resize(-Y + 6, 1).Address))

Nhưng như thế dài dòng văn tự. Đơn giản chỉ là

ActiveCell.Value = Application.WorksheetFunction.Sum(Sheets("Reference").Cells(5 * X + 10, 12).Offset(Y, 0).Resize(-Y + 6))

Nhưng lưu ý rằng Cells(5 * X + 10, 12).Offset(Y, 0) = Cells(5 * X + 10 + Y, 12) nên cuối cùng có là

ActiveCell.Value = Application.WorksheetFunction.Sum(Sheets("Reference").Cells(5 * X + 10 + Y, 12).Resize(-Y + 6))
 
Upvote 0
ActiveCell.Value = Application.WorksheetFunction.Sum(Sheets("Reference").Range(Sheets("Reference").Cells(5 * X + 10, 12).Offset(Y, 0).Resize(-Y + 6, 1)))

là sai. Nếu muốn dùng Range(...) thì phải là

ActiveCell.Value = Application.WorksheetFunction.Sum(Sheets("Reference").Range(Sheets("Reference").Cells(5 * X + 10, 12).Offset(Y, 0).Resize(-Y + 6, 1).Address))

Nhưng như thế dài dòng văn tự. Đơn giản chỉ là

ActiveCell.Value = Application.WorksheetFunction.Sum(Sheets("Reference").Cells(5 * X + 10, 12).Offset(Y, 0).Resize(-Y + 6))

Nhưng lưu ý rằng Cells(5 * X + 10, 12).Offset(Y, 0) = Cells(5 * X + 10 + Y, 12) nên cuối cùng có là

ActiveCell.Value = Application.WorksheetFunction.Sum(Sheets("Reference").Cells(5 * X + 10 + Y, 12).Resize(-Y + 6))
Tuyệt vời bạn ạ. Code của mình đã hoàn thiện và chạy ổn định.
Cảm ơn bạn vì những feedback để giúp mình coding tối ưu hơn và thức đêm giải đáp giúp mình hoàn thiện project này.
 
Upvote 0
1603551097635.png

mọi người giúp dùm , tự nhiên nó bị lỗi vậy , fix như thế nào ạ
 
Upvote 0
Người xịn tiếng Tây thì đáng lẽ phải biết phân biệt dạng sín-ghìu-là và pơ-lú-rồn của danh tự chứ.
 
Upvote 0
mọi người giúp dùm , tự nhiên nó bị lỗi vậy , fix như thế nào ạ
Lần sau bạn đừng đá những từ tiếng Anh nhé. Chỉ dùng khi thật cần.
Code không tự xuất hiện nên đừng nói "tự nhiên nó bị lỗi vậy". Ai đã viết wb As Workbooks? Bạn nhìn kỹ xem có thấy gì bất thường không.
 
Upvote 0
Chào anh chị!
Cho em hỏi.. Khi trong vòng lặp lấy dữ liệu từ 1 danh sách ở vùng chọn có giá trị = 0 thì next bỏ qua dùng câu lệnh gì ạ.
 
Upvote 0
Chào anh chị!
Cho em hỏi.. Khi trong vòng lặp lấy dữ liệu từ 1 danh sách ở vùng chọn có giá trị = 0 thì next bỏ qua dùng câu lệnh gì ạ.
PHP:
For i=1 to ...
If gia_tri <> 0 Then
'code cũ
End If
Next i
Hoặc
PHP:
For i = 1 to ...
If gia_tri = 0 Then goto ẻm_mới
'code cũ
ẻm_mới:
Next i
 
Upvote 0
Chào anh chị!
Cho em hỏi.. Khi trong vòng lặp lấy dữ liệu từ 1 danh sách ở vùng chọn có giá trị = 0 thì next bỏ qua dùng câu lệnh gì ạ.
Vòng lặp của VBA không có lệnh tương tự như Continue (chạy xuống Next) như nhiều ngôn ngữ khác.
Có hai cách cho VBA:
1. dùng block IF
2. đặt một cái label ngay chỗ next và dùng lệnh goto
(xem bài #2780)
 
Upvote 0
PHP:
For i=1 to ...
If gia_tri <> 0 Then
'code cũ
End If
Next i
Hoặc
PHP:
For i = 1 to ...
If gia_tri = 0 Then goto ẻm_mới
'code cũ
ẻm_mới:
Next i

Như này à anh
VetMini
befaint

Mã:
Sub In_MaChonLoc()
    Dim sRng As Range, cell_ As Range
    Dim Ws As Worksheet
  
    On Error GoTo Thoat
    ActiveSheet.DisplayPageBreaks = False
    Set sRng = Application.InputBox(Prompt:="Chon Du lieu IN", Title:="Vung Data", Type:=8)
    For Each cell_ In sRng
        Set Ws = ActiveSheet
        With Ws
            .Range("AZ1").Value = cell_.Value
            .PrintOut 'Vung in Set
        End With
    Next cell_
Thoat:
End Sub
 
Upvote 0
Web KT
Back
Top Bottom