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 chào A/C,
Em đang muốn xây dựng đoạn code cứ 15 giây thì code chạy sub DuLieu 1 lần (có nút bấm chạy và dừng).
Hiện tại Em mới mày mò ra được đoạn code nếu bấm vào thì sau 15 giây nó đã chạy. Nhưng sau đó nó chưa lặp lại được ạ. Đây là đoạn code của Em:
Sub CapNhatDuLieu()
Application.OnTime Now + TimeSerial(0, 0, 15), "DuLieu"
End Sub
Mong A/C giúp Em hoàn thiện tiếp đoạn code trên. Em cảm ơn A/C!
Như thế này mới được.
Mã:
Sub CapNhatDuLieu()
       Application.OnTime Now + TimeSerial(0, 0, 15), " CapNhatDuLieu"
       Call DuLieu
End Sub
 
Upvote 0
Như thế này mới được.
Mã:
Sub CapNhatDuLieu()
       Application.OnTime Now + TimeSerial(0, 0, 15), " CapNhatDuLieu"
       Call DuLieu
End Sub
Em cảm ơn Anh, code chạy ngon lành Anh ạ.
Nếu Em tạo thêm 2 nút bấm "Cập nhật liên tục" và "Dừng" Anh và các bạn có thể giúp Em thêm code cho 2 nút bấm này được không ạ? Em cảm ơn nhiều!
 
Upvote 0
Nếu Em tạo thêm 2 nút bấm "Cập nhật liên tục" và "Dừng" Anh và các bạn có thể giúp Em thêm code cho 2 nút bấm này được không ạ? Em cảm ơn nhiều!
1. Ở đầu module khai báo biến toàn cục
Mã:
Private lastTime As Double


2. Sửa CapNhatDuLieu thành
Mã:
Sub CapNhatDuLieu(ByVal start As Boolean)
    If start Then
        lastTime = Now + TimeSerial(0, 0, 15)
        Application.OnTime lastTime, "DuLieu"
    ElseIf lastTime <> 0 Then
        Application.OnTime lastTime, "DuLieu", , False
        lastTime = 0
    End If
End Sub

3. Trong sub DuLieu ở trước dòng End Sub hãy thêm dòng
Mã:
CapNhatDuLieu True

4.
Khi muốn BẬT thì
Mã:
CapNhatDuLieu True

Khi muốn TẮT thì
Mã:
CapNhatDuLieu False
 
Upvote 0
1. Ở đầu module khai báo biến toàn cục
Mã:
Private lastTime As Double


2. Sửa CapNhatDuLieu thành
Mã:
Sub CapNhatDuLieu(ByVal start As Boolean)
    If start Then
        lastTime = Now + TimeSerial(0, 0, 15)
        Application.OnTime lastTime, "DuLieu"
    ElseIf lastTime <> 0 Then
        Application.OnTime lastTime, "DuLieu", , False
        lastTime = 0
    End If
End Sub

3. Trong sub DuLieu ở trước dòng End Sub hãy thêm dòng
Mã:
CapNhatDuLieu True

4.
Khi muốn BẬT thì
Mã:
CapNhatDuLieu True

Khi muốn TẮT thì
Mã:
CapNhatDuLieu False
Tuyệt quá, Em làm theo code chạy như mong đợi rồi Anh ạ. Cảm ơn Anh và mọi người rất nhiều!
 
Upvote 0
1. Ở đầu module khai báo biến toàn cục
Mã:
Private lastTime As Double


2. Sửa CapNhatDuLieu thành
Mã:
Sub CapNhatDuLieu(ByVal start As Boolean)
    If start Then
        lastTime = Now + TimeSerial(0, 0, 15)
        Application.OnTime lastTime, "DuLieu"
    ElseIf lastTime <> 0 Then
        Application.OnTime lastTime, "DuLieu", , False
        lastTime = 0
    End If
End Sub

3. Trong sub DuLieu ở trước dòng End Sub hãy thêm dòng
Mã:
CapNhatDuLieu True

4.
Khi muốn BẬT thì
Mã:
CapNhatDuLieu True

Khi muốn TẮT thì
Mã:
CapNhatDuLieu False

