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:
Em có việc khó không biết làm sao nhờ cả nhà giúp.
Em có 1 Form nhập dữ liệu vào 1 sheet A. giờ em gặp khó là làm sao khi nhập vào form mà trùng tên (VD: text tên trùng với cột B trong Sheet A là tên) thì khi click vào lưu thì báo đã có tên trùng với tên đó và không cho lưu dữ liệu trùng đó nữa. Tks cả nhà.
Dùng cách dò tìm, trong VBA thì Range.Find.... tức là dùng method Find của Range
 
Upvote 0
Chào mọi người, mọi người giúp e code VBA với điều kiện
nếu trong vùng dữ liệu có 1 ô nào có gtri bằng 0 thì xóa luôn dòng đó với ạ.
e cám ơn nhiều.
 

File đính kèm

Upvote 0
Chào mọi người, mọi người giúp e code VBA với điều kiện
nếu trong vùng dữ liệu có 1 ô nào có gtri bằng 0 thì xóa luôn dòng đó với ạ.
e cám ơn nhiều.
Bạn xem thử
PHP:
Sub Xoadong()
    Dim sArr, I As Long, J As Long, Er As Long
    Dim rng As Range, Dk As Boolean: Dk = False
Er = Range("A" & Rows.Count).End(xlUp).Row
If Er > 1 Then
    sArr = Range("A1:A" & Er).Resize(, 6).Value
    For I = 2 To UBound(sArr)
        For J = 1 To UBound(sArr, 2)
            If sArr(I, J) = Empty Then
                Dk = True
                If rng Is Nothing Then
                    Set rng = Range("A" & I).EntireRow
                Else
                    Set rng = Union(rng, Range("A" & I).EntireRow)
                End If
                Exit For
            End If
        Next J
    Next
    If Dk = True Then
        rng.Select
        'rng.Delete
    Else
        MsgBox "Nothing"
    End If
End If
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn xem thử
Mã:
Sub Xoadong()
    Dim sArr, I As Long, J As Long, Er As Long
    Dim rng As Range
Er = Range("A" & Rows.Count).End(xlUp).Row
If Er > 1 Then
    sArr = Range("A1:A" & Er).Resize(, 6).Value
    For I = 2 To UBound(sArr)
        For J = 1 To UBound(sArr, 2)
            If sArr(I, J) = Empty Then
                If rng Is Nothing Then
                    Set rng = Range("A" & I).EntireRow
                Else
                    Set rng = Union(rng, Range("A" & I).EntireRow)
                End If
                Exit For
            End If
        Next J
    Next
    rng.Select
    'rng.Delete
End If
End Sub
cám ơn nhiều ạ
cho hỏi thêm là nếu vùng dữ liệu mở rộng ra thì code này có thực hiện được không ạ.
với mấy cái code union này kia mình tìm hiểu tài liệu ở đâu được.
 
Upvote 0
cám ơn nhiều ạ
cho hỏi thêm là nếu vùng dữ liệu mở rộng ra thì code này có thực hiện được không ạ.
với mấy cái code union này kia mình tìm hiểu tài liệu ở đâu được.
Tôi vẫn khoái chơi với mảng.
Trong file bạn thì dữ liệu có 6 cột, nếu dữ liệu <>6 cột thì khai báo lại biến CoL
Đặt tên sheet là "GPE".
PHP:
Public Sub sGpe()
Const CoL As Long = 6                 'Số cột là 6 trong bảng dữ liệu.'
Dim sArr(), dArr(), I As Long, J As Long, K As Long, R As Long
With Sheets("GPE")
    sArr = .Range("A2", .Range("A2").End(xlDown)).Resize(, CoL).Value
    R = UBound(sArr)
    ReDim dArr(1 To R, 1 To CoL)
    For I = 1 To R
        K = K + 1
        For J = 1 To CoL
            dArr(K, J) = sArr(I, J)
            If sArr(I, J) = 0 Then
                K = K - 1
                Exit For
            End If
        Next J
    Next I
    Range("A2").Resize(R, CoL).ClearContents
    If K Then .Range("A2").Resize(K, CoL) = dArr
