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:
Dạ "s.FDate" s được gán cho một Bảng trong môi trường SQL còn FDATE là trường của bảng đó ạ.
chuyển Name kia thành hẳn VBA thì viết sao vậy HeSanbi, nhờ bạn giúp đỡ ạ.
Phương thức Execute Sẽ tìm kiếm Hàm và phương thức đã được khởi tạo trước đó.

Đoạn này là một chuỗi phải không?

(s.FDATE >= N'201912211') and (s.FDATE <= N'201912241') and (s.BUMO Like N'%BUR-%')

s.FDATE và s.BUMO thuộc môi trường SQL đã được tạo để VBA hiểu chưa.

Vậy Execute sẽ tìm s.FDate ở đâu?

----------------------------------------------------------

Khởi tạo toàn bộ kết nối SQL sau đó:

Dim SQL As String
SQL = "(s.FDATE >= N'201912211') and (s.FDATE <= N'201912241') and (s.BUMO Like N'%BUR-%')"


Chuyển đoạn:
"(s.FDATE >= N'"&TEXT(PRODUCTION!$B$2,"yyymmdd")&"1') and (s.FDATE <= N'"&TEXT(PRODUCTION!$B$3,"yyymmdd")&"1')"& IF(PRODUCTION!$F$3<>""," and (s.BUMO Like N'%"&PRODUCTION!$F$3&"%')","")&IF(PRODUCTION!$D$3<>""," and (s.LOTNAME Like N'%" &PRODUCTION!$D$3& "%')","")& IF(PRODUCTION!$D$2<>""," and (s.CODE Like N'%"&PRODUCTION!$D$2& "%')","")&IF(PRODUCTION!$F$2<>""," and (s.PORDER Like N'%"&PRODUCTION!$F$2&"%')","")

Thành:
1. Sửa Range:
PRODUCTION!$B$2​
-> Dim B2 As String: B2 = Application.Text(Worksheets("PRODUCTION").[B2].Value, "yyymmdd")​
2. Sửa Hàm:
TEXT -> Application.Text Hoặc VBA.Format​
IF -> VBA.IFF​

Kết quả:
SQL = "(s.FDATE >= N'" & B2 & ...
 
Upvote 0
Khi thiết lập một câu SQL có nhiều thông số/tham số thì người có kinh nghiệm sẽ không dùng thể loại:
Lệnh & 'tham số 1' & lệnh & tham số 2 & ....
Một đống &, đóng quote mở quote tùm lum. Xác suất viết sai khá cao.

Để tránh viết sai, và cũng dễ đọc câu SQL, người ta dùng cách SQL động giả (emulate) command parameters:
Const SQLCOMMAND = "lệnh <tham1> lệnh <tham2> ..."
SQLstr = Replace(Replace(SQLCOMMAND, "<tham1>", tham số 1), "<tham2>", tham số 2)
Có bao nhiêu tham số thì bấy nhiêu Replace.
Câu SQLCOMMAND đọc dễ hiểu hơn nhiều.
 
Upvote 0
Mong các anh chị giúp đỡ ạ.
Em có đoạn code sưu tầm như dưới, khi em nhập dữ liệu từ ô thì code hoạt động tốt nhưng khi em copy và paste 2 dòng trở lên thì báo lỗi, mong các anh chị giúp đỡ thêm giúp em thuộc tính copy paste, và hướng dẫn em ạ. Em cảm ơn ạ.

Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim nhom, r As Long, rw As Long, c As Long

nhom = Sheet1.Range("c5:d10000").Value
rw = 0

If Target.Column = 5 And Target.Row > 6 Then
For r = 1 To UBound(nhom)
If nhom(r, 2) = Target.Value Then
rw = r
Exit For
End If
Next r

If rw <> 0 Then
Sheet3.Cells(Target.Row, 4).Value = nhom(r, 1)
Else
MsgBox "Khong Co Ten model  Nay"
End If

End If
End Sub
 

File đính kèm

  • Nhap xuât T1- nháp - Copy.xlsm
    236.8 KB · Đọc: 6
