Thủ thuật trong Excel

Tổng hợp những bài trả lời đáng chú ý

của Nguyễn Phương Thảo đối với học viên và những khách INTERNET.

Người tổng hợp: Nguyễn Lan Anh

Trung tâm Tin học ABC thông báo: Chị Nguyễn Phương Thảo đã FORWARD địa chỉ fthaoabc@yahoo.com vào địa chỉ tinabc@hn.vnn.vn để các giáo viên Trung tâm Tin học ABC trả lời, nên địa chỉ này chỉ dùng để giải đáp Tin học, nó chính là địa chỉ của Trung tâm Tin học ABC. Bạn muốn viết thư riêng cho Nguyễn Phương Thảo xin gửi cho địa chỉ riêng Nguyễn Phương Thảo.

1. Về hàm chuyển số thành chữ:

Hiện nay tôi nhận thấy trên tạp chí PC-World (Thế giới vi tính - Việt Nam) có đăng rất nhiều bài chuyển số thành chữ bằng nhiều phương pháp khác nhau. Tôi sưa tầm được một bài chuyển số thành chữ của Nguyễn Phương Thảo (Được viết bên trong phần mềm "Dự toán 2001" do Trung tâm Tin học ABC thực hiện tháng 1/2000, theo đơn đặt hàng của Công ty Xây dựng số 3 - Thị xã Yên Bái ). Cách chuyển số thành chữ ở đây hoàn toàn khác với các cách mà bạn đã đọc trên tạp chí Thế giới Vi tính.

Hàm được viết bằng ngôn ngữ Visual Basic For Application trong chính môi trường Excel. Cách đề cập hoàn toàn đơn giản. Xây dựng một hàm đọc từng con số. Sau đó đọc số đó lên. Dùng hàm thay thế để thay một số câu "ngang ngang" thành câu sử dụng bằng cách nói thông thường. Đó cũng là một phương pháp tiếp cận nữa của Nguyễn Phương Thảo cho những học viên người dân tộc ở vùng cao Yên Bái. Các học sinh dân tộc cũng đă học tiếng Việt (Kinh) chính bằng phương pháp đó.

Option Explicit

'Hàm đọc số

Function Bangchu(so)

Dim kq, viet, dai, tung, i

'Làm tròn, biến thành chuỗi để đưa vào biến viet

viet = Str(Round(so, 0))

'độ dài của chuỗi đă biến thành...

dai = Len(viet)

'Đánh vần từng con số một theo chiều dài của chuỗi "số"...

For i = 1 To dai - 1

tung = doc(Right(Left(viet, dai - i + 1), 1), i)

kq = tung + " " + kq

'Thêm tiêu đề hàng ngàn triệu tỷ đối với từng nhóm 3 con số

Select Case i

Case 3

If (i + 1) < dai Then

kq = "ngàn " + kq

End If

Case 6

If (i + 1) < dai Then

kq = "triệu " + kq

End If

Case 9

If (i + 1) < dai Then

kq = "tỷ " + kq

End If

Case 12

If (i + 1) < dai Then

kq = "nghìn tỉ " + kq

End If

End Select

Next

' Đặt trạng thái nếu có lỗi thì bỏ qua.

On Error Resume Next

'Tiến hành thay thế các cụm từ ngang ngang thành từ ngữ giao tiếp 'thông thường. Thông qua hàm Replace.

If Left(Trim(kq), 3) = "mốt" Then

kq = "Một" + Mid(LTrim(kq), 4, Len(kq) - 4)

End If

kq = kq + " đồng chẵn"

kq = Replace(kq, " ", " ")

kq = Replace(kq, "mươi mươi", "mươi")

kq = Replace(kq, "mười mươi", "mười")

kq = Replace(kq, "mười mốt", "mười một")

kq = Replace(kq, " linh mươi", "")

kq = Replace(kq, " linh đồng", "đồng")

kq = Replace(kq, " không trăm tỷ", "")

kq = Replace(kq, " không trăm triệu", "")

kq = Replace(kq, " không trăm ngàn", "")

kq = Replace(kq, " không trăm đồng", " đồng")

kq = Replace(kq, " trăm mốt", " trăm một")