Em đang tập nghiên cứu code, nhân đoạn code này Em dịch như sau. Mong A/C xem và sửa giúp Em:
Mã:
Sub CapNhatDuLieu(ByVal start As Boolean)    
    If start Then    
(Nếu biến start là True thì)

        lastTime = Now + TimeSerial(0, 0, 15)     
(Gán lastTime với lịch trình thời gian hiện tại + 15 giây)    
                                                                      
        Application.OnTime lastTime, "DuLieu"                 
(Chạy Sub DuLieu, sau 15 giây kể từ bây giờ)

    ElseIf lastTime <> 0 Then                 
(Ngược lại nếu lastTime <>0 thì... Chỗ này Em đang chưa hiểu lắm? Em có thử sửa lại: ElseIf Start=False Then  -> để theo cái if start = true ở trên. Thì code có chạy được. Em sửa như vậy thì có sao ko Anh nhỉ?)     
                                               
        Application.OnTime lastTime, "DuLieu", , False     
(Chạy Sub DuLieu, sau 15 giây kể từ bây giờ, , dừng thủ tục)       
                                                                                  
        lastTime = 0                                                           
(Khi dừng thủ tục thì gán lastTime =0 )

    End If
End Sub
 
Upvote 0
Em đang tập nghiên cứu code, nhân đoạn code này Em dịch như sau. Mong A/C xem và sửa giúp Em:
Mã:
Sub CapNhatDuLieu(ByVal start As Boolean)   
    If start Then   
(Nếu biến start là True thì)

        lastTime = Now + TimeSerial(0, 0, 15)    
(Gán lastTime với lịch trình thời gian hiện tại + 15 giây)   
                                                                     
        Application.OnTime lastTime, "DuLieu"                
(Chạy Sub DuLieu, sau 15 giây kể từ bây giờ)

    ElseIf lastTime <> 0 Then                
(Ngược lại nếu lastTime <>0 thì... Chỗ này Em đang chưa hiểu lắm? Em có thử sửa lại: ElseIf Start=False Then  -> để theo cái if start = true ở trên. Thì code có chạy được. Em sửa như vậy thì có sao ko Anh nhỉ?)    
                                              
        Application.OnTime lastTime, "DuLieu", , False    
(Chạy Sub DuLieu, sau 15 giây kể từ bây giờ, , dừng thủ tục)      
                                                                                 
        lastTime = 0                                                          
(Khi dừng thủ tục thì gán lastTime =0 )

    End If
End Sub
Đặt chỗ đó Start = False thì hóa ra true, false gì cũng chạy cả, bạn không thể dừng code được.
 
Upvote 0
ElseIf lastTime <> 0 Then
(Ngược lại nếu lastTime <>0 thì... Chỗ này Em đang chưa hiểu lắm? Em có thử sửa lại: ElseIf Start=False Then -> để theo cái if start = true ở trên. Thì code có chạy được. Em sửa như vậy thì có sao ko Anh nhỉ?)

Application.OnTime lastTime, "DuLieu", , False
(Chạy Sub DuLieu, sau 15 giây kể từ bây giờ, , dừng thủ tục)

lastTime = 0
(Khi dừng thủ tục thì gán lastTime =0 )

End If
End Sub
[/CODE]
Không phải. Nếu start = True thì dĩ nhiên nhánh IF được thực hiện, tức vd. Application.OnTime lastTime, "DuLieu"
Vậy nếu đã xét tới ELSE ... thì ắt hẳn start = False rồi, khỏi phải kiểm tra nữa, tức không phải là ELSEIF start = False, vì cái điều kiện này (start = False) dĩ nhiên là thỏa.

Tại sao tôi kiểm tra điều kiện lastTime? Dụng ý là gì?

Giả sử không có ELSEIF lastTime <> 0, mà chỉ có ELSE.

Lúc đó code nhánh ELSE sẽ được thực hiện bất kể lastTime = 0 hay lastTime <> 0.

Giả sử bạn có code TẮT, được gán cho nút "Tắt đồng hồ".
Mã:
CapNhatDuLieu False
Khi người dùng mở tập tin rồi lỡ nhân nút "Tắt đồng hồ", hoặc họ cố tình "phá hoại" thì sẽ xuất hiện LỖI vì ở thời điểm đó lastTime = 0. Vì thế tôi viết ELSEIF lastTime <> 0 để trong tình huống này thì điều kiện lastTie <> 0 KHÔNG THỎA để code không được thực hiện.