Upvote 0
Mong các anh chị giúp đỡ ạ.
Em có đoạn code sưu tầm như dưới, khi em nhập dữ liệu từ ô thì code hoạt động tốt nhưng khi em copy và paste 2 dòng trở lên thì báo lỗi, mong các anh chị giúp đỡ thêm giúp em thuộc tính copy paste, và hướng dẫn em ạ. Em cảm ơn ạ.

Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim nhom, r As Long, rw As Long, c As Long

nhom = Sheet1.Range("c5:d10000").Value
rw = 0

If Target.Column = 5 And Target.Row > 6 Then
For r = 1 To UBound(nhom)
If nhom(r, 2) = Target.Value Then
rw = r
Exit For
End If
Next r

If rw <> 0 Then
Sheet3.Cells(Target.Row, 4).Value = nhom(r, 1)
Else
MsgBox "Khong Co Ten model  Nay"
End If

End If
End Sub
Code này mà Copy Paste một lần hàng trăm ô thì hơi bị "Rùa".
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Nhom(), Cll As Range, r As Long
    Nhom = Sheet1.Range("c5", Sheet1.Range("d10000").End(xlUp)).Value
If Target.Column = 5 And Target.Row > 6 Then
    For Each Cll In Target
        For r = 1 To UBound(Nhom)
            If Nhom(r, 2) = Cll.Value Then
                Cll.Offset(, -1).Value = Nhom(r, 1)
                Exit For
            End If
        Next r
    Next Cll
End If
End Sub
 
Upvote 0
Giải thích giúp mình đoạn code này
Mã:
ArrData = Sheet1.Range(Sheet1.Cells(10, 126), Sheet1.Cells(&H100000, 2).End(xlUp)).Value

Mình ko hiểu chỗ này: Sheet1.Cells(&H100000, 2) (dấu & có ý nghĩa gì)

Giúp mình giải thích luôn toàn bộ ý nghĩa câu lệnh này, do ko hiểu chỗ dấu & nên ko biết nó muốn thể hiện lệnh nào

Thanks
 
Lần chỉnh sửa cuối:
Upvote 0
Giải thích giúp mình đoạn code này
Mã:
ArrData = Sheet1.Range(Sheet1.Cells(10, 126), Sheet1.Cells(&H100000, 2).End(xlUp)).Value

Mình ko hiểu chỗ này: Sheet1.Cells(&H100000, 2) (dấu & có ý nghĩa gì)

Giúp mình giải thích luôn toàn bộ ý nghĩa câu lệnh này, do ko hiểu chỗ dấu & nên ko biết nó muốn thể hiện lệnh nào

Cảm ơn
Bạn có thể cung cấp (truyền) mỗi một giá trị Long bằng 2 cách: nhập số ở dạng thập phân hoặc ở dạng hex (hệ 16). Vd. số 15 ở dạng hex là 0F. Nhưng nhập 15 thì được còn nhập 0F thì không được. Bạn phải thêm tiền tố là &H (H <- Hex) để chỉ ra đó là số ở dạng hex. Tức trong ví dụ là phải nhập - truyền &H0F.

&H100000 (dạng hex) = 1048576 (thập phân).

Vậy thì
Mã:
ArrData = Sheet1.Range(Sheet1.Cells(10, 126), Sheet1.Cells(&H100000, 2).End(xlUp)).Value
tương đương với
Mã:
ArrData = Sheet1.Range(Sheet1.Cells(10, 126), Sheet1.Cells(1048576, 2).End(xlUp)).Value

Sheet1.Cells(10, 126) là ô ở dòng 10 và cột 126, tức ô ở dòng 10 và cột DV, tức là ô DV10 trong Sheet1.

Sheet1.Cells(1048576, 2).End(xlUp) là ô cuối cùng có dữ liệu ở cột 2 - cột B. Diễn giải là: hãy xuất phát từ ô ở dòng 1048576 và cột 2, tức ô B1048576 (thường thì là ô trống) và đi lên trên (xlUp) cho tới khi gặp ô <> trống thì dừng. Muốn xác định ô cuối cùng có dữ liệu trong một cột nào đó thì ô xuất phát - ô B1048576 trong ví dụ phải rỗng. Thường thì những ô ở những dòng cuối cùng của trang tính là rỗng nên có thể yên tâm.

