Đố vui về VBA!

Liên hệ QC

anhtuan1066

Thành viên gạo cội
Tham gia
10/3/07
Bài viết
5,802
Được thích
6,905
Nhằm cũng cố kiến thức về VBA cho các bạn mới bắt đầu và cả những bạn đang ứng dụng mà chưa hiểu nhiều về nó, tôi mở topic này với mong mõi qua những câu hỏi vui, các bạn sẽ nhận định lại sự hiểu biết cũa mình... (Kễ cã chính tôi cũng đang tập tành nên có rất nhiều cái chưa biết)
Mong rằng topic sẽ mang đến cho các bạn những khám phá thú vị với những cái tưỡng chừng như đã biết
Mong nhận dc bài viết về câu đố cũa các cao thủ! Còn các bạn mới thì đừng ngại khi đưa ra ý kiến cũa mình.. Có sai có sữa sẽ hoàn thiện!
Tôi xin mỡ màn trước bằng 1 câu hỏi đơn giãn
ANH TUẤN

CÂU HỎI 1: Tại sao biến K ko hoạt động?
Tôi muốn khi nhấn vào 1 button thì cell A1 sẽ tăng lên 1 đơn vị... Tôi đã làm như sau:
-Tạo 1 Command Button (nút nhấn thuộc thanh Control Toolbox), click phải chuột lên nút nhấn, chọn View code, rồi gõ vào đoạn code sau:
PHP:
Private Sub CommandButton1_Click()
   K = K + 1
   Range("A1").Value = K
End Sub
Ban đầu K chưa có gì, xem như =0, nhấn nút lần thứ nhất thì K dc tăng thêm 1, vậy K hiện tại sẽ bằng 1, và gán K vào cell A1 thì đương nhiên A1 sẽ =1... Nhấn nút lần 2, K lại dc tăng thêm 1 nên hiện tại K sẽ =2 và cell A1 cũng sẽ =2... vân vân.. từ đó diễn tiến tiếp...
Hi.. hi.. Điều này nghe qua có vẽ rất hợp lý, ấy thế mà khi nhấn nút nó chỉ hoạt động dc duy nhất 1 lần (A1 = 1) rồi thôi ko nhút nhít nữa...
Các bạn có thể giãi thích tại sao lại như thế ko? Tại sao những lần nhấn nút sau đó K lại ko tăng thêm tí nào (vì thực tế A1 vẫn cứ = 1 hoài) ?
ANH TUẤN
 
Cách gọi code thông qua lệnh call nhằm mục đích bố trí sắp xếp và quản lý chương trình cho khoa học hơn, nhất là đối với những chương trình lớn và phức tạp, có nhiều lệnh phải thực hiện nhiều lần, khi chúng ta cần đến một nhiệm vụ chúng ta không cần phải viết lại cả đoạn code thực hiện nhiệm vụ đó nữa, chỉ cần dùng lệnh call...

pmt0412 đã viết:
Giải thích rất đúng. Khi 1 code sử dụng nhiều lần và sub nào cũng có thể gọi đến nó, sub ấy gọi là Procedure. Procedure (thủ tục) là thuật ngữ dùng chung trong lý thuyết lập trình của mọi ngôn ngữ, (VBA là 1 trong các ngôn ngữ).

Nhưng phải bổ sung thêm là:

Khi 1 code sử dụng nhiều lần và sub nào cũng có thể gọi đến nó và có thể thay đổi với bộ số liệu đầu vào (truyền ) khi gọi đến nó
 
Upvote 0
Có cách nào trên trang tính để hiện đủ ba hộp thoại trong đoạn code sau

