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:
Cám ơn anh @snow25@CHAOQUAY nhiều nhiều ạ. Code của anh @snow25 thấy chạy ổn ạ
Code anh @CHAOQUAY không hiểu sao nó báo lỗi như hình ảnh trên ạ.1588584201168.png
Có điều em chưa hiểu lắm đoạn
Mã:
For Each t In ActiveWorkbook.Names
        If .exists(t) Then .remove t
    Next t
Tức là duyệt qua tên của từng sheet. nếu cái nào trùng trong key thì loại bỏ ạ.
Nếu anh có thời gian. có thể bớt chút thời gian chỉ cho em hiểu với ạ
 

File đính kèm

Upvote 0
Cám ơn anh @snow25@CHAOQUAY nhiều nhiều ạ. Code của anh @snow25 thấy chạy ổn ạ
Code anh @CHAOQUAY không hiểu sao nó báo lỗi như hình ảnh trên ạ.View attachment 236828
Có điều em chưa hiểu lắm đoạn
Mã:
For Each t In ActiveWorkbook.Names
        If .exists(t) Then .remove t
    Next t
Tức là duyệt qua tên của từng sheet. nếu cái nào trùng trong key thì loại bỏ ạ.
Nếu anh có thời gian. có thể bớt chút thời gian chỉ cho em hiểu với ạ
Sửa lại bên dưới.
Mã:
Sub A_Tach_sheet()
Dim i%, LR%, Rng As Range, Cll As Range
Dim t As Variant
Set Rng = Application.InputBox("Quet vung chon:", "Thong bao", Type:=8)
With CreateObject("Scripting.Dictionary")
    For Each Cll In Rng
        If Trim(Cll) <> "" Then .Item(Trim(Cll)) = ""
    Next Cll
    For Each t In Worksheets
        If .exists(t.Name) Then .Remove t.Name
    Next t
    If .Count Then
        For Each t In .keys
            Sheet2.Copy after:=Sheets(Sheets.Count)
            ActiveSheet.Name = t
        Next t
    End If
End With
End Sub

---
Mã:
For Each t In ActiveWorkbook.Names
        If .exists(t) Then .remove t
    Next t
"Tức là duyệt qua tên của từng sheet. nếu cái nào trùng trong key thì loại bỏ ạ."

Đúng là phải thực hiện bước này.
Ý định là như vậy nhưng viết không đúng. Phải sửa lại for each t in worksheets như trên.
Workbook.Names là name người dùng, không phải tên sheet nên không đúng.
 
Lần chỉnh sửa cuối:
Upvote 0
Cám ơn anh @snow25@CHAOQUAY nhiều nhiều ạ. Code của anh @snow25 thấy chạy ổn ạ
Code anh @CHAOQUAY không hiểu sao nó báo lỗi như hình ảnh trên ạ.View attachment 236828
Có điều em chưa hiểu lắm đoạn
Mã:
For Each t In ActiveWorkbook.Names
        If .exists(t) Then .remove t
    Next t
Tức là duyệt qua tên của từng sheet. nếu cái nào trùng trong key thì loại bỏ ạ.
Nếu anh có thời gian. có thể bớt chút thời gian chỉ cho em hiểu với ạ
Bon chen 1 tý. Bạn tham khảo thêm nhé
Mã:
Sub Tach_sheet()
    Dim Rng As Range, Cll As Range
On Error GoTo Handle
Set Rng = Application.InputBox("Quet vung chon:", "Thong bao", Type:=8)
For Each Cll In Rng
    If Not WsExit(Cll.Value) Then
        Sheet2.Copy after:=Sheets(Sheets.Count)
        Worksheets(Worksheets.Count).Name = Cll.Value       
    End If
Next Cll
Handle:
End Sub
Function WsExit(wsName As String) As Boolean
    On Error Resume Next
    WsExit = CBool(Len(Worksheets(wsName).Name) > 0)
End Function
 
Lần chỉnh sửa cuối:
Upvote 0
Em chào các thầy cô ạ.
Em có 1 file gồm 3 sheet:
DATA: chứa dữ liệu
DULEU: Là nơi chứa dữ liệu lọc trùng theo số hóa đơn từ sheet DATA
Form: để in dữ liệu từ số hóa đơn