Lúc này thì
Mã:
ArrData = Sheet1.Range(Sheet1.Cells(10, 126), Sheet1.Cells(&H100000, 2).End(xlUp)).Value

có nghĩa là: lấy vùng dữ liệu (lấy giá trị) xác định bởi DV10 và ô cuối cùng có dữ liệu ở cột B từ Sheet1 vào mảng ArrData
------------
Sheet1.Cells(1048576, 2).End(xlUp) có thể thay bằng Sheet1.Cells(Rows.Count, 2).End(xlUp) hoặc
Sheet1.Range("B" & 1048576).End(xlUp) hoặc Sheet1.Range("B" & Rows.Count).End(xlUp), bởi Rows.Count trong Excel >= 2007 trả về giá trị 1048576 (số dòng trong trang tính)
---------
Bạn có thể định nghĩa hằng số theo 2 cách tương đương như sau:

Const MySecretNumber = 15
Const MySecretNumber = &H0F
 
Upvote 0
Bạn có thể cung cấp (truyền) mỗi một giá trị Long bằng 2 cách: nhập số ở dạng thập phân hoặc ở dạng hex (hệ 16). Vd. số 15 ở dạng hex là 0F. Nhưng nhập 15 thì được còn nhập 0F thì không được. Bạn phải thêm tiền tố là &H (H <- Hex) để chỉ ra đó là số ở dạng hex. Tức trong ví dụ là phải nhập - truyền &H0F.

&H100000 (dạng hex) = 1048576 (thập phân).

Vậy thì
Mã:
ArrData = Sheet1.Range(Sheet1.Cells(10, 126), Sheet1.Cells(&H100000, 2).End(xlUp)).Value
tương đương với
Mã:
ArrData = Sheet1.Range(Sheet1.Cells(10, 126), Sheet1.Cells(1048576, 2).End(xlUp)).Value

Sheet1.Cells(10, 126) là ô ở dòng 10 và cột 126, tức ô ở dòng 10 và cột DV, tức là ô DV10 trong Sheet1.

Sheet1.Cells(1048576, 2).End(xlUp) là ô cuối cùng có dữ liệu ở cột 2 - cột B. Diễn giải là: hãy xuất phát từ ô ở dòng 1048576 và cột 2, tức ô B1048576 (thường thì là ô trống) và đi lên trên (xlUp) cho tới khi gặp ô <> trống thì dừng. Muốn xác định ô cuối cùng có dữ liệu trong một cột nào đó thì ô xuất phát - ô B1048576 trong ví dụ phải rỗng. Thường thì những ô ở những dòng cuối cùng của trang tính là rỗng nên có thể yên tâm.

Lúc này thì
Mã:
ArrData = Sheet1.Range(Sheet1.Cells(10, 126), Sheet1.Cells(&H100000, 2).End(xlUp)).Value

có nghĩa là: lấy vùng dữ liệu (lấy giá trị) xác định bởi DV10 và ô cuối cùng có dữ liệu ở cột B từ Sheet1 vào mảng ArrData
------------
Sheet1.Cells(1048576, 2).End(xlUp) có thể thay bằng Sheet1.Cells(Rows.Count, 2).End(xlUp) hoặc
Sheet1.Range("B" & 1048576).End(xlUp) hoặc Sheet1.Range("B" & Rows.Count).End(xlUp), bởi Rows.Count trong Excel >= 2007 trả về giá trị 1048576 (số dòng trong trang tính)
---------
Bạn có thể định nghĩa hằng số theo 2 cách tương đương như sau:

Const MySecretNumber = 15
Const MySecretNumber = &H0F
Để mình test thử rồi báo bạn kết quả. Thanks bạn
 
