Những câu hỏi về code, xin giải thích các code, đề nghị các bạn gửi vào đây

Liên hệ QC
Status
Không mở trả lời sau này.

ST-Lu!

Love Wingchun
Tham gia
19/8/08
Bài viết
730
Được thích
546
Nghề nghiệp
Xích lô một thời
Kể từ hôm nay, tất cả những câu hỏi nhờ giải thích dùm một đoạn code, hay là hỏi những vấn đề linh tinh gì liên quan đến cách viết code, đề nghị các bạn gửi chung vào đây.

Những đề tài mới với tiêu đề: "Nhờ giải thích dùm đoạn code", mà không nói rõ là code gì, code dùng để làm gì, sẽ bị xóa.

BQT

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


Em xin được hỏi 2 đoạn code sau có tương đương nhau ?

Cells(Cells.Rows.Count, 1).End(xlUp).Row có tương đương với [A65000].End(xlup).row

Cám ơn các anh chỉ giáo
 
Chỉnh sửa lần cuối bởi điều hành viên:
True / False

Cái này là quy định của Micorsoft thôi... chắc chắn phải có nguyên nhân, nhưng là nguyên nhân gì thì mọi người vẫn... đang bàn...

Hằng logic False luôn có giá trị 0 ở tất cả các ngôn ngữ lập trình (chưa thấy ở đâu quy định khác). Riêng hằng True được quy định là <> 0, tuy nhiên nó mang giá trị 1 hay -1 là do tính thứ tự của các giá trị True, False khi khai báo kiểu Enum. Trong VB (và VBA), 2 giá trị này có thứ tự là (TRUE, FALSE), do đó true < false, từ đó VB quy định True có giá trị là -1. Trong Excel thì tính có thứ tự của cặp T, F không mang ý nghĩa đặc biệt, và vì Excel đã quy định thứ tự (False, True) từ trước khi có macro cho nên đến giờ nó không thể thay đổi được.


Ngoài ra, trong VBA và Excel còn có sự khác nhau quan trọng giữa hàm làm tròn ROUND.

Round trong (E) đơn thuần làm tròn đến chữ số thập phân theo nguyên tắc >=5 và <5. Nhưng trong VBA, hàm Round làm tròn theo uy ước phân bố thống kê. Chúng ta thấy rằng, từ 0 đến 10 có 11 giá trị, khi đó 5 đứng giữa của khoảng, khi làm tròn nguyên, các giá trị 1.5, 3.5, 5.5, 7.5, 9.5 sẽ được làm tròn len 2, 4, 6, 8, 10. Nhưng các giá trị 0.5, 2.5, 4.5, 6.5, 8.5 sẽ được làm tròn xuống 0, 2, 4, 6, 8 để tạo sự phân bố đều ra 2 phía của khoảng (0..10).

Từ đó, khi dùng hàm làm tròn Round trong VBA để xử lý kết quả trong (E) thì nên dùng hàm sẵn có của (E) thay cho hàm Round của VBA:

WorksheetFunction.Round(...)
 
Upvote 0
Em dùng code còn phát hiện 1 lỗi nữa. Đó là lúc AutoFilter bằng code thì có 1 trường hợp như sau:
Nếu định dạng trong Windows là "d/m/yyyy" và tất nhiên trong Excel vẫn hiểu định dạng này (tức là 31/12/2007 vẫn nằm bên phải, và hàm Month vẫn cho kết quả là 12).
Nhưng nếu ngày nhỏ hơn 12 (1,2,3,...,12) thì khi qua dòng lệnh:
PHP:
Sheet2.Range("B1:M" & HC).AutoFilter Field:=2, Criteria1:=">=" & [G5], Operator:=xlAnd, Criteria2:="<=" & [I5]
Với: [G5]=1/12/2007 và [I5]=10/12/2007
Thì xem lại trong Sheet2 không có dữ liệu. Mặt dù biết rằng vẫn có vùng thời gian này.
Xét đến tận cùng thì phát hiện trong Custom (AutoFilter) nó báo rằng 12/1/2007, 12/10/2007.
Vậy xin hỏi làm sao để có được 1/12/200710/12/2007.
Mọi người có thể tự làm thử. Điều này hình như là luôn đúng nữa rồi.
Thân.
Đây không phải là lỗi đâu Po_Pi ạ. Định dạng ngày tháng trong system không hề ảnh hưởng gì đến VBA. Trong VBA nếu làm việc với kiểu dữ liệu Ngày/Tháng thì nên dùng hàm Date******, còn nếu là kiểu chuỗi thì phải theo định dạng "Tháng/Ngày/Năm" hoặc "Năm/Tháng/Ngày". Tôi vẫn thích dùng theo định dạng "Năm/Tháng/Ngày" hơn.
 