Bạn nên nhớ là trong cấu trúc IF ... không chỉ 1 điều kiện được kiểm tra mà có thể RẤT NHIỀU
Mã:
If lt = "Vân Anh" then    ' lớp trưởng
...
ElseIf lp = "Diễm My" then    ' lớp phó
...
ElseIf cgcn = "Tuyết Mai" then    ' cô giáo chủ nhiệm
...
Else
...
End If

Vì thế tôi kiểm tra 2 điều kiện start và lastTime <> 0 là quá khiêm tốn, không có gì là khó hiểu cả.
 
Lần chỉnh sửa cuối:
Upvote 0
Đặt chỗ đó Start = False thì hóa ra true, false gì cũng chạy cả, bạn không thể dừng code được.
Sao lại không? Nếu sửa thế thì chỉ là thừa vì chắc chắn lúc này start = False rồi, khỏi cần kiểm tra. Mà đã thỏa Else thì
Application.OnTime lastTime, "DuLieu", , False

được thực hiện, tức là dừng đồng hồ. Chỉ có điều nếu bỏ lastTime <> 0 mà lỡ nhấn TẮT khi đồng hồ đang chưa chạy (đã được tắt), tức khi lastTime = 0, thì sẽ có LỖI. Vì
Mã:
Application.OnTime lastTime, "DuLieu", , False
sẽ có lỗi khi lastTime = 0.

Khi viết code tôi luôn phục vụ các tình huống khi người dùng mệt mỏi và có thể nhầm lẫn, khi người dùng sơ ý hoặc cố ý ... Người ta nói là phải viết code sao cho nó chịu được lửa, chịu được nước, và chịu được cả những ngu dốt của người dùng.

Nhớ xem cả bài 3009
 
Upvote 0
Sao lại không? Nếu sửa thế thì chỉ là thừa vì chắc chắn lúc này start = False rồi, khỏi cần kiểm tra. Mà đã thỏa Else thì
Application.OnTime lastTime, "DuLieu", , False

được thực hiện, tức là dừng đồng hồ. Chỉ có điều nếu bỏ lastTime <> 0 mà lỡ nhấn TẮT khi đồng hồ đang chưa chạy (đã được tắt), tức khi lastTime = 0, thì sẽ có LỖI. Vì
Mã:
Application.OnTime lastTime, "DuLieu", , False
sẽ có lỗi khi lastTime = 0.

Khi viết code tôi luôn phục vụ các tình huống khi người dùng mệt mỏi và có thể nhầm lẫn, khi người dùng sơ ý hoặc cố ý ... Người ta nói là phải viết code sao cho nó chịu được lửa, chịu được nước, và chịu được cả những ngu dốt của người dùng.

Nhớ xem cả bài 3009
Em cảm ơn Anh batman1 rất nhiều!
- Em có thử sửa code theo hướng lúc trước Em đang nhầm giữa Elseif và Else, thì khi bấm dừng với thủ tục "CapNhatDuLieu False" nếu bấm liên tục 2 lần thì code báo lỗi.
- Với code của Anh đã lường trước các trường hợp nên code ko bị lỗi gì cả.


Em ngồi mày mò tìm hiểu về thủ tục hủy, phương thức Application.OnTime. Nhưng nhìn code mãi vẫn chưa tư duy ra được hết ý nghĩa 3 dòng code này:
Mã:
    ElseIf lastTime <> 0 Then    'Nếu lastTime <>0 thì
        Application.OnTime lastTime, "DuLieu", , False      'Schedule:=False dừng lịch trình. Em đang chưa hiểu điều kiện gì để False?
        lastTime = 0              'Gán lastTime=0
 
Upvote 0
Em ngồi mày mò tìm hiểu về thủ tục hủy, phương thức Application.OnTime. Nhưng nhìn code mãi vẫn chưa tư duy ra được hết ý nghĩa 3 dòng code này:
Mã:
    ElseIf lastTime <> 0 Then    'Nếu lastTime <>0 thì
        Application.OnTime lastTime, "DuLieu", , False      'Schedule:=False dừng lịch trình. Em đang chưa hiểu điều kiện gì để False?
        lastTime = 0              'Gán lastTime=0