Ví dụ tôi có trang tính gồm chí ít 2 cột B & C;
Cột 'B' chứa tên (An, Bi, By, Ca, Cy, Bi, Sy, My, Na, . ..
Cột 'C' chứa hệ số lương, chẳng hạn ( 1,4 ; 1.71; 1,89 ; . . . .)
Và đoạn code như sau:
PHP:
Option Explicit
Sub DatabaseWithHeaders()
Dim rCSDL As Range:            Dim lHeaderRow As Long

2    Set rCSDL = Sheet5.Range("B2").CurrentRegion
    lHeaderRow = rCSDL.ListHeaderRows
4    MsgBox rCSDL.Address, , "A"
    If lHeaderRow > 0 Then
6        Set rCSDL = rCSDL.Resize(rCSDL.Rows.Count - lHeaderRow)
        MsgBox rCSDL.Address, , "B"
8        Set rCSDL = rCSDL.Offset(1)
9        MsgBox rCSDL.Address, , "C"
    End If
End Sub
Hãy sửa 1 hay 2 ô dữ liệu để hiện lên các hộp thoại; Nhất là 2 cái sau!

Phần mới bổ sung (2/01/08):
1*/ Diễn nôm 1 số từ dùng:
Tên macro 'DatabaseWithHeaders' diễn nôm có nghĩa là CSDL với các tiêu đề;
rCSDL - vùng cơ sở dữ liệu;
lHeaderRow - Có thể coi như biến kiểu long (l) chứa dòng tiêu đề;
CurrentRegion := vùng hiện sử dụng, Vùng hiện hành (cái này dịch chưa chuẩn mấy!). Các bạn có thể xem thêm trên DĐ;
Resize - Tính chất của Range. Nếu ta có Set Rng = Range("B1")
Thì Rng.Resize(2,2) sẽ có địa chỉ là '$B$1:$C$2'. Tạm coi như tính chất mở rọng 1 vùng có sẵn;
2*/ Chúng ta có thể gán cho biến lHeaderRow những giá trị <> 0 xen vô các dòng thích hợp để thấy các hộp thoại đưa ra kết quả gì. Từ đó có thể có những kết luận cần thiết (có thể là thú vị với 1 ai đó)!
Mã:
 [B][I][SIZE="3"]           Chúc mừng năm mới: Hạnh phúc & thành đạt với tất cả mọi người!! [/SIZE][/I][/B]
 
Lần chỉnh sửa cuối:
Upvote 0
Ví dụ tôi có trang tính gồm chí ít 2 cột B & C;
Cột 'B' chứa tên (An, Bi, By, Ca, Cy, Bi, Sy, My, Na, . ..
Cột 'C' chứa hệ số lương, chẳng hạn ( 1,4 ; 1.71; 1,89 ; . . . .)
Và đoạn code như sau:
Có lẽ vì topic này là dành cho người mới chập chững VBA
nên thiết nghĩ bác SA_DQ nên gợi ý rõ và mở vấn đề hơn,
thế này thì ........ hơi hoa mắt đây
 
Lần chỉnh sửa cuối:
Upvote 0
anhtuan1066 đã viết:
Câu hỏi 4: Select
Tôi đặt name cho vùng Sheet1!A1:A10VUNG1
Trong 1 module, tôi viết 1 đoạn code đễ chọn VUNG1 như sau:
PHP:
Sub Chon()
Range("VUNG1").Select
End Sub
Đứng tại Sheet1, Code chạy ko có vấn đê.. nhưng khi tôi chuyễn Refer to cũa VUNG1 thành Sheet2!A1:A10 rồi cũng đứng tại Sheet1 đễ chạy code thì bị báo lỗi...
Tại sao vậy?
ANH TUẤN

Xin chào cac anh, em mới lên mong các anh chỉ giáo thêm.
Em đã thử sữa lại như sau:
Mã:
Sub Chon()
Sheets("Sheet2").Select
Range("VUNG1").Select
[COLOR=blue]End Sub[/COLOR]
Vậy em nghĩ rằng nó báo lổi ở chổ chưa xác định được vị trí để hiển thị.
Thêm dòng lệnh trên để nó biết mình đang ở đâu mà thi hành.
Em xin hết.
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
hauomdldgh đã viết:
Vậy em nghĩ rằng nó báo lổi ở chổ chưa xác định được vị trí để hiển thị.
Tại sao lại chưa xác định nhỉ? Rõ ràng Define name tôi đã ghi rõ nó là: Sheet2!A1:A10 rồi còn gì.. chẳng lẽ như thế lại ko rõ ràng?
hi.. hi..
Cách giãi quyết cũa bạn thì đúng rồi... nhưng chưa thễ giãi thích tại sao
Tại sao?... Tại sao?...
ANH TUẤN
Cách giãi
 
Upvote 0
Thôi được em chịu thua, em chỉ biết rằng trong VBA phải xác định được vị trí Sheet đang thi hành còn nó có nạp dữ liệu từ trong Define vào hay không thì chịu. Xin anh giải thích rõ giùm.
 
Upvote 0
Tôi thì nghĩ như thế này đây:
Bất cứ thứ gì mình làm bằng tay dc thì macro gần như cũng làm dc, và phải tuân thủ theo trình tự mà ta đã làm...
Lấy ví dụ.. bạn muốn chọn VUNG1 nằm tại sheet2, nhưng hiện tai bạn đang đứng ở sheet1, nếu bạn thao tác bằng tay có phải là bạn sẽ làm theo 2 cách:
1> Chuyễn con trỏ chuột sang sheet2 rồi quét chọn VUNG1
2> Trong hộp name box bạn gõ vào chử VUNG1 rồi Enter (tương đương lệnh Goto)
Vậy thì khi "dạy" cho macro hiểu dc bạn muốn chọn VUNG1 bạn cũng sẽ làm như thế... Record macro sẽ thấy...
Tất nhiên ta ko thể từ Sheet1 "bay" 1 nhát sang sheet2 lập tức rồi... phải có 1 thao tác gì đó chuyễn tiếp chứ ... hi.. hi.. Nếu ko nó sẽ tưởng bạn đang nói về Sheet hiện hành... (có lẽ đây là quy định của MS)
Trong 2 cách trên tôi khoái nhất là Goto... hi.. hi..
Tóm lại 1 câu: Ta làm bằng tay thế nào thì hãy "nói" cho macro hiễu y chang thế (nếu ko nó sẽ hiễu lầm)
ANH TUẤN
 
Upvote 0
Em đồng ý rằng nó phải biết được Sheet đang chạy là sheet nào.
Nhưng sao em dùng hàm lại có thể chuyển dữ liệu qua giữa các Sheet một cách tự động mà không cần phải thấy sheet hiển thị lên.
Ví dụ như nạp dữ liệu từ Sheet [ThongKe] sang sheet [DanhBa] để lưu trữ thông tin chấm công theo ngày rồi xuất dữ liệu trở lại Sheet [ThongKe] để xem tiền lương của người đó. Em chỉ cần nạp dữ liệu cũng như xem dữ liệu trên 1 Sheet duy nhất mà không cần phải qua các Sheet khác. Vậy, trong Macro phải làm thế nào? Em không thấy Macro có tính năng này.
 
Upvote 0
Bạn dùng hàm thì bạn cũng có chổ phải ghi vào công thức tên Sheet đó thôi.. Ko có thì nó biết đâu mà lần...
ANH TUẤN
 
Upvote 0
À, em hiểu rồi. Nó chỉ có thể lấy dữ liệu trên Sheet khác chứ không thể tạo mới một lệnh nằm ở Sheet khác được phải không anh!
 
Upvote 0
anhtuan1066 đã viết:
Câu hỏi 3:
. . .

Nếu thay đoạn Selection.Paste thành ActiveSheet.Paste hoặc Selection.PasteSpecial Paste:=xlPasteAll thì ko có vấn đề
Tại sao thế?
ANH TUẤN
Gợi ý: câu trả lời nằm trong thông báo lỗi.
 
Upvote 0
anhtuan1066 đã viết:
Câu này tôi nghĩ đơn giãn hơn... Cái này là tại vì... ông Bill ổng quy định thế... Phải nói theo ngôn ngữ cũa ổng thì ổng mới chịu... he... he...
ANH TUẤN

Ko, chắc phải đâu atuan - có những cái nó phải theo logic
hoặc phòng trừ những cái lỗi tránh phải
a giải thích thế thì ........
 
Upvote 0
Xin phép AnhTuan1066 cho ké nha!

Macro được đưa ra dưới đây bắt nguồn từ http://giaiphapexcel.com/forum/showthread.php?t=7302
Xin các bạn dịch từ ngôn ngữ VBA sang ngôn ngữ tiếng việt & giải nghĩa (nếu cần) giúp với nha
Xin cảm ơn đã quan tâm & sẽ có hậu tạ sau 1 tuần!
PHP:
Option Explicit
Dim Rng As Range
Dim lRow As Long:                       Dim iCol As Integer

Sub CopyToVisible()
 Dim vRng As Range, dRng As Range
 Dim lRowV As Long, lColection As Long:          Dim iColV As Integer
 
 Set Rng = Range("A1:C7")                   'Selection'
 lRow = Rng.Rows.Count:                     iCol = Rng.Columns.Count
 Application.ScreenUpdating = False
 Set vRng = Range("D5").Resize(lRow, iCol).SpecialCells(xlCellTypeVisible)
 lRowV = vRng.Rows.Count:                   iColV = vRng.Columns.Count
 Set vRng = Range("D5"):                    lColection = 1
10  ' In Sheet1'
 If lRowV < lRow And iColV = iCol Then
    Do
11        Set dRng = vRng.Resize(lRow, iCol).SpecialCells(xlCellTypeVisible).Cells(1, 1)
12        lRowV = vRng.Resize(lRow, iCol).SpecialCells(xlCellTypeVisible).Rows.Count
13        If lColection + lRowV > lRow Then lRowV = lRow - lColection + 1
14        Rng.Cells(lColection, 1).Resize(lRowV, iCol).Copy Destination:=dRng
15        lColection = lColection + lRowV
16        Set vRng = vRng.Offset(1 + lRowV)
17        If lColection > lRow Then Exit Do
    Loop
20  'In Sheet2'
 ElseIf lRowV = lRow And iColV < iCol Then
    Do
21        Set dRng = vRng.Resize(lRow, iCol).SpecialCells(xlCellTypeVisible).Cells(1, 1)
22        iColV = vRng.Resize(lRow, iCol).SpecialCells(xlCellTypeVisible).Columns.Count
23        If lColection + iColV > iCol Then iColV = iCol - lColection + 1
24        Rng.Cells(1, lColection).Resize(lRow, iColV).Copy Destination:=dRng
25        lColection = lColection + iColV
26        Set vRng = vRng.Offset(, 1 + iColV)
27        If lColection > iCol Then Exit Do
        
    Loop
30
 ElseIf lRowV = lRow And iColV = iCol Then
    Rng.Copy Destination:=Range("D5")
40
 Else
    MsgBox "CHUA LAM DUOC"
 End If
 Set Rng = Nothing
End Sub
 
Upvote 0
Góp vui với bác SA cái nào. Tôi đố các bác làm một hàm xác định một số có phải là số nguyên tố hay không?

Ví dụ : songuyento(7) = true
songuyento(8)=false

Số nhập vào không có giới hạn đâu nhé.
 
Upvote 0
workman đã viết:
Góp vui với bác SA cái nào. Tôi đố các bác làm một hàm xác định một số có phải là số nguyên tố hay không?

Ví dụ : songuyento(7) = true
songuyento(8)=false

Số nhập vào không có giới hạn đâu nhé.

Thế hàm ISEVEN để làm gì hả workman ?
 
Upvote 0
kongcom đã viết:
Thế hàm ISEVEN để làm gì hả workman ?

Chào bạn Kongcom

Rất vui được làm quen với bạn.

Hàm Iseven được định nghĩa như sau: Returns TRUE if number is even, or FALSE if number is odd.

Even là số chẵn, Odd là số lẻ.

Nếu bạn có thời gian, bạn xem thử bài đố của tôi nhé. Đương nhiên việc tìm số nguyên tố có rất nhiều phương pháp, nhưng quan trọng là giải pháp nào tối ưu và nhanh nhất.

À, tôi quên nói lại định nghĩa số nguyên tố, sợ có bạn lại hiểu lầm tôi thì chết:

"Số nguyên tố được định nghĩa là chỉ chia hết cho 1 và cho chính nó", ví dụ: 1, 2, 3, 5, 7, 11, 13 ... là các số nguyên tố.
 
Upvote 0
workman đã viết:
Góp vui với bác SA cái nào. Tôi đố các bác làm một hàm xác định một số có phải là số nguyên tố hay không?

Ví dụ : songuyento(7) = true
songuyento(8)=false

Số nhập vào không có giới hạn đâu nhé.

@workman

Không giới hạn là sao nhỉ?
Số nguyên tố chỉ có thể là số nguyên dương thôi - cái nay có giới hạn không nhỉ?

@TV Khác
workman đã viết:
"Số nguyên tố được định nghĩa là chỉ chia hết cho 1 và cho chính nó", ví dụ: 1, 2, 3, 5, 7, 11, 13 ... là các số nguyên tố.
Gợi ý thêm (hay là câu hỏi mở hướng):
+ vậy sẽ phải xét nó chia với nx số nào nhỉ???
+ nếu nó chia hết cho 1 số nào đó -> nó ko phải là số nguyên tố - trái lại là số ng tố
 
Upvote 0
PHP:
Public Function SoNguyenTo(So As Integer)
    If So < 3 Then
    SoNguyenTo = "SO NGUYEN TO"
    Exit Function
    End If
    For i = 2 To So - 1
        If (So / i) - Int(So / i) = 0 Then
        SoNguyenTo = "SO KHONG NGUYEN TO"
        Exit Function
        End If
    Next
    SoNguyenTo = "SO NGUYEN TO"
End Function
 
Upvote 0
Tôi nghĩ nếu dùng vòng lập For thì chỉ cần i chạy đến INT(i/2) là đũ rồi
ANH TUẤN
 
Upvote 0
anhtuan1066 đã viết:
Tôi nghĩ nếu dùng vòng lập For thì chỉ cần i chạy đến INT(i/2) là đũ rồi
ANH TUẤN
Không chính xác a ơi,
Chính xác là: Vòng lập For thì chỉ cần i chạy từ 2 đến INT( SQR(i) )

Và không cần phải If .........<3 đâu

Nếu thêm thì thêm đều kiện Ktra có phải là số Nguyên Dương k?

 
Lần chỉnh sửa cuối:
Upvote 0
Web KT
Back
Top Bottom