End With
End Sub
 
Upvote 0
Upvote 0
Tôi vẫn khoái chơi với mảng.
Trong file bạn thì dữ liệu có 6 cột, nếu dữ liệu <>6 cột thì khai báo lại biến CoL
Đặt tên sheet là "GPE".
PHP:
Public Sub sGpe()
Const CoL As Long = 6                 'Số cột là 6 trong bảng dữ liệu.'
Dim sArr(), dArr(), I As Long, J As Long, K As Long, R As Long
With Sheets("GPE")
    sArr = .Range("A2", .Range("A2").End(xlDown)).Resize(, CoL).Value
    R = UBound(sArr)
    ReDim dArr(1 To R, 1 To CoL)
    For I = 1 To R
        K = K + 1
        For J = 1 To CoL
            dArr(K, J) = sArr(I, J)
            If sArr(I, J) = 0 Then
                K = K - 1
                Exit For
            End If
        Next J
    Next I
    Range("A2").Resize(R, CoL).ClearContents
    If K Then .Range("A2").Resize(K, CoL) = dArr
End With
End Sub
Kiến thức về mảng thấy phức tạp qá
 
Upvote 0
Theo mình nghĩ mảng nó chỉ là.Không thao tác trên excel mà ghi dữ liệu vào mảng.
Bthg thì mình xài vòng lặp for cho từng cột.
Nếu bắp gặp ô nào bằng 0 thì xóa luôn dòng đó.
Chỉ có thắc mắc ở chỗ là nếu sử dụng mảng thì liệu Excel nó có chạy nhanh hơn k
 
Upvote 0
Chỉ có thắc mắc ở chỗ là nếu sử dụng mảng thì liệu Excel nó có chạy nhanh hơn k
Bạn thử tăng dữ liệu lên vạn dòng & 24 cột & sau đó thử với macro xài mảng dưới đây xem sao:
PHP:
Sub Array_()
Dim Arr()
Dim J As Long, W As Long, Tmr As Double, Cot As Integer, Zero As Boolean

Tmr = Timer():                         Arr() = Sheet2.[B1].CurrentRegion.Offset(1).Value
ReDim dArr(1 To UBound(Arr()), 1 To UBound(Arr(), 2))
For J = 1 To UBound(Arr())
    W = W + 1
    For Cot = 1 To UBound(Arr(), 2)
        If Arr(J, Cot) = 0 Then
            Zero = True:                        W = W - 1
            Exit For
        Else
            dArr(W, Cot) = Arr(J, Cot)
        End If
    Next Cot
Next J
MsgBox J & " => " & W, , Timer() - Tmr
End Sub

Máy cà tèng của mình báo là mất .125" & từ 10242 dòng xuống còn 8640
 
Lần chỉnh sửa cuối:
Upvote 0
Còn đây là macro để cho thấy sự tăng giảm thời lượng xài 1 hay 2 mảng (Array) với dữ liệu đủ lớn như bài trên:
PHP:
Sub DuyetCotA_CountIf(Num As Integer)
 Dim Rws As Long, J As Long, W As Long, Tmr As Double, Col As Integer, Cot As Integer
 Dim WF As Object

  Tmr = Timer():                            Rws = Sheet1.[B1].CurrentRegion.Rows.Count
  Col = Sheet1.[B1].CurrentRegion.Columns.Count
  Set WF = Application.WorksheetFunction
  ReDim Arr(1 To Rws, 1 To Col)
  For J = 2 To Rws
    If WF.CountIf(Cells(J, "A").Resize(, Col), 0) = 0 Then
        W = W + 1
        If Num = 2 Then
            ReDim dArr(1 To 1, 1 To Col)
            dArr() = Cells(J, 1).Resize(, Col).Value
        End If
        For Cot = 1 To Col
            If Num = 2 Then
                Arr(W, Cot) = dArr(1, Cot)
            ElseIf Num = 1 Then
                Arr(W, Cot) = Cells(J, 1).Offset(, Col - 1).Value
            End If
        Next Cot
    End If
  Next J
  MsgBox J & " => " & W, , Timer() - Tmr