Bangchu = UCase(Left(kq, 1)) + Mid(kq, 2, Len(kq) - 1)

End Function

'Hàm doc để đánh vần từng con số 1

Function doc(s, i)

Dim kq

Select Case s

Case "0"

If (i Mod 3) = 1 Then

kq = "mươi"

ElseIf (i Mod 3) = 2 Then

kq = "linh"

Else

kq = "không"

End If

Case "1"

If (i Mod 3) = 1 Then

kq = "mốt"

ElseIf (i Mod 3) = 2 Then

kq = "mười"

Else

kq = "một"

End If

Case "2"

kq = "hai"

Case "3"

kq = "ba"

Case "4"

kq = "bốn"

Case "5"

kq = "năm"

Case "6"

kq = "sáu"

Case "7"

kq = "bảy"

Case "8"

kq = "tám"

Case "9"

kq = "chín"

End Select

If ((i Mod 3) = 0) And (kq <> "linh") Then

kq = kq + " trăm"

ElseIf (i Mod 3) = 2 And (kq <> "mươi") Then

kq = kq + " mươi"

End If

doc = kq

End Function

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

2. Bài toán cộng lẫn số và chữ:

Một khách Internet tên là Hải nêu ra một bài toán trong Excel như sau:

Trong cơ sở dữ liệu được ghi thành dạng:

A, 1A, 13A, 23A, 66A, 120A...

345BC, 22BC, 88BC...

444DEF, 1234DEF...

Tức là những số đứng trước chỉ số lượng, phần chữ đứng sau chỉ mặt hàng.

Thiết kế hàm để tính tổng số lượng mặt hàng trong vùng đó. Ví dụ tính mặt hàng A trong vùng $C$5:$E$500 thì đánh:

CONG($C$5:$E$500;"A")

Sẽ ra kết quả là tổng của mặt hàng A. Tương tự với các mặt hàng khác.

Hàm được viết như sau:

Option Explicit

Function CONG(Vung, DL)

Dim KQ, OHT, daiOHT, DaiDL, DaiSo

DL = Trim(DL)

DaiDL = Len(DL)

For Each OHT In Vung

OHT = Trim(OHT)

daiOHT = Len(OHT)

DaiSo = daiOHT - DaiDL

If (Right(OHT, DaiDL) = DL) And (DaiSo = 0) Then

KQ = KQ + 1

ElseIf (Right(OHT, DaiDL) = DL) And IsNumeric(Val(Left(OHT, DaiSo))) Then

KQ = KQ + Val(Left(OHT, DaiSo))

End If

Next

CONG = KQ

End Function

Thủ tục được viết trong Sheet chứa vùng đó để tự động tính khi thay đổi dữ liệu:

Private Sub Worksheet_SelectionChange(ByVal Target As Excel.Range)

Calculate

End Sub

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

3. Giải pháp cho TAMHIEP

Câu hỏi của bác Nguyen Van Hung MailTo: hunghuongus@yahoo.com như sau (Copy nguyên văn thư hỏi):

Trong việc làm tôi có 1 vướng mắc nhỏ xin được hướng dẫn

Tôi có 1 bảng tính gồm 2 sheets

 Sheet 1 đặt tên danh sánh, gồm có (A1)số thứ tự, B2 là 1, B3 là 2 cứ thế tăng dần đến hết danh sách, (A2)tên họ (A3) V.v......., hàng là các tên và thông số cập nhật bằng tay theo hàng tháng theo biến động tháng đó. Danh sách có sẳn nhưng hàng tháng không in hết tất cả mà chỉ in một số khách hàng

Sheet 2 đặt tên in, dùng để in các thông báo cho khách hàng có mẫu sẳn đã đặt nhà máy in các chủ đề chừa các dňng cần in  như họ tên, điạ chỉ v.v....chỉ in các thông số quy định như tên họ, điạ chỉ, ngành nghề  v.v....