Upvote 0
Bạn có thể cung cấp (truyền) mỗi một giá trị Long bằng 2 cách: nhập số ở dạng thập phân hoặc ở dạng hex (hệ 16). Vd. số 15 ở dạng hex là 0F. Nhưng nhập 15 thì được còn nhập 0F thì không được. Bạn phải thêm tiền tố là &H (H <- Hex) để chỉ ra đó là số ở dạng hex. Tức trong ví dụ là phải nhập - truyền &H0F.

&H100000 (dạng hex) = 1048576 (thập phân).

Vậy thì
Mã:
ArrData = Sheet1.Range(Sheet1.Cells(10, 126), Sheet1.Cells(&H100000, 2).End(xlUp)).Value
tương đương với
Mã:
ArrData = Sheet1.Range(Sheet1.Cells(10, 126), Sheet1.Cells(1048576, 2).End(xlUp)).Value

Sheet1.Cells(10, 126) là ô ở dòng 10 và cột 126, tức ô ở dòng 10 và cột DV, tức là ô DV10 trong Sheet1.

Sheet1.Cells(1048576, 2).End(xlUp) là ô cuối cùng có dữ liệu ở cột 2 - cột B. Diễn giải là: hãy xuất phát từ ô ở dòng 1048576 và cột 2, tức ô B1048576 (thường thì là ô trống) và đi lên trên (xlUp) cho tới khi gặp ô <> trống thì dừng. Muốn xác định ô cuối cùng có dữ liệu trong một cột nào đó thì ô xuất phát - ô B1048576 trong ví dụ phải rỗng. Thường thì những ô ở những dòng cuối cùng của trang tính là rỗng nên có thể yên tâm.

Lúc này thì
Mã:
ArrData = Sheet1.Range(Sheet1.Cells(10, 126), Sheet1.Cells(&H100000, 2).End(xlUp)).Value

có nghĩa là: lấy vùng dữ liệu (lấy giá trị) xác định bởi DV10 và ô cuối cùng có dữ liệu ở cột B từ Sheet1 vào mảng ArrData
------------
Sheet1.Cells(1048576, 2).End(xlUp) có thể thay bằng Sheet1.Cells(Rows.Count, 2).End(xlUp) hoặc
Sheet1.Range("B" & 1048576).End(xlUp) hoặc Sheet1.Range("B" & Rows.Count).End(xlUp), bởi Rows.Count trong Excel >= 2007 trả về giá trị 1048576 (số dòng trong trang tính)
---------
Bạn có thể định nghĩa hằng số theo 2 cách tương đương như sau:

Const MySecretNumber = 15
Const MySecretNumber = &H0F
Mình đã làm dc. Thanks ban
 
Upvote 0
CHo mình hỏi thêm chút về code khi gọi outlook để sent email (mình đang dùng office 2019) thì nó xuất hiện cái box này. CÓ cách nào để nó auto sent mà không phải request không (file đính kèm)

*** Mình đang viết code để sent email auto by outlook

Đây là code mình đã viết
Mã:
'Progame sent email to many people (chuong trinh goi email hang loat cho nhieu nguoi)
Sub sent_email()

'Call app Outlook
Dim OlApp As Outlook.Application
Set OlApp = CreateObject("Outlook.Application")

Dim i, y As Integer

'i la bien cot the hien email nguoi nhan
'y la bien so nguoi nhan email
y = Excel.WorksheetFunction.CountA(ThisWorkbook.Sheets(8).Range("G:G"))

For i = 2 To y
'Open app email
Dim olmail As Outlook.MailItem
Set olmail = OlApp.CreateItem(olMailItem)

Dim body_messenge As String
body_messenge = ThisWorkbook.Sheets(8).Cells(1, 13)
body_messenge = Excel.WorksheetFunction.Substitute(Excel.WorksheetFunction.Substitute(body_messenge, "staff", ThisWorkbook.Sheets(8).Cells(i, 8)), "password", ThisWorkbook.Sheets(8).Cells(i, 9))