Em có viết 1 đoạn code:
Mã:
Sub ABC()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
    Dim iRow&, sWS As Worksheet, sArr(), KQ(), iC&, a&, b&, rC&, WF As Object
    Dim i&, j&, dC&, Arr(), ans&, WS As Worksheet, dWS As Worksheet
    Set WF = Application.WorksheetFunction
    Set WS = Sheets("Form"): Set sWS = Sheets("DATA"): Set dWS = Sheets("DULIEU")
        iRow = sWS.Range("E" & Rows.Count).End(xlUp).Row
        dC = dWS.Range("D" & Rows.Count).End(xlUp).Row
        Arr = dWS.Range("A3:F" & dC).Value
        sArr = sWS.Range("A15:T" & iRow).Value2
        ReDim KQ(1 To UBound(sArr, 1), 1 To 6)
        WS.Range("A8:F10000").Delete
            For i = 1 To UBound(Arr)
                WS.Range("D1").Value = UCase(Arr(i, 4))
                WS.Range("D2").Value = UCase(Arr(i, 5))
                WS.Range("D3").Value = UCase(Arr(i, 3))
                WS.Range("A6").Value = dWS.Range("I1").Value & _
                Arr(i, 1) & "/" & Day(Arr(i, 2)) & Month(Arr(i, 2)) & _
                Year(Arr(i, 2)) & " KH: YT/18P"
                For iC = 1 To UBound(sArr)
                    If sArr(iC, 5) = Arr(i, 1) Then
                    a = a + 1
                    KQ(a, 1) = a
                    KQ(a, 2) = sArr(iC, 11)
                    KQ(a, 3) = sArr(iC, 12)
                    KQ(a, 4) = sArr(iC, 13)
                    KQ(a, 5) = sArr(iC, 14)
                    KQ(a, 6) = sArr(iC, 15)
                    End If
                Next iC
                With WS
                If a Then .Range("A8:F8").Resize(a).Value = KQ
                .Range("A7:F7").Resize(a + 1).Borders.LineStyle = 1
                rC = .Range("A" & Rows.Count).End(xlUp).Row
                dWS.Range("I2:N9").Copy .Range("A" & rC)
                .PrintPreview
                End With
                a = 0: KQ = Empty
            Next i
    MsgBox ("da xong")
    Application.ScreenUpdating = True
    Application.DisplayAlerts = True
End Sub
như file đính kèm
Nhưng không hiểu sao cứ tới lúc bắt đầu vào vòng lặp
Mã:
For i = 1 To UBound(Arr)
này trở đi thì nó lại bị hiện tượng treo máy.
Nhờ các thầy cô có thể giải thích giúp em được không ạ. Hoặc có cách nào hay hơn nhờ thầy cô giúp với ạ.
Em xin cám ơn
 

File đính kèm

Upvote 0
Em có đoạn code ntn.. và e muốn khi chạy đoạn mã này nó sẽ hiện ra 1 ô thông báo để mình chọn số đơn vị muốn làm tròn cd: 3;0;-3. Vì trong code này nó mặc định bằng 0 nên nhiều lúc phải chỉnh tay khá mất công.. e xin cảm ơn ạ.

Public Sub ChenRound()
Dim Vung, Cll, Tam
Set Vung = Application.InputBox("Nhap vung muon chen ham ROUND", , , , , , , 8)
For Each Cll In Vung
Tam = Replace(Cll.Formula, "=", "")
Cll.Formula = "=ROUND(" & Tam & ",0)"
Next Cll
End Sub
 
Upvote 0
Em chào các thầy cô ạ.
Em có 1 file gồm 3 sheet:
DATA: chứa dữ liệu
DULEU: Là nơi chứa dữ liệu lọc trùng theo số hóa đơn từ sheet DATA
Form: để in dữ liệu từ số hóa đơn

