Bài tập VBA đơn giản dành cho người mới bắt đầu [Phần 2] (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

ChanhTQ@

0901452không62
Tham gia
5/9/08
Bài viết
4,254
Được thích
4,861
Xin các bạn có bài tập nào hay hay đăng lên để cùng nhau luyện cho mau tiến bộ nhe!
Mình xin mở màn bài đầu:
ĐỀ BÀI 1:

Tôi có bảng số liệu từ cột [A..E] như sau:

| A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W 2 |HoTen|Date1|Date2|Date3|Date4|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18
3 |Hồ Lễ|3|5|7|13|Do|Do|Do|Xh|Xh|Vg|Vg|Tm|Tm|Tm|Tm|Tm|Tm||.|||
4 |Đỗ Nè|4|8|13|15|Nu|Nu|Nu|Nu|Xh|Xh|Xh|Xh|Xm|Xm|Xm|Xm|Xm|Dn|Dn|||
5 |Vũ Xe|2|4|12|13|Do|Do|Vg|Vg|Nu|Nu|Nu|Nu|Nu|Nu|Nu|Nu|Hg|||.|||

Phần từ cột [F] trở đi là phần cần viết 1 macro để nó tô màu nền khác nhau theo những giá trị cùng dòng từ cột [B..E];
Màu tô do bạn tự chọn, cốt fân biệt giữa chúng & dịu mắt là được!


PHẦN TỔNG HỢP CÁC ĐỀ BÀI TẬP:

Tên|Tóm tắc|Bài thứ
Đề bài 1|Tô màu theo trị số các ô bên trái cùng dòng| #1
Đề bài 1A|Lọc theo các số cần thiết từ các chuỗi số| #73
Đề bài 1B|Xác định loại tam giác dựa trên 3 số ngẫu nhiên được tạo ra| #82
Đề bài 2|Lập danh sách học sinh theo từng lớp| #11
Đề bài 2A|Dịch ngôn ngữ VBA sang tiếng Việt| #19
BĐT(*)|Lập danh sách các nữ HS có ngày sinh trong 1 quí| #101
Đề bài 3|Thống kế kết quả điểm của từng lớp theo từng môn học| #22
Đề bài 4|Lập danh sách HS các lớp đạt điểm cực trị của từng môn| #46
Đề bài 4A|Tìm trong danh sách thí sinh, số báo danh nào có tổng điểm các môn cao nhất| #94
Đề bài 5|Thống kê từng khoảng điểm của môn học| #58
Đề bài 6|Thống kê điểm trung bình theo giới tính| #71

(*) BĐT: Bài đọc thêm

.
.
.
 
Lần chỉnh sửa cuối:
Nếu tôi là người đang học, tôi chỉ làm những bài tập nào mà người ra đề cho biết trước:

Làm xong bài này, người làm sẽ học thêm được những gì.
 
Upvote 0
[thongbao]Làm xong bài này, người làm sẽ học thêm được những gì.
[/thongbao]

Với bài tập này, chúng ta muốn hóa giải cần nhiều thời gian suy sét kỹ trước khi đặt bút viết thử các dòng lệnh.
 
Upvote 0
Xin các bạn có bài tập nào hay hay đăng lên để cùng nhau luyện cho mau tiến bộ nhe!
Mình xin mở màn bài đầu:
ĐỀ BÀI 1:

Tôi có bạn số liệu từ cột [A..E] như sau:

|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W
2|HoTen|Date1|Date2|Date3|Date4|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18
3|Hồ Lễ|3|5|7|13|Do|Do|Do|Xh|Xh|Vg|Vg|Tm|Tm|Tm|Tm|Tm|Tm||.|||
4|Đỗ Nè|4|8|13|15|Nu|Nu|Nu|Nu|Xh|Xh|Xh|Xh|Xm|Xm|Xm|Xm|Xm|Dn|Dn|||
5|Vũ Xe|2|4|12|13|Do|Do|Vg|Vg|Nu|Nu|Nu|Nu|Nu|Nu|Nu|Nu|Nu|||.|||

Phần từ cột [F] trở đi là phần cần viết 1 macro để nó tô màu nền khác nhau theo những giá trị cùng dòng từ cột [B..E];
Màu tô do bạn tự chọn, cốt fân biệt giữa chúng & dịu mắt là được!
Em làm thử trươc, nhờ bác kiểm tra và hướng dẫn thêm:
[gpecode=vb]
Sub ToMau()
Dim Rng As Range, iR As Integer, jC As Integer
Set Rng = Sheet1.Range("B3:E" & Sheet1.Range("B65535").End(xlUp).Row)
Rng.Offset(, 4).Resize(, 18).Interior.ColorIndex = 0
For iR = 1 To Rng.Rows.Count
For jC = 4 To 1 Step -1
Rng(iR, 5).Resize(, Rng(iR, jC)).Interior.ColorIndex = Sheet1.[Z1] - jC
Next jC
Next iR
End Sub
[/gpecode]
Với ô Z1 dùng để chọn màu cho đỡ chói.
 

File đính kèm

Upvote 0
Với ô Z1 dùng để chọn màu cho đỡ chói.

Thảo có thể xài dòng lệnh này:
PHP:
Rng(iR, 5).Resize(, Rng(iR, jC)).Interior.ColorIndex = 33 + Cells(iR + 2, jC + 1).Value

Thay vì fải thiết kế vùng bảng màu
 
Upvote 0
Thảo có thể xài dòng lệnh này:
PHP:
Rng(iR, 5).Resize(, Rng(iR, jC)).Interior.ColorIndex = 33 + Cells(iR + 2, jC + 1).Value

Thay vì fải thiết kế vùng bảng màu
"Tô màu nền khác nhau theo những giá trị cùng dòng từ cột [B..E]", vậy thì các dòng tô màu không đồng nhất phải không bác?
Và em chưa hiểu lắm mục đích của bác về các ký hiệu: Do, Dn, Xh, Xm, Tm, Nu, ... có phải là các màu đỏ, đen, xanh, xám, tím, nâu? Chắc là nằm trong bài tập 2 của bác đây?
 
Upvote 0
Xin các bạn có bài tập nào hay hay đăng lên để cùng nhau luyện cho mau tiến bộ nhe!
Mình xin mở màn bài đầu:
ĐỀ BÀI 1:

Tôi có bảng số liệu từ cột [A..E] như sau:

| A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W 2 |HoTen|Date1|Date2|Date3|Date4|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18
3 |Hồ Lễ|3|5|7|13|Do|Do|Do|Xh|Xh|Vg|Vg|Tm|Tm|Tm|Tm|Tm|Tm||.|||
4 |Đỗ Nè|4|8|13|15|Nu|Nu|Nu|Nu|Xh|Xh|Xh|Xh|Xm|Xm|Xm|Xm|Xm|Dn|Dn|||
5 |Vũ Xe|2|4|12|13|Do|Do|Vg|Vg|Nu|Nu|Nu|Nu|Nu|Nu|Nu|Nu|Hg|||.|||

Phần từ cột [F] trở đi là phần cần viết 1 macro để nó tô màu nền khác nhau theo những giá trị cùng dòng từ cột [B..E];
Màu tô do bạn tự chọn, cốt fân biệt giữa chúng & dịu mắt là được!
Bài này nằm trong Topic VBA, nhưng nếu không phải thì có thể dùng CF cũng được. Chọn F3:W5.
Công thức CF đầu tiên:
Mã:
=AND(COLUMN(F3)-5<=$E3,COLUMN(F3)-5>$D3)
Công thức CF thứ 2:
Mã:
=AND(COLUMN(F3)-5<=$D3,COLUMN(F3)-5>$C3)
Công thức CF thứ 3:
Mã:
=AND(COLUMN(F3)-5>$B3,COLUMN(F3)-5<=$C3)
 

File đính kèm

Upvote 0
Xin các bạn có bài tập nào hay hay đăng lên để cùng nhau luyện cho mau tiến bộ nhe!
Mình xin mở màn bài đầu:
ĐỀ BÀI 1:
..........................
Màu tô do bạn tự chọn, cốt fân biệt giữa chúng & dịu mắt là được!
Rất bổ ích, đúng là rất phù hợp với những người mới học VBA như em. Mong anh và các thành viên khác tiếp tục ra các bài tập tiếp theo. Nếu có ứng dụng vào công việc thực tế thì sẽ tốt hơn!
 
Upvote 0
Rất bổ ích, đúng là rất phù hợp với những người mới học VBA như em. Mong anh và các thành viên khác tiếp tục ra các bài tập tiếp theo. Nếu có ứng dụng vào công việc thực tế thì sẽ tốt hơn!
Đang hóng Đề Bài 2.
Có lẽ bác ChanhTQ@ xỉn từ tối qua tới giờ chưa dậy, kaka ...
 
Upvote 0
Bài 2

ĐỀ BÀI 2:

@$@!^%
Trong file là CSDL của khối lớp 12 của 1 trường học;
Người ta cần tạo ở ô [H2] danh sách các lớp để từ đó lựa ra 1 lớp (Ví dụ lớp 12A2)
Thì tại [B3] ta sẽ có dòng tiêu đề báo cáo:

"DANH SÁCH HỌC SINH CỦA LỚP 12A2."


& dưới dòng này có bảng báo cáo liệt kê danh sách của lớp đó với nội dung giống như sau:


5 |TT|SBD|HoTen|Nu|DanToc|Ngayinh
6 |1|3500210|Nguyễn Việt ..|1|Kinh|12/13/1993
7 |2|3500190|Vũ Phú ..||Kinh|1/19/1993
. ||3500900| ..||..|...


__--____--__
 
Lần chỉnh sửa cuối:
Upvote 0
ĐỀ BÀI 2:

@$@!^%
Trong file là CSDL của khối lớp 12 của 1 trường học;
Người ta cần tạo ở ô [H2] danh sách các lớp để từ đó lựa ra 1 lớp (Ví dụ lớp 12A2)
Thì tại [B3] ta sẽ có dòng tiêu đề báo cáo:

"DANH SÁCH HỌC SINH CỦA LỚP 12A2."


& dưới dòng này có bảng báo cáo liệt kê danh sách của lớp đó với nội dung giống như sau:


5 |TT|SBD|HoTen|Nu|DanToc|Ngayinh
6 |1|3500210|Nguyễn Việt ..|1|Kinh|12/13/1993
7 |2|3500190|Vũ Phú ..||Kinh|1/19/1993
. ||3500900| ..||..|...
Em xin nộp bài cách giải hơi Gà vì mình kết hợp ghi Macro. Mong các thành viên khác góp ý cho em.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
ĐỀ BÀI 2:

@$@!^%
Trong file là CSDL của khối lớp 12 của 1 trường học;
Người ta cần tạo ở ô [H2] danh sách các lớp để từ đó lựa ra 1 lớp (Ví dụ lớp 12A2)
Thì tại [B3] ta sẽ có dòng tiêu đề báo cáo:

"DANH SÁCH HỌC SINH CỦA LỚP 12A2."


& dưới dòng này có bảng báo cáo liệt kê danh sách của lớp đó với nội dung giống như sau:


5 |TT|SBD|HoTen|Nu|DanToc|Ngayinh
6 |1|3500210|Nguyễn Việt ..|1|Kinh|12/13/1993
7 |2|3500190|Vũ Phú ..||Kinh|1/19/1993
. ||3500900| ..||..|...
Làm thử bài này nộp sư phụ xem, module lấy duy nhất lớp sau đó đặt 1 cái tên và sử dụng data validation để đưa vào H2
module trích lọc dữ liệu từ sheet1 qua sheet 2
 

File đính kèm

Upvote 0
Em có một ý kiến nho nhỏ góp ý với anh ChanhTQ, đó là sau một thời gian nhất định nào đó, VD 1 tuần, 2 tuần...(tùy anh) sau khi đưa đề bài anh nên đưa đáp án của anh để bọn em học hỏi thêm với ạ. Hiện tại là bài tập 1 anh vẫn chưa cho đáp án. Chắc có lẽ mới có 1 lời giải của leonguyen nên anh chưa đưa đáp án ạ?
 
Upvote 0
Làm thử bài này nộp sư phụ xem, module lấy duy nhất lớp sau đó đặt 1 cái tên và sử dụng data validation để đưa vào H2
module trích lọc dữ liệu từ sheet1 qua sheet 2
Xem code anh Phi viết thì đâu còn giành cho người mới bắt đầu nữa. Thấy có cả dic và trong đó nữa, cái này chắc phải 1 thời gian dài nữa em mới ngấm được. Em chỉ làm bài này với công cụ của 1 người mới học VBA thôi!
To: ChanhTQ
+ Không thấy anh ChanhTQ nói rõ là lọc trực tiếp trên Sheet1 hay là đưa kết quả sang sheet khác nữa! Lần sau ra đề mong anh có kết quả minh họa bằng tay để cho bọn em đỡ phải đoán mò!
 
Upvote 0
Vài nhận xét macro ở #13

PHP:
Sub DinhDang(i As Long)
'DINH DANG  '
1    Sheet2.Select
    Range("A7:Z2000").Select
    Selection.Borders(xlDiagonalDown).LineStyle = xlNone
    Selection.Borders(xlDiagonalUp).LineStyle = xlNone
    Selection.Borders(xlEdgeLeft).LineStyle = xlNone
    Selection.Borders(xlEdgeTop).LineStyle = xlNone
    Selection.Borders(xlEdgeBottom).LineStyle = xlNone
    Selection.Borders(xlEdgeRight).LineStyle = xlNone
    Selection.Borders(xlInsideVertical).LineStyle = xlNone
    Selection.Borders(xlInsideHorizontal).LineStyle = xlNone
    
2   Range("A7:G" & i + 6).Select
   Selection.Borders(xlEdgeLeft).Weight = xlThin
   Selection.Borders(xlEdgeTop).Weight = xlThin
   Selection.Borders(xlEdgeBottom).Weight = xlThin
   Selection.Borders(xlEdgeRight).Weight = xlThin
   Selection.Borders(xlInsideVertical).Weight = xlThin
   Selection.Borders(xlInsideHorizontal).Weight = xlThin
 
End Sub

(*) Nên khai báo thêm 1 biến đếm & dùng 2 vòng lặp cho 2 vùng dòng lệnh sau số 1 & 2;

(*) Vùng chọn Range("A7:Z2000").Select
Là quá dư giả, có nghĩa là chưa tiết kiệm
Nếu là mình thì mình sẽ xem xét lại câu lệnh này: Sheet2.Range("A7:Z100000").ClearContents

Có thể thay bỡi câu lệnh xóa các dòng có chứa dữ liệu học sinh của lần chạy macro lần trước mà thôi.
(Nếu xóa dòng thì macro con DinhDang ta sẽ bớt đi 1 nữa động tác thừa);

Vài thiển í & chúc vui!




 
Upvote 0
[thongbao]+ Không thấy anh ChanhTQ nói rõ là lọc trực tiếp trên Sheet1 hay là đưa kết quả sang sheet khác nữa! Lần sau ra đề mong anh có kết quả minh họa bằng tay để cho bọn em đỡ phải đoán mò![/thongbao]

Đúng là đề bài chưa nói rõ chuyện này;
Nhưng có 1 cái gần như là nguyên tắc rằng đã là CSDL thì ta hết sức tránh thao tác trức tiếp trên nó!

Yêu cầu của đề bài là làm báo cáo thì ngầm định là báo cáo nên ở 1 trang khác.
 
Upvote 0
ĐỀ BÀI 2:@$@!^%
Trong file là CSDL của khối lớp 12 của 1 trường học;Người ta cần tạo ở ô [H2] danh sách các lớp để từ đó lựa ra 1 lớp (Ví dụ lớp 12A2)Thì tại [B3] ta sẽ có dòng tiêu đề báo cáo:"DANH SÁCH HỌC SINH CỦA LỚP 12A2."& dưới dòng này có bảng báo cáo liệt kê danh sách của lớp đó với nội dung giống như sau:
5 |TT|SBD|HoTen|Nu|DanToc|Ngayinh 6 |1|3500210|Nguyễn Việt ..|1|Kinh|12/13/1993 7 |2|3500190|Vũ Phú ..||Kinh|1/19/1993 . ||3500900| ..||..|...
Thấy các bạn làm bài mình tham gia tý . Hình như đề chỉ yêu cầu đến cột "Ngày sinh" thì phải . Chuột đúng là nhanh .
 

File đính kèm

Upvote 0
Bài tập 2A:

Đề bài:
(1) Bạn hãy dịch ngôn ngữ VBA này sang tiếng Việt:

PHP:
 'Tác Giả: Ngoai Thanh;581885'
Private Sub Worksheet_Change(ByVal Target As Range)
1 Application.ScreenUpdating = False
 If Intersect(Target, [H2]) Is Nothing Then Exit Sub
3 Me.UsedRange.Resize(, 8).Offset(5).Clear
 Sheet1.[A6:H2000].AdvancedFilter 2, [IV1:IV2], [A6]
5 Range("G5:H1000").Select
 Selection.Delete Shift:=xlToLeft
7 Range("B3") = "Danh sách h" & ChrW(7885) & "c sinh c" & ChrW(7911) & "a l" & ChrW(7899) & "p" & Range("H2").Value & "."
 Range("D1").Select
9 Application.ScreenUpdating = True
End Sub

(2) Dòng lệnh có số 7 có thể có cách nào khác mà vẫn đạt kết quả như vậy?
 
Upvote 0
Đề bài:
(1) Bạn hãy dịch ngôn ngữ VBA này sang tiếng Việt:

PHP:
 'Tác Giả: Ngoai Thanh;581885'
Private Sub Worksheet_Change(ByVal Target As Range)
1 Application.ScreenUpdating = False
 If Intersect(Target, [H2]) Is Nothing Then Exit Sub
3 Me.UsedRange.Resize(, 8).Offset(5).Clear
 Sheet1.[A6:H2000].AdvancedFilter 2, [IV1:IV2], [A6]
5 Range("G5:H1000").Select
 Selection.Delete Shift:=xlToLeft
7 Range("B3") = "Danh sách h" & ChrW(7885) & "c sinh c" & ChrW(7911) & "a l" & ChrW(7899) & "p" & Range("H2").Value & "."
 Range("D1").Select
9 Application.ScreenUpdating = True
End Sub

(2) Dòng lệnh có số 7 có thể có cách nào khác mà vẫn đạt kết quả như vậy?
Mong anh góp ý chút về lời giả của em!
 
Upvote 0
Những tham khảo liên quan đến đề bài tập 2A

Ở "Bài tập 2A", tại dòng lệnh 2 trong macro của tác giả “Ngoai Thanh” ta thấy có dòng lệnh
PHP:
If Intersect(Target, [H2]) Is Nothing Then Exit Sub
Điều đầu tiên ta hiểu nôm na với nhau rằng Intersect() là 1 fương thức dùng để kiểm tra sự giao nhau giữa các vùng ô; Mà cụ thể ở đây là Target & ô [H2]
Trong sự kiện Worksheet_Change thì “Target” là ô hay vùng ô mà ta vừa tác động đến nó;
Bạn nào muốn nghiên cứu sâu về fương thức này, mình xin mời lại đây:
http://www.giaiphapexcel.com/forum/showthread.php?40179-Hỏi-về-Phương-thức-Intersect

(Bài của NDU): Target: Chính là cell mà bạn đang chọn (thường nằm trong sự kiện Change hoặc SelectionChange)... Khi bạn thay đổi cell chọn, hoặc thay đổi số liệu trên 1 cell thì cell ấy chính là Target
Resize: Chỉnh lại vùng Range, cái này gần giống với hàm OFFSET của công thức Excel

Về UsedRange các bạn nên đọc thêm ở đây: http://www.giaiphapexcel.com/forum/showthread.php?6419-Thuộc-tính-UsedRange
 
Upvote 0
Bài tập số 3

ĐỀ BÀI 3

Các bạn tạo giúp báo cáo thống kê điểm cao/thấp nhất của từng môn học theo từng lớp với các nội dung cần có như sau:

(Trên 1 trang tính mới) tại [H1] là ô Validation có 2 mục chọn "CAO" & "THẤP"

Tại [C3], nếu [H2] là "CAO" sẽ hiện dòng "THỐNG KÊ ĐIỂM CAO NHẤT CỦA TỪNG LỚP."

Ngược lại sẽ là "THỐNG KÊ ĐIỂM THẤP NHẤT CỦA TỪNG LỚP."

Dữ liệu báo cáo theo mẫu sau:

5 |TT|Lớp|Văn|Lí|Địa|Toán|Sinh|Anh
6 |1|12A1|10|5|6|10|7|9
7 |2|12A10|6.5|5|8.5|3.5|2.5|9
8 |3|12A11|6.5|5.5|4|3.5|2|9
.. |.|;;;;;;;;;;;|..|.|.|.||.


Chúc các bạn thành công!
 
Upvote 0
ĐỀ BÀI 3

Các bạn tạo giúp báo cáo thống kê điểm cao/thấp nhất của từng môn học theo từng lớp với các nội dung cần có như sau:

(Trên 1 trang tính mới) tại [H1] là ô Validation có 2 mục chọn "CAO" & "THẤP"

Tại [C3], nếu [H2] là "CAO" sẽ hiện dòng "THỐNG KÊ ĐIỂM CAO NHẤT CỦA TỪNG LỚP."

Ngược lại sẽ là "THỐNG KÊ ĐIỂM THẤP NHẤT CỦA TỪNG LỚP."

Dữ liệu báo cáo theo mẫu sau:

5 |TT|Lớp|Văn|Lí|Địa|Toán|Sinh|Anh
6 |1|12A1|10|5|6|10|7|9
7 |2|12A10|6.5|5|8.5|3.5|2.5|9
8 |3|12A11|6.5|5.5|4|3.5|2|9
.. |.|;;;;;;;;;;;|..|.|.|.||.


Chúc các bạn thành công!
Anh có File dữ liệu không ạ? Em nghĩ là trong mỗi lớp phải có cả danh sách học sinh của lớp đó chứ ạ? Nói thật là em vẫn chưa hình dung ra dữ liệu gốc có cấu trúc ra sao nữa.
 
Upvote 0
ĐỀ BÀI 3

Các bạn tạo giúp báo cáo thống kê điểm cao/thấp nhất của từng môn học theo từng lớp với các nội dung cần có như sau:

(Trên 1 trang tính mới) tại [H1] là ô Validation có 2 mục chọn "CAO" & "THẤP"

Tại [C3], nếu [H2] là "CAO" sẽ hiện dòng "THỐNG KÊ ĐIỂM CAO NHẤT CỦA TỪNG LỚP."

Ngược lại sẽ là "THỐNG KÊ ĐIỂM THẤP NHẤT CỦA TỪNG LỚP."

Dữ liệu báo cáo theo mẫu sau:

5 |TT|Lớp|Văn|Lí|Địa|Toán|Sinh|Anh
6 |1|12A1|10|5|6|10|7|9
7 |2|12A10|6.5|5|8.5|3.5|2.5|9
8 |3|12A11|6.5|5.5|4|3.5|2|9
.. |.|;;;;;;;;;;;|..|.|.|.||.


Chúc các bạn thành công!
Nộp bài này cho sư phụ xem áp dụng thuật toán lính canh
 

File đính kèm

Upvote 0
ĐỀ BÀI 3
Các bạn tạo giúp báo cáo thống kê điểm cao/thấp nhất của từng môn học theo từng lớp với các nội dung cần có như sau:
(Trên 1 trang tính mới) tại [H1] là ô Validation có 2 mục chọn "CAO" & "THẤP"
Tại [C3], nếu [H2] là "CAO" sẽ hiện dòng "THỐNG KÊ ĐIỂM CAO NHẤT CỦA TỪNG LỚP."
Ngược lại sẽ là "THỐNG KÊ ĐIỂM THẤP NHẤT CỦA TỪNG LỚP."
...
Chúc các bạn thành công!
Thật sự là bài này "đơn giản dành cho người mới bắt đầu"?
Mặc dù em cũng "mới bắt đầu" nhưng khi gặp bài này lại phải dùng Dictionary và Mảng.
[gpecode=vb]
Private Sub Worksheet_Change(ByVal Target As Range)
Dim sArr(), rArr(), iR As Long, jC As Long
Dim Dic As Object, kD As Long, Tmp As Single
Set Dic = CreateObject("Scripting.Dictionary")
sArr = Sheet1.Range("H7:N" & Sheet1.Range("H65535").End(xlUp).Row).Value
ReDim rArr(LBound(sArr) To UBound(sArr), 1 To 8)
If Not Intersect(Target, [H2]) Is Nothing Then
For iR = LBound(sArr) To UBound(sArr)
If Not Dic.Exists(sArr(iR, 1)) Then
kD = kD + 1
Dic.Add sArr(iR, 1), kD
rArr(kD, 1) = kD
rArr(kD, 2) = sArr(iR, 1)
For jC = 1 To 6
rArr(kD, jC + 2) = sArr(iR, jC + 1)
Next jC
Else
For jC = 1 To 6
Tmp = Val(rArr(Dic.Item(sArr(iR, 1)), jC + 2))
If Target.Value = "CAO" Then
rArr(Dic.Item(sArr(iR, 1)), jC + 2) = _
IIf(Tmp > sArr(iR, jC + 1), Tmp, sArr(iR, jC + 1))
Else
rArr(Dic.Item(sArr(iR, 1)), jC + 2) = _
IIf(Tmp < sArr(iR, jC + 1), Tmp, sArr(iR, jC + 1))
End If
Next jC
End If
Next iR
End If
If kD Then
[A5:H50].Clear
[A5].Resize(kD, 8) = rArr
[A5].Resize(kD, 8).Borders.LineStyle = 1
End If
Set Dic = Nothing
End Sub
[/gpecode]
 

File đính kèm

Upvote 0
Anh có File dữ liệu không ạ? Em nghĩ là trong mỗi lớp phải có cả danh sách học sinh của lớp đó chứ ạ? Nói thật là em vẫn chưa hình dung ra dữ liệu gốc có cấu trúc ra sao nữa.
CSDL có đăng ở bài trước mà, bạn!

& cho fép mình khuyên bạn giải quyết bài này theo cách xài DMAX() hay DMIN() với sự trợ giúp nho nhỏ của macro là được; Bạn đừng đi theo vết xe đỗ của 2 bài trả lời cho BT 3 bên trên.

Trân trọng!
 
Upvote 0
CSDL có đăng ở bài trước mà, bạn!

& cho fép mình khuyên bạn giải quyết bài này theo cách xài DMAX() hay DMIN() với sự trợ giúp nho nhỏ của macro là được; Bạn đừng đi theo vết xe đỗ của 2 bài trả lời cho BT 3 bên trên.

Trân trọng!
Cảm ơn thầy nhiều! Em cũng thấy 2 bài trên đao to búa lớn quá! Chắc tại mấy bạn đó không phải là người mới bắt đầu theo đúng nghĩa của nó. hi
 
Upvote 0
Cảm ơn thầy nhiều! Em cũng thấy 2 bài trên đao to búa lớn quá! Chắc tại mấy bạn đó không phải là người mới bắt đầu theo đúng nghĩa của nó. hi
Không có đao to búa lớn gì đâu nghĩ sao làm vậy thôi, bài tập này tôi sử dụng thuật toán lính canh thôi rất đơn giản, tôi cũng mới tiếp cận VBA thôi. chưa tới 1 năm , và đang tập chuyển thuật toán từ ngôn ngữ C++ qua VBA(phương pháp viết là chia để trị)
 
Lần chỉnh sửa cuối:
Upvote 0
Không có đao to búa lớn gì đâu nghĩ sao làm vậy thôi, bài tập này tôi sử dụng thuật toán lính canh thôi rất đơn giản, tôi cũng mới tiếp cận VBA thôi. chưa tới 1 năm , và đang tập chuyển thuật toán từ ngôn ngữ C++ qua VBA(phương pháp viết là chia để trị)

Tôi chỉ nói cái này cho dân từng viết code C++ thôi. Không áp dụng cho những người khác.

Bạn là dân chuyên C++ mà quên mất "namespace" hay sao?
Từ code của Sheet3 (CommandButton_Click). Muốn gọi hàm của các modules khác thì phải ghi rõ phạm vi chúng.
Private Sub CommandButton1_Click()
Call Module2.LOP_DUYNHAT
Call Module4.DATA
End Sub

Mỗi module trong VBAProject có thể tạm coi như là một static class.
 
Upvote 0
Tôi chỉ nói cái này cho dân từng viết code C++ thôi. Không áp dụng cho những người khác.

Bạn là dân chuyên C++ mà quên mất "namespace" hay sao?
Từ code của Sheet3 (CommandButton_Click). Muốn gọi hàm của các modules khác thì phải ghi rõ phạm vi chúng.
Private Sub CommandButton1_Click()
Call Module2.LOP_DUYNHAT
Call Module4.DATA
End Sub

Mỗi module trong VBAProject có thể tạm coi như là một static class.
Dạ do mới làm quen với VBA nên chưa có rành lắm, cảm ơn anh nhiều, cái này rất hay và em sẽ cần rất nhiều, vì em viết 1 file có rất nhiều module mà mỗi lần gọi là không biết nằm ở trong module nào, có cái này của anh em sẽ dễ tìm tới nơi chứa code nhanh hơn
 
Upvote 0
CSDL có đăng ở bài trước mà, bạn!

& cho fép mình khuyên bạn giải quyết bài này theo cách xài DMAX() hay DMIN() với sự trợ giúp nho nhỏ của macro là được; Bạn đừng đi theo vết xe đỗ của 2 bài trả lời cho BT 3 bên trên.

Trân trọng!
Dùng hàm CSDL phải dùng để vùng điều kiện, tạm thời là dùng 1 cột phụ rồi xoá nó.
[gpecode=vb]
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Rng As Range, Rng2 As Range, iR As Long
Set Rng = Sheet1.Range("H6:N" & Sheet1.Range("H65535").End(xlUp).Row)
If Not Intersect(Target, [H2]) Is Nothing Then
[B5] = "Lop"
Range([A6], [A6].End(xlDown)).Clear
Rng.AdvancedFilter 2, [B5], [B5], True
Set Rng2 = Range([B6], [B6].End(xlDown))
[K5:Q5].Value = [B5:H5].Value
For iR = 1 To Rng2.Rows.Count
[K6] = Rng2(iR)
Rng2(iR).Offset(, -1) = iR
If Target.Value = "CAO" Then
[L6].Resize(, 6).FormulaR1C1 = "=DMAX(Sheet1!R6C8:R65535C14,R5C,R[-1]C11:RC11)"
Else
[L6].Resize(, 6).FormulaR1C1 = "=DMIN(Sheet1!R6C8:R65535C14,R5C,R[-1]C11:RC11)"
End If
Rng2(iR).Offset(, 1).Resize(, 6).Value = [L6].Resize(, 6).Value
Next iR
[B5] = "L" & ChrW(7899) & "p"
[K5:Q6].Clear
[A6].Resize(iR - 1, 8).ClearFormats
[A6].Resize(iR - 1, 8).Borders.LineStyle = 1
End If
End Sub

[/gpecode]
Em chỉ làm được vậy thôi. Chờ bài khác tối ưu hơn.
 

File đính kèm

Upvote 0
ĐỀ BÀI 3

Các bạn tạo giúp báo cáo thống kê điểm cao/thấp nhất của từng môn học theo từng lớp với các nội dung cần có như sau:

(Trên 1 trang tính mới) tại [H1] là ô Validation có 2 mục chọn "CAO" & "THẤP"

Tại [C3], nếu [H2] là "CAO" sẽ hiện dòng "THỐNG KÊ ĐIỂM CAO NHẤT CỦA TỪNG LỚP."

Ngược lại sẽ là "THỐNG KÊ ĐIỂM THẤP NHẤT CỦA TỪNG LỚP."

Dữ liệu báo cáo theo mẫu sau:

5 |TT|Lớp|Văn|Lí|Địa|Toán|Sinh|Anh
6 |1|12A1|10|5|6|10|7|9
7 |2|12A10|6.5|5|8.5|3.5|2.5|9
8 |3|12A11|6.5|5.5|4|3.5|2|9
.. |.|;;;;;;;;;;;|..|.|.|.||.

Chúc các bạn thành công!
Em nộp bài nhờ các anh chị xem và góp ý. Bài làm đúng theo "PHONG CÁCH" người mới bắt đầu biết VBA!
P/S: Có sử dụng gợi ý của HYEN17
Thank bạn!
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Không hiểu sao bài của mình và anh leonguyen(Dùng Dmax, Dmin) ra kết quả giống nhau nhưng lại không giống kết quả của anh Phi và của anh ChanhTQ nhỉ. Phải chăng có sai sót ở đâu đây?
 
Upvote 0
Bài đọc thêm

PHP:
Option Explicit
Function CucTri(CSDL As Range, Lop As String, Optional Max_ As Boolean = True)
 Dim Rw As Long, J As Long, W As Byte, Tmp As Double
 Dim Arr()
 
 Rw = CSDL.Rows.Count:              ReDim KQ(1 To 1, 1 To 6)
  Arr = CSDL.Value
 If Max_ Then
    Tmp = Application.WorksheetFunction.Min(CSDL) - 1
 Else
    Tmp = 1 + Application.WorksheetFunction.Max(CSDL)
 End If
 For W = 1 To 6
    KQ(1, W) = Tmp
 Next W
 
 For J = 1 To Rw
    If Arr(J, 1) = Lop Then
        For W = 1 To 6
            If Max_ Then
                If Arr(J, 1 + W) > KQ(1, W) Then KQ(1, W) = Arr(J, 1 + W)
            Else
                
            End If
        Next W
    End If
 Next J
 CucTri = KQ()
End Function

(1) Các bạn diễn dịch hàm này ra ngôn ngữ VN giúp;

(2) Cho biết cách xài nó trong BT 3 nêu trên;
 
Lần chỉnh sửa cuối:
Upvote 0
Ha, ha, . . . Vậy là cũng có người sập bẫy!

Không hiểu sao bài của mình và anh leonguyen(Dùng Dmax, Dmin) ra kết quả giống nhau nhưng lại không giống kết quả của anh Phi và của anh ChanhTQ nhỉ. Phải chăng có sai sót ở đâu đây?

Cái bẫy đó là do kí tự đại diện trong ecel nó hại nhà ngươi!
Bạn đốt đuốc tìm coi lớp 12A1 có em nào 9.5 điểm môn địa không?
Thử đi, trên CSDL í là biết nhau ngay tấp lự!

Bài học này bạn sẽ để đời, mình tin là vậy!
 
Upvote 0
Cái bẫy đó là do kí tự đại diện trong ecel nó hại nhà ngươi!
Bạn đốt đuốc tìm coi lớp 12A1 có em nào 9.5 điểm môn địa không?
Thử đi, trên CSDL í là biết nhau ngay tấp lự!

Bài học này bạn sẽ để đời, mình tin là vậy!
Em đã thử tìm trong cột môn địa không có em nào lớp 12A1 được 9.5 điểm cả. Nên mới thắc mắc vậy?

Cái bẫy đó là do kí tự đại diện trong ecel nó hại nhà ngươi!
.........................................................................
Bài học này bạn sẽ để đời, mình tin là vậy!
Mong Thầy giải thích rõ hơn giúp em với!
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Upvote 0
PHP:
Option Explicit
Function CucTri(CSDL As Range, Lop As String, Optional Max_ As Boolean = True)
 Dim Rw As Long, J As Long, W As Byte, Tmp As Double
 Dim Arr()
 
 Rw = CSDL.Rows.Count:              ReDim KQ(1 To 1, 1 To 6)
  Arr = CSDL.Value
 If Max_ Then
    Tmp = Application.WorksheetFunction.Min(CSDL) - 1
 Else
    Tmp = 1 + Application.WorksheetFunction.Max(CSDL)
 End If
 For W = 1 To 6
    KQ(1, W) = Tmp
 Next W
 
 For J = 1 To Rw
    If Arr(J, 1) = Lop Then
        For W = 1 To 6
            If Max_ Then
                If Arr(J, 1 + W) > KQ(1, W) Then KQ(1, W) = Arr(J, 1 + W)
            Else
                
            End If
        Next W
    End If
 Next J
 CucTri = KQ()
End Function
Sao em thấy giải thuật bài Dic (bài #25) em viết gần giống giải thuật của hàm này.
Và sau khi phát hiện ra hàm cơ sở dữ liệu lấy luôn ký tự đại diện thì hướng dẫn:
& cho fép mình khuyên bạn giải quyết bài này theo cách xài DMAX() hay DMIN() với sự trợ giúp nho nhỏ của macro là được; Bạn đừng đi theo vết xe đỗ của 2 bài trả lời cho BT 3 bên trên.
Trân trọng!
... cũng thua luôn.
Đúng là bài học để đời. Ẹc ẹc...
 
Upvote 0
Và sau khi phát hiện ra hàm cơ sở dữ liệu lấy luôn ký tự đại diện thì hướng dẫn:

... cũng thua luôn.
Đúng là bài học để đời. Ẹc ẹc...
Em vẫn mù mờ chỗ này quá(chỗ in đậm) mong anh leonguyen và thầy HYen17 giải thích kĩ hơn cho em được không ạ và phải sửa trong code thế nào ạ(Code của em đó).
 
Upvote 0
Em vẫn mù mờ chỗ này quá(chỗ in đậm) mong anh leonguyen và thầy HYen17 giải thích kĩ hơn cho em được không ạ và phải sửa trong code thế nào ạ(Code của em đó).
Điều kiện trong hàm CSDL lấy ký tự đại diện, ví dụ điều kiện cột Lớp là 12A1 thì hàm sẽ lấy luôn dữ liệu có Lớp là 12A1* (ví dụ 12A11, 12A12, ...). Bạn test thử sẽ biết, nhưng chỉ lấy phần đầu, chứ không phải đại diện hoàn toàn (kiểu *12A1*).
 
Upvote 0
Điều kiện trong hàm CSDL lấy ký tự đại diện, ví dụ điều kiện cột Lớp là 12A1 thì hàm sẽ lấy luôn dữ liệu có Lớp là 12A1* (ví dụ 12A11, 12A12, ...). Bạn test thử sẽ biết, nhưng chỉ lấy phần đầu, chứ không phải đại diện hoàn toàn (kiểu *12A1*).
Vậy cách khắc phục như thế nào đây anh. Áp dụng với code của em ạ???
 
Upvote 0
Vậy cách khắc phục như thế nào đây anh. Áp dụng với code của em ạ???
Đã nói ở bài #39 là thua luôn mà. Làm sao sử dụng DMAX, DMIN cho bài này được.
Cách còn lại để áp dụng code với hàm cơ sở dữ liệu là convert lại tên lớp về dạng 12A??, ví dụ 12A1 đến 12A9 thì chuyển về 12A01 đến 12A09, sau đó áp dụng code.
 
Upvote 0
Đã nói ở bài #39 là thua luôn mà. Làm sao sử dụng DMAX, DMIN cho bài này được.
Cách còn lại để áp dụng code với hàm cơ sở dữ liệu là convert lại tên lớp về dạng 12A??, ví dụ 12A1 đến 12A9 thì chuyển về 12A01 đến 12A09, sau đó áp dụng code.
Em đã làm thử như anh nói đó là convert lại tên lớp về dạng 12A?? những vẫn không ra kết quả như tác giả đã đưa.
 
Upvote 0
Em đã làm thử như anh nói đó là convert lại tên lớp về dạng 12A?? những vẫn không ra kết quả như tác giả đã đưa.
Ví dụ A1 là tên lớp, đặt công thức chuyển lớp về dạng 12A??, vì là lớn 12A cả:
Mã:
="12A"&TEXT(MID(A1,4,2),"00")
Kết quả trong file của bạn.
 

File đính kèm

Upvote 0
Đọc & dịch macro sự kiện này nà

Để biết cách vượt qua cửa ải đó bằng cách nào:

PHP:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
 Dim Rws As Long, J As Byte:                Dim Txt As String
 Dim Sh As Worksheet, Rng As Range, WF As Object, Cls As Range, Cll As Range, Rg0 As Range
 
 Set Sh = ThisWorkbook.Worksheets("Sheet1")
 Rws = Sh.[h6].CurrentRegion.Rows.Count
 Set Rng = Sh.[h6].Resize(Rws, 7)
 Set Rg0 = Sh.[i6].Resize(, 6)
 Set WF = Application.WorksheetFunction
 If Not Intersect(Target, [H1]) Is Nothing Then
    Txt = Left(Target.Value, 1)
    For Each Cls In Range([b6], [b6].End(xlDown))
3        Sh.[AA4].Value = Cls.Value
        For J = 1 To 6
            If Txt = "C" Then
5                Cls.Offset(, J).Value = WF.DMax(Rng, Rg0(J), Sh.[AA1:AA2])
            Else
7                Cls.Offset(, J).Value = WF.DMin(Rng, Rg0(J), Sh.[AA1:AA2])
            End If
        Next J
    Next Cls
 End If
End Sub
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Bải tập 4: Lập danh sách tất cả học viên đạt tối đa/tối thiểu theo từng môn.

ĐỀ BÀI 4
Dựa vô bảng điểm của bài 3, xin các bạn lập ra danh sách các học viên đạt điểm tối đa hay tối thiểu của khối 12 này.


Trên diễn đàn gần đây có loại bài này rồi; Các bạn có thể tham khảo để có thể làm hay hơn!

Chúc thành công!

Mẫu báo cáo:

DANH SÁCH CÁC EM HOC VIÊN ĐẠT ĐIỂM TỐI ĐA/TỐI THIỂU

TT|HoTen|Lop|Văn|Lí|Địa|Toán|Sinh|Anh
01|Trần Hồ|12A9| 10 |5|6|..| 9| 6
02|Lê La|12A7|4| 8 |7|. . . .|6|5.5
03|Vủ Phu|12A|8| 7.5 |. | . |5|6.5
..|--=0||. . .|..|
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
ĐỀ BÀI 4
Dựa vô bảng điểm của bài 3, xin các bạn lập ra danh sách các học viên đạt điểm tối đa hay tối thiểu của khối 12 này.


Trên diễn đàn gần đây có loại bài này rồi; Các bạn có thể tham khảo để có thể làm hay hơn!

Chúc thành công!

Mẫu báo cáo:

DANH SÁCH CÁC EM HOC VIÊN ĐẠT ĐIỂM TỐI ĐA/TỐI THIỂU

TT|HoTen|Lop|Văn|Lí|Địa|Toán|Sinh|Anh
01|Trần Hồ|12A9| 10 |5|6|..| 9| 6
02|Lê La|12A7|4| 8 |7|. . . .|6|5.5
03|Vủ Phu|12A|8| 7.5 |. | . |5|6.5
..|--=0||. . .|..|
em chưa hiểu bài này lắm, điểm tối đa của các môn hay là sao? với lại bài 3 là điểm lớn nhất của từng cột nên nó sẽ không đồng nhất với từng dòng?
hay là sư phụ muốn tìm ra ai đó có điểm cao nhất rồi đưa ra tên của người đó trong danh sách em chép về hình như là không có tên trần hồ
nếu bài này dựa vào danh sách bài 3 rồi tìm ra điểm max từng dòng sau đó sử so sánh điểm max với CSDL để lấy ra tên thì em có thể sử dụng lưu lại vị trí max/min rồi truy cập tới nó để lấy ra tên
 
Lần chỉnh sửa cuối:
Upvote 0
em chưa hiểu bài này lắm, điểm tối đa của các môn hay là sao? với lại bài 3 là điểm lớn nhất của từng cột nên nó sẽ không đồng nhất với từng dòng?
hay là sư phụ muốn tìm ra ai đó có điểm cao nhất rồi đưa ra tên của người đó trong danh sách em chép về hình như là không có tên trần hồ
Em cũng chung băn khoăn với anh.
 
Upvote 0
Thì bài trên ta biết điểm tối đa của lớp 12A1 là 10(V), 5(L), 6(D), 10 (T), 7(S) & 9(A)
Nhiệm vụ giớ là lập danh sách 6 (hay hơn) những em đạt điểm như vậy của lớp này. . . Sau đó là đến các lớp khác tương tự

Mong các bạn chớ nản lòng!
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Thì bài trên ta biết điểm tối đa của lớp 10A1 là 10(V), 5(L), 6(D), 10 (T), 7(S) & 9(A)
Nhiệm vụ giớ là lập danh sách 6 (hay hơn) những em đạt điểm như vậy của lớp này. . . Sau đó là đến các lớp khác tương tự

Mong các bạn chớ nản lòng!
Dạo này em thấy mấy lần bác viết nhầm, H1 & H2, 10A1 & 12A1, Học viên & Học sinh, ..., Dồn trí lực cho tụi em nhiều quá phải không bác? Cố gắng giữ sức khỏe nha bác!
Bài tập 4 em suy nghĩ đến hàm COUNTIF, phương thức Find, hoặc AdF, ... nhưng sau đó lại chuyển hướng qua vòng lặp và Dic.
[gpecode=vb]
Sub DSachHS()
Dim sArr1(), sArr2(), rArr(), Rng As Range, Dic As Object
Dim i As Long, j As Long, k As Long, l As Long, m As Long
sArr1 = Sheet1.[C7:O699].Value
sArr2 = Sheet2.[B6:H20].Value
ReDim rArr(1 To UBound(sArr1), 1 To 9)
Set Dic = CreateObject("Scripting.Dictionary")
For i = LBound(sArr1) To UBound(sArr1)
For j = LBound(sArr2) To UBound(sArr2)
If sArr1(i, 7) = sArr2(j, 1) Then
For k = 1 To 6
If sArr1(i, k + 7) = sArr2(j, k + 1) Then
If Not Dic.Exists(sArr1(i, 1)) Then
l = l + 1
Dic.Add sArr1(i, 1), l
rArr(l, 1) = l
rArr(l, 2) = sArr1(i, 1)
For m = 1 To 7
rArr(l, m + 2) = sArr2(j, m)
Next m
End If
End If
Next k
End If
Next j
Next i
If l Then
Sheet3.[A6:I1000].Clear
Sheet3.[A6].Resize(l, 9) = rArr
Sheet3.[A6].Resize(l, 9).Borders.LineStyle = 1
End If
Set Dic = Nothing
End Sub
[/gpecode]
 

File đính kèm

Upvote 0
Bài này làm AdvancedFilter cũng được;
Nhưng danh sách lọc ra xong sẽ có nhiều em trùng (vì học quá giỏi ở cả các môn)
Nên cuối cùng fải tìm cách xử lí những dòng dữ liệu trùng đó.

Còn nếu xài Fương thức FIND() thì công việc cũng fải tìm cách xử chuyện trùng này.

Tất nhiên, áp dụng 2 cách này thì không cần kiến thức VBA cao lắm
 
Upvote 0
ĐỀ BÀI 4
Dựa vô bảng điểm của bài 3, xin các bạn lập ra danh sách các học viên đạt điểm tối đa hay tối thiểu của khối 12 này.


Trên diễn đàn gần đây có loại bài này rồi; Các bạn có thể tham khảo để có thể làm hay hơn!

Chúc thành công!

Mẫu báo cáo:

DANH SÁCH CÁC EM HOC VIÊN ĐẠT ĐIỂM TỐI ĐA/TỐI THIỂU

TT|HoTen|Lop|Văn|Lí|Địa|Toán|Sinh|Anh
01|Trần Hồ|12A9| 10 |5|6|..| 9| 6
02|Lê La|12A7|4| 8 |7|. . . .|6|5.5
03|Vủ Phu|12A|8| 7.5 |. | . |5|6.5
..|--=0||. . .|..|
Sư phụ test dùm em bài này trường hợp max như vậy có đúng không? em lấy điểm max từng môn sau đó so sánh để lấy tên học sinh cho đúng
hình như bị lặp lại những thằng học giỏi (chắc phải xử lý lại tí nữa)
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Sư phụ test dùm em bài này trường hợp max như vậy có đúng không? em lấy điểm max từng môn sau đó so sánh để lấy tên học sinh cho đúng
hình như bị lặp lại những thằng học giỏi (chắc phải xử lý lại tí nữa)
Sau khi xử lý xóa trùng sư phụ xem dùm nha, còn trường hợp min thì mình thêm điều kiện chọn lựa nữa là xong
 

File đính kèm

Upvote 0
Bài đọc thêm

PHP:
Option Explicit
Sub LapDS()
 Dim Sh0 As Worksheet, Sh1 As Worksheet, Cls As Range, CSDL As Range
 Dim Rws As Long, J As Long, W As Long
 
 Set Sh0 = ThisWorkbook.Worksheets("Sheet1")
 Sheet3.Select
 Rws = Sh0.[j7].CurrentRegion.Rows.Count
 ReDim Arr(1 To Rws, 1 To 7):               ReDim KQ(1 To Rws, 1 To 1)
 Arr() = Sh0.[i7].Resize(Rws, 7).Value
 Set Sh1 = ThisWorkbook.Worksheets("Sheet2")
 For Each Cls In Sh1.Range(Sh1.[B6], Sh1.[B6].End(xlDown))
    For J = 1 To Rws
        For W = 1 To 6
            If Arr(J, 1) = Cls.Value And Arr(J, 1 + W) = Cls.Offset(, W).Value Then
                KQ(J, 1) = "Y":                   Exit For
            End If
        Next W
    Next J
 Next Cls
 Sh0.[d7].Resize(Rws) = KQ()
 Set CSDL = Sh0.[B6].Resize(Rws, 14)
 CSDL.AdvancedFilter Action:=xlFilterCopy, CriteriaRange:=Sh0.Range( _
    "Ad1:Ad2"), CopyToRange:=[B6].Resize(, 9), Unique:=False
 Sh0.[d7].Resize(Rws) = ""
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Trong file ở bài #46, tại trang Sheet2 có lời giải bài tập 3 bằng hàm mảng tự tạo để các bạn tham khảo;

;;;;;;;;;;; ;;;;;;;;;;; ;;;;;;;;;;;


Nội dung hàm này cũng đã có ở #34


--=0 --=0 --=0
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Bài đọc thêm: Lập danh sách các học sinh điểm kém

PHP:
Option Explicit
Sub DSHocSinhKem()
 Dim Sh As Worksheet
 Dim Rws As Long, J As Long
 
 Set Sh = ThisWorkbook.Worksheets("Sheet1")
 Rws = [I6].CurrentRegion.Rows.Count
 ReDim Arr(1 To Rws, 1 To 6):           ReDim KQ(1 To Rws, 1 To 1)
 Arr() = Sh.[J7].Resize(Rws, 6).Value
 For J = 1 To Rws
    KQ(J, 1) = HSK(Arr(J, 1), Arr(J, 4), Arr(J, 2), Arr(J, 3), Arr(J, 5), Arr(J, 6))
 Next J
 Sh.[D7].Resize(Rws).Value = KQ()
End Sub

--=0--=0--=0--=0


Mã:
[B]
Function HSK(Vn, Tn, Li, Da, Sh, Ah) As String[/B]
 Dim Dm As Byte
 
 If Vn <= 4 Or Tn <= 4 Then
    HSK = "X":                      Exit Function
 Else
    If Li <= 4 Then Dm = Dm + 1
    If Da <= 4 Then Dm = Dm + 1
    If Sh <= 4 Then Dm = Dm + 1
    If Ah <= 4 Then Dm = Dm + 1
 End If
 If Dm > 1 Then HSK = "X"
[B]End Function[/B]
 
Lần chỉnh sửa cuối:
Upvote 0
Bài tập số 5

ĐỀ BÀI 5:
Với CSDL đã có, xin các bạn thống kê điểm các môn học theo từng lớp như sau

Tại [H23] của trang 'Sheet2' ta có ô chọn của 6 môn học (Văn,. .. ,Anh)
Khi ta chọn 1 môn nào đó, ta sẽ thu được số liệu báo cáo theo mẫu sau:

TT|Lớp|<=4|<=6|<=8|<=10|Ghi chú
1|12A1|0|5|24|12|
2|12A10|2|6|28|8|
..|}}}}}||..||.|
15|12A9|2|16|19|8|
Chúc các bạn thành công
 