'Sent email
olmail.To = ThisWorkbook.Sheets(8).Cells(i, 7)
olmail.Subject = "CTY A GOI PHIEU LUONG THANG ABC"
olmail.BodyFormat = olFormatHTML
olmail.HTMLBody = body_messenge
olmail.Attachments.Add ThisWorkbook.Path & "\Phieuluong Jan-2020\" & ThisWorkbook.Sheets(8).Cells(i, 10)
olmail.Send

Next
End Sub
 

File đính kèm

  • msb out.PNG
    msb out.PNG
    10.7 KB · Đọc: 4
Upvote 0
CHo mình hỏi thêm chút về code khi gọi outlook để sent email (mình đang dùng office 2019) thì nó xuất hiện cái box này. CÓ cách nào để nó auto sent mà không phải request không (file đính kèm)

*** Mình đang viết code để sent email auto by outlook

Đây là code mình đã viết
Mã:
'Progame sent email to many people (chuong trinh goi email hang loat cho nhieu nguoi)
Sub sent_email()

'Call app Outlook
Dim OlApp As Outlook.Application
Set OlApp = CreateObject("Outlook.Application")

Dim i, y As Integer

'i la bien cot the hien email nguoi nhan
'y la bien so nguoi nhan email
y = Excel.WorksheetFunction.CountA(ThisWorkbook.Sheets(8).Range("G:G"))

For i = 2 To y
'Open app email
Dim olmail As Outlook.MailItem
Set olmail = OlApp.CreateItem(olMailItem)

Dim body_messenge As String
body_messenge = ThisWorkbook.Sheets(8).Cells(1, 13)
body_messenge = Excel.WorksheetFunction.Substitute(Excel.WorksheetFunction.Substitute(body_messenge, "staff", ThisWorkbook.Sheets(8).Cells(i, 8)), "password", ThisWorkbook.Sheets(8).Cells(i, 9))


'Sent email
olmail.To = ThisWorkbook.Sheets(8).Cells(i, 7)
olmail.Subject = "CTY A GOI PHIEU LUONG THANG ABC"
olmail.BodyFormat = olFormatHTML
olmail.HTMLBody = body_messenge
olmail.Attachments.Add ThisWorkbook.Path & "\Phieuluong Jan-2020\" & ThisWorkbook.Sheets(8).Cells(i, 10)
olmail.Send

Next
End Sub
Mình đã tìm ra nguyên nhân.
Tắt chức năng này trong OUT là sẽ không bị nữa
Sử dụng Programmatic Access cho Outlook. Chọn thẻ File > Options > Trust Center > Trust Center Settings > Thẻ Programmatic Access > Bấm dấu tích vào “Never warn me about suspicious activity (not recommended) rồi bấm OK (Nhớ chạy OUT dưới quyền admin mới chỉnh được chức năng này)
 
Upvote 0
Nhờ các anh/chị trên diễn đàn giải đáp giúp em. em có đoạn code dùng Dictionary như sau:
Mã:
Sub dictMadoituong()
Dim dongcuoi As Long
Dim vungchon() As Variant
Dim khoa As String
Dim i As Long
Dim dic As Object
Set dic = CreateObject("scripting.dictionary")
With Sheets("DATA")
dongcuoi = .Cells(.Rows.Count, "N").End(xlUp).Row
vungchon = Range("N2:N" & dongcuoi)
For i = 1 To dongcuoi - 1
    khoa = vungchon(i, 1)
    If Not dic.exists(khoa) Then
    dic.Add vungchon(i, 1), 1
    Else
    dic.Item(khoa) = dic.Item(khoa) + 1
    End If
Next i
End With
With Sheets("Sheet1")
Range("a14:a" & dic.Count + 13) = Application.Transpose(dic.keys)
Range("b14:b" & dic.Count + 13) = Application.Transpose(dic.items)
End With
End Sub

Ngay sau chỗ With Sheets("Sheet1"), em muốn dán kết quả từ Dic vào ô A14 và B14 của sheet1, nhưng excel không làm đúng ý em. Em gởi theo file đính kèm.
Nhờ anh/chị chỉ chỗ em làm sai với ạ. Em cám ơn.
 