Em có viết 1 đoạn code:
Mã:
Sub ABC()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
    Dim iRow&, sWS As Worksheet, sArr(), KQ(), iC&, a&, b&, rC&, WF As Object
    Dim i&, j&, dC&, Arr(), ans&, WS As Worksheet, dWS As Worksheet
    Set WF = Application.WorksheetFunction
    Set WS = Sheets("Form"): Set sWS = Sheets("DATA"): Set dWS = Sheets("DULIEU")
        iRow = sWS.Range("E" & Rows.Count).End(xlUp).Row
        dC = dWS.Range("D" & Rows.Count).End(xlUp).Row
        Arr = dWS.Range("A3:F" & dC).Value
        sArr = sWS.Range("A15:T" & iRow).Value2
        ReDim KQ(1 To UBound(sArr, 1), 1 To 6)
        WS.Range("A8:F10000").Delete
            For i = 1 To UBound(Arr)
                WS.Range("D1").Value = UCase(Arr(i, 4))
                WS.Range("D2").Value = UCase(Arr(i, 5))
                WS.Range("D3").Value = UCase(Arr(i, 3))
                WS.Range("A6").Value = dWS.Range("I1").Value & _
                Arr(i, 1) & "/" & Day(Arr(i, 2)) & Month(Arr(i, 2)) & _
                Year(Arr(i, 2)) & " KH: YT/18P"
                For iC = 1 To UBound(sArr)
                    If sArr(iC, 5) = Arr(i, 1) Then
                    a = a + 1
                    KQ(a, 1) = a
                    KQ(a, 2) = sArr(iC, 11)
                    KQ(a, 3) = sArr(iC, 12)
                    KQ(a, 4) = sArr(iC, 13)
                    KQ(a, 5) = sArr(iC, 14)
                    KQ(a, 6) = sArr(iC, 15)
                    End If
                Next iC
                With WS
                If a Then .Range("A8:F8").Resize(a).Value = KQ
                .Range("A7:F7").Resize(a + 1).Borders.LineStyle = 1
                rC = .Range("A" & Rows.Count).End(xlUp).Row
                dWS.Range("I2:N9").Copy .Range("A" & rC)
                .PrintPreview
                End With
                a = 0: KQ = Empty
            Next i
    MsgBox ("da xong")
    Application.ScreenUpdating = True
    Application.DisplayAlerts = True
End Sub
như file đính kèm
Nhưng không hiểu sao cứ tới lúc bắt đầu vào vòng lặp
Mã:
For i = 1 To UBound(Arr)
này trở đi thì nó lại bị hiện tượng treo máy.
Nhờ các thầy cô có thể giải thích giúp em được không ạ. Hoặc có cách nào hay hơn nhờ thầy cô giúp với ạ.
Em xin cám ơn

Mình có một số góp ý tiến trình xử lý tiện nhất:

Thứ tự thực hiện:
B1. Do DATA được bạn dùng kiểu bảng tính
--> Bạn không tận dụng được tối đa object table trong viết VBA
--> Giải pháp: sheet data format thành table + bỏ các dòng không cần thiết
B2. PIVOT DATA thành danh sách HD muốn in (cần phải có điều kiện PIVOT) hoặc viết điều kiện input trong VBA (chắc chưa cần) --> đưa vào biến mảng (theo mình nên học thêm collection hoặc Dictionary) sẽ tiện dụng hơn
B3. Đọc biến lưu và truyền vào FORM; nếu in mỗi lần bằng input số hóa đơn thì không cần sheet DU LIEU

Mình có làm mẫu thử trên file đính kèm để theo tham khảo nhé. Alt + F8 --> chạy xem kết quả lấy dữ liệu. Nếu viết tiếp thì từ đó đưa vào sheet FORM là xong
 

File đính kèm

Upvote 0
Xin chào tất cả mọi người,

OT viết một câu lệnh đại loại như sau,nếu như thế này, sau khi xử lý hết công việc 1 sẽ tiến hành công việc 2.

Mã:
Sub macro

    Cong viec 1
    Goto Xuly

    Cong viec 2
    Goto Xuly
Xuly:
    Cau lenh xu ly
End sub

Nhưng khi xong công việc 1 thì code không xử lý công việc 2 do câu lệnh Goto Xuly
Nếu viết như thế này, thì sẽ lặp có 2 dòng Cau lenh xu ly :
Mã:
Sub macro

    Cong viec 1
    Cau lenh xu ly

    Cong viec 2
    Cau lenh xu ly

End sub

OT muốn viết 1 dòng "Cau lenh xu ly" rồi sử dụng Goto Xuly thì sẽ viết như thế nào ạ?
 
Upvote 0
Đi tìm hiểu về từ khoá GoSub.
Tôi chỉ như vậy là do ý bạn muốn vậy. Chứ nếu toi viết code thì thiết kế giải thuật khác. Đối với tôi, Go <cái gì đó> là loại lệnh bất đắc dĩ mới phải dùng.

Đại khái nó sử dụng như vầy:

Sub TestCodeGoSub()
code...
congviec1
GoSub CongViecChung
congviec2
GoSub CongViecChung
code...
Exit Sub ' lệnh này rất quan trọng, dùng để tránh code chạy vào sub con bên dưới

CongViecChung:
' sub con, chứa bên trong sub mẹ
những câu lệnh xử lý gì đó...
Return ' lệnh này bảo VBA trở về chạy tiếp dòng sau lệnh gosub

End Sub ' TestCodeGoSub

Lưu ý: sub con là code nội của sub mẹ. Nó sử dụng mọi biến nội của sub mẹ.
 
Upvote 0
Hình như phải xài 2 macro Cha & Con, như sau:
PHP:
Sub MacroCha
'Các Công Viêc Cua CôngViec01  '
XuLy
'Các Công Viêc Cua CôngViec02    '
XuLy '?'
End Sub
Mã:
Sub XuLy()
'Các Câu Lênh Trung Gian
End Sub
 
Upvote 0
Đi tìm hiểu về từ khoá GoSub.
Tôi chỉ như vậy là do ý bạn muốn vậy. Chứ nếu toi viết code thì thiết kế giải thuật khác. Đối với tôi, Go <cái gì đó> là loại lệnh bất đắc dĩ mới phải dùng.

Đại khái nó sử dụng như vầy:

Sub TestCodeGoSub()
code...
congviec1
GoSub CongViecChung
congviec2
GoSub CongViecChung
code...
Exit Sub ' lệnh này rất quan trọng, dùng để tránh code chạy vào sub con bên dưới

CongViecChung:
' sub con, chứa bên trong sub mẹ
những câu lệnh xử lý gì đó...
Return ' lệnh này bảo VBA trở về chạy tiếp dòng sau lệnh gosub

End Sub ' TestCodeGoSub

Lưu ý: sub con là code nội của sub mẹ. Nó sử dụng mọi biến nội của sub mẹ.

Xin chào Bác VetMini,
Con cảm ơn Bác đã chỉ dẫn ạ, con không có kinh nghiệm viết code nên không biết dùng cách nào cho tối con mới chỉ nghĩ đến cách đó.
Nếu Bác có cách nào khác xin chỉ dẫn cho con thêm ạ.
Cảm ơn Bác VetMini.

Hình như phải xài 2 macro Cha & Con, như sau:
PHP:
Sub MacroCha
'Các Công Viêc Cua CôngViec01  '
XuLy
'Các Công Viêc Cua CôngViec02    '
XuLy '?'
End Sub
Mã:
Sub XuLy()
'Các Câu Lênh Trung Gian
End Sub

Con cảm ơn Bác SA_DQ đã chỉ dẫn
Bài đã được tự động gộp:

Đi tìm hiểu về từ khoá GoSub.
Tôi chỉ như vậy là do ý bạn muốn vậy. Chứ nếu toi viết code thì thiết kế giải thuật khác. Đối với tôi, Go <cái gì đó> là loại lệnh bất đắc dĩ mới phải dùng.

Đại khái nó sử dụng như vầy:

Sub TestCodeGoSub()
code...
congviec1
GoSub CongViecChung
congviec2
GoSub CongViecChung
code...
Exit Sub ' lệnh này rất quan trọng, dùng để tránh code chạy vào sub con bên dưới

CongViecChung:
' sub con, chứa bên trong sub mẹ
những câu lệnh xử lý gì đó...
Return ' lệnh này bảo VBA trở về chạy tiếp dòng sau lệnh gosub

End Sub ' TestCodeGoSub

Lưu ý: sub con là code nội của sub mẹ. Nó sử dụng mọi biến nội của sub mẹ.
Xin chào Bác VetMini
Bác ơi, Bác có thể chỉ con cách dùng câu lệnh với: Resume <label> trong trường hợp này được không ạ?
 
Lần chỉnh sửa cuối:
Upvote 0
Hình như phải xài 2 macro Cha & Con, như sau:
...
2 macro Cha và Con là 2 khối riêng biệt và độc lập với nhau. Chúng không chia sẻ biến nội hay cái gì cả, ngoại trừ biến toàn cục.

Nếu macro Con không cần gì đến biến nào của Cha thì nên dùng 2 macro's. Nếu cần một vài biến thì cũng có thể dùng tham để truyền. Cách này khiến Con độc lập với Cha, và rất dễ kiểm soát.

