Từ macro đến VBA. Bài 1

  • Thread starter SA_DQ
  • Ngày gửi
S

SA_DQ

Thành viên thân thiết
29/6/05
435
38
28
61
HCM city
#1
. . . . . . . . . . . . . . . . . . . . PHẦN MỞ ĐẦU. . . . . . . . . . . . . . . . . . . .
Microsoft excel là một công cụ mạnh dùng trong việc phân tích & trình bày các thông tin. Thế mạnh của bảng tính excel, ngoài các công thức sẵn có, còn là macro của nó.
Kể từ khi xuất hiện version 5.0 đến nay, ngôn ngữ dùng trong excel là Visual Basic for Applications (VBA). Đó là ngôn ngữ lập trình dùng chung cho nhiều phần mềm trong windows.
Quyễn ghi chép này sẽ nhằm giới thiệu cách thức làm quen với macro, và cách thức tuần tự chinh phục ngôn ngữ VBA trong excel.
Bài 1 /(/hững macro đơn giản nhất

1./ Bộ thu macro

/(/gôn ngữ macro là một ngôn ngữ lập trình thật sự. Nhưng mặt trái của sự mạnh mẽ này là làm cho ta không dễ đọc & hiểu ngay được.
Để bước đầu làm quen với nó ta nhờ bộ thu macro, bộ thu này luôn có sẵn trong excel. Nó giúp bạn tạo ra những tác phẩm đầu tay và rất thực tế. Để rồi sau đó ta sẽ tạo ra những macro phức tạp, thực hiện những công việc theo sở thích của bạn!

2./ Tạo macro đầu tay:


Khi thực hành với excel, chúng ta đôi lúc cũng phải định dạng dẫy ô nào đó. Muốn dẫy biểu thị dạng tiền VNĐ không có số lẽ, ta chọn dãy ô; vô menu Format -> Cells; ->Number ta chọn Currency trong hộp thoại Category; trong hộp Decimal places ta chọn giá trị 0; trong hộp Symbol ta chọn None; cuối cùng trong hộp Negative numbers ta chọn hàng thứ ba (đang là (1.2340)) và nhấp vô nút OK để trở về trang tính
Excel mặc định dạng thức tiền có hai số lẽ. Trong thực tế nhiều khi không cần nhiều số lẽ đến vậy!. Chúng ta tạo một macro để định dạng ô theo kiểu tiền không có số lẽ.
a./ Chuẩn bị:

Ta quét chọn các ô từ A2 đến A9; bấn chuột lên thanh công thức và nhập các hàm sau:
= INT(9 * RAND()) ^ 8 và kết thúc bằng tổ hợp hai fím CTRL+ENTER
b./ Tạo macro

Vô menu Tool -> Macro ->Record New Macro. . .; cửa sổ New Macro xuất hiên; Trong hộp Macro Name ta nhập FormatCurrency và nhấp nút OK.
Trên màn hình sẽ hiện thêm thành phần thanh Toolbar của macro. Chúng ta bắt đầu thực hiện việc ghi vô bộ thu macro:
(Với các ô A2:A9 đã chọn), vô menu Format -> Cells. . . và chọn ngăn Number; Tiếp theo chọn Currency trong hộp thoại Category; trong hộp Decimal places ta chọn giá trị 0; trong hộp Symbol ta chọn None; cuối cùng trong hộp Negative numbers ta chọn hàng thứ ba (đang là (1.2340)) và nhấp vô nút OK để trở về trang tính.
Kết thúc ghi macro bằng cách nhấp vô nút close trên thanh Toolbar của macro vừa xuất hiện
Chú ý: Một số thao tác có thể có nhiều cách để đạt được; thí dụ tổ hợp phím CTRL +1 sẽ nhanh chóng đưa ta đến hộp thoại Format Cells; Ta cũng có thể kết thúc ghi macro khi chọn trên menu Tool -> macro -> Stop Recording; Trong phần ghi chép này chỉ ghi một cách thức (còn các cách khác ta tự áp dụng)
Tác phẩm đầu tay đã xong; Chúng ta nóng ruột muốn biết đứa con tinh thần nó hình hài ra sao & sẽ chạy nhãy như thế nào!
Để xem hình hài ta vô menu Tool -> Macro; trong danh sách liệt kê nó là tên duy nhất mà ta đã ấn định: FormatCurrency; Nội dung nó như sau:

Sub FormatCurrency()

'
' FormatCurrency Macro
' Macro recorded 10/10/2006 by Quai Dang
'
'
Selection.NumberFormat = "#,##0_);(#,##0)"
End Sub
Thực ra chỉ có ba dòng lệnh trong macro là quan trọng thôi; các dòng có dấu nháy đầu dòng là những ghi chú, nhắc chúng ta fút nó chào đời như: tên, tuổi , fím nóng để vận hành . . .
c./ Chạy macro

Để biết nó đi đứng ra sao ta quét chọn vài ô dữ liệu số trên trang tính; vô menu Tool -> Macro -> Macros; chọn tên macro và ấn nút Run
d./ Gán tổ hợp phím tắt cho macro
Vô menu Tool -> Macro -> Macros; cửa sổ Macro xuất hiện trở lại; Phía phải của cửa sô (CS), ngoài nút Run mới quen, còn có các nút khác mà ta sẽ dần làm quen. Và nút kế tiếp ta làm quen là Option; Ta nhấp vô nó để hiện lên CS Macro Option; Ta bấm chuột vô ô Shortcut key; ấn giữ phím Shift và nhấn tiếp phím ‘F’. (Như vậy là ta gán cho macro FormatCurrency tổ hợp 3 fím CTRL+SHIFT+F
Chú ý: Tất nhiên ta cũng có thể không giữ fím Shift; nhưng việc đó lợi bất cập hại vì dễ gây xung đột!
Chú ý: Ta cũng có thể gán tổ hợp phím nóng ngay từ đầu, sau khi đặt tên: Khi đó ta cũng đã thấy CS Shortcut key trong hộp thoại Record Macro

3./ Macro thay đổi nhiều thuộc tính

a./ Chuẩn bị: Nhập vô ô B2 chuỗi sau:
‘Tổng hợp số liệu tháng 10/06’. Chọn ô B2 này;
b./ Thu macro:

Vô menu Tool -> Macro ->Macros . . . Trong CS Macro name nhập tên: ‘DinhDangTieuDe’; Trong CS Shortcut key ta giữ phím Shift & nhấn phím ‘D’ và nhấn nút OK để ghi macro mới..
Khi ô B2 vẫn được chọn, vô menu Format -> Cells. . .Tiếp theo vô ngăn Aligment; Trong CS Text aligment ta chọn tại cả hai CS Horizontal & Vertical đều là Center; Sau đó ấn nút OK để trở về trang tính; Ta quét chọn các ô từ B2 đến F2; Sau đó nhấp vô nút Merge and Center để tiêu đề canh giữa của các ô liệt kê. Kết thúc việc ghi macro DinhDangTieuDe bằng 1 trong các cách nêu trên.
Để xem nội dung macro ta nhấn đồng thời hai phím ALT + F6 để mở CS Macro và chọn tên DinhDangTieuDe; xong rồi ấn chọn nút Edit để hiện màn hình Microsoft Visual Basic có chứa đoạn code sau:

Sub DinhDangTieuDe()

'
' DinhDangTieuDe Macro
' Macro recorded 10/10/2006 by Quang Duc
'
' Keyboard Shortcut: Ctrl+Shift+D
'

Range("B2").Select
With Selection
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
.WrapText = False
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
Range("B2:F2").Select
With Selection
.HorizontalAlignment = xlCenter
.WrapText = False
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
Selection.Merge
End Sub
(ái macro trước thực tế chỉ có một dòng lệnh; nhưng macro này rất nhiều dòng lệnh.
c./ Bước đầu tác động lên macro:

Trước tiên, ta biết các dòng có dấu nháy đơn đầu dòng lá những dòng chú thích; ta bỏ hẵn 5 dòng. (Chỉ để dòng ' Keyboard Shortcut: Ctrl+Shift+D). Nhưng cắt nó dán sau 2 dấu ngoạt đơn; của dòng Sub DinhDangTieuDe()
Ta vô menu Debug và chọn thanh Compile VBAProject; Nếu chúng ta không thấy CS thông báo lỗi nào thì ta biết rằng VBA chấp nhận những thay đổi của chúng ta (chứng tỏ không có lỗi biên dịch.)
Hơn nữa ta lại biết thêm rằng, các chú thích có thể ngay sau câu lệnh, miễn trước nó có dấu nháy đơn;
Tiếp theo ta thực hiện đánh số vô các dòng lệnh và sau đó mạnh dạn bỏ các dòng lệnh từ 5 đến 11. Ta lại thực hiện kiểm lỗi biên dịch nhờ menu Debug như nêu trên; Nếu không được báo lỗi nào, ta yên tâm bấm nút lưu lại
Tiếp một bước xa hơn, ta đặt dấu nháy trước các số của các dòng lệnh từ 14 đến 23. Tức là ta vô hiệu các dòng lệnh này một cách tạm thời;
Thực hiện phép thử macro lần cuối, như sau:
Xoá nguyên dòng 2 chứa định dạng mà macro đã thực hiện; Nhập dòng khác thay thế (VD: ‘BÁO CÁO TÌNH HÌNH THÁNG TRƯỚC.’ và thử chạy macro DinhDanhTieuDe; Nếu nó vẫn làm việc theo đúng như lúc chưa sửa gì là ô kê!
Sub DinhDangTieuDe() ' Keyboard Shortcut: Ctrl+Shift+D
1 Range("B2").Select
2 With Selection
3 .HorizontalAlignment = xlCenter
4 .VerticalAlignment = xlCenter
12 End With
13 Range("B2:F2").Select
14 With Selection
15 .HorizontalAlignment = xlCenter
16 .WrapText = False
17 .Orientation = 0
18 .AddIndent = False
19 .IndentLevel = 0
20 .ShrinkToFit = False
21 .ReadingOrder = xlContext
22 .MergeCells = False
23 End With
24 Selection.Merge
End Sub
/(/hư vậy, macro của chúng ta chỉ còn là:

Sub DinhDangTieuDe()
' Keyboard Shortcut: Ctrl+Shift+D
Range("B2").Select
With Selection
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
End With
Range("B2:F2").Select
Selection.Merge
End Sub

d./ Đọc & diễn dịch nội dung các câu lệnh:

Macro được bắt đầu bằng từ Sub (tạm hiểu là từ viết tắt của Subroutine); & dòng cuối của macro là End Sub;
Macro luôn có tên, (VD ta đã có DinhDangTieuDe & FormatCurrency); Hơn nữa tên phải tuân thủ một quy luật nghiêm:
Không gồm các khoảng trắng, không là các ký số ở đầu tên.. . ( việc này VBA sẽ truyền đạt cho bạn rõ, một khi bạn không tuân thủ!)
Macro DinhDangTieuDe thực ra làm hai công việc:
- Chọn ô B2 & định dạng canh giữa theo chiều ngang & chiều dọc;
- Canh giữa đoạn văn bản trên toàn bộ các ô “B2:F2”
Vì một lý do nào đó, chúng ta có thể viết hai dòng lệnh trên một hàng, nhưng phải cách nhau bằng dấu hai chấm ‘:’
Range("B2:F2").Select: Selection.Merge
Ngược lại, với câu lệnh quá dài, chúng ta có thể bố trí trên nhiều dòng; lúc này dấu ngang dưới ‘_’ được nhập cuối dòng trên để báo cho VBA biết rằng dòng lệnh còn tiếp theo ở dòng dưới. Ta xem xét đến ví dụ macro dùng để xếp danh sách theo tên (“C1”), như sau

Sub SortByName()

Columns("A:C").Select
Selection.Sort Key1:=Range("C1"), Order1:=xlAscending, Key2:=Range("A1") _
, Order2:=xlAscending, Key3:=Range("B1"), Order3:=xlAscending, Header:= _
xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal, DataOption2:=xlSortNormal, DataOption3:= _
xlSortNormal
End Sub
Như vậy, câu lệnh thứ hai trong macro trãi dài qua 5 dòng & nối kết với nhau bằng dấu gạch dưới (chú ý có khoảng trắng trước nó)
Câu lệnh này được hiểu như sau:
Tại ba cột A-C đã chọn (ở câu lệnh trước đó), hãy xếp theo hướng tăng dần giá trị tại cột C;
Tiếp theo là xếp theo thứ tự tăng dần các giá trị tại cột A;
Và cuối cùng là xếp theo cột B cũng theo chiều tăng dần ;

Bài tập của bài 1:


1./ Tạo macro để xoá thanh trang bảng tính (sheet tab): Thường thanh này nằm trên thanh cuộn ngang, Ta có thể vô menu Tool-> Option -> View rồi bỏ chọn hộp Sheet Tabs

2./ Chuyển công thức thành giá trị: Tại trang tính để chuẩn bị ghi macro đầu tiên ta có công thức = INT(9 * RAND()) ^ 8 tại các ô cột A; Bạn thử lập macro chuyển các ô từ A2 đến A9 này thành giá trị!

3./ Tại cột D, bắt đầu từ D1, D2 ta nhập tương ứng 1 & 2
Tại cột E kế bên ta nhập 1 & 4; Tại cột F ta nhập F1 là 36; F2 là 100
Hãy tạo macro để thực hiên các hành động sau: Chọn vùng từ D1:F2; vô menu Edit -> Copy; Sau đó chọn ô D4 và cũng vô menu Edit -> Paste Special; tại CS Paste Special ta đánh dấu hộp kiểm Transpose; sau khi dán xong ta nhấn phím ESC để bỏ vùng chọn.

4,/ Tại trang bảng tính của VD 3; thiết lập macro ghi lại những hành động sau:
Chọn ô A1, vô menu Edit -> Go to; Trong hộp thoại
 
Sửa lần cuối:
S

SA_DQ

Thành viên thân thiết
29/6/05
435
38
28
61
HCM city
#2
Bài 2

. . . . . . . . . . .Bài 2 /(/hữ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;
/(/ế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):

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("F3").Select: ActiveSheet.Paste
End Sub

2./ Thực hiện việc thêm vô macro:


Macro Thuong còn những bất tiện:
- Nếu cơ quan tăng người thì phải sửa lại dòng lệnh đầu;
- Lượng tăng giảm tiền thưởng là theo ý chủ quan của sếp (doanh nghiệp tư nhân)
Vấn đề đầu hơi dễ giải quyết, ta cứ việc ấn định thừa lên; thay vì G95 ta nhập G450, Việc này cũng chưa phải tối ưu, nhưng tại thời điểm này nên chấp nhận giải pháp. Đợi khi nào sau này trình độ ta khá lên, sẽ giải một cách căn cơ hơn!
Để giải quyết vấn đề còn lại, ta thực hiện từng bước như sau:
Tại dòng lệnh đầu tiên ta nhập tiếp dấu hai chấm (‘:’), sau đó ấn một lần phím {TAB} và 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 như sau là đú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 khi ENTER, nhập tiếp dòng sau:
strc = "=RC[-1]*" & strc
Cuối cùng ta sửa lại dòng lệnh kế tiếp trở thành:
Selection.FormulaR1C1 = strc
Khi đó macro có nội dung như sau:

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 đầu tiên mà ta thêm vô macro là câu lệnh khai báo với VBA rằng tôi sẽ sử dụng biến có tên là StrC, kiểu chuỗi. Câu lệnh thứ nữa sẽ là: Hãy lấy giá trị cho biến StrC là giá trị tôi nhập vô; câu tiếp dịch nôm na là: hãy nối biến chuỗi tôi vừa nhập vô sau chuỗi tôi ghi; Và cuối cùng (câu lệnh ta sửa): hãy gán giá trị biến mà tôi khai báo & thiết lập, trở thành công thức của ô hiện hành;
 Khi khai báo một tên biến, ta nên viết cả chữ hoa & chữ thường, như vậy ta tận dụng được lợi thế sẵn có của chương trình kiểm lỗi chính tả của VBA; Ở trường hợp này là StrC;
Tuy là khai báo như vậy, nhưng khi nhập tên biến ta cứ nhập không theo như vậy, và nhờ VBA sẽ sửa cho ta, là một dịp để kiểm tra phát hiện lỗi chính tả do nhập sai tên biến. Tên biến cũng không được chứa các kí tự toán học & không được dài quá 64 kí tự
 Về kiểu của biến thí có rất nhiều; đến đây ta chỉ cần biết những kiểu hay thường dùng:
Kiểu Byte là kiểu số nguyên, miền giá trị từ 0 đến 255
Kiểu Boolean: là kiểu logic, loại này chỉ nhận một trong hai giá trị: True & False
Kiểu Integer: Số nguyên, miền giá trị từ -32768 đến 32767
Kiểu Long: Cũng là 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, được chứa trong 8 byte ô nhớ
Kiểu String: kiểu chuỗi ký tự, miền lưu giữ có thể tối đa là 65.400 ký tự
 Lệnh gán, trong ngôn ngữ VBA dùng dấu = làm lệnh gán; Ví dụ sau khi khai báo biến StrC như trên, ta có thể dùng lệnh gán: StrC = "=RC[-1]*"; Ở đây hai dấu nháy kép chỉ để bao một chuỗi cần gán vô biến.
 Trong macro có hàm InputBox( “. . .”). Hàm này làm xuất hiện hộp thoại, nhận giá trị chuỗi mà ta nhập vô nó. Trong trường hợp này nó sẽ gán vô biến StrC giá trị mà ta nhập vô;
 Trong câu lệnh dài, chiếm 2 dòng đó, ta có thể vô hiệu hoá đoạn cuối, kể từ dấu ‘,’ thứ hai bằng cách thêm dấu nháy trước nó; Khi đó dòng hai của câu lệnh sẽ bị tô đỏ, báo cho ta biết sự bất ổn trong nó; Sự việc là do ta đã vô hiệu hoá luôn cả dấu nối 2 dòng lệnh. Để khắc phục, ta nhập thêm dấu nháy đơn vô đầu dòng bị tô đỏ đó là được; Cuối cùng, trước khi chạy tác phẩm, ta nên vô menu Debug và chọn dòng Compile VBAProject, còn để làm chi bạn đã biết rồi.
Trước khi chạy macro mới ta thực hiện việc gán phím tắt CTRL+SHIFT+T cho nó; Có thể có bạn hỏi, những điều này là bắt buộc?, không, hoàn toàn tự nguyện, nhưng nên như vậy. Cũng giống như ta không nên đi bộ bằng một chân trên vĩa hè & một chân dưới lòng đường.

3./ Tính toán các giá trị trong một cột

Ta xét trường hợp một đơn vị hành chính sự nghiệp cần lập danh sách thưởng định kỳ; Để thưởng theo hệ số đơn vị và hệ số thành tích cá nhân, người ta đã lập bảng dữ liệu gồm các trường: [Ma], [Ho], [Ten], [MDV], [XL], [TThuong] (6 cột bắt đầu từ A ).
Nhiệm vụ của macro là tính số tiền thưởng của mỗi cá nhân tương ứng với hệ số cá nhân và hệ số đơn vị (tại cột ‘F’) với sự trợ giúp của bảng được đặt tên là HeSo. Bảng HeSo này gồm 3 cột & 5 dòng. Cột thứ hai ghi hệ số thưởng của các đơ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 được
Để bắt đầu thu macro ta cũng vô menu Tool -> Macro -> Record New Macro & đặt tên macro là Tinh_Thuong.
Trên trang tính ta chọn ô F6, nơi cần xuất hiện tiền thưởng của người đầu tiên trong 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 là VLOOKUP và nhấn nút Go và chọn trong CS Select a function hàm VLOOKUP().
Khi bảng trợ giúp hàm này xuất hiện, ta thấy dấu nhắc đang ở ô Lookup_Value, ta nhấp chuột vô ô D6 ( chứa mã đơn vị của người đầu tiên); Trong ô Table_array ta nhập HeSo; cuối cùng trong ô Col_Index_Num ta nhập số 2; Xong ta ENTER để về trang tính;
Ta trỏ chuột lại lên thanh công thức; nhập dấu nhân ‘*’ và lại vô menu Insert lặp lại các bước trên. Duy chỉ khác là thay vì số 2 ta nhập số 3 vô ô Col_Index_Num;
Trở về trang tính, ta chọn lại ô F6 này và dùng chức năng AutoFill để chép công thức xuống các dòng dưới; (VD: tới dòng cuối là 21)
Sau đó ta chọn vùng F6:F22 và bấm lên nút AutoSum trên thanh công cụ; Excel báo cho ta là sẽ tính tổng của cộ & nhập vô ô 23. Ta tán thành việc làm này và kết thúc macro như cách đã biết.
Macro thu được của bạn có trùng khớp như vầy?
(Thực tế ta có thể vô hiệu hoá hay bỏ dòng thứ hai đi!)

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 của nó; Trong đó có dùng hai hàm SUM() & VLOOKUP(). Kinh nghiệm cho thấy, ta đọc từ phải sang trái thì dễ hiểu câu lệnh hơn. Vì dụ hai câu lệnh gần cuối được hiểu như sau:
Chọn ô ‘F23’
Lấy tổng các ô từ ô thứ 17 hàng trước ô hiện hành, cho tới ô trước ô hiện hành 1 ô gán cho ô hiện 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 trong ô F23 xong ta thực hiện ENTER. Kết quả của nó là đến ô F24 như máy đã ghi!
Trong dòng lệnh thứ hai, hàm VLOOKUP() có đối số thứ nhất được ghi là RC[-2]; chữ C chỉ số cột, chữ R chỉ số hàng; Í nghĩa thực tế là đối số thứ nhất của hàm đang tại ô cùng hàng & phía bên trái cách 2 cột
Trong câu lệnh lấy tổng, chúng ta đã nói trên; nhưng ở đây VBA lại ghi theo dạng thức tương tự như “B2:D9”: góc trên trái nhất & góc dưới phải nhất của vùng chọn.
Để rõ hơn ta xét đến một macro ghi lại các chuyển đông bằng bàn phím như sau:
Vẫn lấy ví dụ tính tiền thưởng nêu trên, mà trong đó CSDL (cơ sở dữ liệu) gồm có 23 dòng tấc cả (tại cột ‘F’). Ta thu một macro (tên là DiChuyen) với những hành động như sau:
Chọn ô B2; ấn đồng thời 2 phím CTRL & phím mũi tên xuống (điểm sáng sẽ tới ô B5, là ô đầu tiên trong cột có giá trị (đang chứa Ký tự ‘Ho’ được tô đậm)
Lặp lại lần nữa, ô được kích hoạt sẽ là ô 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 được dòng cuối của trang tính!
Bây chừ thì phải ngược lên thôi: ấn CTRL+ phím mũi tên lên: ô kích hoạt sẽ lại là B21;
lặp lại hành động này một lần nữa sẽ là – B5
Cuối cùng sẻ là ô B1 nếu ta muốn!

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ó khi macro chạy nhanh quá, không làm bạn tin!?! Muốn ghi nhận lại vị trí ô được kích hoạt khi thực hiện 1 lần ta làm theo cách sau:
Đầu dòng lệnh thứ nhất ta nhập câu lệnh sau
dim lJ as long: và nhấn hai lần phím {TAB} (chú í có cả dấu hai chấm ‘:’)
Để điểm chèn cuối dòng lệnh thứ hai & ấn ENTER, như vậy sẽ thêm 1 dóng trắng. ta nhập lên nó hai câu lệnh cách nhau bằng dấu hai chấm, như sau:
lj = selection.row: msgbox str(Lj)
(chú ý: giữa chữ selection & chữ row có dấu chấm)
Ta chịu khó lặp lại chuyện này ở tất cả các dòng lệnh trước End Sub
Thực hiện biên dịch Sub như đã nêu & cho chạy lại macro
Trước khi kết thúc macro sẽ đưa ra sáu hộp thoại báo cho ta biết ô kích hoạt đang là hàng thứ mấy trong trang tính.
Chú ý:
 Tại sao ta phải khai báo biến lj có kiểu là Long, mà không là Integer hay Double?
Nếu khai báo chỉ là Integer thì biến không đủ năng lực để đến được dòng 65536 đã bị bắt lỗi
Nhưng ngược lại, nếu khai báo kiểu dữ liệu Double thì quá dư thừa & lãng fí tài nguyên. Hơn nữa không vì thế mà macro chạy nhanh hơn!
 Hàm MsgBox() tương tự như hàm InputBox() nêu trên, chỉ có điều chiều tác động thì ngược lại, hàm sau nhận thông tin tự người dùng, còn hàm mới này thông báo cho người dùng cái gì đó mà người dùng đang thiếu thông tin!
 Hàm Str(Num), hay hàm CStr(Num) sẽ biến đổi kiểu dữ liệu dạng số ( Byte, Integer, Long. . .) thành chuỗi kí số.
Cần nhớ rằng CStr(Num) & Str(Num) có khác nhau ở nhiều trường hợp! Ví dụ
Cú pháp Range( “A” & CStr(9) ).Select thì VBA hiểu, còn Range(“A” & Str(9)).Select thì không! Tuy rằng khi biên dịch VBA không phát hiện ra lỗi này!

5./ Nối các macro


Ta có thể chép hết các dòng lệnh của macro sau cùng (chỉ trừ câu Sub DiChuyen & dòng End Sub) vô trước dòng End Sub của macro nêu đầu tiên trong bài. Điều này làm được do hai macro làm các công việc hoàn toàn khác nhau, công việc này xong không còn liên quan đến công việc sau.
Một cách khác nữa là ta nhập tên macro sau vô trên dòng lệnh vừa nêu của macro trước:

Sub Thuong()
[color="Blue"
' . . . . * * *
' . . . . . * * *[/color]
DiChuyen[b]
End Sub[/b][/quote]
Hay [quote][b]
Sub Tinh_Thuong()[/b]
. . . .
.. . . .
DiChuyen[b]
End Sub[/b][/quote]
tất nhiên trong mỗi trường hợp, hộp thoại ta ghi thêm sẽ đưa ra thông tin có thể khác nhau!

[color="red"]
Bài tập của bài hai :
[/color]
1./ Tạo macro xoá dòng (hay cột) chứa mẫu tin
2./ Tạo macro cho ẩn hay hiện cột (hay dòng) chứa dữ liệu
3./ Hãy tạo bảng tính đã có các cột [ĐG] & [SL], hãy 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.
 
Thích: phuoc hieu
S

SA_DQ

Thành viên thân thiết
29/6/05
435
38
28
61
HCM city
#3
Bài 3

. . . . . . . . . . . . . .Bài 3 /(/(acro thực hiện các việc lặp lại
1./ Tạo macro tô màu nền một ô

Trước tiên ta cần chuẩn bị CSDL (cơ sở dữ liệu) như một danh sách (DS) học sinh của trường phổ thông hay một cơ quan nào đó gần ngàn người; có tối thiểu các trường dữ liệu như sau: [Ma], [Ho], [Ten], [NgaySinh], & một số trường khác nữa. . . Nhiệm vụ nêu ra là đến cuối bài học ta sẽ tô màu khác nhau cho những người trong DS có các tháng sinh khác nhau;
Bước đầu ta thực hiện việc tô màu cho 1 ô & di chuyển xuống ô kế tiếp. Ta vô menu Tool -> Macro -> Record New Macros và đặt tên macro là ToMau
Sau khi ấn nút OK trở về bảng tính ta chọn cột (trường) [NgaySinh] với ô trên cùng chứa dữ liệu của người đầu tiên trong DS. (Ví dụ đó là ô ‘G6’)
Tiếp theo ta rà mũi chuột vô biểu tượng Fill Color trên thanh Toolbar, bấm hình mũi tên xuống để mở bảng màu nền.
Ta nhấn vô ô màu trái nhất hàng dưới cùng; xong ta nhấn mũi tên xuống trên bàn phím.
Lại rà mũi chuột lên bảng màu, ấn chọn vô màu kề nó phía phải màu vừa chọn & lại ấn phím mũi tên xuống;
Lặp lại quá trình này cho đến hết số màu trong hàng cuối của bảng màu;
Kết thúc thu macro, ta sẽ có nội dung như sau (tác giả đã thu gọn một số cập lệnh lên trên một dòng & bỏ bớt các câu lệnh tô màu từ ô G11 trở đi):

Sub ToMau()

Range("G6").Select
With Selection.Interior
.ColorIndex = 38: .Pattern = xlSolid
End With
Range("G7").Select
With Selection.Interior
.ColorIndex = 40: .Pattern = xlSolid
End With
Range("G8").Select
With Selection.Interior
.ColorIndex = 36: .Pattern = xlSolid
End With
Range("G9").Select
With Selection.Interior
.ColorIndex = 35: .Pattern = xlSolid
End With
Range("G10").Select
With Selection.Interior
.ColorIndex = 34: .Pattern = xlSolid
End With
End Sub
.
Trong macro, mỗi khi đến 1 ô mới, VBA gán 2 thuộc tính màu nền và đặt tính pattenrn solid cho ô. Macro này chỉ tiện hơn cách làm thủ công tí tẹo!
Chú ý: Hai câu lệnh gán thuộc tính cho mỗi ô có khác hơn so với macro FormatCurrency đầu tay. Ở đây tên mỗi thuộc tính đều nằm riêng biệt, mà không nằm sau từ Selection & cách 1 dấu chấm như ở Sub FormatCurrency.
Cặp câu lệnh With Selection . . . End With làm các câu lệnh nằm giữa chúng sẽ tác động lên phần chọn; coi như mỗi câu đều có từ Selection. đứng trước. Rõ ràng cấu trúc này khiến cho macro sáng sủa & dễ đọc hơn. Còn hơn thế, nó làm cho macro chạy nhanh hơn vì giảm bớt một số khâu trở lại ban đầu: Thay vì chỉ vô căn phòng 1 lần, rót nước uống, rồi châm thuốc hút, ta lại vô fòng, rót nước uống, lại ra, xong vô lại & châm thuốc hút trong fòng í!

2./ Chỉ cho macro biết lựa chọn


Vấn đề nêu ra là macro phải biết tô màu nào ứng với giá trị chứa trong ô đó; Và mục tiêu của ta sẽ là tô màu khác nhau cho các tháng sinh khác nhau. Để làm việc này ta tô chọn tất cả các dòng, trừ hai dòng đầu & cuối và mạnh tay xoá cả đi (bằng phím Delete)
Nhập các dòng lệnh dưới đây

Sub ToMau()

1 Dim Thang, StrC As String: Dim Ij As Integer
2 For Ij = 6 To 900
3 StrC = "G" & CStr(Ij): Range(StrC).Select
4 With Selection
5 Thang = .Value
6 If .Value = "" Then Exit For
7 Thang = Month(Thang)
8 Select Case Thang
9 Case Is < 3
10 .Interior.ColorIndex = 38
11 Case Is < 5
12 .Interior.ColorIndex = 40
13 Case Is < 7
14 .Interior.ColorIndex = 36
15 Case Is < 9
16 .Interior.ColorIndex = 35
17 Case Is < 11
18 .Interior.ColorIndex = 34
Case Else
20 .Interior.ColorIndex = 37

End Select
End With
23 Next Ij
Exit Sub: End Sub
.
Ta khai báo biến StrC để lưu giữ một chuỗi các địa chỉ thay đổi (tăng dần từ G6 trở đi)
Chú ý:[/b] 1. Biến Thang ở đây không được khai báo kiểu dữ liệu, lúc đó máy mặc nhiên hiểu kiểu dữ liệu là Variant. Một biến kiểu Variant có thể chứa các kiểu dữ liệu mà ta biết từ bài đầu đến nay. Tất nhiên bộ nhớ giành cho nó cũng phải nhiều hơn, & sau này nó còn chứa được nhiều thứ khác nữa.

2. Ta có thể ghi số vô đầu mỗi câu lệnh, để cho máy cũng như ta nhận biết điều này.

3./ Vòng lặp For . . .Next
Để macro có thể thực hiện chu trình lặp lại, ta sử dụng một cấu trúc tạo vòng lặp từ câu lệnh dòng 2 đến dòng 23; Trong một lần lặp, macro sẽ làm những việc sau: Lấy giá trị trong ô để tính ra tháng sinh nhật; tô màu nền ứng với tháng tìm được.
Trong cấu trúc này khối các câu lệnh trong vòng lặp bình thường sẽ thực hiện theo số lần đã xác định; mà cụ thể ở đây là (900 – 6) lần. Tuy nhiên tại câu lệnh số 6, người ta ấn định điều kiện nếu trong ô không chứa giá trị sẽ thoát vòng lặp. /(/hư vậy, thay vì lặp lại những tính toán vô nghĩa, máy sẽ thoát ra ngay đúng lúc. Và các bạn sẽ tiết kiệm rất nhiều tài nguyên một khi dữ liệu chúng ta đang ít.
Trong excel chúng ta cũng đã thấy bóng dáng vòng lặp này trong hàm =FACT(Num);
Cú pháp đầy đủ của vòng lặp For . . . Next như sau:
For Counter = First To last [Step step]
(statements)
[Exit for]
(statements)
Next [Counter]
Trong đó, các từ tô đậm là từ khóa của VBA, những từ khóa mà VBA giành quyền sử dụng thì ta nên tránh càng xa càng tốt, nếu không muốn bị báo lỗi xâm phạm chủ quyền.
Counter là một biến đếm, (trong VD chúng ta là ij) tùy phạm vi vòng lặp mà ta khai báo kiểu dữ liệu của biến này cho hợp lẽ.
First là giá trị ban đầu của bộ đếm; còn last là cuối; Nhưng nên biết rằng cuối chưa chắc là lớn, vì có những người, những lúc cần đếm ngược, như

Sub CaiSoDe()

For iZ = 65535 to 1 Step -5
If iZ Mod 999 = 0 then Exit For
Next iz
Msgbox Str(iZ)
End Sub
.
Ở đây, lưu í trước tiên biến iZ phải được khai báo như sau: Dim iZ As Long
Còn trong ví dụ, biến iZ không được khai báo trước. Và như vậy biến sẽ được hiểu có kiểu dữ liệu Variant. (Điều không báo trước này trong nghề y khuyên là chống chỉ định!)
Đây là vòng lặp giảm dần, mỗi lần biến đếm iZ giảm 5 đơn vị cho tới 1 hay cho tới khi gặp số iZ chia hết cho 999. Mod là một toán tử, hiểu như trong excel sẽ là
=If( MOD( iZ ; 999) = 0 ; ‘Exit For’; ‘Tiếp’)
Như vậy ta cũng thấy, nếu bước không được xác định nó sẽ lấy giá trị là 1. Một chống chỉ định nữa là đừng bao giờ thay giá trị biến đếm (iZ, hay Ij . . ) khi đang còn trong vòng lặp; chuyện này nên hỏi ‘bác sỹ’ nếu chưa rành về VBA)

4./ Cấu trúc Select. . . .End Select


Trong excel ta đã biết cấu trúc phân nhánh bằng cách dùng hàm
=IF(logical_test; value_if_true; value_if_false)
Hàm này chúng ta hiểu nôm na là trên đường lưu thông chúng ta tới ngã ba; Rẽ phải hay trái tùy thuộc vé ta cầm trên tay; Hiển nhiên, trong excel cấu trúc If được phép lồng nhau (đến 7 lần); Vậy thực ra ta hiểu: không phải trước ngã ba, mà là còn chia các ngã khác nữa.
Lệnh Select Case sẽ được phép rẽ nhiều nhánh ngay một lúc;
(ấu trúc cú pháp của Select Case như sau:
Select Case TestExpression
[Case Expression (i)]
[Statements (i)]
[Case Else
[ElseStatements]
End Select
TestExpression là 1 biểu thức số hay chuỗi bất kỳ. Trong ví dụ trên biến Thang giữ vai trò này. Cần nói thêm rằng lúc đầu Thang chứa giá trị dữ liệu của ô hiện hành (dòng 5); sau đó Thang chứa kết quả =MONTH(Thang) – Được gán giá trị tháng của dữ liệu (dòng 7) & là TestExpression của cấu trúc Select Case. Trong macro ToMau nêu trên, chúng ta chỉ tô 6 màu khác nhau cho từng cặp tháng; tuy nhiên chúng ta cũng có thể viết
Select Case Thang
Case 1, 7
.Interior.ColorIndex = 38
Case 2, 8
.Interior.ColorIndex = 40
. . . .
Case Else
.Interior.ColorIndex = 37
End Select
Những người thành thục VBA khuyên ta nên luôn nhập câu lệnh Case Else cho mọi trường hợp, có khi sẽ chộp được những giá trị TestExpression không mong muốn xuất hiện.

Bài tập thực hành:

1./ Hãy tạo macro tô màu cho Font chữ trong các ô tương ứng là Đỏ, Vàng, lục, lam, tím. . .; xem & đọc nội dung macro để thực hiện các bài tập dưới;
2./ Hãy đọc để biết macro sau cho kết quả bao nhiêu, khi ta nhập 9 vô hộp thoại xuất hiện:

Sub TongBinhPhuong()

Dim jZ as integer, wZ as Integer, TongBF As Long
wZ =InputBox(“HAY NHAP SO CUOI”): TongBF = 0
For jZ = 1 To wZ
TongBF = TongBF + jZ * jZ
Next jZ
Msgbox Str(TongBF)
End Sub
3./ Giả sử ta có cột “D” là điểm trung bình của học viên trong lớp; ta tạo macro để tô màu theo xếp loại học sinh; (VD: >=9: màu đỏ; >=7,5: Màu vàng . . .)

(ác bạn có thể xem thêm fần bổ sung trong file đính kèm!
 

Đính kèm

Sửa lần cuối:
S

SA_DQ

Thành viên thân thiết
29/6/05
435
38
28
61
HCM city
#4
Bài 4

. . . . . . . .Bài 4 /(/(acro nhập liệu vô CSDL (cơ sở dữ liệu).
1./ Tạm hiểu vể CSDL & cách tìm đến dòng cuối CSDL

Trong thực tế ít nhiều chúng ta đều tiếp xúc với CSDL. Trong excel ta có một số hàm CSDL, ví dụ =DSUM(database,field,criteria) ; database phải thỏa mãn một số yêu cầu:
Hàng đầu tiên là các tên trường, Các tên trường, cũng như tên biến: không có chứa khoảng trắng hay các kí tự đặc biệt, Các hàng trong CSDL (gọi là các record) đều phải có số liệu. Không được dùng ký tự ntr, “ hay – để thay cho các trị trùng với giá trị trường đó của record trên nó.
Ta có thể thấy CSDL học sinh các lớp trong một trường học, DS (danh sách) công nhân viên chức trong đơn vị, bảng kê hóa đơn mua bán hàng hóa, bảng kê sản lượng của bộ phận sản xuất trong đơn vị & còn nhiều những DS khác nữa . . . .
Giả sử ta có DS các chuyến hàng nhập vô nhà máy, có các trường như sau: [STt], [Ngay], [MKH], [SoXe], [TgLuong], [Bi], [Sluong]. Hàng ngày cơ sở sản xuất ấy nhận vô khoảng vài chục xe hàng để làm nguyên liệu. Như vậy sổ ghi chép đầy đủ số liệu nhập loại nguyên liệu này trong thời kỳ nào đó sẽ là một CSDL tốt để chúng ta dùng macro tác động đến tất cả các khâu, từ khâu nhập liệu, thống kê, xử lý số liệu trong báo cáo, quản lý & điều chỉnh quá trình. . .
Nếu không có công cụ macro, chúng ta phải nhập trực tiếp các số liệu của xe hàng vô dòng cuối của CSDL. Làm như vậy rất dễ nhầm lẫn, dẫn đến những sai sót khôn lường. Cách tốt nhất đến thời điểm này (do ta chưa biết gì về Form) là ta nhập số liệu về xe hàng mới vô lên 1 sheet (có tên là Nhap) theo cột từ trên xuống. (Bố trí theo cột vì thường nhập xong số liệu một ô, ấn ENTER thì con trỏ xuống ngay ô dòng dưới!). Sau khi kiểm tra xong, ta ấn nút để macro thay ta chép các số liệu này đến Sheet chứa CSDL (có tên là CSDL), vào đúng nơi yêu cầu: dòng cuối của CSDL. Lúc đó ta tận dụng được cách mà excel copy chuyển cột thành hàng;
Giải bài toán nêu trên bằng cách: Tại Nhap ta thiết kế như sau: Trộn 2 ô A1 & B1 để nó chứa chuỗi: ‘Nhập mới’; Các ô trong cột A kể từ A2 trở xuống chứa lần lượt các chuỗi: ‘Số TT’, ‘Ngày nhập’, ‘Mã chủ hàng’, ‘Biển số’, ‘Trọng lượng cả bì’, ‘Trừ bì’, ‘Số thực nhập’
Ta nhập số liệu một xe hàng vô cột b từ B2 đến B7; Còn giá trị tại B8 ta cài công thức = (B6 – B7). Đến lượt các bạn hãy tự tạo cho mình một macro chép số liệu tại cột B từ B2 cho đến B8 theo các bước sau:
 Đặt tên macro sắp thu. . .
 Dùng chuột tô chọn các ô từ B2 trở xuống B8 của sheet ‘Nhap’, xong vô menu Edit -> Copy;
 Ta chọn tiếp sheets ‘CSDL’; ấn chọn ô A2, & lại vô menu Edit -> Paste Special; Trong ngăn Paste của hộp thoại Paste Special ta chọn Values & ấn vô nút chọn Transpose
 Kết thúc thu macro, & macro này bạn đặt tên Nhap (hay NhapLieu) hay tên nào khác gợi nhớ mà bạn muốn. (Tác giả quyễn ghi chép này muốn các bạn theo dõi bài cần thực hiện macro này tối thiểu 2 lần, nên mới gợi tên tại đây; dù sao cũng là một ý đồ!) Sau mỗi lần thử ta có thể xóa macro đi bằng cách: Tại CS (cửa sổ) excel ta nhấn cùng lúc ALT+F8, CS Macro mở ra, ta chọn tên macro trong ngăn Macro Name mà ta muốn xóa, xong chọn nút lệnh Delete để thực hiện việc này. Mình khuyên các bạn nên xóa tác phẩm macro của mình nhiều lần, sau mỗi lần xóa macro, kiến thức VBA của ta sẽ lớn lên một ít!.
(/iệc này không phải là quên, mà là có chủ tâm: sau bước hai nêu trên, bạn còn một công đoạn nữa là ấn nút ESC trên bàn phím! Việc này ta có thể quên trong khi thao tác trên bảng tính excel (để bỏ chọn dãy ô định Copy). Nhưng ở đây không nên quên tẹo nào, vì dễ bị phiền phức & kiện cáo về sau, hoạc giả chúng ta không biết macro dẫn ta đi đến phương trời nào nữa?!
Chú ý:
 Trong hộp thoại Paste Special bạn thử không chọn nút ấn Value 1 lần và xem macro cho kết quả ra sao?
 Bạn thử một lần đặt tên macro là Nhap_ sẽ bị VBA phản đối hay không ?!
 Bạn nghĩ xem còn có thể làm gì để giao lưu giữa bạn & VBA thông qua macro này không? VD như thử đặt tên là _Nhap xem bị phản đối không?! . . .
Đến đây là xong một công đoạn. Phần thứ đến là xác định dòng cuối của CSDL; Để thực hiện việc này bạn cần tự tạo cho mình một CSDL khoảng vài chục records, và na ná như mình đề ra để dễ theo dõi tiếp. Macro trên bao giờ ta cũng chép vô range A2; Nhưng thực tiển CSDL tăng (giảm) liên tục, nên ta phải làm sao để macro thông minh, hiểu ý ta mà tìm đến dòng cuối để dán dữ liệu vô!
Ta lại thực hiện ghi macro Sub DongCuoi() bằng cách thu macro qua các bước sau:
 Chọn ô A1 của CSDL, giữ phím CTRL & ấn phím mũi tên xuống (Dòng cuối của CSDL được chọn)
 Tiếp tục thực hiện hành động như vậy đễ đến được dòng cuối của trang tính
 (Cuối rồi nên quay lại) Ấn tổ hợp CTRL+ phím mũi tên lên để trở lại dòng cuối của CSDL.
Sau khi ngưng thu macro ta sẽ có những dòng tương tự vày trong CS chứa các macro:

Sub DongCuoi()

Rang(“A1”).Select: Selection.End(xlDown).Select
Selection.End(xlDown).Select: Selection.End(xlUp).Select
End Sub
Điều chúng ta cần là máy cho ta biết dòng trống kế tiếp để chép; điều này thực hiện được bằng cách sửa lại macro trên để có nội dung sau:

Sub DongCuoi()

Dim iRow As Long
Range("A65535").Select: Selection.End(xlUp).Select
iRow = 1 + Selection.Row: MsgBox Str(iRow)
End Sub
Trong macro này có 2 dòng lệnh đáng kể đến. Đó là dòng lệnh thực hiện thao tác CTRL+ mũi tên lên. Dòng lệnh này làm ô chứa dữ liệu cuối của CSDL trên cột ‘A’ được kích hoạt.
Dòng thứ đến là phương thức gán cho biến iRow đã khai báo giá trị, bằng với gía trị hàng hiện hành cộng với 1 (Nên đọc dòng lệnh từ phải qua trái, là: Dòng hiện hành cộng 1, gán vô biến iRow).

2./ Macro nhập liệu

Đã đến giai đoạn lập macro nhập liệu, kết hợp từ hai macro nêu trên & thêm gia vị vô cho món macro thêm hấp dẫn. Nhưng giờ chúng ta dịch ngược từ ngôn ngữ macro sang ngôn từ diễn tả các bước tiến hành của ta, như sau:

Sub Nhap()

401 Sheets("Nhap").Select: Range("B2:B8").Select
402 Selection.Copy
403 Sheets("CSDL").Select: Range("A65535").Select
404 Selection.End(xlUp).Select
405 Selection.Offset(1, 0).Select
406 Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=True
407 Application.CutCopyMode = False: Sheets("Nhap").Select
End Sub

Phần dịch câu lệnh:

401: Chọn vùng cột B tại sheet (“Nhap”);
402: Copy (vùng chọn);
403: Tương tự 401;
404: Đã giải thích trên;
405: Hãy chọn ô có số hàng tăng 1 & số cột vẫn như cũ so với ô kích hoạt;
406 & 407: ‘Quá quen!’
(Vì là ngôn ngữ dịch nên mỗi người có cách dịch khác nhau, có lẽ mình chưa thể dịch tiếng nào ra tiếng ý, mong được cảm thông!). Và các bạn thấy đấy, dịch từ ngôn ngữ VBA sang ngôn ngữ đời thường cũng quan trọng không kém, phải không?!
/(/hân dịp rãnh rỗi các bạn thử bỏ vài vế sau của mệnh đề 406 xem ra răng?!

3./ Tạo nút lệnh cho một macro


(ác bài đầu ta đã biết gán tổ hợp phím tắt cho một macro. Nhưng tiện thì có tiện với ta thôi. Còn khi ta vắng, người khác thay ta nhập liệu thì không biết các phím này!. Để tiện cho việc sử dụng ta thiết lập một nút lệnh trên trang tính, & như vậy bất kỳ ai cũng có thể xài được khâu nhập liệu.
Để làm được điều này, tại trang bảng tính ‘Nhap’ hiện hành, ta vô menu View ->n Toolbars -> Forms để hiện thanh công cụ Forms. Rà mũi chuột lần lượt lên các nút để tìm nút có chữ ‘Button’. Ấn chọn nó, đưa mũi chuột đang có dạng chữ thập mảnh mai đến ô trên vùng C2:D8 (VD tôi chọn C7). Ấn giữ trái chuột & vẽ hình chữ nhật lên ô chọn. Nếu xuất hiện CS Assign Macro thì ta chọn tên macro Nhap tại Macro Name & nhấn OK.
Với Button đang được kích hoạt, ta phải chuột vô nút lệnh để hiện menu tắt của nó. Ta chọn dòng cuối là Format Control. CS Format Control xuất hiện, nhưng ta bấm Cancel cho ẩn đi. Con trỏ chuột trên dòng ‘Button n’. Ta tô toàn bộ chữ này & nhập vô thay bằng chữ việt: ‘Nhập’; Lại tô sáng chữ này & nhấp vô nút có chữ B trên Toolbar, làm đậm chữ. Sau đó chọn màu Font cho nó theo ý bạn. Nếu bạn đã, hay sẽ định gán tổ hợp các phím CTRL+SHIFT+N cho macro Nhap thì lúc này là tốt nhất để bạn tô chữ cái ‘N’ & nhấn vô nút Underline. Động tác này gây ấn tượng giữa hai thực thể ta với máy!
Sau khi tạo ra tác phẩm đầu tay này, nhất thiết việc đến tiếp là thử. Bạn có thể nhấn vô nút này nhiều lần để xem ‘Hắn’ chép những gì có trên cột ‘B’ qua CSDL; Cứ bị nhấn là chép, bất kể miễn còn được cung cấp nguồn điện!

4./ Tạo mộtCombo Box để nhập mã khách hàng


/(/hư trên ta thấy dòng thứ ba trong sheets ‘Nhap’ chứa mã #h (khách) hàng. Bạn có thắt mắc không? Ta không nhập toàn tên #h hàng mà chỉ là mã vì chúng ta ‘lười biếng’?
/(hông đâu các bạn! Bạn thử hình dung có nhiều #h hàng thân thiết ngày nào cũng cung cấp hai đến bốn chuyến thì người nhập cũng mệt & máy cũng mệt. Người mệt thì dễ hiểu rồi! Máy cũng mệt vì CSDL ta phình nhanh quá thay vì trường [MKH] chỉ gồm tối đa 3 kí tự hay ký số ta lại nhập nguyên Công Tằng Tôn Nữ Nguyệt Nga là không cần thiết.
Bạn thử hình dung như thế này trong file nhân sự của một cơ quan 750 người gồm 15 bộ phận
Nếu trường [BoFan] ta nhập nguyên tên đơn vị như: Tổ chức, Hành chánh, Tài chính, PX Nguyên liện, PX Cơ điện. . . thay cho việv nhập A, C, D, E, F . . . thì lãng phí nguồn nhân lực là đáng kể.
Tất nhiên ở đây, cũng như ở trên ta phải có bảng đối chiếu như trong hàm VLOOKUP() hay HLOOKUP() trong excel đã gặp
Trở lại với phần nhập mã #h hàng. Như vậy người dùng sẽ đưa câu chất vấn: Làm sao tôi nhớ mã của trên đôi chục khách đây?! Đúng là một yêu cầu chính đáng mà người biết macro phải đáp ứng. Và cứu tinh đó chính là Combo Box (sẽ viết tắt là Combo)
/(/ó ở đâu?, vẫn trong toolbar Form ý thôi! Bạn rà mũi chuột như ban nãy, nhưng thay vì tìm chữ ‘Button’ ta tìm chữ ‘Combo’ trong khi Tool tips hiện chữ, hay thấy cái nút nào có biểu tượng giông giống cái hộp diêm thì nhào vô kiếm.
/(/hưng kiếm vậy thôi, ta chưa chuẩn bị gì nguồn lực cho nó thì nó cũng vô dụng mà thôi; Giống như ta phải có macro Nhap rồi mới làm nút lệnh cho nó trên trang tính ấy mà!
Để chuần bị nguồn cho Combo, cũng như CSDL quản lý các thượng đế ta cũng sẽ tạo các trường như STT, Ma, HoTen, NgSinh, Dthoai, DiaChi, Fax, NguoiGD, GhiChu, . . .
Các trường khác ta bổ sung sau, nhưng hai trường phải có trước là Ma & HoTen; Giả dụ ta đã có DS này gồm 20 vị, tùy thuộc vô số lượng mà mã nên 2, 3 ký tự (Nếu dưới 1.000 thượng đế ta chỉ dùng 2 ký tự là đủ,)
Giống như tạo nút lệnh cho macro, ta cũng ấn vô biểu tượng Combo trên Toolbar Forms. Sau đó trên mtrang tính ta vẽ hình thanh dài đủ thấy tên của thượng đế trong đó (khoãng chừng 8 Cm). Ta cũng phải chuột vô hình chữ nhật này & chọn Format Control. Trong CS Format Control ta ấn chuột vô hộp Input range. Dùng chuột quét từ đầu đến cuối DS #h hàng. Tiếp theo, trong hộp Cell Link được ấn chuột, trên trang tính ‘Nhap’ ta chọn ô C4 (kề với ô cần nhập mã #h hàng). Tiện tay ta đánh dấu kiểm vô 3-d Shading;
Ta nhấp vô ô trống bất kỳ để kết thúc sơ lược phần format Control. Nếu giờ ta nhấn vô mũi tên xuống của Combo ta chọn tên 1 người thì tại ô C4 xuất hiện số, nói lên thứ thự của thượng đế đó trong DS. Vậy chỉ còn bước cuối cùng là ta phải liên kết giữa số trên C4 với mã #h hàng tương ứng; Điều này các bạn có thể phải tự làm lấy, mình chỉ gới ý hai cách sau:
Tại ô C3 dùng =VLOOKUP() hay dùng hàm =CHOOSE(). Hàm trước cho DS nhiều & sau cho không tới chục #h hàng!
Đến đây ta có thể xoa tay & cười tươi với thành quả của mình. Để khuyếch trương chiến tích, ta làm đẹp Combo bằng cách phải chuột vô Combo & thực hiện chỉnh sửa kích cỡ cho vừa ý (đối với nút lệnh cũng vậy); & tự cho phép mình tìm hiểu các CS có trong Format Control.

Bài tập của bài 4:

1./ Bạn đã gặp macro này ở đâu?

Sub Nhap_()

Sheets("Nhap").Select: Range("B2:B8").Select
Selection.Copy
Sheets("CSDL").Select: Range("A2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=True
Application.CutCopyMode = False
End Sub
:friend:
 
Sửa lần cuối:
S

SA_DQ

Thành viên thân thiết
29/6/05
435
38
28
61
HCM city
#5
Bài 5

. . . . . . . . . .Bài 5 /(/(acro lập báo cáo hàng ngày.

1./ Khảo sát các yêu cầu:

Bài toán nêu ra là việc quản lý chu trình sản xuất tại một CS (cơ sở). Mà cụ thể là Giám đốc CS yêu cầu phân xưởng II gởi BC (báo cáo) số liệu hàng ngày trước 8h30 ngày hôm sau. Trong BC phải đủ số liệu về 4 vấn đề: công nghệ, sản lượng, chất lượng & tiêu hao;
Trong mỗi vấn đề có những yêu cầu chi tiết các hạng mục như sau:
Cônghệ: số hư hỏng ở bốn khâu trong phân xưởng (K1, K2, K3, K4)
Sản lượng: Sản lượng sản xuất 9 mặt hàng của p/x (phân xưởng)
Chất lượng sản phẩm: Số loại I & & loại 2
Tiêu hao : Điện, nguyên liệu & nhiên liệu. . . . . .(xem trong Sheet(“BCao”) đính kèm)
Ta đã biết rằng macro nói riêng (hay VBA nói chung) rất ưa các công việc lặp lại thường xuyên này. Vấn đề là làm như thế nào để lập CSDL (cơ sở dữ liệu) xử lý một cách trơn tru & còn có hướng cho mai sau phát triển!
Trong Sheet(“CSDL”) của file đính kèm có các trường sau: Ngay, Ca, Kip, ThSo, ThNm, SoLieu
Ngay . . . . . . Ca . . Kíp. . .ThSo. . .ThNm. . .SoLieu
23/09/2006. . . A . . . 1. . . .B6A . . . 28 . . . 1,230
1/10/2006. . . . A. . . 1. . . , A1A . . . 29 . . . 9
Trong đó có hai trường cần nói tới (còn các trường khác chắc ai cũng ngẫm ra). Đó là [ThNm] & [ThSo]
[ThNm] là trường biểu trưng cho năm & tháng của [Ngay]. Sau này các bạn sẽ biết nó dùng để lọc dữ liệu theo tháng nào đó trong năm, phục vụ trong chuyện tính lũy kế sản xuất.
[ThSo] gồm 3 kí tự hay kí số. Kí tự đầu biểu trưng cho các vấn đề cần quản lý: Cônghệ, sản lượng, chất lượng & tiêu hao; Ký số thứ đến biểu trưng cho thứ tự yêu cầu chi tiết; Ví dụ: B6A thì ta hiểu là trường SoLieu ghi sản lượng mặt hàng mác 6 (xem trong Sheets(“Nhap”))
A1?: Ghi số hư hỏng tại công đoạn K1 của phân xưởng.
Ký tự cuối cùng chỉ ra ca sản xuất.
Có thể bạn sẽ hõi, vậy lưu kíp thợ làm gì? Xin thưa: Ca đêm được thêm lương & bồi dưỡng giữa ca! Việc này cần thiết để sau này lỡ Sếp trã lương theo kết quả sản phẩm cuối cùng . . .
Cũng đúng nếu ta nói [Ca] là dư. Nhưng ta mới chập chững vô VBA nên phần sử dụng tài nguyên còn chừng mực thôi, chưa phải là tối ưu, mong nhiều bạn thông cảm!

2./ Trích lọc số liệu ngày cần thiết

Các bạn hãy mở trang tính ‘BCao”, trong í đã cài sẵn công thức hết rồi. Công việc của chúng ta là viết macro gán vô nút lệnh ‘Báo cáo” trong sheets ‘Nhap’. Để nó làm tuần tự các nhiệm vụ:
a.) Xếp CSDL theo [Ngay]; lí do: đề phòng nhân viên nhập liệu không theo ngày tháng như bình thường. Việc này các bạn thử ghi lại bằng một macro riêng, xem như một bài tập bổ sung!
b.) Trích lọc toàn bộ dữ liệu trong ngày thể hiện lên hai cột ‘L’ & ‘M’ trong sheet ‘CSDL’. Ngày chỉ định được ghi tại ô B2 của Sheet ‘Nhap’ hay ô H2 thuộc vùng Criteria khi ta sử dụng phương thức Advanced Filter. . trên menu Data. Các bạn cũng nên ghi 1 macro này nữa để hiểu thêm về Advanced Filter để có trong tay những gì ngôn ngữ VBA nói đến chuyện Advanced Filter. (Chuyện này không ai cấm cản bạn thực hiện nhiều lần cả, chỉ có điều bạn có muốn hay không mà thôi! Càng làm nhiều máy nó càng cảm ơn đó; Cụ thể nha: Trong menu Insert ->Name->Define của excel có ghi nhận công lao của bạn đó!) Về phần mình đáng ra tôi nên khóa các macro sẵn có trong file đính kèm, nhưng không vì thế mà các bạn không tự mình viết nhiều lần hai macro đã nêu trên (về xếp trật tự CSDL & Advanced Filter. . .) . Ý tôi muốn là các bạn tự nhận thức là chính & cơ bản nhất. Và đừng tự ái khi máy chỉ cho ta thứ này thứ khác qua ngôn ngữ VBA. Càng không nên nhào ngay vô cái sẵn có của người khác mà mình chưa có đồng vốn nào lận lưng. Và ý cuối cùng: máy tính lúc nào cũng sẵn lòng giúp ta, không hề vụ lợi!
Nếu chúng ta thực hiện xong macro thứ hai này thì trang BC chỉ còn chưa cập nhật số liệu lũy kế tháng (nêu tại cột ‘P’ trong Sheet ‘BCao’). Còn các cột trước nó đã ngon lành.
À còn điều này nói trước: Những bài ghi chép này là nói về VBA, nếu có ai thắc mắc về công thức nào đó của excel (mà cụ thể là trong trang ‘BCao’) thì bản thân xét thấy không có đủ khả năng giải đáp, thông cảm nha!
c.) Tạo số liệu sản lượng lũy kế tháng: Đây là công việc nhọc nhằng, vì chỉ một chục số liệu nhưng lại phải đổ nhiều công sức. Vây nên chuyển nó thành đề mục riêng luôn dưới đây:

3./ Thu thập số liệu các ngày trước đó của tháng

Để lấy dữ liệu từ đầu tháng từ kho lưu trữ ta thực hiện lọc hết dữ liệu từ ngày 1 của tháng đó cho đến ngày sếp yêu cầu. Nên nhớ rằng có lức cuối tháng, nhưng sếp muốn xem kết quả sản xuất của những ngày trong tuần đầu tháng thì sao?!
Vì chúng ta mới quen với VBA, nên chúng ta nên xài cột phụ, đó là trường [ThNm]; Nôm na là trường chứa 2 ký tự, ký tự đầu biểu trưng cho năm, ký tự sau biểu trưng cho tháng của năm ấy! Ở đây người ta làm vậy để chúng ta dễ xài mà thôi. Này nha: nếu chúng ta cung cấp cho macro một biến chuỗi kiểu ‘10/06’, ‘9/06’. . . cho máy cũng sẽ sẫy ra trường hợp bất đồng ngôn ngữ không ít thì nhiều. Vì sẽ có người cho là heo lớn hơn lợn, cũng sẽ có người cho lợn nhớn hơn heo!
Trường này do hàm tự tạo đem lại; Để có khái niệm về hàm tự tạo, ta bắt đầu tư hàm của excel. Hàm excel luôn trả về cho ta một thứ gì đó; Có một số hàm đòi chúng ta cung cấp các đối số, nhưng cũng có những hàm ta ới là nó cho ngay mà chẵng đòi hỏi gì;
(òn VBA cho chúng ta khả năng lập những hàm tùy thích miễn tuân thủ luật chơi về ngôn ngữ.
Trở lại trường tạm nêu trên; Vì trường này chỉ dùng trong hậu trường, và cũng suy ra được từ ngày cần BC, nên độ dài 2 ký tự là đủ. (Sau này có dịp ta sẽ xét kỹ hơn). Hiện thời ta biết nếu dùng Advanced Filter theo trường đó, ta sẽ có số liệu trong nguyên 1 tháng;
Các bạn thử dỡ trang tính ‘CSDL’ ra và thử nhiều lần đi, sẽ thấy tôi nói không sai. Và nếu cần bạn ghi thành macro luôn, khi đã thành thục.
/(/hưng đã nói trên, số liệu nguyên tháng nhiều khi không cần thiết & sẽ dẫn đến thông tin lệch lạc. Vậy là tại vùng kết xuất kết quả tháng, ta phải thực thi nhiệm vụ xóa đi những dữ liệu sau ngày yêu cầu báo cáo!

4./ Xóa đi số liệu các ngày sau của tháng


Macro BaoCao dưới đây, tôi đã sửa lại, bằng cách thay vì những dòng lệnh dài tôi thay bằng cách gọi một macro khác (những macro mà tôi đã khẩn khoảng đề nghị các bạn thực hiện một cách riêng rẽ, như sau (Tên là do tôi áp đặt, các bạn nên xem lại):
Macro xếp CSDL theo ngày (tăng dần) có tên Sub XepNgay()
Macro lọc số liệu theo ngày có tên Sub LocNgayBC()
Macro lọc số liệu theo tháng có tên là Sub LocThang()
Macro xếp theo tháng có tên Sub XepThang(), Về nội dung macro này bạn tham khảo trong file đính kèm! Nó cũng giống như XepNgay & tiện cho ai đó cần xem xét, kiểm tra.
/(/hư vậy macro mà tôi có được sẽ trở thành như sau:

Sub BaoCao()

501 Application.ScreenUpdating = 0: Sheets("CSDL").Select
'Xếp theo Ngày
XepNgay
'Xóa số liệu cũ:
503 Range("L2:M125", "O2:Q125").Select: Selection.ClearContents
'Lọc số liệu ngày:
LocNgayBC
'Lọc số liệu tháng:
LocThang
'Xếp theo tháng:
XepThang
'Tính lũy kế đầu tháng:
507 Dim Dat As Date: Dim StrC As String
Dim Zj As Integer
509 Dat = Range("H2").Value
510 For Zj = 2 To 125
511 StrC = "O" & CStr(Zj): Range(StrC).Select
512 With Selection
513 If Not IsDate(.Value) Or .Value > Dat Then Exit For
514 End With
515 Next Zj
516 Range("O" & CStr(Zj) & ":Q125").ClearContents
Sheets("BCao").Select
518 Exit Sub
'Hiện các dòng dữ liệu:
Selection.Rows.Hidden = False
For Zj = 12 To 19
If Range("P" & CStr(Zj)).Value = 0 Then Rows(Zj).Hidden = True
Next Zj
End Sub
(âu lệnh đầu tiên tại 501 dùng để khỏi lắc lư màn hình khi ta Select từ sheets này sang sheets kia, hay từ đầu CSDL đến ngay cuối CSDL thậm chí đến dòng cuối của trang tính. Câu thứ 2 trong dòng ta đã biết;
Hai câu lệnh trong dòng 503 sẽ chọn vùng gồm 2 khối & làm trống hoàn toàn các ô trong nó.
/(ể từ câu lệnh 507 thực sự cần khảo sát kỹ; trong dòng đó có câu khai báo một biến Dat có kiểu dữ liệu ngày tháng; Kiểu dữ liệu này na ná với kiểu dữ liệi Long, vì thực ra ngày tháng là số nguyên kể từ 1/1/1900 được ấn định là 1, và cứ thế. . . cứ sau 1 ngày tăng 1 đơn vị; Biến này được gán dữ liệu chứa trong ô H2 (tất nhiên trong H2 phải chứa dữ liệu kiểu ngày hay tương tự.) thông qua câu lệnh 509;
Dòng lệnh 510 & 515 ta cho qua?! Dòng 511, ở lệnh đầu là: đổi trị trong biến Zj sang dạng chuỗi và nối vô ký tự ‘O’; VD Zj đang là 35 thì biến StrC sẽ chứa chuỗi ‘O35’ (không có hai dấu nháy đơn). Dòng sau bảo với VBA chọn ô có địa chỉ như vậy làm ô hiện hành. Câu lệnh 512 & 514 ta qua luôn?! Câu 513 nói rằng nếu giá trị chứa trong ô hiện hành lớn hơn biến chứa ngày tháng (Dat) hay ô này không chứa giá trị ô ngày tháng thì thoát khỏi vòng lặp; Tại sao phải có hai ĐK (điều kiện)?; ĐK đầu áp dụng cho trường hợp ngày BC nhỏ hơn ngày sản xuất & đã nhập số liệu; ĐK sau để đúng với trường hợp ngàt BC cũng là ngày nhập số liệu cuối cùng. Nếu thiếu một trong hai có lúc ta bị báo lỗi không ngờ.
Tóm lại, vòng lặp 510 . . .515 sẽ lần lượt duyệt từ ‘O2’ cho đến hết ô 125 hoặc gặp một trong hai điều kiện nêu trên được thõa.
Tuy ra khỏi vòng lặp rồi, nhưng VBA vẫn nhớ hoài giá trị Zj. Nhớ cho đến khi nó gặp các mệnh đề như Exit Sub, End Sub, hoặc ta gán cho nó giá trị mới . . .
(ũng nhờ vậy mà ta viết được lệnh 516: Làm trống toàn bộ các ô trong vùng hình chữ nhật. Mà góc trên trái nhất của hình chự nhật là ô hiện hành cho đến góc phải thấp nhất của hình chữ nhật là Q125.
Mà tại sao là 125 & cứ 125 mãi vậy?! Nó tùy thuộc vô chu trình sản xuất của phân xưởng II này; Khi ta là người ngoài lập cho nhân viên thống kê phân xưởng thì ta phải hỏi số tối đa trong tháng mà ca nào đó có thể sản xuất bao nhiêu sản phẩm.
(/ậy sẽ nẫy sinh câu hỏi: Nếu sau này sản xuất phát triển, gây ra chuyện vượt số 125 dòng trong tháng thì làm cách nào?!
Thực tế, các Lão luyện trong VBA khuyên chúng ta trong trường hợp này là khai báo 1 hằng số trong phần Declarations ở trên cùng của cửa sổ VBA, câu lệnh như sau:
Const DongCuoi = 135
Sau đó trong toàn bộ các macro trong đó có thể xài hằng số này; Một khi cần bảo trì hay nâng cấp, ta khỏi tìm trong các đoạn mã một cách khó khăn mà chỉ việc tăng trị cho hằng số mà thôi. Kể ra nói không sai rằng định luật bảo toàn cũng đúng cả trong trường hợp như vầy!
Tại vùng Declarations này ta còn có thể khai báo nhiều thứ khác nhau, như
Số Pi: Bản thân máy đã có hằng số này; nhưng nó rất dài, ta có thể cần số như 3,142 thôi:
Const Pi = 3.142
Hằng số còn có thể là chuỗi kí tự như
Const Schu = “Chúc Mừng Đến Với VBA”
Để sau đó ta lập macro như sau:

Sub Auto_Open()

MsgBox Schu
End Sub
/(/ếu cũng chưa thỏa mãn theo kiểu phải khai báo hằng số thì có thể dùng vòng lặp Do. . . Loop thay cho vòng For . . . Next. Cú pháp để thực hiện công việc giống với công việc mà for . . . next làm như trên là vầy:
‘Thay cho câu lệnh 510 bằng 3 câu lệnh 5100, 5101 & 5102:
5100 Zj =1
5101 Do
5102 Zj= 1 + Zj
511
512
513 ‘ Câu lệnh này If Not IsDate(.Value) Or .Value > Dat Then Exit For
‘ được thay bằng
5130 If Not IsDate(.Value) Or .Value > Dat Then Exit Do
514 End With
515 ‘ Next Zj được thay bằng
5150 Loop


Bài tập của bài 5:

Voọch cho kỹ càng file đính kèm

:pepsi: :mrstraetz :friend:
 

Đính kèm

Sửa lần cuối:
T

tieutamtk

Thành viên sơ cấp
18/9/13
1
0
0
28
Tây Ninh
#8
Ðề: Từ macro đến VBA. Bài 1

Em thấy hay quá nhưng mà thấy còn quá ích. Mong anh đăng thêm nhiều nữa để em út tìm hiều. Cảm ơn anh nhiều.
 
T

thuynamhung

Thành viên sơ cấp
30/8/12
3
0
1
30
Hai Duong
#10
Ðề: Từ macro đến VBA. Bài 1

E chẳng hiểu nổi cái này. loằng ngoằng khó hiểu . hazzzzzz SA_DQ
 
W

Wnd

Thành viên sơ cấp
3/12/13
41
0
0
TPHCM
#11
Ðề: Từ macro đến VBA. Bài 1

Những đề tài này good, giúp cho các người đi sau học hỏi

Website Giaiphápexcel gì đó, các đây 9 năm trước tôi có vào . Thời đó paste code giúp mà bên VN hay gặp trở ngại vì tiếng Việt . Ví dụ tìm Dir() không được . Gộp nhiều Sheets vào thành 1 thì không sao, cứ gặp trường hợp tìm kiếm là thua vì chữ Việt, Chẳng biết bây giờ có khá hơn ko

Vỗ tay khuyến khích các Anh / Chị em
 
P

phuoc hieu

Thành viên sơ cấp
21/1/16
2
0
1
33
#12
Trong bài 2 có bài tập
1./ Tạo macro xoá dòng (hay cột) chứa mẫu tin
có ai giải goiu1p em với, vì em đang cần nó,
Viết thẳng vô đây càng tốt
GIúp em vớ
iem đang bí về khúc macro của excel, cũng là về nhân sự, do em muốn tìm hiểu thêm,
có 2 sheet, sheet1 là quan lý nhân sự sheet2 là data
Khi thay đổi sheet1 thì data đổi theo, em đã làm được ở macro
cái tiếp theo là, ở cột S, khi em nhập OFF ( tức là người đó nghĩ việc) thì cột sheet Data sẽ không hiện tên người đó ra
đây là hàm em đã chạy ở bước 1

Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
' Dim iHang As Long
Application.ScreenUpdating = False
If Not Intersect(Range("A1:CA100"), Target) Is Nothing Then Sheets("DATA").Range("A1:CA100").Value = Range("A1:CA100").Value
‘If Not Intersect(Range("S5:S100"), Target) Is Nothing Then Sheets("DATA").Range(Null).Value = Range("S5:S100").Value
End Sub

Được giúp em với a, em Thank nhiều
 

Thành viên trực tuyến

  • daongocnam0603
  • xediengiatot
  • KIMTUYEN140517
  • dungpi
  • Vuong Ngoan
  • Hoàng Minh Hà
  • Diepchieunhan

Xem nhiều