File đính kèm

  • 9103_Báo cáo số tháng liên tục - đếm đối tượng - 12 2019.xlsm
    4.3 MB · Đọc: 9
Upvote 0
Nhờ các anh/chị trên diễn đàn giải đáp giúp em. em có đoạn code dùng Dictionary như sau:
Mã:
Sub dictMadoituong()
Dim dongcuoi As Long
Dim vungchon() As Variant
Dim khoa As String
Dim i As Long
Dim dic As Object
Set dic = CreateObject("scripting.dictionary")
With Sheets("DATA")
dongcuoi = .Cells(.Rows.Count, "N").End(xlUp).Row
vungchon = Range("N2:N" & dongcuoi)
For i = 1 To dongcuoi - 1
    khoa = vungchon(i, 1)
    If Not dic.exists(khoa) Then
    dic.Add vungchon(i, 1), 1
    Else
    dic.Item(khoa) = dic.Item(khoa) + 1
    End If
Next i
End With
With Sheets("Sheet1")
Range("a14:a" & dic.Count + 13) = Application.Transpose(dic.keys)
Range("b14:b" & dic.Count + 13) = Application.Transpose(dic.items)
End With
End Sub

Ngay sau chỗ With Sheets("Sheet1"), em muốn dán kết quả từ Dic vào ô A14 và B14 của sheet1, nhưng excel không làm đúng ý em. Em gởi theo file đính kèm.
Nhờ anh/chị chỉ chỗ em làm sai với ạ. Em cám ơn.
Thay
Mã:
vungchon = Range("N2:N" & dongcuoi)
bằng
vungchon = .Range("N2:N" & dongcuoi).Value

Nguyên nhân là do khi chạy code thì sheet1 đang hoạt động và code cũ lấy vùng N2:N*** từ sheet1 vào mảng vungchon. Code sau khi sửa thì lấy N2:N*** từ sheet DATA vào mảng vungchon.
 
Lần chỉnh sửa cuối:
Upvote 0
Thay
Mã:
vungchon = Range("N2:N" & dongcuoi)
bằng


Nguyên nhân là do khi chạy code thì sheet1 đang hoạt động và code cũ lấy vùng N2:N*** từ sheet1 vào mảng vungchon. Code sau khi sửa thì lấy N2:N*** từ sheet DATA vào mảng vungchon.

Trước khi cho vungchon = range... thì đã có With Sheets("DATA") rồi mà anh? sao nó lại lấy từ sheet1 nhỉ? Chỉ cần thêm sửa .Range...Value thì lại lấy từ Sheets("DATA") nhỉ?
 
Upvote 0
Trước khi cho vungchon = range... thì đã có With Sheets("DATA") rồi mà anh? sao nó lại lấy từ sheet1 nhỉ? Chỉ cần thêm sửa .Range...Value thì lại lấy từ Sheets("DATA") nhỉ?
Bạn có vungchon = Range("N2:N" & dongcuoi) nên RANGE là lấy từ ACTIVESHEET (là Sheet1 do Sheet1 đang hoạt động). Viết như bạn thì vungchon = Range("N2:N" & dongcuoi) chính là vungchon = ActiveSheet.Range("N2:N" & dongcuoi), tức vungchon = Sheet1.Range("N2:N" & dongcuoi) Vì thế phải có dấu . trước Range để lấy từ DATA (do có With Sheets("DATA"))
 
Upvote 0
Bạn có vungchon = Range("N2:N" & dongcuoi) nên RANGE là lấy từ ACTIVESHEET (là Sheet1 do Sheet1 đang hoạt động). Viết như bạn thì vungchon = Range("N2:N" & dongcuoi) chính là vungchon = ActiveSheet.Range("N2:N" & dongcuoi), tức vungchon = Sheet1.Range("N2:N" & dongcuoi) Vì thế phải có dấu . trước Range để lấy từ DATA (do có With Sheets("DATA"))
Em cám ơn bác nhiều. Hèn gì nếu đang ở Sheet DATA mà chạy code thì đúng, còn ở Sheet1 thì sai.
Còn dòng này thì sao bác?
With Sheets("Sheet1")
Range("a14:a" & dic.Count + 13) = Application.Transpose(dic.keys)
Em có cần .Range chỗ này không bác nhỉ?
 