Nhưng nếu đúng theo yêu cầu ở bài #2474, phần sub con cần chạy một số lệnh nào đó, và không xác định cách truyền biến thì GoSub đúng là cái mà người hỏi muốn. Trong bài #2475, code của sub con là code của sub mẹ.

Xin chào Bác VetMini
Bác ơi, Bác có thể chỉ con cách dùng câu lệnh với: Resume <label> trong trường hợp này được không ạ?
Resume không áp dụng cho trường hợp này. Resume là lệnh của bắt lỗi, dùng để tháo bẫy lỗi.
Return là câu lệnh bảo trở về dòng lệnh kế tiếp dòng GoSub, chả liên quan gì đến lỗi cả.

Từ Resume có nghĩa là "tiếp tục lại...". Sau khi xử lý lỗi xong thì lại tiếp tục ở vị trí nào đó.
Từ Return có nghĩa là "trở về...". Sau khi chạy xong đống lệnh trong sub con thì trở về nơi đã gọi sub.
 
Lần chỉnh sửa cuối:
Upvote 0
Sub locdulieu()

Sheets(1).Range("A1" & lastcolumn & lastRow).AutoFilter Field:=3, Criteria1:="tangthuong"
lastRow = Range("A85536").End(xlUp).Row
If Sheets("tangthuong").Cells(1, 1) = "" Then
Range("A1:I" & lastRow).Select
Selection.Copy
Sheets("tangthuong").Select
Range("A1").Select
ActiveSheet.Paste
Columns("A:H").Select
Columns("A:H").EntireColumn.AutoFit
Else

Range("A2:I" & lastRow).Select
Selection.Copy
Sheets("tangthuong").Select
lastRow = Range("A85536").End(xlUp).Row
Range("A" & lastRow + 1).Select
ActiveSheet.Paste
Columns("A:H").Select
Columns("A:H").EntireColumn.AutoFit
End If
lastRow = Range("A85536").End(xlUp).Row
Range("A" & lastRow + 1).Select
Sheets(1).Select

mọi người cho hỏi là trong đoạn code này dùng AutoFilter để lọc dữ liệu nhưng khi lọc không có kêt quả nó lại copy ngay dòng tiêu đề để paste ,vậy mn cho hỏi là code sửa ntn để khi autofilter mà không ra kết quả như thế này 1589789855949.png thì sẽ không copy nữa mà thực hiện lệnh tiếp theo của đoạn code sau ah?
 
Lần chỉnh sửa cuối:
Upvote 0
Đi tìm hiểu về từ khoá GoSub.
Tôi chỉ như vậy là do ý bạn muốn vậy. Chứ nếu toi viết code thì thiết kế giải thuật khác. Đối với tôi, Go <cái gì đó> là loại lệnh bất đắc dĩ mới phải dùng.

Đại khái nó sử dụng như vầy:

Sub TestCodeGoSub()
code...
congviec1
GoSub CongViecChung
congviec2
GoSub CongViecChung
code...
Exit Sub ' lệnh này rất quan trọng, dùng để tránh code chạy vào sub con bên dưới

CongViecChung:
' sub con, chứa bên trong sub mẹ
những câu lệnh xử lý gì đó...
Return ' lệnh này bảo VBA trở về chạy tiếp dòng sau lệnh gosub

End Sub ' TestCodeGoSub

Lưu ý: sub con là code nội của sub mẹ. Nó sử dụng mọi biến nội của sub mẹ.
Tôi chưa từng biết Sub Mẹ, Sub Con viết như Bác @VetMini gợi ý.
Làm liều thử 1 bài xem, nếu có người sửa sai thì sẽ là 1 cách học "Chiêu" mới.
PHP:
Public Sub Cha()
Dim I As Long, J As Long, X As Long
    For I = 1 To 10
        X = X + 1           'Cong Viec 1- Lam gi do'
        For J = 1 To 10    
            Cells(X, J) = "GPE" & Format(I, "000")
        Next J
        X = X + 1
        GoSub Con           'Goi Sub Con'
            X = X + 1       'Cong Viec 2 - Lam gi do'
            For J = 1 To 10
                Cells(X, J) = "Hic!" & Format(I, "000")
            Next J
        X = X + 1
        GoSub Con           'Goi Sub Con'
    Next I
    Exit Sub    'Thoat Sub Cha'
