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]
Em mới tập tành VBA nên không biết xử lý vấn đề này sao. Các anh, chị biết xử lý giúp e nha. E nghiên cứu mãi mà không được. Các anh, chị chỉnh sửa dùm e nha.
Em mới tập tành VBA nên không biết xử lý vấn đề này sao. Các anh, chị biết xử lý giúp e nha. E nghiên cứu mãi mà không được. Các anh, chị chỉnh sửa dùm e nha. Cám ơn các anh, chị nhiều.
Qui tắc so sánh chuỗi cùng chiều dài:
So sánh ký tự 1. Nếu không bằng nhau thì kết thúc và chuỗi có ký tự nhỏ hơn thì nhỏ hơn. Nếu bằng nhau thì so sánh ký tự 2. Tương tự nếu không bằng nhau thì kết thúc và chuỗi có ký tự nhỏ hơn thì nhỏ hơn. Nếu bằng nhau thì so sánh ký tự 3 v...v Nếu tất cả các ký tự bằng nhau thì 2 chuỗi bằng nhau.
Với qui tắc trên thì khi so sánh chuỗi "01/11/2019" và "06/10/2019" thì ở ký tự 2 ta có 1 < 6, vậy chuỗi "01/11/2019" < chuỗi "06/10/2019". Tức điều kiện cho IF thỏa và dòng 38 (STT = 37) được thêm vào ListBox. Tương tự với STT = 38-41, 67-71.
Cách khắc phục:
1. So sánh số.
Ngày tháng trong Excel là số nên so sánh số thôi. Tại sao phải biến thành chuỗi rồi so sánh chuỗi?
Mã:
Private Sub UserForm_Activate()
...
Dim AsOFDate As Long, AsOfWeek As Long, MaxARRow As Long, MaxARColumn As Long, ListQuaHanRow As Long, ListDenHanRow As Long
AsOFDate = Date
AsOfWeek = Date + 7
' ...
For i = 2 To MaxARRow
If Cells(i, 5) < AsOFDate Then
' ...
End If
Next i
...
For j = 2 To MaxARRow
If Cells(j, 5) >= AsOFDate And Cells(j, 5) <= AsOfWeek Then
' ...
End If
Next j
End Sub
2. So sánh chuỗi (không khuyến cáo). Nếu thế thì dùng dạng "yyy/mm/dd". Dùng dạng này thì đúng.
Với vd. ở trên thì:
Format(Cells(i, 5), "dd/mm/yyyy") = "2019/11/01"
AsOFDate = "2019/10/06".
Và khi so sánh thì có "2019/11/01" > "2019/10/06" (so sánh kết thúc ở ký tự 7: 1 > 0)
Do vậy điều kiện không thỏa và dòng 38 (STT = 37) không được thêm vào ListBox
Mã:
Private Sub UserForm_Activate()
' ...
Dim AsOFDate As String, AsOfWeek As String, MaxARRow As Long, MaxARColumn As Long, ListQuaHanRow As Long, ListDenHanRow As Long
AsOFDate = Format(Now(), "yyyy/mm/dd")
AsOfWeek = Format(Now() + 7, "yyyy/mm/dd")
' ...
For i = 2 To MaxARRow
If Format(Cells(i, 5), "yyyy/mm/dd") < AsOFDate Then
' ...
End If
Next i
...
For j = 2 To MaxARRow
If Format(Cells(j, 5), "yyyy/mm/dd") >= AsOFDate And Format(Cells(j, 5), "yyyy/mm/dd") <= AsOfWeek Then
' ...
End If
Next j
End Sub
Qui tắc so sánh chuỗi cùng chiều dài:
So sánh ký tự 1. Nếu không bằng nhau thì kết thúc và chuỗi có ký tự nhỏ hơn thì nhỏ hơn. Nếu bằng nhau thì so sánh ký tự 2. Tương tự nếu không bằng nhau thì kết thúc và chuỗi có ký tự nhỏ hơn thì nhỏ hơn. Nếu bằng nhau thì so sánh ký tự 3 v...v Nếu tất cả các ký tự bằng nhau thì 2 chuỗi bằng nhau.
Với qui tắc trên thì khi so sánh chuỗi "01/11/2019" và "06/10/2019" thì ở ký tự 2 ta có 1 < 6, vậy chuỗi "01/11/2019" < chuỗi "06/10/2019". Tức điều kiện cho IF thỏa và dòng 38 (STT = 37) được thêm vào ListBox. Tương tự với STT = 38-41, 67-71.
Cách khắc phục:
1. So sánh số.
Ngày tháng trong Excel là số nên so sánh số thôi. Tại sao phải biến thành chuỗi rồi so sánh chuỗi?
Mã:
Private Sub UserForm_Activate()
...
Dim AsOFDate As Long, AsOfWeek As Long, MaxARRow As Long, MaxARColumn As Long, ListQuaHanRow As Long, ListDenHanRow As Long
AsOFDate = Date
AsOfWeek = Date + 7
' ...
For i = 2 To MaxARRow
If Cells(i, 5) < AsOFDate Then
' ...
End If
Next i
...
For j = 2 To MaxARRow
If Cells(j, 5) >= AsOFDate And Cells(j, 5) <= AsOfWeek Then
' ...
End If
Next j
End Sub
2. So sánh chuỗi (không khuyến cáo). Nếu thế thì dùng dạng "yyy/mm/dd". Dùng dạng này thì đúng.
Với vd. ở trên thì:
Format(Cells(i, 5), "dd/mm/yyyy") = "2019/11/01"
AsOFDate = "2019/10/06".
Và khi so sánh thì có "2019/11/01" > "2019/10/06" (so sánh kết thúc ở ký tự 7: 1 > 0)
Do vậy điều kiện không thỏa và dòng 38 (STT = 37) không được thêm vào ListBox
Mã:
Private Sub UserForm_Activate()
' ...
Dim AsOFDate As String, AsOfWeek As String, MaxARRow As Long, MaxARColumn As Long, ListQuaHanRow As Long, ListDenHanRow As Long
AsOFDate = Format(Now(), "yyyy/mm/dd")
AsOfWeek = Format(Now() + 7, "yyyy/mm/dd")
' ...
For i = 2 To MaxARRow
If Format(Cells(i, 5), "yyyy/mm/dd") < AsOFDate Then
' ...
End If
Next i
...
For j = 2 To MaxARRow
If Format(Cells(j, 5), "yyyy/mm/dd") >= AsOFDate And Format(Cells(j, 5), "yyyy/mm/dd") <= AsOfWeek Then
' ...
End If
Next j
End Sub
Tức dữ liệu cho Cells(i, 5) được thêm vào ListBox. Nhưng rõ ràng là ngày "6 tháng 1 năm 2020" là trong tương lai nên chưa hoàn thành vậy không thể thêm vào ListBox.
Nếu đã so sánh chuỗi thì phải tạo nó theo dạng "năm/tháng/ngày"
Tức dữ liệu cho Cells(i, 5) được thêm vào ListBox. Nhưng rõ ràng là ngày "6 tháng 1 năm 2020" là trong tương lai nên chưa hoàn thành vậy không thể thêm vào ListBox.
Nếu đã so sánh chuỗi thì phải tạo nó theo dạng "năm/tháng/ngày"
Bài đã được tự động gộp:
Chắc chắn chứ? Bạn thử thay E2 = "ngày 6 tháng 1 năm 2020" xem. Lúc đó dòng 2 được nhập vào ListBox trong khi ngày E2 là trong tương lai.
Tại sao khi mở file (file đã lưu vào thư mục) thì có file hỏi "Enable Macro", có file thì không hỏi?
Em đang sử dụng Win 7 và Office 2010
Em cũng đã vào Trust Center để kiểm tra nhưng không thấy sự khác biệt
Nhờ anh/chị giải thích. Em cảm ơn.
Private Sub lb_dulieu_Click()
With Me
If .lb_dulieu.ListIndex >= 0 Then _
.txt_sanpham_2.Value = .lb_dulieu.List(lb_dulieu.ListIndex, 1)
....
.txt_sotien_2.Value = .lb_dulieu.List(lb_dulieu.ListIndex, 16)
End With
End Sub
Theo lôgíc thì tất cả các dòng chứ không chỉ dòng đầu tiên đều phải nằm trong IF ... END IF.
Tức bỏ ký tự "_" sau Then và thêm "End If" trước "End With"
------
Vùng dữ liệu nguồn cho lb_dulieu được bạn thiết lập là data_sp (lb_dulieu.RowSource = data_sp).
tới cuối thì do các textbox không chứa các hậu tố " mới" mà chỉ chứa các giá trị y như trên sheet nên hiển nhiên là các giá trị trên sheet được thay bằng chính chúng nên không thể có hậu tố " mới" được.
Nếu có nhu cầu chỉnh sửa trên sheet thì không được phép chỉnh sửa trong vùng RowSource của ListBox. Nếu cần chỉnh sửa trong một vùng mà vùng đó đồng thời là dữ liệu nguồn cho ListBox thì phải cẩn thận khi dùng ListBox_Change và ListBox_Click. Nếu trong ListBox_Click code thay đổi giá trị của các textbox như của bạn, tức chúng được thay đổi - lấy từ vùng nguồn của ListBox, thì công lao chỉnh sửa các textbox trước đó đổ xuống sông xuống biển. Tôi hiểu là code Click phải thế để lấy các giá trị của dòng được chọn trong ListBox vào các textbox. Vậy thì phải từ bỏ dùng RowSource và dùng List để nhập dữ liệu vào ListBox.
Tóm lại:
0. Thêm End If vào lb_dulieu_Click
1. Xóa lb_dulieu.RowSource.
2. Thêm code vào Form
Mã:
Private Sub UserForm_Initialize()
lb_dulieu.List = Worksheets("SP").Range("data_sp").Value
End Sub
3. Đễ làm mới lb_dulieu sau khi ghi xuống sheet thì trong Sub btnchange_Click sau dòng End With thì thêm code
Private Sub lb_dulieu_Click()
With Me
If .lb_dulieu.ListIndex >= 0 Then _
.txt_sanpham_2.Value = .lb_dulieu.List(lb_dulieu.ListIndex, 1)
....
.txt_sotien_2.Value = .lb_dulieu.List(lb_dulieu.ListIndex, 16)
End With
End Sub
Theo lôgíc thì tất cả các dòng chứ không chỉ dòng đầu tiên đều phải nằm trong IF ... END IF.
Tức bỏ ký tự "_" sau Then và thêm "End If" trước "End With"
------
Vùng dữ liệu nguồn cho lb_dulieu được bạn thiết lập là data_sp (lb_dulieu.RowSource = data_sp).
tới cuối thì do các textbox không chứa các hậu tố " mới" mà chỉ chứa các giá trị y như trên sheet nên hiển nhiên là các giá trị trên sheet được thay bằng chính chúng nên không thể có hậu tố " mới" được.
Nếu có nhu cầu chỉnh sửa trên sheet thì không được phép chỉnh sửa trong vùng RowSource của ListBox. Nếu cần chỉnh sửa trong một vùng mà vùng đó đồng thời là dữ liệu nguồn cho ListBox thì phải cẩn thận khi dùng ListBox_Change và ListBox_Click. Nếu trong ListBox_Click code thay đổi giá trị của các textbox như của bạn, tức chúng được thay đổi - lấy từ vùng nguồn của ListBox, thì công lao chỉnh sửa các textbox trước đó đổ xuống sông xuống biển. Tôi hiểu là code Click phải thế để lấy các giá trị của dòng được chọn trong ListBox vào các textbox. Vậy thì phải từ bỏ dùng RowSource và dùng List để nhập dữ liệu vào ListBox.
Tóm lại:
0. Thêm End If vào lb_dulieu_Click
1. Xóa lb_dulieu.RowSource.
2. Thêm code vào Form
Mã:
Private Sub UserForm_Initialize()
lb_dulieu.List = Worksheets("SP").Range("data_sp").Value
End Sub
3. Đễ làm mới lb_dulieu sau khi ghi xuống sheet thì trong Sub btnchange_Click sau dòng End With thì thêm code
Các anh/ chị cho e hỏi, có cách nào chỉnh được như comment trong hình ko vậy anh/chị?
Em mới tập tành VBA nên cũng ko rõ lắm. Cám ơn anh/chị trước nhé.
Các anh/ chị cho e hỏi, có cách nào chỉnh được như comment trong hình ko vậy anh/chị?
Em mới tập tành VBA nên cũng ko rõ lắm. Cám ơn anh/chị trước nhé.
Mình nghĩ ra 2 cách bạn xem dùng được thì dùng:
Cách 1: Thay đổi công thức ở cột C thành: =+IF(-TODAY()+E2<0;"Hoàn thành";IF(-TODAY()+E2=0;"Đến hạn";"Còn "&E2-TODAY()&" ngày"));
Cách 2: thay đoạn code:
'Loc Phát Sinh Dén Han: '
...
Me.ListDenHan.List(ListDenHanRow, 2) = Cells(j, 3)
....
Thành code:
If Cells(j, 3) = ChrW(272) & ChrW(7871) & "n h" & ChrW(7841) & "n" Then
Me.ListDenHan.List(ListDenHanRow, 2) = Cells(j, 3)
Else: Me.ListDenHan.List(ListDenHanRow, 2) = "Còn " & Cells(j, 3) & "ngày"
End If
Bổ sung cách 3 ngắn và đơn giản nhất:
thay code:
'Loc Phát Sinh Dén Han: '
...
Me.ListDenHan.List(ListDenHanRow, 2) = Cells(j, 3)
....
Thành code:
'Loc Phát Sinh Dén Han: '
...
Me.ListDenHan.List(ListDenHanRow, 2) = Cells(j, 3).text
....