Macro to merge values from one column into one cell and retain source formatting.
Example:
Source: A1= "It is going to cost "
A2= "$1000.00" (A2 is formatted to underline value)
Destination: (desired result) B2= "It is going to cost $1000.00" (A2 value is still underlined)
Đề bài có thể tóm gọn lại như sau:
Trên cột [A:A] ta có những dòng thuyết minh & dưới nó là những con số đã được định dạng bằng nhiều cách khác nhau để fân biệt như chữ in nghiên, chữ số được tô đậm hay Font có màu đỏ,. . . .
Macro có nhiệm vụ: Hễ dòng nào có số thì ô bên fải liền kề cần được mang nội dung cũa ô trên ô có số & bản thân số của ô đang xét; Mặt khác định dạng ô giống với ô mang số liệu
Chúc thành công
Bảng liệt kê:
TT
|
Tên bài
|
Tại
|
Diễn giải
01|Bài tập 01|#1|Nối chuỗi & định dạng
02|Bài tập 02 | #11|Thống kê số lần lặp
03|Bài tập 03|#19|Trích lọc danh sách theo năm
04|Bài tập 04|#27|Thêm dòng theo số liệu tháng - năm
05|Bài tập 05|#31|Tổng hợp số liệu hoạt động theo từng kỳ (tháng)
06|Bài tập 06|#73|Ghí chú ngày có chi fí lớn nhất trong từng tháng khảo sát
07|Bài tập 07|#84|Thêm dòng tính tổng, sau khi đã thống kê số liệu
08|Bài tập 08|#103|Kẻ dòng, viền khung & format báo cáo hoàn chỉnh
09|
BT Fần B
|
#206
|
(Ở đây có bảng liệt kê riêng)
Thực ra về phần thuật toán, mình chưa đủ kiến thức để lĩnh hội. Nhưng mình nói về bài toán và đáp án :
Đề:Ví dụ tiếp theo Cho 1 dãy số nguyên từ A2:A14. Viết code để tìm giá trị max của A1:A14, không dùng các hàm có sẵn trong excel. tức là từ A2 đến A14 ta nhập một dãy số bất kỳ và không được dùng hàm có sẵn của excel để tìm số lớn nhất của dãy số, mà phải viết code(thay hàm Max) để tìm Max của dãy số này (Mình hiểu vậy, chả biết đúng không ? mung lung quá). Mình coppy đáp án dán vào module, nhưng nó không chạy.Tập tin đính kèm
VBA - để hình dung được thuật toán là khó nhất, cách học thuật toán của mình đó là tưởng tượng mình làm bằng tay như thế nào thì mô tả lại như thế, ví dụ thế này :
PHP:
Sub timMax()
Dim i As Long, maxV As Long
Dim Rng As Range
Set Rng = Range("A2:A14")
maxV = Cells(2, 1).Value
For i = 3 To 14
If Cells(i, 1).Value > maxV Then maxV = Cells(i, 1).Value
Next
MsgBox maxV
End Sub
Có phải làm bằng tay thì thế này không?
Đầu tiên sẽ nhìn dòng đầu tiên của vùng dữ liệu đó coi giá trị đó là lớn nhất- ghi giá trị đó vào giấy nháp, sau đó đi dò các dòng tiếp theo sau, cứ em nào lớn hơn thì ghi tiếp nó ra giấy nháp, cứ như thế dò cho đến hết vùng dữ liệu đó ta sẽ được giá trị cuối cùng chính là giá trị max.
Mình làm đúng như thế đó. Thực ra theo mình mới học VBA thì làm những ví dụ đơn giản mà ngắn ngắn thôi, chứ dài ngoằng chỉ mỗi việc ngồi theo dõi thuật toán thôi cũng đủ KHÓC rồi.
Tôi thì tôi cho rằng 1 là tôi đươc 0 điểm, 2 là các bạn vì hiểu sai đề: Cho một dãy số nguyên từ A2:A14 ( tức là dãy số này cho trước đầy đủ từ A2:A14 ). Yêu cầu :Viết code tìm giá trị Max của A1:A14 (trong code cũng không được dùng công thức của hàm Max, hoặc hàm khác của Excel) theo hướng của thày NDU nhưng phải ở dạng code, không phải dạng công thức và khi ta thay đổi giá trị bất kỳ của dãy số trên, code vẫn phải cho gia trị Max đúng. Nếu sai thầy cho điểm 0 tối tôi về nộp cho vợ !
manuchungtinh VBA - để hình dung được thuật toán là khó nhất, cách học thuật toán của mình đó là tưởng tượng mình làm bằng tay như thế nào thì mô tả lại như thế, ví dụ thế này :
thật ra thuật toán trong VBA cũng chính là những thuật toán mà các bạn đã được học trong lơp phổ thông rồi, nhưng do sự phát triển của công nghệ, các lớp trẻ ngày nay lạm dụng vào máy móc mà quên đi các thuật giải cơ bản của toán học mà thôi.
HƯỚNG DẪN TẠO 1 MACRO LỌC MỞ RỌNG (AdvancedFilter)
Chúng ta đến trang tính có tên là ‘Nhap’ để thực hiện thiết kế & thi công quá trình AdvancedFilter nhờ sự giúp đỡ của bộ thu macro trong excel
Chúng ta chia ra làm 2 công đoạn, đó là công đoạn làm thủ công & công đoạn thu tự động
1./ Công đoạn thủ công:
(Ta fải thực hiện thực nhuần nhuyễn công đoạn này bằng tay; Đó là tiền đề tốt để sang công đoạn sau không có 1 sai sót nào)
Để thuận tiện trong quá trình chọn vùng dữ liệu cần lọc, ta chọn 1 vùng dữ liệu độ vài dòng & cột đầu; Sau đó vô menu ‘Window’, trong menu con vừa xuất hiện ta chọn dòng ‘Preeze Panes’
Tiếp theo ta cho ẩn các cột từ [H:Z] chưa cần thiết trong sử dụng;
Tại [Ac1:AC2] ta lập công thức =[A1]
Tại [AA1] ta nhập 1 ngày nào đó có trong CSDL, như 8/13/2012
Tại [AA3] ta cũng nhập 1 ngày nào đó lớn hơn, như 8/17/2012
Tại [Ac2] ta thiết lập công thức =">="&AA1
Tương tự, tại ô bên fải liền kề ta nhập công thức tham chiếu đến ô [AA3] như sau: ="<="&AA3
(Ta hiểu ngầm với nhau rằng: ngày tại [AA1] là ngày bắt đầu khảo sát số liệu & [AA3] chứa ngày cuối khảo sát số liệu)
Bước tiếp theo là ta chép toàn bộ tiêu đế của CSDL đến ô [AC4] & những ô bên fải liền kế của nó;
Nhưng bên trang ‘BC’ ta thấy trong bản BC này không cần trường [SoFieu], nên ta tìm cách di dời toàn bộ các trường bên fải nó sang trái 1 ô;
Đó là ta đã hoàn thành xong việc thiết kế;
Giờ ta tiếp sang chu trình thi công thủ công:
(Những bạn đã quá quen với fần sau này, chỉ thao tác 1 lần cho quen với CSDL mới này cũng được)
Để vậy, ta lôi nút trên thanh trượt bên fải màn hình xuống gần tới 2/3 dữ liệu;
Tiếp theo ta bấm chuột vô menu Data -> Filter -> Advanced Filter. .
Excel ngay lập tức cung cấp cho ta 1 CS (cửa sổ) mới; Trên CS này ta thực hiện 1 số bước sau:
Trên ngăn ‘Action’ ta chọn dòng thứ 2 (Copy to another location)
Nếu trong ngăn List range Excel đã ghi giúp ta vùng bao gồm toàn bộ CSDL thì tốt, còn không ta dùng chuột quét chọn toàn bộ vùng dữ liệu các cột [A:F] mà ta thấy được trên màn hình
Với ngăn dưới tiếp theo, ta bấm vô CS này xóa dữ liệu nếu có & dùng chuột quét chọn vùng[AC1:AD2] để vùng địa chỉ này hiện trên CS;
Với ngăn dưới nữa, ta cũng làm tương tự, nhưng với vùng các ô từ [AC4:AG4]
Sau đó ta bấm vô nút ‘OK’ để Excel lọc vùng dữ liệu & cung cấp ra ngay dưới nếu có.
Chu trình này các bạn nên lặp đi lặp lại nhiều rằng, để chắc chắn rằng khi bước vô công đoạn thu macro ta không 1 tí nào sơ sảy.
2./ Công đoạn thu macro
Để vậy ta vô menu Tool -> Macro -> Record New Macro . . . & bấm chọn dòng này;
Khi đó CS VBE hiện cho ta 1 CS be bé; Lúc này ta có thể chấp nhận cả 4 đề nghị của VBE, có nghĩa là ta bấm vô nút ‘OK’ để đi tiếp giai đoạn sau
(Nhưng chú í rằng sau này ta có thể tùy chỉnh theo í mình với 1 số đề nghị của VBE)
B1: Dùng chuột quét chọn vùng dữ liệu;
B2: Vô menu Data -> Filter -> Advanced Filter. . .
Lúc đó VBE đưa ra CS mà ta có thể thấy tên là Advanced Filter
Tại ngăn Action ta bấm chọn dòng ‘Copy to another location
Tại ngăn List range, nếu VBE hiện đúng địa chỉ vùng ta đã chọn thì xuống tiếp ngăn dưới;
Bằng chưa thì ta bấm chuột vô ngăn này & rê chuột lên trang tính & chọn tất cả các cột trước cột [H]
Trong ngăn Criteria range ta có thể bấm chọn vô ngăn để xóa bỏ địa chỉ nào đó chưa đúng. Sau đó dùng chuột quét chọn vùng[AC1:AC2]
Trong ngăn Copy to ta thực hiện tương tự để có địa chỉ $AC$4:$AG$4 trong ngăn này & bấm vô nút ‘OK’ để kết thúc fương thức thu-ghi macro AdvancedFilter
(Sau khi bấm ‘OK’, ta sẽ thấy dữ liệu xuất hiện mới lên vùng dưới [Ac4])
Như vậy ta kết thúc công đoạn thu macro; Thực hiện việc kết thúc này có thể bằng 1 trong 2 cách đơn giản sau:
Nếu trên màn hình có hộp thoại để kết thúc macro, ta cứ việc bấm vô nó là được;
Cách thứ 2 cực hơn xíu là fải vô menu Tool -> Macro -> . . . để làm việc này
3./ Công đoạn chỉnh sửa macro
Nội dung macro của chúng ta thu được có thể là vầy:
PHP:
Option Explicit
Sub Macro1()
'. . . '
' . . . .'
Range("A1:G1449").AdvancedFilter Action:=xlFilterCopy, CriteriaRange:=Range _
("AC1:AD2"), CopyToRange:=Range("AC4:AG4"), Unique:=False
End Sub
Macro do VBE đưa ra chỉ có 1 dòng lệnh là đáng nể thôi;
Dịch sang tiếng việt dòng lệnh có nghĩa là:
Áp dụng fương thức AdvancedFilter cho vùng dữ liệu [A1:G1449] theo vùng chuần là [AC1:AD2], số liệu có được đem hiện ra dưới vùng mà VBE gọi là Extract
Sao ta lại fải chỉnh sửa macro?
Vì chúng ta mới làm việc với trang tính ‘Nhap’ mà thôi; Nay mai sẽ còn trang tính ‘Xuát’ nữa là tất nhiên;
Để macro này có thể xài được cho cả 2 trang tính, ta cần chỉnh hoặc bên này hay bên kia các iếu tố có trên dòng lệnh;
(Ta tạm hiểu rằng chình bên này là chỉnh trên dòng lệnh; chỉnh bên kia là chỉnh thiết kế của trang tính chứa dữ liệu)
Cái mà ta gọi là ‘bên này’ ấy là địa chỉ đầu tiên ta gặp trong câu lệnh.
Ta biết chắc 1 điều rằng cấu trúc 2 trang tính ‘Nhap’ & ‘Xuat’ không thể trùng nhau về số dòng dữ liệu;
Ngoài ra ta sẽ ngừa rằng chúng khác biết nhau về số trường chứa dữ liệu; (Hiển nhiên 1 điều rằng chúng giống nhau về số cột, thì không dại gì tách làm 2 trang tính như vậy)
Tùy theo trình độ của bạn, bạn chỉnh sửa lại theo các hướng sau đây
a./ Không chỉnh gì cả;
Như vậy sẽ không mệt bây chừ, như sau này sẽ mệt.
b./ Đưa vô 1 biến đối tượng đã khai báo thêm từ đầu chương trình, như
Mã:
Dim Rng As Range
Sau đó là dòng gán nội dung cho nó:
Set Rng = Range("A1:G1449")
Cách này vẫn bất lợi do dữ liệu sẽ thường liện tục tăng (Có thể giảm . . .) làm chi trị 1449 chỉ đúng cho hôm nay, nhưng ngày mai khác,. . .
c./ Cách tối ưu nhất, Nhưng muốn xài cách này ta cần thêm kiến thức về thuộc tính CurrentRegion
(Thuộc tính này các bạn có thể tìm trên diễn đàn để làm chủ nó lúc rỗi)
Lúc đó câu lệnh trong cách 2 sẽ chuyển thành
Set Rng= [B2].CurrentRegion
Bài tập B1: Tạo macro lọc dữ liệu của 4 ngày giữa tháng 7 bất kỳ sang trang 'BC'
Bạn nào đã biết macro sự kiện, ta có thể tao macro tại ô nhập ngày cuối của trang 'BC' để các bạn khác tham khảo & trao đổi.
Chúc các bạn thành công.
Bảng liệt kê:
TT
|
Tên bài
|
Tại
|
Diễn giải
01|Bài tập B1|#206|Lọc DL 4 ngày tháng 7 sang trang 'BC'
02|Bài tập B2 | #215|Chép số liệu các trang tính 'Nhap' & 'Xuat' sang 'BC'
03|Bài tập B3|#224|Tính tồn kho tháng giêng của 2012.
04|Bài tập B4|#| -
05|Bài tập B5|#|()
06|Bài tập B6|#|
07|Bài tập B7|#|
08|Bài tập B8|#|,
09|...||
chờ mãi không thấy ai lên bảng, nhà em nộp bài vậy. Để lĩnh hội được bài của thày ChanhTQ@ ở trên chắc phải còn dài dài mới hiểu được. Phải thêm cột phụ cho đáp án, thấy cũng không hay, các bạn góp ý.
Thấy tiêu đề "Những bài tập VBA đơn giản dành cho người mới bắt đầu", mình cũng cố chạy theo các bạn, ai ngờ mới dăm bữa đã không theo được, bị thày đuổi rồi. Dù sao cũng phải cảm ơn các thày và các bạn. Dốt khổ thật!
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, [B3]) Is Nothing Then Exit Sub
Me.UsedRange.Resize(, 11).Offset(3).Clear
Sheet1.[A3:J2000].AdvancedFilter 2, [B2:B3], [A5]
End Sub
Bạn 'KB' có trình độ là thầy giáo của những người đứng lớp này. Đó là điều khẳn định;
Điều khẳng định nữa, đó là:
Không fải người có khả năng dạy học viên đại học hay cao hơn lại có thể hướng dẫn cho cấp I làm tốt bài tập;
Chứng minh:
Không nên truyền đạt cho học viên "tiểu học" câu lệnh như vầy
Mã:
Sheet1.[A3:J2000].AdvancedFilter 2, [B2:B3], [A5]
& Kết quả câu lệnh này là dữ liệu vừa được lọc & vừa được chép qua 'BC'
Nhưng chệch khá xa so với iêu cầu đề bài;
Nói lên điều này, để thấy rằng, để "Giảng viên" ngồi trong lớp chỉ tổ fá rối học viên khác & lớp mà thôi.
1 - Xin lỗi thầy vì nhà em nhầm đề, tưởng vẫn làm theo bài tập cũ cho hệ thống. Nhưng thực ra đề đã chuyển sang bài #205 rồi.
2 - Nhà em muốn học là thật mà. Thực ra code trên cũng là kiến thức của các thày mà, nhà em chỉ mang ra ứng dụng mà thôi. Thấy các bạn viết code cho bài giải, đêm đêm ngồi xem thấy hay quá, phục thật! và chỉ mong theo kịp các bạn mà thôi. Mong thày và các bạn đừng hiểu lầm .
Public Sub Xuan()
Dim Rng(), Arr(), I As Long, J As Long, K As Long, NgayDau As Date, NgayCuoi As Date
With Sheets("Nhap")
Rng = .Range(.[A2], .[A65536].End(xlUp)).Resize(, 7).Value
End With
ReDim Arr(1 To UBound(Rng, 1), 1 To 6)
With Sheets("BC")
NgayDau = .[E1].Value
NgayCuoi = .[E2].Value
For I = 1 To UBound(Rng, 1)
If Rng(I, 1) >= NgayDau And Rng(I, 1) <= NgayCuoi Then
K = K + 1
Arr(K, 1) = K
Arr(K, 2) = Rng(I, 1)
Arr(K, 3) = Rng(I, 4)
Arr(K, 4) = Rng(I, 5)
Arr(K, 5) = Rng(I, 6)
End If
Next I
.[A5:F1000].ClearContents
.[A5].Resize(K, 6).Value = Arr
End With
End Sub
Public Sub Xuan()
Dim Rng(), Arr(), I As Long, J As Long, K As Long, NgayDau As Date, NgayCuoi As Date
With Sheets("Nhap")
Rng = .Range(.[A2], .[A65536].End(xlUp)).Resize(, 7).Value
End With
ReDim Arr(1 To UBound(Rng, 1), 1 To 6)
With Sheets("BC")
NgayDau = .[E1].Value
NgayCuoi = .[E2].Value
For I = 1 To UBound(Rng, 1)
If Rng(I, 1) >= NgayDau And Rng(I, 1) <= NgayCuoi Then
K = K + 1
Arr(K, 1) = K
Arr(K, 2) = Rng(I, 1)
Arr(K, 3) = Rng(I, 4)
Arr(K, 4) = Rng(I, 5)
Arr(K, 5) = Rng(I, 6)
End If
Next I
.[A5:F1000].ClearContents
.[A5].Resize(K, 6).Value = Arr
End With
End Sub
Câu lệnh trên cùng (Rng = .Range(.[A2], .[A65536].End(xlUp)).Resize(, 7).Value) nằm trong câu lệnh With Sheets("Nhap"), do đó các dấu chấm ở trên cho biết những gì đi sau nó là thuộc tính (hoặc đối tượng con) của đối tượng Sheets("Nhap"), có nghĩa là nếu đầy đủ thì phải viết như sau (nếu không có câu lệnh With):
Dấu chấm trước đối tượng thay cho cái gì đó sau With
Dấu chấm sau đối tượng là thuộc tính của đối tượng đó.
Như ví dụ .[A2].Borders....
Chấm đầu thay cho Sheet1, chấm sau là thuộc tính Borders của [A2]
With sheet1
Ví dụ:
Mã:
[B].[A2].Borders.Linestyle=xlContinuous[/B]
Và câu:
Mã:
[B]Sheet1.[A2].Borders.Linestyle=xlContinuous[/B]
Là như nhau.
Chỉ sử dụng With khi muốn thay cho 1 đối tượng nào đó nhiều lần, nhiều dòng phải lặp lại cùng 1 nội dung như thế.
Ví dụ:
Sheet1.[A2:J1000].clearcontents
Sheet1.[A2].resize(,5).value=Arr
Sheet1.[A2].resize(K,5).Interior.ColorIndex= xlNong
Sheet1.[A2].Font.ColorIndex=3
Như trong Code của mình, dấu chấm ở dòng 4 là thay cho Sheets("Nhap")
Dấu chấm từ dòng 8 trở xuống là thay cho Sheets("BC")
Ngoài lề một chút, không giải thích dấu chấm theo đề bài này, theo sách của anh Phan Tự Hướng mình có đọc là:
Khi Tham chiếu tới đối tượng:
Wb(“ten book”).Worksheet(“ten sheet”).Range(“B3”)
Dấu chấm có ý nghĩa là ký tự đường dẫn.
Ban đầu khi mình học A,B,C cũng là tìm hiểu về đối tượng, thuộc tính, về các ký tự trong cửa sổ soạn thảo VBA. dấu móc đơn, dấu chấm, dấu gạch dưới, ....các ký tự khác khi tiến hành ghi macro.
(1) XuanNguyen82 đã giải bằng biến mảng ở bài B1 rồi mà, sao không tiếp tục vậy?
(Thực ra với CSDL trong file, tốc độ thực thi của fương thức AdvancedFilter & cách xài biến mảng đang là tương đương; Nhưng cách xài biến mảng là đán khuyết khích & ngợi khen!)
(2) Tại sao macro thứ 3 lại đi xóa 2 thiết kế trên trang tính dùng để lọc đi vậy? (Rồi sau đó, mỗi khi chạy macro 1 & macro 2 lại thiết kế lại)
Mấy ngày ngồi xem các bạn học, thấy buồn. Mình cám ơn XuânNguyễn về tinh thần học tập nghiêm túc của bạn. Với vài tháng làm quen với VBA mình chưa thể tự viết Code được, nhưng mình thử nhốt 3 code của bạn xem sao. Không biết có đúng không nữa, các bạn và các thầy xem và góp ý.
Đề bài B3: Lập macro tính lượng tồn kho tháng giêng
Dưới đây là hình chụp từ trang tính 'DMuc' của CSDL bài trên
So với CSDL gốc, người ta đã thêm 1 số trường [12/11], [01/12], [02/12],. . . . về fía fải của CSDL
Nếu chú í kỹ ô nơi được kích hoạt, ta sẽ thấy thực chất các trường này là ngày đầu của 1 tháng nào đó.
Những người xây dựng CSDL này muốn chúng ta hiểu các trường này lập ra để tính tồn kho của cuối tháng đó; Hơn nữa, trường [12/11] là số liệu giả tưởng, mà các bạn nên nhập vô trước khi làm bài tập này.
Bài tập B3 có nội dung như sau:
Hảy viết macro điền số liệu vô cột (trường) [01/12] dựa trên số liệu các trang 'Nhap' & 'Xuat'
Gợi í: Các bạn cho chạy macro bài B2, nhưng với khoảng thời gian từ #1/1/2012# cho đến #31/1/2012# để số liệu hiện lên trang 'BC';
Từ số liệu đó làm cơ sở tính ra lượng tồn các mặt hàng trong tháng;
(1) XuanNguyen82 đã giải bằng biến mảng ở bài B1 rồi mà, sao không tiếp tục vậy?
(Thực ra với CSDL trong file, tốc độ thực thi của fương thức AdvancedFilter & cách xài biến mảng đang là tương đương; Nhưng cách xài biến mảng là đán khuyết khích & ngợi khen!)
(2) Tại sao macro thứ 3 lại đi xóa 2 thiết kế trên trang tính dùng để lọc đi vậy? (Rồi sau đó, mỗi khi chạy macro 1 & macro 2 lại thiết kế lại)
Em tiếp tục với bài tập B2. Kính nhờ các Thầy và các anh chị, các bạn chỉ bảo thêm ạ.
Mã:
Public Sub Xuan()
Dim Ws As Worksheet, I As Long, J As Long, K As Long, Arg(), Arr(1 To 65000, 1 To 6)
Dim TuNgay As Date, DenNgay As Date
TuNgay = Sheets("BC").[E1].Value
DenNgay = Sheets("BC").[E2].Value
For Each Ws In ThisWorkbook.Worksheets
If Ws.Name = "Nhap" Or Ws.Name = "Xuat" Then
Arg = Ws.Range(Ws.[A2], Ws.[A65536].End(xlUp)).Resize(, 9).Value
For I = 1 To UBound(Arg, 1)
If Arg(I, 1) >= TuNgay And Arg(I, 1) <= DenNgay Then
K = K + 1: Arr(K, 1) = K
Arr(K, 2) = Arg(I, 1)
If Ws.Name = "Nhap" Then
Arr(K, 3) = Arg(I, 4): Arr(K, 4) = Arg(I, 5)
Arr(K, 5) = Arg(I, 6)
Else
Arr(K, 3) = Arg(I, 6): Arr(K, 4) = Arg(I, 7)
Arr(K, 6) = Arg(I, 8)
End If
End If
Next I
End If
Next
With Sheets("BC").[A5].Resize(K, 6)
.Resize(1000).ClearContents
.Resize(1000).Borders.LineStyle = xlNone
.Value = Arr
.Borders.LineStyle = xlContinuous
.Offset(, 1).Sort Key1:=Range("B5"), Order1:=xlAscending, Key2:=Range("C5"), Order2:=xlAscending
End With
If K Then
Else
Sheets("BC").[A5:F1000].ClearContents
MsgBox "Khong co Nhap Xuat trong thoi gian nay", , "XUAN.NGUYEN82"
End If
End Sub
Lớp này rất được cộng đồng 2uan tâm (Thông qua số liệu truy cập hàng ngày)
Chỉ có điều rất nhiều người chưa mạnh dạn hay quen với kiểu topic này đang làm
Tất nhiên không loại trừ những người có vô vàn lí do khác để ghé xem qua. . . .
Nói tới quản lý nhập, xuất & tồn, ta không thể không đếm xỉa tới những tờ thẻ kho.
Mình đã sưu tầm trên diễn đàn nào đó cái thẻ kho có hình như vầy:
Nếu nghiên cứu & đối chiếu với nội dung trong trang'BC' mà ở các bài B1 & B2 ta đã đề cập đến thì chúng có họ hàng với nhau;
Theo mình Thẻ kho có nguồn góc từ 'BC'
(*) Nếu trên trang 'BC' chỉ liệt kê hoạt động của 1 mặt hàng
(*) Nếu ngày bắt đầu trong 'BC' là mốc đầu tiên để làm thẻ kho
Thì lúc đó 'BC' trở thành cái thẻ kho cho mặt hàng cụ thể nào đó.
Trở lại trang tính 'DMuc' ta có thể thấy điều này:
Cột [F] là lưu tồn của năm trước; Tiếp sau đó về bên fải liền kề là các cột/trường liệt kê số tồn từng tháng tăng dần cho đến tháng 12 của năm;
Ta có thể suy ra rằng, cách làm của cơ quan này là sau 1 năm hoạt động, 1 khi có số tồn cuối năm thì CQ đó sẽ xóa 12 cột kể từ cột [F] này đi
& như vậy số liệu tồn sẽ tiếp tục với niên hạn năm 2013 mới.
Và điều này sẽ sẩy ra: Thẻ kho lại lấy mốc bắt đầu từ 1/1/2013
Chúng ta cùng hình dung tiến trình như vậy để chuẩn bị sang bài tập B4 (sẽ có trong nay mai . . .)
So với CSDL gốc, người ta đã thêm 1 số trường [12/11], [01/12], [02/12],. . . . về fía fải của CSDL
Nếu chú í kỹ ô nơi được kích hoạt, ta sẽ thấy thực chất các trường này là ngày đầu của 1 tháng nào đó.
Những người xây dựng CSDL này muốn chúng ta hiểu các trường này lập ra để tính tồn kho của cuối tháng đó; Hơn nữa, trường [12/11] là số liệu giả tưởng, mà các bạn nên nhập vô trước khi làm bài tập này.
Bài tập B3 có nội dung như sau:
Hảy viết macro điền số liệu vô cột (trường) [01/12] dựa trên số liệu các trang 'Nhap' & 'Xuat'
Gợi í: Các bạn cho chạy macro bài B2, nhưng với khoảng thời gian từ #1/1/2012# cho đến #31/1/2012# để số liệu hiện lên trang 'BC';
Từ số liệu đó làm cơ sở tính ra lượng tồn các mặt hàng trong tháng;
Private Sub Worksheet_Change(ByVal Target As Range)
On Error Resume Next
Application.EnableEvents = False
Application.ScreenUpdating = False
Dim Rng As Range, RngA As Range, Cll As Range, K As Long, Nhap As Long, Xuat As Long
If Not Intersect(Target, [G1:Z1]) Is Nothing Then
If Target.Columns.Count = 1 Then
If Target.Rows.Count = 1 Then
If Target <> "" Then
With Sheets("BC")
.[E1].Value = Target.Value
.[E2].Value = DateSerial(Year(Target), Month(Target) + 1, 0)
Set Rng = .Range(.[C5], .[C65536].End(xlUp)).Resize(, 5)
End With
With Sheets("DMuc")
Set RngA = .Range(.[D2], .[D65536].End(xlUp))
For Each Cll In RngA
K = K + 1
With Application.WorksheetFunction
Nhap = .SumIf(Rng, Cll, Rng.Offset(, 2))
Xuat = .SumIf(Rng, Cll, Rng.Offset(, 3))
Target.Offset(K).Value = Target.Offset(K, -1) + Nhap - Xuat
End With
Next
End With
End If
End If
End If
End If
Set Rng = Nothing
Set RngA = Nothing
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
Có bạn học chung rất vui, bạn Kh biet giỏi thật đấy, nhìn cách bạn làm mà xuan.nguyen82 theo hông kịp.
Bầu chọn bạn Kh biet làm lớp trưởng nghen.
Cảm ơn bạn!
lớp này ko phải chỉ có 2 người học đâu, mà khá đông đó nhìn số người view xem, nhưng có lẽ do các thành viên khiêm tốn không nộp bài hoặc do học kém không có bài để nộp (số này có mình à nhe!) nên đành làm kháng giả chưa lên sân khấu được ...
lớp này ko phải chỉ có 2 người học đâu, mà khá đông đó nhìn số người view xem, nhưng có lẽ do các thành viên khiêm tốn không nộp bài hoặc do học kém không có bài để nộp (số này có mình à nhe!) nên đành làm kháng giả chưa lên sân khấu được ...
Ẹc, mình cũng có biết mô tê gì đâu, cứ tham gia để mà nếu có sai thì có người sửa. Lần sau khỏi bị sai. Hihi.
Nhiều thành viên đáng để gọi là sư phụ trong lập trình rồi....