Upvote 0
Mã:
Option Explicit
Sub DSHocSinhKem()
 Dim Sh As Worksheet
 Dim Rws As Long, J As Long
 
 Set Sh = ThisWorkbook.Worksheets("Sheet1")
 Rws = [I6].CurrentRegion.Rows.Count
 ReDim Arr(1 To Rws, 1 To 6):           ReDim KQ(1 To Rws, 1 To 1)
 Arr() = Sh.[J7].Resize(Rws, 6).Value
[COLOR=#ff0000] For J = 1 To Rws
    KQ(J, 1) = HSK(Arr(J, 1), Arr(J, 4), Arr(J, 2), Arr(J, 3), Arr(J, 5), Arr(J, 6))
 Next J
[/COLOR] Sh.[D7].Resize(Rws).Value = KQ()
End Sub

Mã:
[B]
Function HSK(Vn, Tn, Li, Da, Sh, Ah) As String[/B]
 Dim Dm As Byte
 
 If Vn <= 4 Or Tn <= 4 Then
    HSK = "Y":                      Exit Function
 Else
    If Li <= 4 Then Dm = Dm + 1
    If Da <= 4 Then Dm = Dm + 1
    If Sh <= 4 Then Dm = Dm + 1
    If Ah <= 4 Then Dm = Dm + 1
 End If
 If Dm > 1 Then HSK = "Y"
[B]End Function[/B]

Nếu muốn đặt một môn quan trọng hơn các môn khác thì chỉ cần đặt hệ số của nó tăng lên (theo bài này là trên 1)

Mã:
Dim xetDiem as Integer
For J = 1 To Rws
  KQ(J, 1) = ""
  diemKem = 0
  For J2 = 1 to 6
    diemKem =  diemKem + IIF(Arr(J, J2) > 4, 0, IIF(J2 = 1 Or J2 = 4, 2, 1))
    If diemKem > 1 Then
      KQ(J, 1) = "Y"
      Exit For
    End If
  Next J2
Next J

Thật tình mà nói. Mấy cái bài này tôi nhìn không đơn giản chút nào, và tôi không tin là "người mới bắt đầu" học được cái gì cả.
Tôi chỉ góp 1 vài giải thuật mà tôi cho là có thể cải tiến thôi.
 
Lần chỉnh sửa cuối:
Upvote 0
Nếu muốn đặt một môn quan trọng hơn các môn khác thì chỉ cần đặt hệ số của nó tăng lên (theo bài này là trên 1)

Mã:
Dim xetDiem as Integer
For J = 1 To Rws
  KQ(J, 1) = ""
  diemKem = 0
  For J2 = 1 to 6
    diemKem =  diemKem + IIF(Arr(J, J2) > 4, 0, IIF(J2 = 1 Or J2 = 4, 2, 1))
    If diemKem > 1 Then
      KQ(J, 1) = "Y"
      Exit For
    End If
  Next J2
Next J

Thật tình mà nói. Mấy cái bài này tôi nhìn không đơn giản chút nào, và tôi không tin là "người mới bắt đầu" học được cái gì cả.
Tôi chỉ góp 1 vài giải thuật mà tôi cho là có thể cải tiến thôi.
Quả thật khi đọc tiêu để topic mấy bài đầu em cũng hồ hởi có tham gia nhưng mấy bài sau này thì buồn không muốn suy nghĩ nữa rồi, vì rất khó, vượt quá sức của mình. Phải nói thật là với những người mới bắt đầu(đúng nghĩa) là quá sức. Vài lời chân thành mong anh ChanhTQ đừng buồn!
 
Upvote 0
ĐỀ BÀI 5:
Với CSDL đã có, xin các bạn thống kê điểm các môn học theo từng lớp như sau

Tại [H23] của trang 'Sheet2' ta có ô chọn của 6 môn học (Văn,. .. ,Anh)
Khi ta chọn 1 môn nào đó, ta sẽ thu được số liệu báo cáo theo mẫu sau:

TT|Lớp|<=4|<=6|<=8|<=10|Ghi chú
1|12A1|0|5|24|12|
2|12A10|2|6|28|8|
..|}}}}}||..||.|
15|12A9|2|16|19|8|
Chúc các bạn thành công
Nhờ sư phụ chỉnh lại không biết sai ở đâu. Trong file tách ra từng điều kiện thì ok.
Nhưng code bên dưới muốn gộp lại thì lại bị lỗi. mong sư phụ chỉnh code bên dưới cho đúng kết quả như trong file