Muốn tắt đồng hồ thì bắt buộc Schedule:=False. Vì thế trong code có False.

Còn tại sao thiết lập lastTime = 0?

Nếu bạn bấm liên tục 2 lần (vd. lỡ tay) thì:
- lần nhấn 1 sẽ tắt đồng hồ và thiết lập lastTime = 0
- ở lần bấm 2 thì điều kiện lastTime <> 0 không thỏa (đang có lastTime = 0 do lần 1 thiết lập), vậy code
Mã:
Application.OnTime lastTime, "DuLieu", , False
sẽ không được thực hiện. Và chính xác phải là thế. Không táy máy nghịch TẮT cái đồng hồ đang được TẮT.
 
Upvote 0
Muốn tắt đồng hồ thì bắt buộc Schedule:=False. Vì thế trong code có False.

Còn tại sao thiết lập lastTime = 0?

Nếu bạn bấm liên tục 2 lần (vd. lỡ tay) thì:
- lần nhấn 1 sẽ tắt đồng hồ và thiết lập lastTime = 0
- ở lần bấm 2 thì điều kiện lastTime <> 0 không thỏa (đang có lastTime = 0 do lần 1 thiết lập), vậy code
Mã:
Application.OnTime lastTime, "DuLieu", , False
sẽ không được thực hiện. Và chính xác phải là thế. Không táy máy nghịch TẮT cái đồng hồ đang được TẮT.
Dạ vâng Em cảm ơn Anh!
 
Upvote 0
Em chào A/C!
Em có đoạn code dưới đây đang lấy giá trị của các hiện hành khi bấm vào.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Sheet1.Range("A1").Value = Selection.Value
End Sub

Em muốn nhờ A/C giúp Em sửa code chỗ ( = Selection.Value ) để code lấy giá trị của dòng 2 theo từng cột.
VD: Em có bảng dữ liệu với tiêu đề ở dòng số 2:
A2: Mặt hàng
B2: Kho hàng

Nếu Em đặt chuột ở bất kỳ vị trí nào ở cột A thì code đều lấy giá trị trả về là giá trị của ô A2 là "Mặt hàng", ở bất kỳ vị trí nào trong cột B thì code cũng trả về giá trị ô B 2 là "Kho hàng". Mong A/C giúp Em. Cảm ơn A/C nhiều!
 
Upvote 0
Em chào A/C!
Em có đoạn code dưới đây đang lấy giá trị của các hiện hành khi bấm vào.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Sheet1.Range("A1").Value = Selection.Value
End Sub

Em muốn nhờ A/C giúp Em sửa code chỗ ( = Selection.Value ) để code lấy giá trị của dòng 2 theo từng cột.
VD: Em có bảng dữ liệu với tiêu đề ở dòng số 2:
A2: Mặt hàng
B2: Kho hàng

Nếu Em đặt chuột ở bất kỳ vị trí nào ở cột A thì code đều lấy giá trị trả về là giá trị của ô A2 là "Mặt hàng", ở bất kỳ vị trí nào trong cột B thì code cũng trả về giá trị ô B 2 là "Kho hàng". Mong A/C giúp Em. Cảm ơn A/C nhiều!
Dùng tạm
Sheet1.Range("A1").Value =cells(2, Selection.column).Value
 
Upvote 0
chào anh chị
em muốn hạn chế thời gian nhập nội dung vào 1 ô trên excel có được không ạ. Ví dụ như nội dung ngày 21/10 thì đến ngày 22 không thế nhập vào ô đó nữa ạ
em cảm ơn ạ
 