Upvote 0
Em dùng code còn phát hiện 1 lỗi nữa. Đó là lúc AutoFilter bằng code thì có 1 trường hợp như sau:
Nếu định dạng trong Windows là "d/m/yyyy" và tất nhiên trong Excel vẫn hiểu định dạng này (tức là 31/12/2007 vẫn nằm bên phải, và hàm Month vẫn cho kết quả là 12).
Nhưng nếu ngày nhỏ hơn 12 (1,2,3,...,12) thì khi qua dòng lệnh:
PHP:
Sheet2.Range("B1:M" & HC).AutoFilter Field:=2, Criteria1:=">=" & [G5], Operator:=xlAnd, Criteria2:="<=" & [I5]
Với: [G5]=1/12/2007 và [I5]=10/12/2007
Thì xem lại trong Sheet2 không có dữ liệu. Mặt dù biết rằng vẫn có vùng thời gian này.
Xét đến tận cùng thì phát hiện trong Custom (AutoFilter) nó báo rằng 12/1/2007, 12/10/2007.
Vậy xin hỏi làm sao để có được 1/12/200710/12/2007.
Mọi người có thể tự làm thử. Điều này hình như là luôn đúng nữa rồi.
Thân.
Thử sửa lại điều kiện thành:
Criteria1:=">=" & Format([G5], "#")

Criteria2:="<=" & Format([I5], "#")
xem thế nào!
Hoặc:
Criteria1:=">=" & CDbl([G5])
và:
Criteria2:="<=" & CDbl([I5])
 
Lần chỉnh sửa cuối:
Upvote 0
Vâng, em làm được rồi! Cảm ơn hai bác nha.
Thân.
 
Upvote 0
Nhờ các bác viết hộ bài toán đơn giản như sau:
Nếu tại ô H1="Delete" thì xóa toàn bộ dòng đó luôn, áp dụng cho toàn bộ cột H.

Thanks các bác!
 
Upvote 0
Bạn nhấn phải chuột vào tên Sheet -> chọn View Code -> Rồi nạp đoạn code dưới vào trang trắng hiện ra. Rồi bạn thử gõ Delete ở 1 ô nào đó trên cột H xem.
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
On Error Resume Next
If Target.Column = 8 And Target = "Delete" Then
Target.EntireRow.ClearContents
End If
End Sub
Thân.
 
Upvote 0
Nếu chọn đúng ô có chữ "Delete" thì nó sẽ xóa luôn ô đó và không có gì thay đổi. Nhưng khi Ctrl+Z lại lệnh vừa rồi thì nó lại xóa cả dòng luôn. Còn nếu chọn ô nào khác thì không có gì thay đổi cả.
 
Upvote 0
Vậy thực ra bác muốn như thế nào chứ? Bác toàn viết hiện trạng ra không thì làm sao giải quyết được?
Và yêu cầu cuối là nên đưa file đó lên đi?
Việc xóa dòng đâu nhất thiết phải gõ Delete như vậy? Vì dùng chuột chọn 1 dòng rồi nhấn Delete chẳng phải nhanh hơn không?
Thân.
 
Upvote 0
Mình gửi file đính kèm nhé! Mình muốn xóa bỏ tất cả những dòng bôi hồng đi và sẽ căn cứ theo cột H để xóa (gần như là xóa tiêu đề của mỗi bảng đi vậy). Mình dùng phần mềm để trộn rất nhiều file vào một file vì vậy sẽ có Form rất giống nhau. Nếu mình phải tìm từng dòng một để xóa thì lâu nắm. Bác giữ lại dòng đầu nhé!

Thanks!
 

File đính kèm

  • Book1.xls
    14 KB · Đọc: 8
Upvote 0
Vậy thì dùng code này đi. Đơn giản là xóa dữ liệu của các dòng đó đi hết là xong chứ gì?
PHP:
Sub xoa()
For i = [H65000].End(xlUp).Row To 1 Step -1
If Cells(i, 8) = "Delete" Then
Rows(i).ClearContents
End If
Next
End Sub
Thân.
 

File đính kèm

  • Book1.xls
    22 KB · Đọc: 15
Upvote 0
Hi, không phải là xóa dữ liệu mà là xóa cả dòng đó đi luôn. Nhưng bác nhớ để lại dòng đầu tiên lại nhé!
 
Upvote 0
Vầy thì chỉnh lại như vầy ha!
PHP:
Sub xoa()
For i = [H65000].End(xlUp).Row To 2 Step -1
If Cells(i, 8) = "Delete" Then
Rows(i).EntireRow.Delete
End If
Next
End Sub
Thân.
 
Upvote 0
PHP:
Sub xoa()
For i = [H65000].End(xlUp).Row To 2 Step -1
If Cells(i, 8) = "Delete" Then
Rows(i).EntireRow.Delete
End If
Next
End Sub
Macro này còn có thể tăng tốc bằng các cách sau:
* Không cho lay động màn hình; (Phụ :-=)
* Dùng phương thức tìm kiếm, dấu hiệu tìm là từ 'Delete' nêu trên, phạm vi tìm là cột 'H'
Tìm thấy thì gôm vô biến đã khai báo, sau giai đoạn tìm chỉ xóa 1 lần. Riêng chuyện gôm vô rồi xóa 1 lần cũng nhanh hơn là xóa từng hàng như macro trên. (--=0 Chính)
 