Sub DATA_THONGKE()


Dim rngs(), rngs2(), ARR(), I As Long, J As Long, K As Long, M As Long, L As Long
On Error Resume Next
Dim TAM As Double
Dim SODUOI As Double


With Sheet1
rngs = .Range(.[A7], .[A60000].End(xlUp)).Resize(, 20).Value
End With
With Sheet2
rngs2 = .Range(.[A7], .[A60000].End(xlUp)).Resize(, 20).Value
End With


'''''''''''TIM VI TRI THONG KE
'''''''''''K LA VI TRI CAN THONG KE
For K = 1 To 15
If (Sheet2.Cells(2, 8).Value = Sheet1.Cells(6, K).Value) Then
Exit For
End If
Next

ReDim ARR(1 To UBound(rngs2, 1), 1 To 4)


For I = 1 To UBound(rngs2, 1)
SODUOI = 0
For L = 4 To 10 Step 2
TAM = 0
M = 1
For J = 1 To UBound(rngs, 1)
If (rngs2(I, 2) = rngs(J, 8)) Then
If (rngs(J, K) <= L And rngs(J, K) > SODUOI) Then
TAM = TAM + 1
End If
End If
Next J
ARR(I, M) = TAM
SODUOI = L
M = M + 1
Next L
Next I

