Nếu như cùng thao tác ghi MC giống nhau mà cho 2 đoạn Code khác nhau có lẽ sử dụng Office khác nhau. Mình dùng 2007
Vì đoạn code của Ngọc không ấn định nameSheet nên sang Sheet khác chạy vô tư là đúng.
Mình vẫn là câu thắc mắc như trên Tại sao? Cùng là ghi MC tự động cái thì bị gán name Sh cố định cái thì không ?
Em đã xem file của anh Minh và anh Ngọc nhưng em thấy việc sắp xếp chỉ được ở những vùng đã chọn khi ghi macro mà không áp dụng được với vùng khác (bất kỳ) mình tạo ra sau đó (em có gửi file đính kèm). Mong thầy giáo và các anh chị giải đáp giúp!
Em đã xem file của anh Minh và anh Ngọc nhưng em thấy việc sắp xếp chỉ được ở những vùng đã chọn khi ghi macro mà không áp dụng được với vùng khác (bất kỳ) mình tạo ra sau đó (em có gửi file đính kèm). Mong thầy giáo và các anh chị giải đáp giúp!
Chúc mừng bạn! MC làm như vậy nhưng mình cũng phải hiểu là từng đoạn code trong đó nó thực hiện cái gì bạn ah
Tất nhiên với trình của AE mình bây giờ không thể biết tường tận thì cũng nên biết
Chức năng sắp xếp nó chỉ cần đoạn này
Sub Sapxep()
Selection.Sort Key1:=Range(Cells(Selection.Row,Selection.Column).Address), Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
End Sub
Bạn chia cửa sổ Excel và VBE làm hai nửa màn hình. Sau đó ghi MC sẽ thấy MC nó làm gì với mỗi hành động của ta làm.
Như vậy, các hành động thừa ta sẽ xoá bỏ bớt đi. VD: trong Code trên. Bạn chỉ cần sắp xếp thì xoá bỏ các đoạn Code tô viền của ô đi.
Với việc chia màn hình ra thế này để xem, sửa, chạy thử… xem dc ngay kết quả của Excel làm khi ta tác động vào Code.
Mình thấy cách làm này rất hay mình muốn chia sẻ với tất cả mọi người mới học như mình.
Mình có góp ý nhỏ với Ngọc nhé!
Tất cả các trường hợp có thưởng đều có điều kiện chung là: Ngaycong >=20 và Giadinh = "Co" -> Vậy sao Bạn không gộp nó thành điều kiện chung rồi dùng IF cho trường hợp còn lại là chức vụ thôi.
Đại loại như vầy:
Mã:
Function Thuong(ByVal CVu As String, NgCong As Long, GDinh As String) As String
If NgCong >= 20 And GDinh = "Co" Then
If CVu = "GD" Then Thuong = "Xe may Attila"
If CVu = "PGD" Then Thuong = "Xe may Jupiter"
If CVu = "TP" Then Thuong = "Xe may Wave anpha"
If CVu = "NV" Then Thuong = "Bo hoa tuoi"
Else
Thuong = "That dang tiec!"
End If
End Function
Cho Mình tham gia giải với nhé! Trình đo VBA Mình còn kém lắm, tự học là chính, đây là điều kiện tốt...hè...hè
Mình có góp ý nhỏ với Ngọc nhé!
Tất cả các trường hợp có thưởng đều có điều kiện chung là: Ngaycong >=20 và Giadinh = "Co" -> Vậy sao Bạn không gộp nó thành điều kiện chung rồi dùng IF cho trường hợp còn lại là chức vụ thôi.
Đại loại như vầy:
Mã:
Function Thuong(ByVal CVu As String, NgCong As Long, GDinh As String) As String
If NgCong >= 20 And GDinh = "Co" Then
If CVu = "GD" Then Thuong = "Xe may Attila"
If CVu = "PGD" Then Thuong = "Xe may Jupiter"
If CVu = "TP" Then Thuong = "Xe may Wave anpha"
If CVu = "NV" Then Thuong = "Bo hoa tuoi"
Else
Thuong = "That dang tiec!"
End If
End Function
Cho Mình tham gia giải với nhé! Trình đo VBA Mình còn kém lắm, tự học là chính, đây là điều kiện tốt...hè...hè
Dạ, cám ơn anh! Em cũng làm được như vậy rồi. Nhưng tại lớp em còn có nhưng người mới nữa nên em đưa bài làm như vậy để mọi người tiếp thu dần dần anh ah! Một lần nữa cám ơn anh Minh Công!
Function TinhThuong(ByVal sChucVu As String, lNgayCong As Long, sGiaDinh As String) As String
If (sChucVu = "GD") And (lNgayCong >= 20) And (sGiaDinh = "Co") Then
TinhThuong = "Xe may Attila"
ElseIf (sChucVu = "PGD") And (lNgayCong >= 20) And (sGiaDinh = "Co") Then
TinhThuong = "Xe may Jupiter"
ElseIf (sChucVu = "TP") And (lNgayCong >= 20) And (sGiaDinh = "Co") Then
TinhThuong = "Xe may Wave anpha"
ElseIf (sChucVu = "NV") And (lNgayCong >= 20) And (sGiaDinh = "Co") Then
TinhThuong = "Bo hoa tuoi"
Else
TinhThuong = "That dang tiec!"
End If
End Function
Để ý dòng nào cũng có điều kiện (lNgayCong >= 20) And (sGiaDinh = "Co") vậy sao không đưa nó lên đầu cùng
Kiểu vầy:
PHP:
Function TinhThuong(ByVal sChucVu As String, lNgayCong As Long, sGiaDinh As String) As String
TinhThuong = "That dang tiec!"
If (lNgayCong >= 20) And (sGiaDinh = "Co") Then
If sChucVu = "GD" Then TinhThuong = "Xe may Attila"
If sChucVu = "PGD" Then TinhThuong = "Xe may Jupiter"
If sChucVu = "TP" Then TinhThuong = "Xe may Wave anpha"
If sChucVu = "NV" Then TinhThuong = "Bo hoa tuoi"
End If
End Function
Có gọn hơn không?
Ngoài ra còn có thể dùng Select Case thay cho IF
---------------------------
Dạ, cám ơn anh! Em cũng làm được như vậy rồi. Nhưng tại lớp em còn có nhưng người mới nữa nên em đưa bài làm như vậy để mọi người tiếp thu dần dần anh ah! Một lần nữa cám ơn anh Minh Công!
Mình cũng tham gia tí nhé! Thấy Hàm TinhThuong này mình thử làm Select Case:
PHP:
Function TinhThuong(ByVal sChucVu As String, lNgayCong As Long, sGiaDinh As String) As String
If (lNgayCong >= 20) And (sGiaDinh = "Co") Then
Select Case sChucVu
Case "GD": TinhThuong = "Xe may Attila"
Case "PGD": TinhThuong = "Xe may Jupiter"
Case "TP": TinhThuong = "Xe may Wave anpha"
Case "NV": TinhThuong = "Bo hoa tuoi"
Case Else: TinhThuong = "That dang tiec!"
End Select
End If
End Function
Hình như chưa chuẩn, như thế này mới đúng:
PHP:
Function TinhThuong(ByVal sChucVu As String, lNgayCong As Long, sGiaDinh As String) As String
TinhThuong = "That dang tiec!"
If (lNgayCong >= 20) And (sGiaDinh = "Co") Then
Select Case sChucVu
Case "GD": TinhThuong = "Xe may Attila"
Case "PGD": TinhThuong = "Xe may Jupiter"
Case "TP": TinhThuong = "Xe may Wave anpha"
Case "NV": TinhThuong = "Bo hoa tuoi"
End Select
End If
End Function
Function TinhThuong(ByVal sChucVu As String, lNgayCong As Long, sGiaDinh As String) As String
TinhThuong = "That dang tiec!"
If (lNgayCong >= 20) And (sGiaDinh = "Co") Then
If sChucVu = "GD" Then TinhThuong = "Xe may Attila"
If sChucVu = "PGD" Then TinhThuong = "Xe may Jupiter"
If sChucVu = "TP" Then TinhThuong = "Xe may Wave anpha"
If sChucVu = "NV" Then TinhThuong = "Bo hoa tuoi"
End If
End Function
va minhcong thực sự là sáng tạo (trong khuôn khổ lớp học của bọn E) còn của learnig_Excel thì cấu trúc Select case bọn E chưa học tới
Rất cám ơn các bác đã nhiệt tình tham gia .
Option Explicit
Function TinhThuong(ByVal sChucVu As String, lNgayCong As Long, sGiaDinh As String) As String
Const GPE As String = "PGDTPNV"
If lNgayCong >= 20 And sGiaDinh = "Co" And InStr(GPE, sChucVu) Then
TinhThuong = Switch(sChucVu = "GD", "Xe may Attila", sChucVu = "PGD", "Xe may Jupiter" _
, sChucVu = "TP", "Xe may Wave anpha", sChucVu = "NV", "Bo hoa tuoi")
ElseIf Not InStr(GPE, sChucVu) Then
TinhThuong = "That dang tiec!"
End If
End Function
Option Explicit
Function TinhThuong(ByVal sChucVu As String, lNgayCong As Long, sGiaDinh As String) As String
Const GPE As String = "PGDTPNV"
If lNgayCong >= 20 And sGiaDinh = "Co" And InStr(GPE, sChucVu) Then
TinhThuong = Switch(sChucVu = "GD", "Xe may Attila", sChucVu = "PGD", "Xe may Jupiter" _
, sChucVu = "TP", "Xe may Wave anpha", sChucVu = "NV", "Bo hoa tuoi")
ElseIf Not InStr(GPE, sChucVu) Then
TinhThuong = "That dang tiec!"
End If
End Function
Trước tiên, Switch() là 1 hàm của VBA giống như hàm Choose(jJ,"1","1A","@C",. . .) cũng trong VBA
Nhưng hàm Choose(. . .), thì trị jJ đó fải là kiểu Byte, hay Integer
Còn hàm Switch() như bạn thấy nó có thề xài với tham biến nhiều kiểu dữ liệu khác nhau
Có lúc mình đã thử hơn 100 trị Jj trong hàm nó vẫn không kêu ca chi hết.
Thí dụ: GPE= Switch(jJ<3,0 , Jj=5, 3,. . . . )
Bạn có thể tìm hiểu thêm lúc rỗi trong fần trợ giúp của CS VBE, nói nhiều hơn ở đây e không fải chổ.
IF btLogic Then
Làm gì đó khi btLogic = True
End If
Dạng 2:
Mã:
IF btLogic Then
Làm gì đó khi btLogic = True
Else
Làm gì đó khi btLogic = False
End If
Dạng 3:
Mã:
IF btLogic1 Then
Làm gì đó khi btLogic1 = True
ElseIF btLogic2 Then
Làm gì đó khi btLogic2 = True
...
ElseIF btLogicN Then
Làm gì đó khi btLogicN = True
Else
Làm gì đó khi tất cả các btLogic1,2,...N đều = False
End If
Chúng ta lưu ý các vấn đề:
1. Có thể không cần dùng nhánh Else nếu ta không quan tâm tới các trường hợp không thỏa mãn điều kiện (các btLogic đều = False).
2. Có If thì phải có End If để kết thúc khối lệnh If. Nhánh Else, ElseIf thì không cần End If. Nếu lệnh If...Then... trên một dòng thì không dùng End If.
3. Biểu thức logic (btLogic) là gì?
Biểu thức logic là một phép toán so sánh mà kết quả của nó trả về giá trị kiểu Logic - Boolean tức là chỉ trả về 1 trong 2 giá trị True, False
Phép toán so sánh:
= bằng
> lớn hơn
>= lớn hơn hoặc bằng
< nhỏ hơn
<= nhỏ hơn hoặc bằng
<> khác (không bằng)
Like -->như là :học sau
Is -->là: học sau
Xây dựng phép toán so sánh
A so soánh với B. Ví dụ A = B, A > B, A>= B ,....
Viết hàm trả lời theo các tình huống của các ví dụ dưới đây.
Ví dụ 1: Nếu tuổi lớn hơn hoặc bằng 18 thì trả lời được phép lập gia đình
Mã:
Function KiemTra(Byval lTuoi As Long) As String
If lTuoi >= 18 Then
KiemTra = "Được phép lập gia đình"
End If
End Function
Ví dụ 2: Nếu tuổi lớn hơn hoặc bằng 18 thì trả lời "Được phép lập gia đình", trường hợp khác trả lời "Không đủ tuổi lập gia đình"
Mã:
Function KiemTra(Byval lTuoi As Long) As String
If lTuoi >= 18 Then
KiemTra = "Được phép lập gia đình"
Else
KiemTra = "Không đủ tuổi lập gia đình"
End If
End Function
Ví dụ 3: Nếu tuổi lớn hơn hoặc bằng 18 và giới tính là Nam thì trả lời "Được phép lấy vợ"
Nếu tuổi lớn hơn hoặc bằng 18 và giới tính là Nữ thì trả lời "Được phép lấy chồng"
Trường hợp khác trả lời "Không được phép lập gia đình"
Mã:
Function KiemTra(Byval lTuoi As Long, Byval sGioiTinh As String) As String
If lTuoi >= 18 Then
If sGioiTinh = "Nam" Then
KiemTra = "Được phép lấy vợ"
ElseIf sGioiTinh = "Nữ" Then
KiemTra = "Được phép lấy chồng"
End If
Else
KiemTra = "Không được phép lập gia đình"
End If
End Function
Một biểu thức logic có thể là sự kết hợp của nhiều cặp logic khác, có thể dùng các phép hợp: And - và; Or - hoặc; Not (btLogic) - phủ định btLogic
Vẫn ví dụ trên, ta có thể viết cách khác
Mã:
Function KiemTra(Byval lTuoi As Long, Byval sGioiTinh As String) As String
If (lTuoi >= 18) And (sGioiTinh = "Nam") Then
KiemTra = "Được phép lấy vợ"
ElseIf (lTuoi >= 18) And (sGioiTinh = "Nữ") Then
KiemTra = "Được phép lấy vợ"
Else
KiemTra = "Không được phép lập gia đình"
End If
End Function
Vẫn ví dụ trên, chỉ cần tuổi >=18 còn giới tính Nam hoặc Nữ thì trả lời "Được phép lập gia đình", trường hợp khác trả lời "Không được phép lập gia đình"
Mã:
Function KiemTra(Byval lTuoi As Long, Byval sGioiTinh As String) As String
If (lTuoi >= 18) And ((sGioiTinh = "Nam") Or (sGioiTinh = "Nữ")) Then
KiemTra = "Được phép lập gia đình"
Else
KiemTra = "Không được phép lập gia đình"
End If
End Function
Qua ví dụ trên chúng ta phát triển biểu thức logic phức tạp hơn. Chúng ta chú ý tới ngoặc mở "(" và ngoặc đóng ")" cho mỗi biểu thức logic.
btlogic (lTuoi >= 18) được so sánh và/And với cả btlogic ((sGioiTinh = "Nam") Or (sGioiTinh = "Nữ"))
btlogic ((sGioiTinh = "Nam") Or (sGioiTinh = "Nữ")) trả về đúng nếu ít nhất một cặp logic trong đó đúng, bằng sai khi tất cả các cặp logic trong đó sai--->Giống hàm OR trong Excel.
VB (Visual Basic) thực hiện việc tính toán từ trái sang phải, trong ngoặc trước ngoài ngoặc sau. Có nghĩa là:
(lTuoi >= 18) được duyệt đầu tiên sau đó mới duyệt đến ((sGioiTinh = "Nam") Or (sGioiTinh = "Nữ")) ,
Trong ((sGioiTinh = "Nam") Or (sGioiTinh = "Nữ")) nó lại duyệt (sGioiTinh = "Nam") rồi mới đến (sGioiTinh = "Nữ")
Chúng ta cần am hiểu điều này thật sâu sắc để sau này xây dựng những biểu thức logic phức tạp hơn nhiều, cần biết cái gì được tính trước và cái gì thì sau trong VB.
Nói về kết hợp Or - Hoặc
btLogic ((sGioiTinh = "Nam") Or (sGioiTinh = "Nữ")) trả về đúng khi ít nhất một btLogic trong đó đúng. Có nghĩa là khi VB duyệt (sGioiTinh = "Nam") mà là đúng thì thôi không duyệt btLogic (sGioiTinh = "Nữ") nữa vì kết quả biểu thức này chắc chắn là đúng cho dù các btLogic đứng sau đó kết quả là gì chăng nữa. Nhưng VB vẫn tính tất cả-->Đây là điều rất dở của ngôn ngữ VB vì không đảm bảo tính tối ưu trong tính toán, suy diễn, phải tính hết lẽ ra chỉ phải tính 1==>Tốc độ ứng dụng chạy chậm!
Viết lệnh If sao cho máy tính giảm công việc tính toán ==> Tối ưu tính toán ==> Tốc độ ứng dụng nhanh!
Ví dụ 4: Hàm đọc số thành chữ, từ 1->9 Cách 1:
Mã:
Function SoThanhChu(Byval lSo1_9 As Long) As String
SoThanhChu = "Không biết"
If (lSo1_9 = 1) Then SoThanhChu = "Một"
If (lSo1_9 = 2) Then SoThanhChu = "Hai"
If (lSo1_9 = 3) Then SoThanhChu = "Ba"
If (lSo1_9 = 4) Then SoThanhChu = "Bốn"
If (lSo1_9 = 5) Then SoThanhChu = "Năm"
If (lSo1_9 = 6) Then SoThanhChu = "Sáu"
If (lSo1_9 = 7) Then SoThanhChu = "Bảy"
If (lSo1_9 = 8) Then SoThanhChu = "Tám"
If (lSo1_9 = 9) Then SoThanhChu = "Chín"
End Function
Tôi nhắc lại là nếu lệnh If được viết trên cùng một dòng thì không cần End If
Nhận xét cách 1:
Khi thoả mãn một btLogic và nhận giá trị thì VB lại xuống dòng tiếp theo để duyệt và tính tiếp, số lần tính toán là 10 lần! Lẽ ra nó chỉnh phải tính 1 lần rồi thoát!
Vậy cách 1 không tốt ==>KHÔNG ĐƯỢC DÙNG IF KIỂU NÀY!!!
Cách 2:
Mã:
Function SoThanhChu(Byval lSo1_9 As Long) As String
If (lSo1_9 = 1) Then
SoThanhChu = "Một"
ElseIf (lSo1_9 = 2) Then
SoThanhChu = "Hai"
ElseIf (lSo1_9 = 3) Then
SoThanhChu = "Ba"
ElseIf (lSo1_9 = 4) Then
SoThanhChu = "Bốn"
ElseIf (lSo1_9 = 5) Then
SoThanhChu = "Năm"
ElseIf (lSo1_9 = 6) Then
SoThanhChu = "Sáu"
ElseIf (lSo1_9 = 7) Then
SoThanhChu = "Bảy"
ElseIf (lSo1_9 = 8) Then
SoThanhChu = "Tám"
ElseIf (lSo1_9 = 9) Then
SoThanhChu = "Chín"
Else
SoThanhChu = "Không biết"
End If
End Function
Nhận xét cách 2:
Khi thoả mãn một btLogic và nhận giá trị thì thoát khỏi hàm mà không duyệt và tính tiếp các logic đúng sau nó. Như vậy số phép tính có thể là từ 1->10, nếu thoả mãn ở dòng thứ 1 thì số phép tính là 1, nếu thoả mãn ở dòng thứ 4 thì số phép tính là 4, ....Như vậy số phép tính và VB phải tính phụ thuốc vào số các btLogic đứng trước không thoả mãn! NÊN DÙNG CÁCH 2 HƠN CÁCH 1!!! (cách 1 dù thế nào cũng phải mất 10 phép tính)
Cách 3:
Mã:
Function SoThanhChu(Byval lSo1_9 As Long) As String
If (lSo1_9 < 1) Or (lSo1_9 > 9) Then '//Ngoài khoảng
SoThanhChu = "Không biết"
ElseIf (lSo1_9 = 1) Then
SoThanhChu = "Một"
ElseIf (lSo1_9 = 2) Then
SoThanhChu = "Hai"
ElseIf (lSo1_9 = 3) Then
SoThanhChu = "Ba"
ElseIf (lSo1_9 = 4) Then
SoThanhChu = "Bốn"
ElseIf (lSo1_9 = 5) Then
SoThanhChu = "Năm"
ElseIf (lSo1_9 = 6) Then
SoThanhChu = "Sáu"
ElseIf (lSo1_9 = 7) Then
SoThanhChu = "Bảy"
ElseIf (lSo1_9 = 8) Then
SoThanhChu = "Tám"
ElseIf (lSo1_9 = 9) Then
SoThanhChu = "Chín"
End If
End Function
Nhận xét cách 3:
Khi điều kiện không thoả mãn (lSo1_9 ngoài khoảng xét) thì thoát khỏi hàm và không duyệt phép tính nào nữa, số phép tính là 1. Cũng là trường hợp không thoả mãn này mà ở cách 2 thì số phép tính 10. Vậy NÊN DÙNG CÁCH 3 HƠN CÁCH 2!!!
Như vậy chúng ta đã biết, để tối ưu trong tính toán ta nên dùng cách 3.
Trong một ứng dụng tổng hợp, chúng ta có rất nhiều phép tính, với sự am hiểu hãy tối ưu nó để tiết kiệm năng lực của máy và tăng tốc độ ứng dụng.
Còn một số vấn đề khác liên quan tới hàm If cũng như xây dựng biểu thức logic với phép so sánh: Not, Like, Is tôi sẽ phân tích sau. Nội dung chỉ nằm trong phạm vi đã được học của lớp VBA căn bản, các vấn để nâng cao hơn sẽ trình bày ở các bài học sau này.
Nhân bài giảng về cấu trúc If của lớp VBA căn bản tại Hà Nội, tôi viết bài phân tính cấu trúc cũng như cách ứng dụng nó để chúng ta hiểu sâu sắc về nó cũng như ứng dụng trong các trường hợp được linh hoạt, đảm bảo tính tối ưu.
Ở lớp VBA này, tôi muốn hướng dẫn các bạn để có kiến thức nền tảng về ngôn ngữ VB từ đó chúng ta tự nâng cao kiến thức sau này.
Cảm ơn các thành viên đã cùng chia sẻ kinh nghiệm!
Đây là ví dụ bài tập mà buổi học tối qua thầy giáo cho. Mình đã làm và giờ mình post lên để mọi người tham khảo nha!
Mã:
Function TinhThuong(ByVal sChucVu As String, lNgayCong As Long, sGiaDinh As String) As String
If (sChucVu = "GD") And (lNgayCong >= 20) And (sGiaDinh = "Co") Then
TinhThuong = "Xe may Attila"
ElseIf (sChucVu = "PGD") And (lNgayCong >= 20) And (sGiaDinh = "Co") Then
TinhThuong = "Xe may Jupiter"
ElseIf (sChucVu = "TP") And (lNgayCong >= 20) And (sGiaDinh = "Co") Then
TinhThuong = "Xe may Wave anpha"
ElseIf (sChucVu = "NV") And (lNgayCong >= 20) And (sGiaDinh = "Co") Then
TinhThuong = "Bo hoa tuoi"
Else
TinhThuong = "That dang tiec!"
End If
End Function
Mới học viết được như vậy là khá đấy Ngọc à. Qua hàm Ngọc viết, tôi có nhận xét thế này.
+ Về cách đặt tên tham số đúng quy ước ==>Tốt.
+ Về định dạng code đúng theo quy ước ==> Tốt.
+ Trình bày cấu trúc If đúng ==> Tốt.
+ Khai báo kiểu giá trị, tham số sGiaDinh As String nên là bGiaDinh As Boolean vì tham số này chỉ nhận 1 trong hai giá trị True, False mà thôi.
+ Khai báo tham số thiếu Byval ==> Không chuẩn. "Làm gì đều cần có lý do" .
Qua bài phân tích hàm If của tôi ở trên, Ngọc và các bạn khác hãy chỉnh lại cho tối ưu hơn?
Qua đây để nói thêm đây chỉ là bài học VBA căn bản ở lớp của Hà Nội vì vậy các cao thủ không nên đưa ra các ví dụ rút gọn cao siêu dễ dẫn đến " Rối loạn tiêu hoá"