Bài 2: Những macro phức tạp hơn 1. Tăng đồng loạt tiền thưởng cho một danh sách Gần cuối tháng sếp yêu cầu bạn lập danh sách tiền thưởng của toàn cơ quan, kèm theo lệnh: Tăng 15% so với tháng trước; Nếu tháng nào sếp cũng chỉ đạo tăng hay giảm tiền thưởng so với tháng trước, thì đây là miếng đất màu mỡ để macro hoạt động; Vấn đề là bạn đã có danh sách CNV trong toàn cơ quan. Trong đó, cột F, kể từ F3 là dữ liệu tiền thưởng tháng trước. Bạn nên thu một macro để sử dụng cho các tháng sau với những hành động như sau: Vô menu Tool > Macro > Record New Macro. . . . Tại cửa sổ (CS) Record Macro ta nhập Thuong (là tên macro), xong OK Quét chọn từ ô G3 đến ô G99 (ô chứa người cuối cùng trong danh sách cơ quan) Bấm chuột lên thanh công thức và nhập dấu bằng ( =), dùng trỏ chuột ấn vô ô F3, sau đó nhập tiếp dấu nhân và giá trị 1,15 (như ý của sếp). Kết thúc việc nhập liệu bằng hai phím CTRL+ENTER Vẫn những ô được chọn, ta vô menu Edit > Copy; Sau đó thực hiện Paste Special; Trong CS Paste Special ta đánh dấu kiểm tại dòng Value Công đoạn cuối cùng là cắt toàn bộ dữ liệu cột G này dán lên cột F Ta thu được macro có nội dung sau (đã thu gọn các dòng lệnh ngắn):
Bài 2: Những macro phức tạp Tăng đồng loạt tiền thưởng cho danh sách Gần cuối tháng sếp yêu cầu bạn lập danh sách tiền thưởng toàn quan, kèm theo lệnh: "Tăng 15% so với tháng trước; Nếu tháng sếp đạo tăng hay giảm tiền thưởng so với tháng trước, miếng đất màu mỡ để macro hoạt động; Vấn đề bạn có danh sách CNV tồn quan Trong đó, cột F, kể từ F3 liệu tiền thưởng tháng trước Bạn nên thu macro để sử dụng cho tháng sau với hành động sau: * Vô menu Tool -> Macro -> Record New Macro Tại cửa sổ (CS) Record Macro ta nhập Thuong (là tên macro), xong OK * Quét chọn từ ô G3 đến ô G99 (ô chứa người cuối danh sách quan) * Bấm chuột lên công thức nhập dấu ( '='), dùng trỏ chuột ấn vô ô F3, sau nhập tiếp dấu nhân '*' giá trị 1,15 (như ý sếp) Kết thúc việc nhập liệu hai phím CTRL+ENTER * Vẫn chọn, ta vơ menu Edit -> Copy; Sau thực Paste Special; Trong CS Paste Special ta đánh dấu kiểm dòng Value * Cơng đoạn cuối cắt toàn liệu cột G dán lên cột F Ta thu macro có nội dung sau (đã thu gọn dòng lệnh ngắn): Code: Sub Thuong() Range("G3:G95").Select Selection.FormulaR1C1 = "=RC[-1]*1.15" Selection.Copy Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False Application.CutCopyMode = False: Selection.Cut Range"F").Select: ActiveSheet.Paste End Sub Thực việc thêm vơ macro: Macro Thuong bất tiện: - Nếu quan tăng người phải sửa lại dòng lệnh đầu; - Lượng tăng giảm tiền thưởng theo ý chủ quan sếp (doanh nghiệp tư nhân) Vấn đề đầu dễ giải quyết, ta việc ấn định thừa lên; thay G95 ta nhập G450, Việc chưa phải tối ưu, thời điểm nên chấp nhận giải pháp Đợi sau trình độ ta lên, giải cách hơn! Để giải vấn đề lại, ta thực bước sau: Tại dòng lệnh ta nhập tiếp dấu hai chấm (':'), sau ấn lần phím {TAB} thêm chuỗi: dim StrC as string; Để kết thúc, nhấn ENTER Nếu excel sửa lại cho ta, trở thành sau đúng: Range("G3:G450").Select: Dim StrC As String Tại dòng trống ta vừa tạo ra, ta nhập câu lệnh: ctrc = inputbox("HAY NHAP HE SO: ") Sau ENTER, nhập tiếp dòng sau: strc = "=RC[-1]*" & strc Cuối ta sửa lại dòng lệnh trở thành: Selection.FormulaR1C1 = strc Khi macro có nội dung sau: Code: Sub Thuong() Range("G3:G15").Select: Dim StrC As String StrC = InputBox("HAY NHAP HE SO: ") StrC = "=RC[-1]*" & StrC Selection.FormulaR1C1 = StrC Selection.Copy Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False Application.CutCopyMode = False Selection.Cut Range("F3").Select ActiveSheet.Paste End Sub Chú ý: * Câu lệnh mà ta thêm vô macro câu lệnh khai báo với VBA sử dụng biến có tên StrC, kiểu chuỗi Câu lệnh thứ là: Hãy lấy giá trị cho biến StrC giá trị nhập vô; câu tiếp dịch nôm na là: nối biến chuỗi vừa nhập vô sau chuỗi ghi; Và cuối (câu lệnh ta sửa): gán giá trị biến mà khai báo & thiết lập, trở thành công thức ô hành; * Khi khai báo tên biến, ta nên viết chữ hoa & chữ thường, ta tận dụng lợi sẵn có chương trình kiểm lỗi tả VBA; Ở trường hợp StrC; Tuy khai báo vậy, nhập tên biến ta nhập không theo vậy, nhờ VBA sửa cho ta, dịp để kiểm tra phát lỗi tả nhập sai tên biến Tên biến không chứa kí tự tốn học & khơng dài 64 kí tự * Về kiểu biến thí có nhiều; đến ta cần biết kiểu hay thường dùng: Kiểu Byte kiểu số nguyên, miền giá trị từ đến 255 Kiểu Boolean: kiểu logic, loại nhận hai giá trị: True & False Kiểu Integer: Số nguyên, miền giá trị từ -32768 đến 32767 Kiểu Long: Cũng số nguyên có miền lớn hơn: -2.147.483.648 đến 2.147.483.647 Kiểu Currency: tiền tệ; Kiểu Double: kiểu số thực, chứa byte ô nhớ Kiểu String: kiểu chuỗi ký tự, miền lưu giữ tối đa 65.400 ký tự * Lệnh gán, ngôn ngữ VBA dùng dấu = làm lệnh gán; Ví dụ sau khai báo biến StrC trên, ta dùng lệnh gán: StrC = "=RC[1]*"; Ở hai dấu nháy kép để bao chuỗi cần gán vô biến * Trong macro có hàm InputBox( " .") Hàm làm xuất hộp thoại, nhận giá trị chuỗi mà ta nhập vơ Trong trường hợp gán vô biến StrC giá trị mà ta nhập vô; * Trong câu lệnh dài, chiếm dòng đó, ta vơ hiệu hố đoạn cuối, kể từ dấu ',' thứ hai cách thêm dấu nháy trước nó; Khi dòng hai câu lệnh bị tơ đỏ, báo cho ta biết bất ổn nó; Sự việc ta vơ hiệu hố ln dấu nối dòng lệnh Để khắc phục, ta nhập thêm dấu nháy đơn vơ đầu dòng bị tơ đỏ được; Cuối cùng, trước chạy tác phẩm, ta nên vơ menu Debug chọn dòng Compile VBAProject, để làm chi bạn biết Trước chạy macro ta thực việc gán phím tắt CTRL+SHIFT+T cho nó; Có thể có bạn hỏi, điều bắt buộc?, khơng, hồn tồn tự nguyện, nên Cũng giống ta không nên chân vĩa hè & chân lòng đường 3./ Tính tốn giá trị cột Ta xét trường hợp đơn vị hành nghiệp cần lập danh sách thưởng định kỳ; Để thưởng theo hệ số đơn vị hệ số thành tích cá nhân, người ta lập bảng liệu gồm trường: [Ma], [Ho], [Ten], [MDV], [XL], [TThuong] (6 cột A ) Nhiệm vụ macro tính số tiền thưởng cá nhân tương ứng với hệ số cá nhân hệ số đơn vị (tại cột 'F') với trợ giúp bảng đặt tên HeSo Bảng HeSo gồm cột & dòng Cột thứ hai ghi hệ số thưởng đơn vị; Cột thứ ba ghi số tiền thưởng cá nhân tương ứng với danh hiệu thi đua đạt Để bắt đầu thu macro ta vô menu Tool -> Macro -> Record New Macro & đặt tên macro Tinh_Thuong Trên trang tính ta chọn ô F6, nơi cần xuất tiền thưởng người danh sách Tiếp theo vô menu Insert -> Function Trong CS Insert Function vừa xuất hiện, ta nhập tên hàm VLOOKUP nhấn nút Go chọn CS Select a function hàm VLOOKUP() Khi bảng trợ giúp hàm xuất hiện, ta thấy dấu nhắc ô Lookup_Value, ta nhấp chuột vô ô D6 ( chứa mã đơn vị người đầu tiên); Trong ô Table_array ta nhập HeSo; cuối ô Col_Index_Num ta nhập số 2; Xong ta ENTER để trang tính; Ta trỏ chuột lại lên công thức; nhập dấu nhân '*' lại vô menu Insert lặp lại bước Duy khác thay số ta nhập số vơ ô Col_Index_Num; Trở trang tính, ta chọn lại ô F6 dùng chức AutoFill để chép công thức xuống dòng dưới; (VD: tới dòng cuối 21) Sau ta chọn vùng F6:F22 bấm lên nút AutoSum công cụ; Excel báo cho ta tính tổng cột & nhập vơ 23 Ta tán thành việc làm kết thúc macro cách biết Macro thu bạn có trùng khớp vầy? (Thực tế ta vơ hiệu hố hay bỏ dòng thứ hai đi!) Code: Sub Tinh_Thuong() Range("F6").Select ActiveCell.FormulaR1C1 = "=VLOOKUP(RC[-2],HeSo,2)" ActiveCell.FormulaR1C1 = "=VLOOKUP(RC[2],HeSo,2)*VLOOKUP(RC[-1],HeSo,3)" Selection.AutoFill Destination:=Range("F6:F21"), Type:=xlFillDefault Range("F6:F21").Select Range("F23").Select ActiveCell.FormulaR1C1 = "=SUM(R[-17]C:R[-1]C)" Range("F24").Select End Sub Hãy cố đọc để hiểu nội dung nó; Trong có dùng hai hàm SUM() & VLOOKUP() Kinh nghiệm cho thấy, ta đọc từ phải sang trái dễ hiểu câu lệnh Vì dụ hai câu lệnh gần cuối hiểu sau: Chọn ô 'F23' Lấy tổng ô từ ô thứ 17 hàng trước ô hành, ô trước ô hành ô gán cho ô hành 4./ Chuyển động tuyệt đối & tương đối Ta xem xét đến câu lệnh Range("F23").Select & câu lệnh Range("F24").Select Trong thực tế ta không dùng chuột ấn vơ nút này, mà nhập cơng thức tính tổng ô F23 xong ta thực ENTER Kết đến F24 máy ghi! Trong dòng lệnh thứ hai, hàm VLOOKUP() có đối số thứ ghi RC[-2]; chữ C số cột, chữ R số hàng; Í nghĩa thực tế đối số thứ hàm ô hàng & phía bên trái cách cột Trong câu lệnh lấy tổng, nói trên; VBA lại ghi theo dạng thức tương tự "B2:D9": góc trái & góc phải vùng chọn Để rõ ta xét đến macro ghi lại chuyển đông bàn phím sau: Vẫn lấy ví dụ tính tiền thưởng nêu trên, mà CSDL (cơ sở liệu) gồm có 23 dòng tất (tại cột 'F') Ta thu macro (tên DiChuyen) với hành động sau: Chọn B2; ấn đồng thời phím CTRL & phím mũi tên xuống (điểm sáng tới ô B5, ô cột có giá trị (đang chứa Ký tự 'Ho' tô đậm) Lặp lại lần nữa, kích hoạt B21 (là dòng cuối khơng kề dòng chứa cơng thức tổng) Nếu tiếp tục ta đến dòng cuối trang tính! Bây chừ phải ngược lên thơi: ấn CTRL+ phím mũi tên lên: kích hoạt lại B21; lặp lại hành động lần – B5 Cuối sẻ ô B1 ta muốn! Code: Sub DiChuyen() Range("B2").Select Selection.End(xlDown).Select Selection.End(xlDown).Select Selection.End(xlDown).Select Selection.End(xlUp).Select Selection.End(xlUp).Select Selection.End(xlUp).Select End Sub Có macro chạy nhanh quá, không làm bạn tin!?! Muốn ghi nhận lại vị trí kích hoạt thực lần ta làm theo cách sau: Đầu dòng lệnh thứ ta nhập câu lệnh sau dim lJ as long: nhấn hai lần phím {TAB} (chú í có dấu hai chấm ':') Để điểm chèn cuối dòng lệnh thứ hai & ấn ENTER, thêm dóng trắng ta nhập lên hai câu lệnh cách dấu hai chấm, sau: lj = selection.row: msgbox str(Lj) (chú ý: chữ selection & chữ row có dấu chấm) Ta chịu khó lặp lại chuyện tất dòng lệnh trước cụm từ End Sub Thực biên dịch Sub nêu & cho chạy lại macro Trước kết thúc macro đưa sáu hộp thoại báo cho ta biết ô kích hoạt hàng thứ trang tính Chú ý: Ø Tại ta phải khai báo biến lj có kiểu Long, mà khơng Integer hay Double? Nếu khai báo Integer biến khơng đủ lực để đến dòng 65536, mà bị bắt lỗi! Nhưng ngược lại, khai báo kiểu liệu Double q dư thừa & lãng fí tài ngun Hơn khơng mà macro chạy nhanh hơn! Ø Hàm MsgBox() tương tự hàm InputBox() nêu trên, có điều chiều tác động ngược lại, hàm sau nhận thơng tin tự người dùng, hàm thơng báo cho người dùng mà người dùng thiếu thơng tin! Ø Hàm Str(Num), hay hàm CStr(Num) biến đổi kiểu liệu dạng số ( Byte, Integer, Long .) thành chuỗi kí số Cần nhớ CStr(Num) & Str(Num) có khác nhiều trường hợp! Ví dụ Cú pháp Range( "A" & CStr(9) ).Select VBA hiểu; Còn Range("A" & Str(9)).Select khơng! Tuy biên dịch VBA khơng phát lỗi này! 5./ Nối macro Ta chép hết dòng lệnh macro sau (chỉ trừ câu Sub DiChuyen & dòng End Sub) vơ trước dòng End Sub macro nêu Điều làm hai macro làm cơng việc hồn tồn khác nhau, cơng việc xong khơng liên quan đến cơng việc sau Một cách khác ta nhập tên macro sau vô dòng lệnh vừa nêu macro trước: Code: Sub Thuong() DiChuyen End Sub Hay Code: Sub Tinh_Thuong() DiChuyen End Sub tất nhiên trường hợp, hộp thoại ta ghi thêm đưa thơng tin khác nhau! Bài tập hai : 1./ Tạo macro xố dòng (hay cột) chứa mẫu tin 2./ Tạo macro cho ẩn hay cột (hay dòng) chứa liệu 3./ Hãy tạo bảng tính có cột [ĐG] & [SL], tạo macro tính cột [TTien] 4./ Hãy tạo macro xếp học lực cho HS theo điểm trung bình mơn học ... "=VLOOKUP(RC[ -2] ,HeSo ,2) " ActiveCell.FormulaR1C1 = "=VLOOKUP(RC [2] ,HeSo ,2) *VLOOKUP(RC[-1],HeSo,3)" Selection.AutoFill Destination:=Range("F6:F21"), Type:=xlFillDefault Range("F6:F21").Select Range("F23").Select... cơng thức xuống dòng dưới; (VD: tới dòng cuối 21 ) Sau ta chọn vùng F6:F 22 bấm lên nút AutoSum công cụ; Excel báo cho ta tính tổng cột & nhập vơ ô 23 Ta tán thành việc làm kết thúc macro cách biết... đến 25 5 Kiểu Boolean: kiểu logic, loại nhận hai giá trị: True & False Kiểu Integer: Số nguyên, miền giá trị từ - 327 68 đến 327 67 Kiểu Long: Cũng số nguyên có miền lớn hơn: -2. 147.483.648 đến 2. 147.483.647