Con:            'Sub Con Lam gi do'
        For J = 1 To 10
            Cells(X, J) = "Con" & " - " & Format(J, "000")
        Next J
Return  'Quay lai dong lenh sau GoSub'
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi chưa từng biết Sub Mẹ Sub, Con viết như Bác @VetMini gợi ý.
Làm liều thử 1 bài xem, nếu có người sửa sai thì sẽ là 1 cách học "Chiêu" mới.
PHP:
Public Sub Cha()
Dim I As Long, J As Long, X As Long
    For I = 1 To 10
        X = X + 1           'Cong Viec 1- Lam gi do'
        For J = 1 To 10    
            Cells(X, J) = "GPE" & Format(I, "000")
        Next J
        X = X + 1
        GoSub Con           'Goi Sub Con'
            X = X + 1       'Cong Viec 2 - Lam gi do'
            For J = 1 To 10
                Cells(X, J) = "Hic!" & Format(I, "000")
            Next J
        X = X + 1
        GoSub Con           'Goi Sub Con'
    Next I
    Exit Sub    'Thoat Sub Cha'
Con:            'Sub Con Lam gi do'
        For J = 1 To 10
            Cells(X, J) = "Con" & " - " & Format(J, "000")
        Next J
Return  'Quay lai dong lenh sau GoSub'
End Sub

Con cảm ơn Thầy đã chỉ dẫn,con sẽ nghiên cứu tìm hiểu để áp dụng ạ.
 
Upvote 0
Upvote 0
Sub locdulieu()
Sheets(1).Range("A1" & lastcolumn & lastRow).AutoFilter Field:=3, Criteria1:="活动优惠"
lastRow = Range("A85536").End(xlUp).Row
If Sheets("活动优惠").Cells(1, 1) = "" Then
Range("A1:I" & lastRow).Select
Selection.Copy
Sheets("活动优惠").Select
Range("A1").Select
ActiveSheet.Paste
Columns("A:H").Select
Columns("A:H").EntireColumn.AutoFit
Else
Range("A2:I" & lastRow).Select
Selection.Copy
Sheets("活动优惠").Select
lastRow = Range("A85536").End(xlUp).Row
Range("A" & lastRow + 1).Select
ActiveSheet.Paste
Columns("A:H").Select
Columns("A:H").EntireColumn.AutoFit
End If
astRow = Range("A85536").End(xlUp).Row
Range("A" & lastRow + 1).Select
Sheets(1).Select
Trong code có đoạn nào nói về đường lưỡi bò không vậy bạn?
 
Upvote 0
mong mn giúp đỡ
Bài đã được tự động gộp:

Sub locdulieu()

Sheets(1).Range("A1" & lastcolumn & lastRow).AutoFilter Field:=3, Criteria1:="tangthuong"
lastRow = Range("A85536").End(xlUp).Row
If Sheets("tangthuong").Cells(1, 1) = "" Then
Range("A1:I" & lastRow).Select
Selection.Copy
Sheets("tangthuong").Select
Range("A1").Select
ActiveSheet.Paste
Columns("A:H").Select
Columns("A:H").EntireColumn.AutoFit
Else

Range("A2:I" & lastRow).Select
Selection.Copy
Sheets("tangthuong").Select
lastRow = Range("A85536").End(xlUp).Row
Range("A" & lastRow + 1).Select
ActiveSheet.Paste
Columns("A:H").Select
Columns("A:H").EntireColumn.AutoFit
End If
lastRow = Range("A85536").End(xlUp).Row
Range("A" & lastRow + 1).Select
Sheets(1).Select

mọi người cho hỏi là trong đoạn code này dùng AutoFilter để lọc dữ liệu nhưng khi lọc không có kêt quả nó lại copy ngay dòng tiêu đề để paste ,vậy mn cho hỏi là code sửa ntn để khi autofilter mà không ra kết quả như thế này View attachment 237539 thì sẽ không copy nữa mà thực hiện lệnh tiếp theo của đoạn code sau ah?
mong mn giúp đỡ
 