Sheet 2 tôi có đặt các công thức thí dụ  ô B2 là 1( lấy số thứ tự ở sheet danh sách cột A, ô A4=VLOOKUP(in!B2;danhsanh!A1:F11;2) thì ô A4 sẽ kết ra nội dung trong sheet danh sách và cứ thế tiếp tục canh và đặt công thức cho phù hợp với mẫu in

Xong tôi có tạo một nút lệnh bằng command button ở sheet danh sách và  viết macro như sau:

Frivate Sub commandButton_Click()

Worksheets("in").Range("B2").Value = ""

Worksheets("in").Range("B28").Value = ""

   For I = 1 to 151 Step 2

   Worksheets("in").Activate

Worksheets("in").Range("B2").Value = 1

Worksheets("in").Range("B28").Value = I +1

   ActivateSheet.PrintOut

Next

  Worksheets("in")Activate

End Sub

Hàng tháng khi in thông báo tôi chỉ nhấn nút lệnh là macro hoạt động.( Như thư trộn bên Word ) tự kết các điạ chỉ vào sheet in và in ra theo thứ tự từ đến hết số thứ tự, vì giấy in sẵn 1 tờ chỉ bằng 1/2 tờ A4 nên tôi phải làm 2 điạ chỉ để nhận lŕ dòng B2 và B28, tức là kết 1 tờ A4 làm 2 tờ mẫu in sẵn. mọi việc in tốt, nhưng tôi muốn như sau có được không.

1. Hàng tháng khi in thông báo có bớt một số người và thêm 1 số người, bớt thì xoá thứ tự đánh số thứ tự lại ( người không in thì không đánh số ), thêm thì nhập thêm thông tin và đánh số tiếp, khi đánh số thứ tự sẽ biết bao nhiêu bảng in rồi phải vào macro\VBA sửa lại dòng in từ số bao nhiêu đến số bao nhiêu vì mỗi tháng in khác nhau, không thôi sẽ in thừa hoặc thiếu như vậy rất mất công. Có cách nào khi bấm nút lệnh sẽ cho ra hộp thoại để chọn lưạ trang in từ số đến số rồi Oke lŕ in không ? vẫn kết trang điạ chỉ

2.  Mỗi khi in phải đánh số thứ tự lại không thôi sẽ in thừa hoặc thiếu có cách nŕo khỏi phải đánh số thứ tự lại mà danh sách in vẫn đạt yên cầu như mong muốn.

Xin bạn hướng dẫn dùm rất cám ơn, nếu có gợi ý gì hay hãy chỉ dùm

Hình 1:Sheet 1 tên danh sách(có nút lệnh in thông báo)

Hình 2: Sheet 2 Tên In (có các tiêu đề để kết xuất khi in )Lấy B2 để chọn người cần in vŕ B28 Người cần in thứ 2 ( 1 trang in 2 người)các công thức mô tả D4, D5, D6 v.v....

Hình 3 là mô tả viết VBA

Cấu trúc xong, Click nút lệnh Thông báo in VBA sẽ kết công thức cho từng trang in theo mẫu.( giấy in liên tục) và sẻ kết trang in từ trang 1 đến 6 trang theo dòng( for i = 1 To 6 Slep 2)

Hỏi:

1. Có cách nào khi Click nút lệnh phải cho ra hộp thoại để lựa chọn trang in không(để đánh số trang từ....đến...), và khi Click nút lệnh nó sẽ in liên tục ( bạn thử rồi biết).

2. Nếu trong Sheet danh sách có đến 120 người, có người cần in có người không, tôi phải đánh số thứ tự lại, người không in không đánh số, mổi lần in không được trůng lắp thì in mới đúng,và phải vào VBA chỉnh trang in thí dụ 100 người ( for i = 1 To 100 Slep 2), có cách nào khi kết xuất ra máy in tự lựa chọn ô nào không có số không in ô nào có số thì in và in đến hết không dư trang thiếu trang, khỏi phải điều chỉnh thông số trong dňng ( for i = 1 To.... Slep 2).

3.Có rất nhiều Sheet cần in mổi sheet 1 tên khác tôi phải thiết kế trang in và VBA cho sheet đó( Thí dụ: Sheets "danh sách" có sheet "in" kèm, "danh sách 2" có "in2" kèm v.v.., phải làm sao để có 1 trang in VBA in cho tất cả sheets trong bảng tính chỉ cần 1 VBA.   

4. Nếu không lấy ô B1 & B28 bằng số thứ tự bên bảng danh sách ta có thể lấy bằng chữ như CN, CL TL, TN v.v...có kết in được không thě sử dụng công thức nào.

    Nếu bạn có phương pháp nào hay hơn xin chỉ giáo. Mục tiêu là in những danh sách kia theo yêu cầu như bên thư trộn cuả Word 

Xin thành thật cám ơn

MailTo: hunghuongus@yahoo.com

Đề xuất giải quyết vấn đề của Nguyễn Phương Thảo:

- Danh sách Sheet nguồn của bác đổi tên "danhsanh" thành "danhsach"

- Chọn Insert\ Name\Define rồi đánh tên Name là TT, với hộp Refer to là:

=OFFSET('Danhsach"!$a$2;0;0;COUNTA($b:$b)-1;1)

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

Khi sử dụng, những ô nào bác không muốn in, thì đánh vào ô ở cột STT dấu x. Còn muốn in thì bỏ trống, hoặc để nguyên số cũ. EXcel sẽ đánh lại.

Bác có thể bổ sung thêm bao nhiêu hàng tuỳ ý trong danh sách mà không cần phải sửa lại VBA.

Khi in sẽ in toàn bộ phần không đánh dấu X.

Private Sub CommandButton1_Click()
'Đánh số thứ tự tự động cho vůng số thứ tự.
'Những ai không in thì đánh bằng dấu X ở cột STT

 Dim oht, stt, hoten, diachi, nghe, tien
stt = 1
For Each oht In Range("TT")
Sheets("danhsach").Select
If UCase(oht.Value) <> "X" Then

 'Nếu ô bỏ trống thì thay số TT vào ô đó
oht.Value = Str(stt)

 If (stt Mod 2) = 1 Then
'Với số thứ tự lẻ điền lên trên
Worksheets("in").Range("B2").Value = stt

 'Lấy giá trị của ô có cột họ tên, điền vŕo ô B3. Theo công thức Cells(hàng, cột) sẽ 'được giá trị của ô Trong đó hàng đợc tính theo ô hiện tại bằng công thức oht.row

hoten = Cells(oht.Row, 2)
Worksheets("in").Range("B3").Value = hoten

 'Tương tự lấy giá trị của ô thuộc cột địa chỉ điền vào ô B4
diachi = Cells(oht.Row, 3)
Worksheets("in").Range("B4").Value = diachi

 'Tương tự lấy giá trị của ô thuộc cột nghề điền vào ô B5
nghe = Cells(oht.Row, 4)
Worksheets("in").Range("B5").Value = nghe

 'Tương tự lấy giá trị của ô thuộc cột tiền điền vào ô B6
tien = Cells(oht.Row, 5)
Worksheets("in").Range("B6").Value = tien

 Else
'Với số thứ tự chẵn điền xuống dưới
Worksheets("in").Range("B28").Value = stt

 'Lấy giá trị của ô có cột họ tên, điền vào ô B29. Theo công thức Cells(hàng, cột) sẽ được giá trị của ô
'Trong đó hŕng được tính theo ô hiện tại bằng công thức oht.row
hoten = Cells(oht.Row, 2)
Worksheets("in").Range("B29").Value = hoten

 'Tương tự lấy giá trị của ô thuộc cột địa chỉ điền vào ô B30
diachi = Cells(oht.Row, 3)
Worksheets("in").Range("B30").Value = diachi

 'Tương tự lấy giá trị của ô thuộc cột nghề điền vào ô B31
nghe = Cells(oht.Row, 4)
Worksheets("in").Range("B31").Value = nghe

 'Tương tự lấy giá trị của ô thuộc cột tiền điền vào ô B32
tien = Cells(oht.Row, 5)
Worksheets("in").Range("B32").Value = tien
'Thực hiện in
Sheets("in").Select
ActiveSheet.PrintOut
End If
'Tăng biến đếm STT cho vňng sau
stt = stt + 1
End If
Next
'In người cuối cùng nếu không đủ còn lẻ
If (stt Mod 2) = 0 Then
Sheets("in").Select
ActiveSheet.PrintOut
End If
End Sub


PcLeHoan 1996 - 2002
Mirror : http://www.pclehoan.com
Mirror : http://www.lehoanpc.net

Mirror : http://www.ktlehoan.com