Upvote 0
Muốn ngắn hả? Như vầy có ngắn không?
PHP:
Sub xoa()
Range("H1:H" & [H65000].End(xlUp).Row).AutoFilter 1, "Delete"
Range("H2:H" & [H65000].End(xlUp).Row).SpecialCells(12).EntireRow.Delete
End Sub
Thân.
 
Upvote 0
Muốn ngắn hả? Như vầy có ngắn không?
PHP:
Sub xoa()
Range("H1:H" & [H65000].End(xlUp).Row).AutoFilter 1, "Delete"
Range("H2:H" & [H65000].End(xlUp).Row).SpecialCells(12).EntireRow.Delete
End Sub
Thân.
Ngắn hơn nữa:
PHP:
Sub Test()
 Range([H1], [H65536].End(xlUp)).AutoFilter 1, "Delete"
 Range([H1], [H65536].End(xlUp)).SpecialCells(12).EntireRow.Delete
End Sub
Thật ra dùng AutoFilter cho trường hợp này sẽ cho tốc độ rất nhanh ---> Có điều tôi thao tác bằng tay cũng được, cần gì code nhỉ
Này nhé:
- Chọn cell H1, bấm Ctrl + Shift + mũi tên xuống
- Vào menu Data\Filter\AutoFilter
- Bấm mũi tên xổ xuống, chọn chử Delete
- Click phải vào vùng vừa Filter, chọn Delete Row --> OK
Vậy là xong!
Ẹc.. Ẹc...
 
Lần chỉnh sửa cuối:
Upvote 0
Bác test code chưa vậy? Em nghĩ chắc là chưa rồi! hi hihihi
Vì nó xóa luôn dòng đầu tiên mất rồi!
PHP:
Sub Test()
 Range([H1], [H65536].End(xlUp)).AutoFilter 1, "Delete"
 Range([H1], [H65536].End(xlUp)).SpecialCells(12).EntireRow.Delete
End Sub
Sữa lại thành:
PHP:
Sub Test()
 Range([H1], [H65536].End(xlUp)).AutoFilter 1, "Delete"
 Range([H2], [H65536].End(xlUp)).SpecialCells(12).EntireRow.Delete
End Sub
Thân.
 
Upvote 0
Bác test code chưa vậy? Em nghĩ chắc là chưa rồi! hi hihihi
Vì nó xóa luôn dòng đầu tiên mất rồi!
PHP:
Sub Test()
 Range([H1], [H65536].End(xlUp)).AutoFilter 1, "Delete"
 Range([H1], [H65536].End(xlUp)).SpecialCells(12).EntireRow.Delete
End Sub
Sữa lại thành:
PHP:
Sub Test()
 Range([H1], [H65536].End(xlUp)).AutoFilter 1, "Delete"
 Range([H2], [H65536].End(xlUp)).SpecialCells(12).EntireRow.Delete
End Sub
Thân.
Thì dòng đầu cũng có chử Delete ---> Xóa luôn đi chứ để làm gì ---> Nếu H1 không phải là chử Delete thì tính tiếp...
Ẹc...Ẹc...
Ý tôi không phải nói về code (vì lòng vòng vẩn là AutoFilter) ---> Mà tôi muốn nói yêu cầu này quá dể dàng để thao tác bằng tay ---> KHÔNG CẦN CODE
 
Upvote 0
Thì dòng đầu cũng có chử Delete ---> Xóa luôn đi chứ để làm gì ---> Nếu H1 không phải là chử Delete thì tính tiếp...
Ẹc...Ẹc...
Ý tôi không phải nói về code (vì lòng vòng vẩn là AutoFilter) ---> Mà tôi muốn nói yêu cầu này quá dể dàng để thao tác bằng tay ---> KHÔNG CẦN CODE

Theo em nếu là để học code thì ok, nhưng nếu là để phục vụ công việc thì cứ theo nguyên tắc "thơm, ngon, bổ, rẻ" --> sao cho vừa nhanh vừa tiện thôi.
Thực ra làm bằng tay cũng được mà
 
Upvote 0
Xin hỏi trong cửa sổ VBA (Alt+F11) có chế độ nào tự động mở không. Không hiểu sao mỗi lần mở máy (sau khi đã khóa máy) thì cửa sổ của VBA luôn luôn hiên lên mặc dù trước đó không hề mở. Có cách nào để bỏ nó đi không các bác?? (nghĩa là cửa sổ VBA không tự động mở mỗi lần mở máy nữa)
 
Upvote 0
Status
Không mở trả lời sau này.
Web KT
Back
Top Bottom