Upvote 0
Tôi chưa từng biết Sub Mẹ Sub, Con viết như Bác @VetMini gợi ý.
Làm liều thử 1 bài xem, nếu có người sửa sai thì sẽ là 1 cách học "Chiêu" mới.
PHP:
Public Sub Cha()
Dim I As Long, J As Long, X As Long
    For I = 1 To 10
        X = X + 1           'Cong Viec 1- Lam gi do'
        For J = 1 To 10  
            Cells(X, J) = "GPE" & Format(I, "000")
        Next J
        X = X + 1
        GoSub Con           'Goi Sub Con'
            X = X + 1       'Cong Viec 2 - Lam gi do'
            For J = 1 To 10
                Cells(X, J) = "Hic!" & Format(I, "000")
            Next J
        X = X + 1
        GoSub Con           'Goi Sub Con'
    Next I
    Exit Sub    'Thoat Sub Cha'
Con:            'Sub Con Lam gi do'
        For J = 1 To 10
            Cells(X, J) = "Con" & " - " & Format(J, "000")
        Next J
Return  'Quay lai dong lenh sau GoSub'
End Sub

Mục đích chính của GoSub là để tránh lặp lại code.
Nếu công việc 1 và công việc 2 gần giống nhau thì bạn cũng có thể tạo một sub con nữa.
Lưu ý rằng hai công việc có các lệnh giống nhau nhưng thong số khác nhau cho nên ta phải dùng một biến để thực hiện thông số này (biến danDau trong code).

PHP:
Public Sub Cha()
Dim I As Long, J As Long, X As Long
DIM daDau As String
    For I = 1 To 10
      ' công việc 1, làm gì đó '
      danDau = "GPE"
      GoSub Con_Ruot
      danDau = "Con - "
      GoSub Con_Ghe
      ' công việc 2, làm gì đó '
      danDau = "Hic!"
      GoSub Con_Ruot
      danDau = "Con - "
      GoSub Con_Ghe
    Next I
    Exit Sub    'Thoat Sub Cha'

Con_Ruot:
        ' công việc 3, làm gì đó '
        ' sau khi hoàn tất công việc 3, gọi sub Con_Ghe để thực hiện việc tăng X và ghi trị vào 10 cells '
        GoSub Con_Ghe
Return

Con_Ghe:            'Sub Con Lam gi do'
        X = X + 1
        For J = 1 To 10
            Cells(X, J) = danDau & Format(J, "000")
        Next J
Return
End Sub

Code trên tôi cố tình cho thấy Con_Ruot có thể gọi Con_Ghe vô tư.
(ngược lại, Con_Ghe có thể gọi Con_Ruot nếu muốn)
 
Upvote 0
Mục đích chính của GoSub là để tránh lặp lại code.
Nếu công việc 1 và công việc 2 gần giống nhau thì bạn cũng có thể tạo một sub con nữa.
Lưu ý rằng hai công việc có các lệnh giống nhau nhưng thong số khác nhau cho nên ta phải dùng một biến để thực hiện thông số này (biến danDau trong code).

PHP:
Public Sub Cha()
Dim I As Long, J As Long, X As Long
DIM daDau As String
    For I = 1 To 10
      ' công việc 1, làm gì đó
      danDau = "GPE"
      GoSub Con_Ruot
      danDau = "Con - "
      GoSub Con_Ghe
      ' công việc 2, làm gì đó
      danDau = "Hic!"
      GoSub Con_Ruot
      danDau = "Con - "
      GoSub Con_Ghe
    Next I
    Exit Sub    'Thoat Sub Cha'

Con_Ruot:
        ' công việc 3, làm gì đó
        ' sau khi hoàn tất công việc 3, gọi sub Con_Ghe để thực hiện việc tăng X và ghi trị vào 10 cells
        GoSub Con_Ghe           'Goi Sub Con'
Return

Con_Ghe:            'Sub Con Lam gi do'
        X = X + 1
        For J = 1 To 10
            Cells(X, J) = danDau & Format(J, "000")
        Next J
Return
End Sub

Code trên tôi cố tình cho thấy Con_Ruot có thể gọi Con_Ghe vô tư.
(ngược lại, Con_Ghe có thể gọi Con_Ruot nếu muốn)
Bác cứ phức tạp vấn đề, cứ chia ra sub con riêng cho nhanh, và như thế thỏa mãi số con mà không rối... còn truyền biến thì độc lập hay phụ thuộc cũng tùy thích

GoSub đúng như bác nói người ta hạn chế dùng, nếu dùng dùng cho trường hợp đặc biệt hay vui mà thôi
 
Upvote 0
Web KT

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

Back
Top Bottom