Upvote 0
Chào moị người
mình có chạy cái file để tách thành các sheet từ 1 sheet code :
Sub locdulieu()
'coppy du lieu
shtam.Range("A:A").Value = data.Range("C:C").Value
shtam.Range("A:A").RemoveDuplicates Columns:=1, Header:=xlNo
Columns("A:A").Select
Selection.Replace What:="/", Replacement:=" ", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False, FormulaVersion:=xlReplaceFormula2
Dim lr As Long, i As Long, lrdata As Long
lr = shtam.Range("A" & Rows.Count).End(xlUp).Row
lrdata = data.Range("H" & Rows.Count).End(xlUp).Row
For i = 2 To lr
data.Range("$A$1:$H" & lrdata).AutoFilter Field:=3, Criteria1:=shtam.Cells(i, 1).Value
data.Range("$A$1:$H" & lrdata).Copy 'coppy du lieu da loc
Worksheets.Add after:=Worksheets(Worksheets.Count)
ActiveSheet.Name = shtam.Cells(i, 1).Value 'doi ten sheet thanh ten khach hang
ActiveSheet.Range("A1").PasteSpecial xlPasteValues

Next i

End Sub
Vì name có dấu / nên khi tới 4 sheet là nó báo lỗi , có cách nào khắc phục được không ạ , mình đã thử xóa dấu / nhưng chạy file vẫn bị lỗi , vì người mới nên nhờ mọi người hỗ trợ giúp ạ .
cảm ơn mọi người
 

File đính kèm

  • thu nghiem tach sheet.xlsm
    531.7 KB · Đọc: 2
Upvote 0
Mã:
Sub ABC()
    Dim Arr(), iR&, ws As Worksheet
    Dim dic As Object, S, X
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Set dic = CreateObject("scripting.dictionary")
For Each ws In Worksheets
    If ws.Name <> "data" Then
        ws.Delete
    End If
Next
With Sheets("data")
    If .AutoFilterMode Then .AutoFilterMode = False
    Arr = .Range("C2:C" & .Range("C" & Rows.Count).End(3).Row).Value
End With
For i = 1 To UBound(Arr, 1)
    If dic.exists(Arr(i, 1)) = False Then
        dic.Add (Arr(i, 1)), ""
    End If
Next
iR = Sheets("data").Range("C" & Rows.Count).End(3).Row
For Each S In dic.keys
    With Sheets("data")
        Worksheets.Add after:=Worksheets(Worksheets.Count)
        .Range("$A$1:$H" & iR).AutoFilter 3, S
        .Range("$A$1:$H" & iR).Copy ActiveSheet.Range("A1")
        S = Replace(S, "/", "-")
        ActiveSheet.Name = Right(S, Len(S) - 7)
    End With
Next
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
Vì name có dấu / nên khi tới 4 sheet là nó báo lỗi , có cách nào khắc phục được không ạ , mình đã thử xóa dấu / nhưng chạy file vẫn bị lỗi , vì người mới nên nhờ mọi người hỗ trợ giúp ạ .
cảm ơn mọi người
Tên sheet không được đặt chuỗi quá 31 kí tự
Ban thử dùng code này. Xóa tất cả sheet đi. để lại sheet data thôi
 
Lần chỉnh sửa cuối:
Upvote 0
Hi bạn
mình có thể đặt tên sheet đó + với sô lượng dòng trong sheet đó dc ko bạn / ví dụ ( Buu Long LM Hub 1998 đơn )
Bài đã được tự động gộp:

Hi bạn
mình có thể đặt tên sheet đó + với sô lượng dòng trong sheet đó dc ko bạn / ví dụ ( Buu Long LM Hub 1998 đơn )
 
Lần chỉnh sửa cuối:
Upvote 0
Hi bạn
mình có thể đặt tên sheet đó + với sô lượng dòng trong sheet đó dc ko bạn / ví dụ ( Buu Long LM Hub 1998 đơn )
Thứ nhất: Bạn đang muốn trao đổi với ai hay tác giả bài đăng nào trong ~ 3 ngàn bài đăng ở đây vậy?
Thứ 2: Tên Trang tính không nên chứa tiếng việt có dấu, mà cụ thể ở đây là 'Đ'
Thứ ba: Như bài trên gần đây có nói, tên trang tính không dài quá số ký tự nào đó (cho từng VER)
Vậy theo mình, ta hạn chế khoảng trắng trong tên (trang tính), vì dụ: Thay vì tên của ví dụ bạn, nên là "BuuLongLM_Hub1998Don"

Chúc mọi điều tốt lành đến tất cả mọi người.
 
Upvote 0
Web KT
Back
Top Bottom