End Sub
 
Upvote 0
Bạn thử tăng dữ liệu lên vạn dòng & 24 cột & sau đó thử với macro xài mảng dưới đây xem sao:
PHP:
Sub Array_()
Dim Arr()
Dim J As Long, W As Long, Tmr As Double, Cot As Integer, Zero As Boolean

Tmr = Timer():                         Arr() = Sheet2.[B1].CurrentRegion.Offset(1).Value
ReDim dArr(1 To UBound(Arr()), 1 To UBound(Arr(), 2))
For J = 1 To UBound(Arr())
    W = W + 1
    For Cot = 1 To UBound(Arr(), 2)
        If Arr(J, Cot) = 0 Then
            Zero = True:                        W = W - 1
            Exit For
        Else
            dArr(W, Cot) = Arr(J, Cot)
        End If
    Next Cot
Next J
MsgBox J & " => " & W, , Timer() - Tmr
End Sub

Máy cà tèng của mình báo là mất .125" & từ 10242 dòng xuống còn 8640
Dữ liệu của mình trung bình 1 file csv 30Mb
Khoảng 4000 cột, gần 1tr dòng.
Chạy cái máy đơ lun :(
 
Upvote 0
Cho e hỏi trong nhiều sub, phía đầu tiêu đề người ta viết như sau
Mã:
Sub DuyetCotA_CountIf(Num As Integer)
những sub này không chạy trực tiếp được.
vậy những sub này là sao ạ. AC giải thích giùm với.
 
Upvote 0
Dữ liệu của mình trung bình 1 file csv 30Mb
Khoảng 4000 cột, gần 1tr dòng.
Máy mình với bộ nhớ hạn hẹp chỉ chạy macro #1664 với 25500 dòng & 255 cột mất >4.656" (file xls 112Mb)
Những sub này không chạy trực tiếp được.
vậy những sub này là sao ạ. AC giải thích giùm với.
Muốn chạy nó cần cung cấp cho nó tham biến {1 hay 2} Nhưng với dữ liệu đồ sộ của bạn thì quên nó đi!
 
Lần chỉnh sửa cuối:
Upvote 0
Máy mình với bộ nhớ hạn hẹp chỉ chạy macro #1664 với 25500 dòng & 255 cột mất >4.656" (file xls 112Mb)

Muốn chạy nó cần cung cấp cho nó tham biến {1 hay 2} Nhưng với dữ liệu đồ sộ của bạn thì quên nó đi!
hic :(
Nhờ A giải thích giùm e khi nào thì mình sử dụng những sub như vậy ạ
Với những sub như vậy thì mục đích nó có khác gì với những sub bình thường ko A
 
Upvote 0
Em có Code VBA như ở trong file đính kèm em hay dùng để copy phần sau khi đã Filter (Như ví dụ dưới là em Filter ở Cột Mã hàng). Trước giờ em vẫn dùng Code này mà không hiểu nó thực hiện như thế nào vì em thấy giá trị trả về đã Paste Value như em mong muốn rồi nhưng hôm nay em không thực hiện Filter trước mà chạy Code luôn thì giá trị trả về có cả công thức ở phần trên xuống. Code hiện tại em đang dùng kiểu như này ạ

Mã:
Sub thu()
[A10:B20].Clear
[A1:B8].Copy [A10]
End Sub

1543368510680.png
Vậy Anh chị cho em hỏi phần [A1:B8].Copy [A10] Bản chất nó là như thế nào ạ (Copy Paste, Copy Paste Special Value hay một cách thức nào khác ạ).Em tự hiểu thì là không Filter là Copy Paste thông thường còn nếu Filter thì nó lại thành Copy Paste Special Value. Em muốn hiểu rõ hơn để áp dụng cho đúng và giải thích cho bạn bè khi cần ạ. Em cảm ơn ạ
 

File đính kèm

Upvote 0
Em có Code VBA như ở trong file đính kèm em hay dùng để copy phần sau khi đã Filter (Như ví dụ dưới là em Filter ở Cột Mã hàng). Trước giờ em vẫn dùng Code này mà không hiểu nó thực hiện như thế nào vì em thấy giá trị trả về đã Paste Value như em mong muốn rồi nhưng hôm nay em không thực hiện Filter trước mà chạy Code luôn thì giá trị trả về có cả công thức ở phần trên xuống. Code hiện tại em đang dùng kiểu như này ạ

Mã:
Sub thu()
[A10:B20].Clear
[A1:B8].Copy [A10]
End Sub

View attachment 208417
Vậy Anh chị cho em hỏi phần [A1:B8].Copy [A10] Bản chất nó là như thế nào ạ (Copy Paste, Copy Paste Special Value hay một cách thức nào khác ạ).Em tự hiểu thì là không Filter là Copy Paste thông thường còn nếu Filter thì nó lại thành Copy Paste Special Value. Em muốn hiểu rõ hơn để áp dụng cho đúng và giải thích cho bạn bè khi cần ạ. Em cảm ơn ạ
Người đẹp thử Code này xem sao
PHP:
Sub thu()
[A10:B20].Clear
[A1:B8].SpecialCells(12).Copy
[A10].PasteSpecial xlPasteValues
Application.CutCopyMode = False
End Sub
Tham khảo thêm: https://docs.microsoft.com/en-us/office/vba/api/excel.range.specialcells
http://access-excel.tips/excel-vba-range-pastespecial/
 
Lần chỉnh sửa cuối:
Upvote 0
Người đẹp thử Code này xem sao
PHP:
Sub thu()
[A10:B20].Clear
[A1:B8].SpecialCells(12).Copy
[A10].PasteSpecial xlPasteValues
Application.CutCopyMode = False
End Sub
Tham khảo thêm: https://docs.microsoft.com/en-us/office/vba/api/excel.range.specialcells
Cái này nó lại bỏ hết Border của tớ đi rồi. Cậu thử xem file của tớ mà xem. Trước giờ tớ cứ dùng chứ nay mới thắc mắc nên lên diễn đàn hỏi cho hiểu sâu hơn tí ý mà
 
Upvote 0
Cái này nó lại bỏ hết Border của tớ đi rồi. Cậu thử xem file của tớ mà xem. Trước giờ tớ cứ dùng chứ nay mới thắc mắc nên lên diễn đàn hỏi cho hiểu sâu hơn tí ý mà
Vậy thêm 2 dòng nữa cho nó hoành tráng :p:p:p
PHP:
Sub thu()
Range("A10:B20").Clear
Range("A1:B8").SpecialCells(12).Copy
With Range("A10")
    .PasteSpecial xlPasteFormats
    .PasteSpecial xlPasteColumnWidths
   .PasteSpecial xlPasteValuesAndNumberFormats
End With
Application.CutCopyMode = False
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Vậy thêm 2 dòng nữa cho nó hoành tráng :p:p:p
PHP:
Sub thu()
Range("A10:B20").Clear
Range("A1:B8").SpecialCells(12).Copy
With Range("A10")
    .PasteSpecial xlPasteFormats
    .PasteSpecial xlPasteColumnWidths
    .PasteSpecial xlPasteValues
End With
Application.CutCopyMode = False
End Sub
Mã:
Sub thu()
[A10:B20].Clear
[A1:B8].Copy [A10]
End Sub
Code chỉ cần thế này là xử lý được rồi nhưng ý tớ là nếu tớ không Filter thì nó trả về kết quả có cả hàm mà Chỉ cần Filter ở Cột Mã hàng thì giá trị trả về tự động là Value luôn nên tớ thấy hay nên muốn hỏi bản chất của Code kia nó thay cho hàm hay thao tác nào trong Excel ý mà
 
Upvote 0
Web KT

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

Back
Top Bottom