Sheet2.Range("C7").Resize(I, 4).Value = ARR
End Sub
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Quả thật khi đọc tiêu để topic mấy bài đầu em cũng hồ hởi có tham gia nhưng mấy bài sau này thì buồn không muốn suy nghĩ nữa rồi, vì rất khó, vượt quá sức của mình. Phải nói thật là với những người mới bắt đầu(đúng nghĩa) là quá sức. Vài lời chân thành mong anh ChanhTQ đừng buồn!

Thật ra mà nói, mấy bài này ta có thể xài vòng lặp, kiến thức về fương thức lọc dữ liệu bằng AdvancedFilter là có thể làm ra được hết; chỉ có điều sẽ tốn chi fí điện nước mà thôi;

Một số bài giải/bài đọc thêm có xài biến mảng; Nhưng nếu ta xài vòng lặp duyệt toàn bộ các dòng dữ liệu thay cho công cụ đó cũng xong ngay thôi.

Còn bài thống kê gần đây nhất, ta tiến xa hơn 1 bước với AdvancedFilter là sang các hàm CSDL.
Vế hàm CSDL là thế mạnh rất nhiều, khi người ta chưa biết về biến mảng, Dic. & cách làm việc với chúng nó.

Mình cũng chưa đồng í với 1 số bạn trong topic này ở chỗ: Mình có kiến thức (KT) gì thì đưa ra xử BT kiến thức ấy; Mà chưa dùng KT tối thiểu của mình để giải quyết 1 bài toán nhằm đến 'Người mới bắt đầu'! Có vậy mới đúng tiêu chí của đề tài topic.