Lần chỉnh sửa cuối:
Upvote 0
Em cám ơn bác nhiều. *** gì nếu đang ở Sheet DATA mà chạy code thì đúng, còn ở Sheet1 thì sai.
Còn dòng này thì sao bác?
With Sheets("Sheet1")
Range("a14:a" & dic.Count + 13) = Application.Transpose(dic.keys)
Em có cần .Range chỗ này không bác nhỉ?
Nguyên tắc là thế này:
- nếu muốn luôn luôn truy cập tới activesheet, bất luận ACTIVESHEET là sheet nào, thì không thể dùng dấu . được.
- nếu muốn luôn luôn truy cập tới sheet cụ thể, bất luận nó có là activesheet hay không, thì luôn luôn phải viết tường minh - gọi tên chỉ mặt cụ thể. Vd. Sheet1.Range(...). Hoặc nếu dùng trong cấu trúc With Sheet1 ... End With thì phải dùng dấu . trước Rang(...)

Bạn có thể không dùng dấu . trước range khi có With Sheets("Sheet1"), nhưng chỉ trong trường hợp cụ thể này của bạn - chạy code bằng cách nhấn nút trên sheet1. Một ngày đẹp trời nào đó bạn cần chạy "code kia" khi thực hiện một code khác. Lúc đó "code kia" sẽ được chạy khi có thể activesheet không là sheet1. Lúc đó kết quả sẽ sai. Vì thế người biết lo xa, biết lường trước các tình huống người ta sẽ dùng dấu . trước Range.

Đừng bao giờ để con ma hên xui nó quyết định cách hoạt động của code của mình. Theo nguyên tắc tôi nêu trên thì "ở chỗ đó" bạn muốn truy cập tới sheet cụ thể là sheet1. Vậy hãy dùng dấu . để không một trường hợp nào làm sai lệch ý muốn của mình. Tại sao bỏ dấu . để rồi phụ thuộc vào hên xui, để rồi ăn không ngon ngủ không yên? Đó không là cách hành xử thông minh.

Nếu không dùng dấu . trong With Sheets("Sheet1") thì With Sheets("Sheet1") là vô dụng, vì bạn luôn truy câp tới activesheet. Nếu sheet1 là activesheet thì dĩ nhiên With Sheets("Sheet1") là thừa rồi. Nếu sheet1 không là activesheet thì With Sheets("Sheet1") cũng thừa vì code truy cập tới activesheet chứ không truy cập tới sheet1.
 
Upvote 0
Nếu không dùng dấu . trong With Sheets("Sheet1") thì With Sheets("Sheet1") là vô dụng, vì bạn luôn truy câp tới activesheet. Nếu sheet1 là activesheet thì dĩ nhiên With Sheets("Sheet1") là thừa rồi. Nếu sheet1 không là activesheet thì With Sheets("Sheet1") cũng thừa vì code truy cập tới activesheet chứ không truy cập tới sheet1.
Em đã hiểu. cám ơn bác nhiều ạ. Trước đó em cứ đinh ninh là trong With Sheets đã rõ ràng rồi. Nếu vậy dùng hẳn Sheet1.Range(...) sẽ đơn giản hơn, không cần phải để trong With..End nữa. Em đã thông rồi ạ.
 