Những bạn trả lời 'Xa xôi' chúng ta coi như là những tham khảo mà thôi!

Vài lời để mong mọi người có bài trong topic này hiểu thêm & thông cảm!

Mình cho rằng, những người tham gia giải BT đã là tốt, nhưng cái tốt hơn đem lại là rất nhiều người quan tâm & truy nhập vô topic.
Mình rất cảm ơn về điều đó!
 
Upvote 0
Thật ra mà nói, mấy bài này ta có thể xài vòng lặp, kiến thức về fương thức lọc dữ liệu bằng AdvancedFilter là có thể làm ra được hết; chỉ có điều sẽ tốn chi fí điện nước mà thôi;

Một số bài giải/bài đọc thêm có xài biến mảng; Nhưng nếu ta xài vòng lặp duyệt toàn bộ các dòng dữ liệu thay cho công cụ đó cũng xong ngay thôi.

Còn bài thống kê gần đây nhất, ta tiến xa hơn 1 bước với AdvancedFilter là sang các hàm CSDL.
Vế hàm CSDL là thế mạnh rất nhiều, khi người ta chưa biết về biến mảng, Dic. & cách làm việc với chúng nó.

Mình cũng chưa đồng í với 1 số bạn trong topic này ở chỗ: Mình có kiến thức (KT) gì thì đưa ra xử BT kiến thức ấy; Mà chưa dùng KT tối thiểu của mình để giải quyết 1 bài toán nhằm đến 'Người mới bắt đầu'! Có vậy mới đúng tiêu chí của đề tài topic.

Những bạn trả lời 'Xa xôi' chúng ta coi như là những tham khảo mà thôi!

Vài lời để mong mọi người có bài trong topic này hiểu thêm & thông cảm!

Mình cho rằng, những người tham gia giải BT đã là tốt, nhưng cái tốt hơn đem lại là rất nhiều người quan tâm & truy nhập vô topic.
Mình rất cảm ơn về điều đó!
Quả thật là lúc trước em cũng có góp ý với chủ topic là với mỗi 1 bài tập sau 1 thời gian nào đó nên đưa lời giải (Giành cho người mới bắt đầu) để bọn em tham khảo và đối chiếu. Tuy nhiên không thấy chủ topic đưa ra. Cũng có 1 vài bài tham khảo(bài đọc thêm) tuy nhiên không phải của chủ topic.
 
Upvote 0
Xem như đã có khung Stt và Lớp, H2 dùng Data Validation để chọn môn học.
[gpecode=vb]
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Rng As Range, i As Long, j As Long, k As Long, Kq As Long
Set Rng = Sheet1.Range("I6:O699")
If Not Intersect(Target, [H2]) Is Nothing Then
Range("C6:F20").ClearContents
For i = 1 To Rng.Rows.Count
For j = 6 To 20
If Rng(i, 1) = Cells(j, 2) Then
For k = 2 To 7
If Rng(1, k) = Target Then
Select Case Rng(i, k)
Case 0 To 4: Cells(j, 3) = Cells(j, 3) + 1
Case 4 To 6: Cells(j, 4) = Cells(j, 4) + 1
Case 6 To 8: Cells(j, 5) = Cells(j, 5) + 1
Case 8 To 10: Cells(j, 6) = Cells(j, 6) + 1
End Select
End If
Next k
End If
Next j
Next i
End If
End Sub
[/gpecode]
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Xem như đã có khung Stt và Lớp, H2 dùng Data Validation để chọn môn học.

Trong CSDL hiện chì có loại điểm >=0;

Nhưng liêu trong bảng điểm thay vì như 6.75 người ta chấm -7; (Có nghĩa chỉ có các loại điểm trong sổ dang 6, 6.5 -7 & 7,. . .) thì macro của Thảo fải sửa thế nào nhỉ?
 
Upvote 0
Trong CSDL hiện chì có loại điểm >=0;

Nhưng liêu trong bảng điểm thay vì như 6.75 người ta chấm -7; (Có nghĩa chỉ có các loại điểm trong sổ dang 6, 6.5 -7 & 7,. . .) thì macro của Thảo fải sửa thế nào nhỉ?
Có thể thêm hàm ABS chỗ Select Case như vậy được không bác?
[gpecode=vb]Select Case Abs(Rng(i, k))[/gpecode]
 
Upvote 0
Ta có thể xài DCOUNTA() để khỏi duyệt toàn bộ gần 700 em HS, tuy nhiên

Cần có 1 số thiết kế sẵn để fục vụ macro sự kiện này tại Sheet2.[H23]:
PHP:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
 Dim Sh As Worksheet, CSDL As Range, Cls As Range, WF As Object
 Dim Rws As Long, J As Long, Min_ As Double, Max_ As Double, Tmr As Double
  
 If Not Intersect(Target, [H23]) Is Nothing Then
    Tmr = Timer()
    Set WF = Application.WorksheetFunction
    Set Sh = ThisWorkbook.Worksheets("Sheet1")
    Rws = Sh.[i6].CurrentRegion.Rows.Count
    Set CSDL = Sh.[i6].Resize(Rws, 7)
    For Each Cls In Range([B26], [B26].End(xlDown))
7        Sh.[AA4].Value = Cls.Value
8        Sh.[AB1:AC1].Value = Target.Value
        For J = 1 To 4
            Min_ = Choose(J, -1, 4, 6, 8)
            Max_ = Choose(J, 4, 6, 8, 10)
9            Sh.[ab4].Value = Min_:          Sh.[ac4].Value = Max_
            Cls.Offset(, J).Value = WF.DCountA(CSDL, Sh.[i6], Sh.[aa1:ac2])
        Next J
    Next Cls
    MsgBox Timer() - Tmr
 End If
End Sub

Các bạn chú í các dòng lệnh có đánh số vì chúng có liên quan với thiết kế tại trang Sheet1; 1 fần của trang đó có liên quan đến các donh lệnh này được mô tả như sau:

| AA | AB | AC 1 |=I6||
2 |="=" & AA4|=">"&AB4|="<="&AC4
3 ||}}}}}|
 
Upvote 0
Mình xin đố các bạn, là

Ta có thể xài DCOUNTA() để khỏi duyệt toàn bộ gần 700 em HS, tuy nhiên

Tại sao trong bài, tác giả xài DCOUNTA() mà không xài DCOUNT()?
 
Upvote 0
Nhờ sư phụ chỉnh lại không biết sai ở đâu. Trong file tách ra từng điều kiện thì ok.
Nhưng code bên dưới muốn gộp lại thì lại bị lỗi. mong sư phụ chỉnh code bên dưới cho đúng kết quả như trong file
Tạm thời sửa như thế này. nhưng vẫn muốn sử dụng vòng lập cho hàng ngang, không muốn sử dụng if hoặc case vì nếu bài này nhiều trường hợp sảy ra thì if và case sẽ không ứng dụng tối ưu được
Sub DATA_THONGKE()


Dim rngs(), rngs2(), ARR(), I As Long, J As Long, K As Long, M As Long, L As Long
On Error Resume Next
Dim TAM As Double
Dim SODUOI As Double
Sheet2.Range("C7:H200").ClearContents
With Sheet1
rngs = .Range(.[A7], .[A60000].End(xlUp)).Resize(, 20).Value
End With
With Sheet2
rngs2 = .Range(.[A7], .[A60000].End(xlUp)).Resize(, 20).Value
End With


'''''''''''TIM VI TRI THONG KE
'''''''''''K LA VI TRI CAN THONG KE
For K = 1 To 15
If (Sheet2.Cells(2, 8).Value = Sheet1.Cells(6, K).Value) Then
Exit For
End If
Next

ReDim ARR(1 To UBound(rngs2, 1), 1 To 4)


For I = 1 To UBound(rngs2, 1)
For J = 1 To UBound(rngs, 1)
If (rngs2(I, 2) = rngs(J, 8)) Then
If (rngs(J, K) <= 4) Then
Sheet2.Cells(I + 6, 3) = Sheet2.Cells(I + 6, 3) + 1
End If

If (rngs(J, K) <= 6 And rngs(J, K) > 4) Then
Sheet2.Cells(I + 6, 4) = Sheet2.Cells(I + 6, 4) + 1
End If

If (rngs(J, K) <= 8 And rngs(J, K) > 6) Then
Sheet2.Cells(I + 6, 5) = Sheet2.Cells(I + 6, 5) + 1
End If

If (rngs(J, K) > 8) Then
Sheet2.Cells(I + 6, 6) = Sheet2.Cells(I + 6, 6) + 1
End If
End If
Next J



Next I
End Sub
nhưng tại sao sử dụng vòng for thì gán dữ liệu vào nó không hợp lý, sư phụ có thể sử dụng code này sử dụng for sau đó gán dữ liệu dùm em xem học hỏi được không
 
Upvote 0
Tạm thời sửa như thế này. nhưng vẫn muốn sử dụng vòng lập cho hàng ngang, không muốn sử dụng if hoặc case vì nếu bài này nhiều trường hợp sảy ra thì if và case sẽ không ứng dụng tối ưu được

nhưng tại sao sử dụng vòng for thì gán dữ liệu vào nó không hợp lý, sư phụ có thể sử dụng code này sử dụng for sau đó gán dữ liệu dùm em xem học hỏi được không
Mới làm được rồi, ngày hôm qua cũng làm như vậy mà sao không ra kết quả hôm nay tự nhiên lại ra
Sub DATA_THONGKE()


Dim rngs(), rngs2(), ARR(), I As Long, J As Long, K As Long, M As Long, L As Long
On Error Resume Next
Dim TAM As Double
Dim SODUOI As Double
Sheet2.Range("C7:H200").ClearContents
With Sheet1
rngs = .Range(.[A7], .[A60000].End(xlUp)).Resize(, 20).Value
End With
With Sheet2
rngs2 = .Range(.[A7], .[A60000].End(xlUp)).Resize(, 20).Value
End With


'''''''''''TIM VI TRI THONG KE
'''''''''''K LA VI TRI CAN THONG KE
For K = 1 To 15
If (Sheet2.Cells(2, 8).Value = Sheet1.Cells(6, K).Value) Then
Exit For
End If
Next

ReDim ARR(1 To UBound(rngs2, 1), 1 To 4)


For I = 1 To UBound(rngs2, 1)
For J = 1 To UBound(rngs, 1)
If (rngs2(I, 2) = rngs(J, 8)) Then

SODUOI = 0
TAM = 2
For L = 4 To 10 Step 2
TAM = TAM + 1
If (rngs(J, K) <= L And rngs(J, K) > SODUOI) Then
Sheet2.Cells(I + 6, TAM) = Sheet2.Cells(I + 6, TAM) + 1
End If
SODUOI = L
Next L
End If
Next J


Next I
End Sub
 
Upvote 0
Bài tập 6: TÍNH ĐIỂM TRUNG BÌNH MÔN HỌC THEO FÁI TÍNH.

Đề bài tập

Với CSDL như trong file của bài 46, chúng ta hoàn toàn có khả năng thông kê số liệu theo bảng sau đây:


|| Văn | Văn |Lí|Lí| Địa | Địa |Toán|Toán| Sinh | Sinh |Anh|Anh| Ghi chú
TT|Lớp|Nam|Nữ| Nam|Nữ| Nam|Nữ| Nam|Nữ| Nam|Nữ| Nam|Nữ|
01|10A1|7.51|7.53|7.46|7.47|7.40|7.42|6.48|6.51|6.42|6.48|5.65|5.55|
.|..|.|.|.|.|.|.|.|.|.|.|.|.|
0?|12A1?|7.10|7.43|7.6|7.7|7.49|7.2|6.8|6.1|6.2|6.8|5.6|5.5|
08|12A2|7.31|7.31|7.24|7.24|7.27|7.27|6.34|6.34|6.32|6.32|6.08|6.08|
.|..|.|.|.|.|.|.|.|.|.|.|.|.|--=0
15|12A9|6.62|6.59|6.56|6.75|6.66|6.79|5.73|5.85|5.70|5.79|5.89|5.89|

Xin mời các bạn gần xa thử sức.
 
Lần chỉnh sửa cuối:
Upvote 0
Các bạn tham khảo 1 trong những cách giải bài tập cuối.

PHP:
Option Explicit
Sub DiemBQTheoFaiTinh()
 Dim Sh As Worksheet, CSDL As Range, Cls As Range, WF As Object
 Dim Rws As Long, J As Byte, W As Byte, Tmr As Double
 
 Tmr = Timer():                                     Set Sh = ThisWorkbook.Worksheets("Sheet1")
 Rws = Sh.[e6].CurrentRegion.Rows.Count
 Set CSDL = Sh.[e6].Resize(Rws, 11)
 Set WF = Application.WorksheetFunction
 For Each Cls In Range([b51], [b51].End(xlDown))
    Sh.[aa4].Value = Cls.Value
    For J = 1 To 6
        For W = 1 To 2
            Sh.[Z2].Value = Choose(W, "", 1)
            Cls.Offset(, 2 * J - (W Mod 2)).Value = WF.DAverage(CSDL, Sh.[I6].Offset(, J), Sh.[z1:aa2])
        Next W
    Next J
 Next Cls
 [o48].Value = Timer() - Tmr
End Sub
 

File đính kèm

Upvote 0
Bài tập 1A: Chọn ra những số theo yêu cầu từ các chuỗi số

ĐỀ BÀI TẬP 1A:


.
.
Mình có các chuỗi số liệu tại cột [A].
Muốn có mácro để từ các chuỗi số đó xử lí & lọc ra các số gồm 32, 33 & 34. Sau đó thể hiện lên cột [C] như bảng dưới đây:


A || C || E
Các số||Kết quả mong muốn||Mong muốn nâng cao
0123,28,29,26,25,332,833,34,52,48,47,57,59,61,64,65||34||34
33,40,34,32,50,86,99||32,33,34|| 33,34,32
09,20,32,33,34,38,40||32,33,34||32,33,34
33,59,60||33||33
32,20,33,34||32,33,34||32,33,34
33||33||33
42||||
32||32||32
01,02,340,05,06,07||||
10,11,12,13,14,15,32||32||32
333334233||||
3,4,2,6||||
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Code này chạy thì ok rồi, nhưng chắc là chưa đúng ý của bác:
[gpecode=vb]
Sub Button1_Click()
Dim Rng As Range, Cell As Range, TmpArr As Variant, i As Long, Tmp As String
Set Rng = Sheet1.Range("A2:A13")
For Each Cell In Rng
If IsNumeric(Cell) And (Cell = 32 Or Cell = 33 Or Cell = 34) Then
Cell.Offset(, 2) = Cell
Else
Tmp = Cell.Offset(, 2)
TmpArr = Split(Cell, ",")
For i = 0 To UBound(TmpArr)
If TmpArr(i) = 32 Or TmpArr(i) = 33 Or TmpArr(i) = 34 Then
Tmp = Tmp & "," & TmpArr(i)
End If
Next i
If Len(Tmp) Then Cell.Offset(, 2) = Right(Tmp, Len(Tmp) - 1)
End If
Next Cell
End Sub
[/gpecode]
 