Upvote 0
'Allowance qty
Select Case (Cells(i, 13).Value)
Case "Voc"
Cells(x + 15, y + resignMonth).Value = Cells(x + 15, y + resignMonth).Value + 1
Sheets("MsTung request").Cells(4, 13 + resignMonth).Value = Sheets("MsTung request").Cells(4, 13 + resignMonth).Value + 1
Case "S.term"
Cells(x + 16, y + resignMonth).Value = Cells(x + 16, y + resignMonth).Value + 1
Sheets("MsTung request").Cells(5, 13 + resignMonth).Value = Sheets("MsTung request").Cells(5, 13 + resignMonth).Value + 1
Case "None"
Cells(x + 17, y + resignMonth).Value = Cells(x + 17, y + resignMonth).Value + 1
Case "Elder3"
Cells(x + 18, y + resignMonth).Value = Cells(x + 18, y + resignMonth).Value + 1
Case "Elder 2"
Cells(x + 19, y + resignMonth).Value = Cells(x + 19, y + resignMonth).Value + 1
Case "Elder 1"
Cells(x + 20, y + resignMonth).Value = Cells(x + 20, y + resignMonth).Value + 1
Case "Skill 4"
Cells(x + 21, y + resignMonth).Value = Cells(x + 21, y + resignMonth).Value + 1
Case "Skill 3"
Cells(x + 22, y + resignMonth).Value = Cells(x + 22, y + resignMonth).Value + 1
Case "Skill 2"
Cells(x + 23, y + resignMonth).Value = Cells(x + 23, y + resignMonth).Value + 1
Case "Skill 1"
Cells(x + 24, y + resignMonth).Value = Cells(x + 24, y + resignMonth).Value + 1
Case "Support 2"
Cells(x + 25, y + resignMonth).Value = Cells(x + 25, y + resignMonth).Value + 1
Case Else
Cells(x + 26, y + resignMonth).Value = Cells(x + 26, y + resignMonth).Value + 1

Cho em hỏi có cách nào để thu gọn các lệnh giống nhau liên tiếp thế này và cải thiện tốc độ chạy của VBA ạ
 
Upvote 0
'Allowance qty
Select Case (Cells(i, 13).Value)
Case "Voc"
Cells(x + 15, y + resignMonth).Value = Cells(x + 15, y + resignMonth).Value + 1
Sheets("MsTung request").Cells(4, 13 + resignMonth).Value = Sheets("MsTung request").Cells(4, 13 + resignMonth).Value + 1
Case "S.term"
Cells(x + 16, y + resignMonth).Value = Cells(x + 16, y + resignMonth).Value + 1
Sheets("MsTung request").Cells(5, 13 + resignMonth).Value = Sheets("MsTung request").Cells(5, 13 + resignMonth).Value + 1
Case "None"
Cells(x + 17, y + resignMonth).Value = Cells(x + 17, y + resignMonth).Value + 1
Case "Elder3"
Cells(x + 18, y + resignMonth).Value = Cells(x + 18, y + resignMonth).Value + 1
Case "Elder 2"
Cells(x + 19, y + resignMonth).Value = Cells(x + 19, y + resignMonth).Value + 1
Case "Elder 1"
Cells(x + 20, y + resignMonth).Value = Cells(x + 20, y + resignMonth).Value + 1
Case "Skill 4"
Cells(x + 21, y + resignMonth).Value = Cells(x + 21, y + resignMonth).Value + 1
Case "Skill 3"
Cells(x + 22, y + resignMonth).Value = Cells(x + 22, y + resignMonth).Value + 1
Case "Skill 2"
Cells(x + 23, y + resignMonth).Value = Cells(x + 23, y + resignMonth).Value + 1
Case "Skill 1"
Cells(x + 24, y + resignMonth).Value = Cells(x + 24, y + resignMonth).Value + 1
Case "Support 2"
Cells(x + 25, y + resignMonth).Value = Cells(x + 25, y + resignMonth).Value + 1
Case Else
Cells(x + 26, y + resignMonth).Value = Cells(x + 26, y + resignMonth).Value + 1

Cho em hỏi có cách nào để thu gọn các lệnh giống nhau liên tiếp thế này và cải thiện tốc độ chạy của VBA ạ
Có: dùng With ..., và tìm quay luật các chỉ số để sửa hợp lý, hoặc đổi ARRAY
Vì chỉ có đoạn code ---> nên đoán đại cho trúng
 
Upvote 0
Web KT
Back
Top Bottom