Upvote 0
Mình mới sửa đáp án ở dòng có con số 42 & xin lỗi các bạn về việc này!

Bài này cũng như fần nâng cao ta có thể viết hàm tự tạo.
 
Upvote 0
Thì... tự suy nghĩ thêm đi! Sao lại không được chứ?
Mình mới sửa đáp án ở dòng có con số 42 & xin lỗi các bạn về việc này!
Bài này cũng như fần nâng cao ta có thể viết hàm tự tạo.
Nếu không có dòng màu cam thì em vẫn nghĩ là không được. Có thể là còn nhiều cách dùng khác, nhưng em chỉ nghĩ được vậy thôi.
[gpecode=vb]
Public Function Trich(Cell As Range, a As Long, _
b As Long, c As Long)
Dim Tmp As String
If Cell = a Or Cell = b Or Cell = c Then
Tmp = Cell
Else
If InStr(1, "," & Cell & ",", "," & a & ",") Then _
Tmp = Tmp & "," & a
If InStr(1, "," & Cell & ",", "," & b & ",") Then _
Tmp = Tmp & "," & b
If InStr(1, "," & Cell & ",", "," & c & ",") Then _
Tmp = Tmp & "," & c
If Len(Tmp) Then Tmp = Right(Tmp, Len(Tmp) - 1)
End If
Trich = Tmp
End Function
[/gpecode]
 

File đính kèm

Upvote 0
Nếu không có dòng màu cam thì em vẫn nghĩ là không được. Có thể là còn nhiều cách dùng khác, nhưng em chỉ nghĩ được vậy thôi.

Thay dấu "," bằng khoảng trắng sẽ hay hơn
(và có thể lợi dụng thằng WorksheetFunction.Trim để "mần")
 
Upvote 0
Cái ni đáp ứng cho việc lọc nâng cao nè, Thảo.

PHP:
Option Explicit
Function TachSo(StrNum As Variant, Num1 As Long, Num2 As Long, Num3 As Long) As String
 Dim Tmp As Long, VT As Byte:               Const DF As String = ","
 On Error GoTo GPE
1                                           StrNum = StrNum & DF
 Do
    VT = InStr(StrNum, DF)
    If VT <= 1 Then Exit Do
    Tmp = Int(Left(StrNum, VT - 1))
    If Tmp = Num1 Then TachSo = TachSo & CStr(Num1) & DF
    If Tmp = Num2 Then TachSo = TachSo & CStr(Num2) & DF
    If Tmp = Num3 Then TachSo = TachSo & CStr(Num3) & DF
    StrNum = Mid(StrNum, VT + 1, Len(StrNum))
 Loop
 If Right(TachSo, 1) = "," Then TachSo = Left(TachSo, Len(TachSo) - 1)
Err_:                                       Exit Function
GPE:
    MsgBox Err, , Erl:                      Resume Err_
End Function
 
Upvote 0
Bài tập 1B: Xác định loại tam giác

ĐỀ BÀI 1B:

Trên 1 trang tính trắng ta tạo 1 nút nhấn (Ví dụ tại [D1])

Khi nhấn nút này, macro sẽ cho ta 3 giá trị ngẫu nhiên nguyên dương từ 5 đến 20 vô các ô [A4:C4]

Tại [D4] ta cài sẵn hàm người dùng để nó xác định giúp ta đó là loại tam giác gì (Lỗi, Thường, Vuông, cân, Vuông cân, đều)

| A | B | C | D 1 |Tam giác|Loại gì?||,,,,,,,
2 ||||
3 |Cạnh A|Cạnh B|Cạnh C|Loại TG:
4 |4|5|6|Thường

Như vậy là chúng ta có 2 yêu cầu:
(1) Tạo macro gắn với nút nhấn, để khi nhấn nó, nó sẽ tạo ra cho ta 3 số ngẫu nhiên nguyên dương từ 5..20
(2) Viết hàm người dùng gài sẵn ở [D4] để kết luận loại tam giác do 3 số ngẫu tạo ra.

Chúc các bạn thành công.
 
Upvote 0
ĐỀ BÀI 1B:

Trên 1 trang tính trắng ta tạo 1 nút nhấn (Ví dụ tại [D1])

Khi nhấn nút này, macro sẽ cho ta 3 giá trị ngẫu nhiên nguyên dương từ 5 đến 20 vô các ô [A4:C4]

Tại [D4] ta cài sẵn hàm người dùng để nó xác định giúp ta đó là loại tam giác gì (Lỗi, Thường, Vuông, cân, Vuông cân, đều)
---
Như vậy là chúng ta có 2 yêu cầu:
(1) Tạo macro gắn với nút nhấn, để khi nhấn nó, nó sẽ tạo ra cho ta 3 số ngẫu nhiên nguyên dương từ 5..20
(2) Viết hàm người dùng gài sẵn ở [D4] để kết luận loại tam giác do 3 số ngẫu tạo ra.

Chúc các bạn thành công.
Em viết đại, chẳng biết đúng hay sai nữa:
[gpecode=vb]
Sub Button1_Click()
Dim a As Integer, b As Integer, c As Integer, cL As Range
With Sheet1
[A4] = Int(Rnd() * 16) + 5
[B4] = Int(Rnd() * 16) + 5
[C4] = Int(Rnd() * 16) + 5
a = Application.Min([A4:C4])
c = Application.Max([A4:C4])
If [A4] = [B4] And [B4] = [C4] Then
[D4] = "Deu"
ElseIf [A4] = [B4] Or [A4] = [C4] Or [B4] = [C4] Then
If c = a ^ 2 Then
[D4] = "Vuong can"
Else
[D4] = "Can"
End If
Else
For Each cL In .[A4:C4]
If cL > a And cL < c Then
b = cL
End If
Next cL
If a ^ 2 + b ^ 2 = c ^ 2 Then
[D4] = "Vuong"
ElseIf a + b >= c Then
[D4] = "Thuong"
Else
[D4] = "Loi"
End If
End If
End With
End Sub
[/gpecode]
 

File đính kèm

Upvote 0
Còn thiếu 2 cái:

2uan trọng là 1 cạnh > 2 cạnh còn lại thì không thể là tam giác.

Chú chưa khởi động bộ tạo số ngẫu.

Chịu khó sửa đi chú.
 
Upvote 0
Ủa, hàm Rnd là số ngẫu nhiên mà bác.
Còn cạnh lớn nhất lớn hơn 2 cạnh còn lại là đã làm theo phương pháp loại trừ rồi.
 
Upvote 0
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Dưới góc độ rèn kỹ năng hàm IF() thì bài này nên viết như sau:

PHP:
Option Explicit
Sub TamGiacGi()
 Dim Aa As Integer, Bb As Integer, Cc As Integer, Tmp As Integer
 Const TG As String = "Tam giác "
 
 Randomize:                                 Cc = 5 + 15 * Rnd() \ 1
 Aa = 5 + 15 * Rnd() \ 1:                   Bb = 5 + Int(15 * Rnd())
 If Bb > Aa Then Tmp = Aa:      Aa = Bb:    Bb = Tmp
 If Cc > Aa Then Tmp = Aa:      Aa = Cc:    Cc = Tmp
 If Bb < Cc Then Tmp = Cc:      Cc = Bb:    Bb = Tmp
 [f3].Value = Aa:                             [h3].Value = Cc
 [g3].Value = Bb
 
 If Aa >= Bb + Cc Then
    Tmp = 0
 ElseIf Aa ^ 2 = Bb * Bb + Cc * Cc Then
    If Bb = Cc Then Tmp = 1 Else Tmp = 2
 ElseIf Aa = Bb Or Bb = Cc Then:            Tmp = 3
 ElseIf Aa = Bb And Bb = Cc Then:           Tmp = 4
 Else:                                      Tmp = 5
 End If
 If Tmp = 0 Then
    [j3].Value = "Khong The Là " & TG
    [j3].Interior.ColorIndex = 3
 Else
    [j3].Value = TG & Choose(Tmp, "Vuong Can", "Vuong", "Can", "Dèu", "Thuòng", "GPE.COM")
    [j3].Interior.ColorIndex = 34 + Tmp
 End If
End Sub

Trong macro, ta đang dùng tiếng Việt nữa vời.
Để trên trang tính ta có những mệnh đề tiếng Việt hoàn ching; Chúng ta có thể gởi trị trong tham biến Tmp vô ô nào trống gần [J3];
Sau đó tại [J3] ta dùng hàm CHOOSE() để thể hiện tiang Việt 1 cách nghiêm chỉnh.

Chúc các bạn ngày cuối tuần vui vẻ!
 
Upvote 0
Mình xóa bài vì thấy không hay .
 
Lần chỉnh sửa cuối:
Upvote 0
Đề nghị bạn fục hồi bài cho không ít người của cộng đồng tham khảo đi nha.

Có gì mà không hay cơ chứ:
[ThongBao]Ngoai Thanh
Mình xóa bài vì thấy không hay . [/ThongBao]
Cách viết tiếng Việt của bạn là chuẩn không cần chỉnh mà!

Tuy nhiên cách trên nêu (Dùng hàm CHOOSE() trong Ex.) cũng có thể đạt được, 1 khi trình độ VBA đang còn cấp thấp!
 
Lần chỉnh sửa cuối:
Upvote 0
Có gì mà không hay cơ chứ:
[ThongBao]Ngoai Thanh
Mình xóa bài vì thấy không hay . [/ThongBao]
Cách viết tiếng Việt của bạn là chuẩn không cần chỉnh mà!

Tuy nhiên cách trên nêu (Dùng hàm CHOOSE() trong Ex.) cũng có thể đạt được, 1 khi trình độ VBA đang còn cấp thấp!
Sợ thày và các bạn cho là "tinh vi", bài thì không làm được lại sửa tiếng việt bài thày nên nhà em xóa bài sợ mình vô duyên . Nếu thày đã nói vậy nhà em xin phục hồi lại .

Sub TamGiacGi()
Dim Aa As Integer, Bb As Integer, Cc As Integer, Tmp As Integer
Const TG As String = "Tam giác "

Randomize: Cc = 5 + 15 * Rnd() \ 1
Aa = 5 + 15 * Rnd() \ 1: Bb = 5 + Int(15 * Rnd())
If Bb > Aa Then Tmp = Aa: Aa = Bb: Bb = Tmp
If Cc > Aa Then Tmp = Aa: Aa = Cc: Cc = Tmp
If Bb < Cc Then Tmp = Cc: Cc = Bb: Bb = Tmp
[f3].Value = Aa: [h3].Value = Cc
[g3].Value = Bb

If Aa >= Bb + Cc Then
Tmp = 0
ElseIf Aa ^ 2 = Bb * Bb + Cc * Cc Then
If Bb = Cc Then Tmp = 1 Else Tmp = 2
ElseIf Aa = Bb Or Bb = Cc Then: Tmp = 3
ElseIf Aa = Bb And Bb = Cc Then: Tmp = 4
Else: Tmp = 5
End If
If Tmp = 0 Then
[j3].Value = "Không th" & ChrW(7875) & " là tam giác"
[j3].Interior.ColorIndex = 3
Else
[j3].Value = TG & Choose(Tmp, "Vuông cân", "vuông", "cân", ChrW(273) & ChrW(7873) & "u", "th" & ChrW(432) & ChrW(7901) & "ng", "GPE.COM")
[j3].Interior.ColorIndex = 34 + Tmp
End If
End Sub
 
Upvote 0
Ký tự ":" bị lạm dụng.
Dùng trong câu lệnh IF thì đúng nhiệm vụ của nó là ép nhiêuf l;ệnh vào một dòng. Nhưng dùng ngoài lệnh IF thì mục đích là nhóm các lệnh cùng nhóm với nhau. Không theo chuẩn làm nhóm lệnh trở nên tối nghĩa.
Dùng ký tự này với lệnh On error Resume Next sẽ có khả năng cho ra kết quả bất ngớ.

@leonguyenz:
Đề bài không bảo ghi vào các ô A4,B4,C4. Bạn ghi vào là sai đề
Muốn sử dụng hàm của application thì dùng Array
Dim snn()
snn = Array(Int(Rnd() * 16) + 5, Int(Rnd() * 16) + 5, Int(Rnd() * 16) + 5)
c = Application.Max(snn)
a = Application.Min(snn)
Nếu muốn tìm đoạn giữa thì:
snn(Application.Match(c, snn, 0) - 1) = a ' thế phần thử lớn nhất phần tử nhỏ nhất
b = Application.Max(snn) ' b là số ở giữa

Tôi chỉ mách cho bạn cách dùng hàm của Application thôi. Còn giải thuật của bạn có đúng hay không tôi chưa xem tới.
 
Upvote 0
ĐỀ BÀI 1B:

Trên 1 trang tính trắng ta tạo 1 nút nhấn (Ví dụ tại [D1])

Khi nhấn nút này, macro sẽ cho ta 3 giá trị ngẫu nhiên nguyên dương từ 5 đến 20 vô các ô [A4:C4]

Tại [D4] ta cài sẵn hàm người dùng để nó xác định giúp ta đó là loại tam giác gì (Lỗi, Thường, Vuông, cân, Vuông cân, đều)

| A | B | C | D 1 |Tam giác|Loại gì?||,,,,,,,
2 ||||
3 |Cạnh A|Cạnh B|Cạnh C|Loại TG:
4 |4|5|6|Thường

Như vậy là chúng ta có 2 yêu cầu:
(1) Tạo macro gắn với nút nhấn, để khi nhấn nó, nó sẽ tạo ra cho ta 3 số ngẫu nhiên nguyên dương từ 5..20
(2) Viết hàm người dùng gài sẵn ở [D4] để kết luận loại tam giác do 3 số ngẫu tạo ra.

Chúc các bạn thành công.
Tham gia cho vui nhà vui cửa, lâu rồi không tham gia chủ đề này
 

File đính kèm

Upvote 0
Hình như bạn này chưa xét trường hợp tam giác vuông cân thì fải

[Thongbao]Tham gia cho vui nhà vui cửa, lâu rồi không tham gia chủ đề này[/Thongbao]
 
Upvote 0
Bài tập 4A: Tìm thí sinh có tổng điểm các môn cao nhất trong 1 danh sách.

ĐỀ BÀI 4A


Ở bài 4 chúng ta đẽ lập ra danh sách các em có điểm từng môn cao nhất (& cả thấp nhất)
Nhiệm vụ lần này của chúng ta có vẻ nhẹ nhàng hơn:

Tìm ra trong danh sách như dưới đây, số báo danh nào có tổng điểm các môn là cao nhất?


STT| SBD |HoTen|Lop|Van|Li|Dia|Toan|Sinh|Anh
001|350030|Đàm Đức Anh|12A|8.8|9|8.8|8|7.8|5.5
002|350031|Đàm Bá Sự|12A|8.8|9|8.8|8|7.7|5.5
003|350097|Doãn Thị Huyền|12A|9|9|8.8|8|8|5.5
..||)*&^)|..|.||.||.|.
108|350629|Trần Hoài Fương|12A9|4.8|5|5.5|4.8|5|8
 

File đính kèm

Upvote 0
Tham gia cho vui nhà vui cửa, lâu rồi không tham gia chủ đề này

Bài giải của bạn có những điểm sau đây:

(A) Trình bày:
Nút bấm ghi là "kiểm tra", trước khi bấm, người ta ta nhìn thấy trên màn hình là a1, b1, c1, và THUONG.
Nếu tôi bấm but, tôi nghí là tôi đang kiểm tra 3 số a1, b1, c1 này
Sau khi bấm, trên màn hình là a2, b2, c2 và THUONG/DEU/... làm tôi bất ngờ

Bạn nên đặt nút tên là "KIEM TRA BA SO KHAC".

(B) Giải thuật:
Bình thường, theo lập trình cơ cấu thì tạo ra từng hàm để xét tính chất là đúng. Nhưng tam giác là trường hợp đặc biệt. Nếu biết được cạnh dài nhất thì hầu hết các tính chất đều sẽ đơn giản 1/2 các con toán so sánh - trừ tính chất cân. Vì vậy, sort giá trị rồi làm luôn một thể thì tiện hơn.

Theo tôi hiểu thì lô gic TG Cân của bạn loại trường hợp TG đều. Như vậy là phản đại số, TG đều chỉ là trường hợp đăc biệt của cân.

(C) Mở rộng:
Tôi nhớ mang máng hình như bạn có nói mình chuyên về C++.
Với trình độ này, bạn nên thử làm hai chiều hướng mở rộng. Các cạnh là số thực, không nhất thiết là số nguyên (*)

(*) đối với người mới bắt đầu, phân biệt sô thực và sô nguyên là một điều căn bản cần phải học, và bài này là một cơ hội tốt.
 
Upvote 0
Bài giải của bạn có những điểm sau đây:

(A) Trình bày:
Nút bấm ghi là "kiểm tra", trước khi bấm, người ta ta nhìn thấy trên màn hình là a1, b1, c1, và THUONG.
Nếu tôi bấm but, tôi nghí là tôi đang kiểm tra 3 số a1, b1, c1 này
Sau khi bấm, trên màn hình là a2, b2, c2 và THUONG/DEU/... làm tôi bất ngờ

Bạn nên đặt nút tên là "KIEM TRA BA SO KHAC".

(B) Giải thuật:
Bình thường, theo lập trình cơ cấu thì tạo ra từng hàm để xét tính chất là đúng. Nhưng tam giác là trường hợp đặc biệt. Nếu biết được cạnh dài nhất thì hầu hết các tính chất đều sẽ đơn giản 1/2 các con toán so sánh - trừ tính chất cân. Vì vậy, sort giá trị rồi làm luôn một thể thì tiện hơn.

Theo tôi hiểu thì lô gic TG Cân của bạn loại trường hợp TG đều. Như vậy là phản đại số, TG đều chỉ là trường hợp đăc biệt của cân.

(C) Mở rộng:
Tôi nhớ mang máng hình như bạn có nói mình chuyên về C++.
Với trình độ này, bạn nên thử làm hai chiều hướng mở rộng. Các cạnh là số thực, không nhất thiết là số nguyên (*)

(*) đối với người mới bắt đầu, phân biệt sô thực và sô nguyên là một điều căn bản cần phải học, và bài này là một cơ hội tốt.

em chỉnh lại như vậy thầy xem thấy được không
Function KIEMTRA(ByVal C1 As Double, ByVal C2 As Double, ByVal C3 As Double)
If ((C1 + C2 <= C3) Or (C1 + C3 <= C2) Or (C2 + C3 <= C1)) Then
KIEMTRA = False
Exit Function
Exit Function
End If
KIEMTRA = True
End Function
Function TINHCHATTAMGIAC(ByVal C1 As Double, ByVal C2 As Double, ByVal C3 As Double) As String
If ((C1 = C2) Or (C1 = C3) Or (C2 = C3)) Then
If (C1 = C2 And C1 = C3) Then
TINHCHATTAMGIAC = "DEU"
ElseIf (C1 * C1 + C2 * C2 = C3 * C3) Or (C1 * C1 + C3 * C3 = C2 * C2) Or (C3 * C3 + C2 * C2 = C1 * C1) Then
TINHCHATTAMGIAC = "VUONGCAN"
Else
TINHCHATTAMGIAC = "CAN"
End If

ElseIf (C1 * C1 + C2 * C2 = C3 * C3) Or (C1 * C1 + C3 * C3 = C2 * C2) Or (C3 * C3 + C2 * C2 = C1 * C1) Then
TINHCHATTAMGIAC = "VUONG"
Exit Function
End If
TINHCHATTAMGIAC = "THUONG"
End Function
Sub BAITAP1()
Dim C1, C2, C3 As Double

C1 = Round(Rnd() * 15 + 5, 1)
C2 = Round(Rnd() * 15 + 5, 1)
C3 = Round(Rnd() * 15 + 5, 1)
Range("A4").Value = C1
Range("B4").Value = C2
Range("C4").Value = C3
If (KIEMTRA(C1, C2, C3) = False) Then
Range("D4").Value = "LOI"
Exit Sub
End If
Range("D4").Value = TINHCHATTAMGIAC(C1, C2, C3)
End Sub
 
Upvote 0
em chỉnh lại như vậy thầy xem thấy được không

Bạn là thầy giáo mà. Mình chơi cho nó toán học một chút:

Luật bất đẳng thức: nếu { a <= b <= c } and { a = c } suy ra { a = b = c }

1. sắp xếp để c >= b >= a
2. đặt TC = 0
3. nếu c > a+b ---> không phải TG; nhảy qua 8, không cần xét tiếp
4. nếu a = c ---> TG đều; TC = TC + 4; nhảy qua 8, không cần xét tiếp vì TG đều không thể vuông
5. nếu a = b hoặc b = c ---> TG cân; TC = TC + 1 nhưng vẫn xét tiếp vì nó có thể vuông
6. nếu c*c = a*a + b*b --> TG vuông; TC = TC + 2
7. nếu TC = 0 --> chả có tính gì cả; TC = 5
8. xét TG
Tinh_Chat_TG = Array( "Không phải TG", "Cân", "Vuông", "Vuông Cân", "Đều", "Thường")(TC)

=== Bổ sung ===

Riêng đề tài số thực thì bạn sai rồi. Cố nhớ lại xem ngày xưa học số thực ra sao - nếu tôi không lầm thì bạn nói mình là dân viết C++ mà!
 
Lần chỉnh sửa cuối:
Upvote 0
em vẫn chưa hiểu thầy nói về đề vấn đề " số thực" không biết là thầy muốn nói đến cách khai báo biến? phạm vi biến? độ lớn biến? hay là .., em vẫn chưa hiểu.thầy có thể giải thích cho em được không? hôm nay em được học hỏi thêm 1 giải thuật về kiểm tra tam giác. đúng em là dân lập trình cơ sở cách viết của em chủ yếu là chia nhỏ để dễ quản lý. em thường chọn những giải thuật đơn giản dễ hiểu để giải quyết vấn đề( giải thuật chưa tỗi ưu). khi nào giải quyết xong vấn đề thì em sẽ tự ngẫm ra các giải thuật khác tối ưu hơn. em cũng mới tiếp cận tới vba chủ yếu là vì cv, mà chưa có rành về code nên nhiều bài viết cũng chưa hay. có nhiều bài em có ý tưởng giải. chạy trên giấy thì ok mà viết vba thì lỗi nên thôi chọn cách viết ra đáp án chữa cháy chờ học hỏi. bên vba này khai báo biến không rõ như bên c nên cũng hơi hơi mù mờ. hy vọng là được học hỏi thêm từ thầy và các tv tren diễn đàn. xin chân thành cảm ơn
 
Upvote 0
em vẫn chưa hiểu thầy nói về đề vấn đề " số thực" không biết là thầy muốn nói đến cách khai báo biến? phạm vi biến? độ lớn biến? ...

khai báo biến? phạm vi biến? độ lớn biến? Những điều đó đều có tính chất tương đối.
Duy có một điều về số thực mà luôn luôn áp dụng, gần như cho mọi hệ thống, mọi ngôn ngữ. Nếu tôi dạy học thì tôi sẽ bảo HS tôi chép 20 lần câu này trong vở:

Số thực không thể so sánh bằng toán từ =

Hai số thực chỉ có thể chấp nhận là bằng nhau với một sai số nào đó. Trong lập trình số thực, người ta đặt ra một sô rất nhỏ làm sai số, vd epsilone = 1E-10 (0.0000000001) và so sánh 2 số thực như sau:

IF ABS(a - b) <= epsilon Then { a coi như bằng b }

Vì đề bài này từ đầu có quy định các cạnh là số nguyên cho nên các bạn cứ thẳng tiến. Nếu các cạnh là số thực thì các code trên tính ra sai hết!
 
Upvote 0
dạ cảm ơn thầy đã giúp, em sẽ tìm hiểu về vẫn đề này. từ trước tới giờ em vẫn không biết số thực không được phép so sánh bằng.
 
Upvote 0

Bài viết mới nhất

Back
Top Bottom