Đố 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,911
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
 
Reg thì khó nhưng với những dạng chuỗi như thế này thì anh Nghĩa có thể hiểu "dễ" như sau

Với
Mã:
.Pattern = " +"
+/ Dấu cộng là lặp lại phần đằng trước từ 1 lần trở lên, => phần đằng trước là dấu cách tương ứng mẫu (\s). (cái này tương ứng "\s+") => Trong đoạn Str cứ chỗ nào có 1 dấu cách trở lên thì đánh dấu nó lại
+/ Dùng .replace để thay thế phần đánh dấu đó.

Với
Mã:
.Pattern = "\s{2,}"
thì anh hiểu như sau
+/ mẫu \s là dấu cách
+/ {x,} => Trong đoạn Str cứ chỗ nào lặp lại phía trước (là dấu cách) ít nhất 2 lần (từ 2 dấu cách trở lên) thì đánh dấu (1 dấu cách thì không đánh dấu)
+/ Dùng Replace để thay thế

Những bài viết về Reg của bác SiwTom rất hay anh có thể tham khảo
(Bài viết có cả chân dài, chân ngắn... sinh động và vô cũng lôi cuốn, anh tìm hiểu xem sao nhé . Hihi)

Mới đọc một số thông tin về cái "match" của em Pattern nè (nói thiệt là cố nhớ mà chả nhớ gì được cả):

[NOTE1]Character / Description
\ Marks the next character as either a special character or a literal. For example, "n" matches the character "n". "\n" matches a newline character. The sequence "\\" matches "\" and "\(" matches "(".

^
Matches the beginning of input.

$
Matches the end of input.

*
Matches the preceding character zero or more times. For example, "zo*" matches either "z" or "zoo".

+
Matches the preceding character one or more times. For example, "zo+" matches "zoo" but not "z".

?
Matches the preceding character zero or one time. For example, "a?ve?" matches the "ve" in "never".

.
Matches any single character except a newline character.

(pattern) Matches pattern and remembers the match. The matched substring can be retrieved from the resulting Matches collection, using Item [0]...[n]. To match parentheses characters ( ), use "\(" or "\)".

x|y
Matches either x or y. For example, "z|wood" matches "z" or "wood". "(z|w)oo" matches "zoo" or "wood".

{n}
n is a nonnegative integer. Matches exactly n times. For example, "o{2}" does not match the "o" in "Bob," but matches the first two o's in "foooood".

{n,}
n is a nonnegative integer. Matches at least n times. For example, "o{2,}" does not match the "o" in "Bob" and matches all the o's in "foooood." "o{1,}" is equivalent to "o+". "o{0,}" is equivalent to "o*".

{n,m}
m and n are nonnegative integers. Matches at least n and at most m times. For example, "o{1,3}" matches the first three o's in "fooooood." "o{0,1}" is equivalent to "o?".

[xyz]
A character set. Matches any one of the enclosed characters. For example, "[abc]" matches the "a" in "plain".

[^xyz]
A negative character set. Matches any character not enclosed. For example, "[^abc]" matches the "p" in "plain".

[a-z]
A range of characters. Matches any character in the specified range. For example, "[a-z]" matches any lowercase alphabetic character in the range "a" through "z".

[^m-z]
A negative range characters. Matches any character not in the specified range. For example, "[m-z]" matches any character not in the range "m" through "z".

\b
Matches a word boundary, that is, the position between a word and a space. For example, "er\b" matches the "er" in "never" but not the "er" in "verb".

\B
Matches a non-word boundary. "ea*r\B" matches the "ear" in "never early".

\d
Matches a digit character. Equivalent to [0-9].

\D Matches a non-digit character. Equivalent to [^0-9].

\f Matches a form-feed character.

\n Matches a newline character.

\r Matches a carriage return character.

\s
Matches any white space including space, tab, form-feed, etc. Equivalent to "[ \f\n\r\t\v]".

\S
Matches any nonwhite space character. Equivalent to "[^ \f\n\r\t\v]".

\t
Matches a tab character.

\v
Matches a vertical tab character.

\w
Matches any word character including underscore. Equivalent to "[A-Za-z0-9_]".

\W
Matches any non-word character. Equivalent to "[^A-Za-z0-9_]".

\num
Matches num, where num is a positive integer. A reference back to remembered matches. For example, "(.)\1" matches two consecutive identical characters.

\n
Matches n, where n is an octal escape value. Octal escape values must be 1, 2, or 3 digits long. For example, "\11" and "\011" both match a tab character. "\0011" is the equivalent of "\001" & "1". Octal escape values must not exceed 256. If they do, only the first two digits comprise the expression. Allows ASCII codes to be used in regular expressions.

\xn
Matches n, where n is a hexadecimal escape value. Hexadecimal escape values must be exactly two digits long. For example, "\x41" matches "A". "\x041" is equivalent to "\x04" & "1". Allows ASCII codes to be used in regular expressions.[/NOTE1]
 
Upvote 0
phần đằng trước là dấu cách tương ứng mẫu (\s).

Nói chính xác thì \s không phải là SPACE, tức " ". SPACE " " là dấu cách, còn \s là dấu cách trắng
\s có nghĩa là tất cả các dấu cách trắng, tức " " (dấu cách), \t (TAB), \f (form-feed), \r (vbCr), \n (vbLf), \v
Tương đương với
[ \f\n\r\t\v] - chú ý ở đầu sau ký tự "[" là ký tự " ".
Được phép dùng \s trong […], ví dụ [a-z\s]
 
Upvote 0
Các bạn có thể lấy tiện ích (miễn phí) này để test RegExp:
 

File đính kèm

  • RegExTester.rar
    26.1 KB · Đọc: 21
Upvote 0
Copy mọi thứ có trong cell, trừ object

Giả sử tôi có vùng dữ liệu A1:A6, vùng này đã format sẵn (font chữ, màu nền, đóng khung và cả comment.. ) vân vân...
Một vài cell trong A1:A6 có chứa các hình vẽ
Xin hỏi: Nếu tôi muốn copy A1:A6 Paste All sang C1:C6 nhưng không bao gồm các hình vẻ thì code phải viết thế nào cho gọn?


Capture.JPG
 
Upvote 0
Giả sử tôi có vùng dữ liệu A1:A6, vùng này đã format sẵn (font chữ, màu nền, đóng khung và cả comment.. ) vân vân...
Một vài cell trong A1:A6 có chứa các hình vẽ
Xin hỏi: Nếu tôi muốn copy A1:A6 Paste All sang C1:C6 nhưng không bao gồm các hình vẻ thì code phải viết thế nào cho gọn?
Như thế này đúng không Sư Phụ
[GPECODE=vb]
Sub CopyWithoutShapes()
With Sheet1
Application.CopyObjectsWithCells = False
.Range("B3:B5").Copy .Range("C3")
End With
Application.CopyObjectsWithCells = True
End Sub[/GPECODE]
 

File đính kèm

  • CopyWithoutShapes.xlsm
    21.1 KB · Đọc: 9
Lần chỉnh sửa cuối:
Upvote 0
Giả sử tôi có vùng dữ liệu A1:A6, vùng này đã format sẵn (font chữ, màu nền, đóng khung và cả comment.. ) vân vân...
Một vài cell trong A1:A6 có chứa các hình vẽ
Xin hỏi: Nếu tôi muốn copy A1:A6 Paste All sang C1:C6 nhưng không bao gồm các hình vẻ thì code phải viết thế nào cho gọn?
Thế này có được không ạ
Mã:
Sub PasteAllWithoutObject()
    [a1:a6].Copy
    [c1].PasteSpecial
End Sub
 
Upvote 0
Như thế này đúng không Sư Phụ
[GPECODE=vb]
Sub CopyWithoutShapes()
With Sheet1
Application.CopyObjectsWithCells = False
.Range("B3:B5").Copy .Range("C3")
End With
Application.CopyObjectsWithCells = True
End Sub[/GPECODE]

Cái mình muốn nói chính là cái này! Vì sau khi có câu lệnh Application.CopyObjectsWithCells = False thì thao tác bằng tay trên bảng tính cũng có tác dụng luôn
Có nghĩa là nếu ta có nhu cầu copy dữ liệu không bao gồm object, ta mở cửa sổ Immediate ra, gõ câu lệnh Application.CopyObjectsWithCells = False rồi Enter 1 phát, xong ra bảng tính copy/paste thoải mái. Xong việc, lại vào cửa sổ Immediate, gõ lệnh Application.CopyObjectsWithCells = True để trả về mặc định
 
Lần chỉnh sửa cuối:
Upvote 0
Làm sao biết một file Excel đã được mở thành công

Giả sử tôi đang có sẵn một code VBA để mở một file Excel nào đó. (Workbooks.Open(..) chẳng hạn)
Sẽ có 2 trường hợp xảy ra:
- File mở thành công
- File bị lỗi gì đó không mở được
Vậy xin hỏi: Tôi phải thêm vào code mở file những đoạn code gì để kiểm tra và biết được file đã được mở thành công hay không?
 
Upvote 0
Giả sử tôi đang có sẵn một code VBA để mở một file Excel nào đó. (Workbooks.Open(..) chẳng hạn)
Sẽ có 2 trường hợp xảy ra:
- File mở thành công
- File bị lỗi gì đó không mở được
Vậy xin hỏi: Tôi phải thêm vào code mở file những đoạn code gì để kiểm tra và biết được file đã được mở thành công hay không?
Thì Anh Duyệt đã có hàm tại đây rồi mà ndu!. Nhưng mà cái này chắc là có nhiều cách lắm nên sợ khó đưa ra đáp án giống ý bạn.
 
Upvote 0
Thì Anh Duyệt đã có hàm tại đây rồi mà ndu!. Nhưng mà cái này chắc là có nhiều cách lắm nên sợ khó đưa ra đáp án giống ý bạn.

Em không để ý nữa!
Nhưng với những bài mà em ĐỐ VUI thì code bảo đảm ngắn gọn (vài dòng thôi) mà cũng có chút gọi là "độc đáo" (ít người biết)
Ẹc... Ẹc...
---------------------------------
Thêm nữa: Em không nói là mở mọi loại tập tin mà chỉ quan tâm đến các FILE EXCEL thôi anh à
 
Lần chỉnh sửa cuối:
Upvote 0
Giả sử tôi đang có sẵn một code VBA để mở một file Excel nào đó. (Workbooks.Open(..) chẳng hạn)
Sẽ có 2 trường hợp xảy ra:
- File mở thành công
- File bị lỗi gì đó không mở được
Vậy xin hỏi: Tôi phải thêm vào code mở file những đoạn code gì để kiểm tra và biết được file đã được mở thành công hay không?
Làm vầy được không anh.
Mã:
Sub CheckOpen()
On Error Resume Next
Dim Wb As Workbook
Set Wb = Workbooks.Open(Filename:="D:\Test.xls")
MsgBox Not Wb Is Nothing
End Sub
 
Upvote 0
Làm vầy được không anh.
Mã:
Sub CheckOpen()
On Error Resume Next
Dim Wb As Workbook
Set Wb = Workbooks.Open(Filename:="D:\Test.xls")
MsgBox Not Wb Is Nothing
End Sub

Vẫn còn cách khác (khá hay... là 1 phương thức có sẵn trong VBA chuyên làm vụ này)
 
Upvote 0
Vẫn còn cách khác (khá hay... là 1 phương thức có sẵn trong VBA chuyên làm vụ này)

Nếu nói về phương thức của VBA (mudule VBA) thì chả nhẽ Tuấn định nói tứi Shell? Nếu thế thì đó không phải là cách hay. Xin nhớ là code phải xác định thành công hay không chứ không phải là người dùng xác định đâu nhé.
--------------
Lưu ý là cách dùng ShellExecute trong code mà thanhlanh gới ý không dùng được. Nếu gặp tập tin bị lỗi không thể mở được thì Excel sẽ bị treo
 
Lần chỉnh sửa cuối:
Upvote 0
Dạ, cái em định nói là FindFile anh à

Nhưng phương thức FindFile của đối tượng nào? Dù gì thì "phương thức có sẵn trong VBA" tôi lại tưởng là phương thức trong module VBA.
Application.FindFile? Nếu thế thì liên quan gì tới mở được hay không mở được?
Mà dù FindFile của "thằng" nào thì cái tên đó gợi ý là tìm được hay không chứ liên quan gì tới mở được hay không mở được nhỉ?
-------------
À, thấy rồi
 
Lần chỉnh sửa cuối:
Upvote 0
Vẫn còn cách khác (khá hay... là 1 phương thức có sẵn trong VBA chuyên làm vụ này)
Chắc anh nói cái này. Làm theo gợi ý của anh.
PHP:
Sub Kiemtra_File_Da_Mo()
Dim kiemtra
kiemtra = Application.FindFile
If kiemtra Then MsgBox "OK"
End Sub
 
Upvote 0
Lưu ý là cách dùng ShellExecute trong code mà thanhlanh gới ý không dùng được. Nếu gặp tập tin bị lỗi không thể mở được thì Excel sẽ bị treo

Đúng rồi, em mới thử dùng thì cũng không được, phải Ctrl + Alt + Delete

Dạ, cái em định nói là FindFile anh à

Hay nhỉ, có một câu lệnh duy nhất mà thay luôn cả Application.FileDialog và Workbooks.Open, ứng dụng luôn được không ta?
 
Upvote 0
Chắc anh nói cái này. Làm theo gợi ý của anh.
PHP:
Sub Kiemtra_File_Da_Mo()
Dim kiemtra
kiemtra = Application.FindFile
If kiemtra Then MsgBox "OK"
End Sub

Nếu đã dùng Application.FindFile thì phải thêm dòng đỏ đỏ,

Mã:
Dim kiemtra
[B][COLOR=#ff0000]On Error Resume Next[/COLOR][/B]

Bởi nếu không thì với 1 tập tin bị lỗi rất có thể không bao giờ code chạy tới dòng

Mã:
If kiemtra Then MsgBox "OK"
 
Upvote 0
Hay nhỉ, có một câu lệnh duy nhất mà thay luôn cả Application.FileDialog và Workbooks.Open, ứng dụng luôn được không ta?

Tôi không hiểu lắm. Tùy việc mà dùng thôi. Giết gà thì dùng dao mổ gà, giết trâu thì dùng dao mổ trâu.
Nếu cần mở tập tin đã biết đường dẫn (vd. được chọn trong ComboBox, có được sau khi đã tìm kiếm ở lần chạy code trước và được nhớ ở biến sPath chẳng hạn v...v) thì chạy code trong bài #711 chứ ai lại dùng code #716 để bắt người dùng nhọc công chọn cái tập tin mà đường dẫn đã được xác định? Còn nếu chưa xác định và cần phải chọn thì chạy code #716. Tùy việc mà chọn công cụ chứ nói cái này ưu điểm vì thay được cái kia thì không đúng.
 
Upvote 0
Tôi không hiểu lắm. Tùy việc mà dùng thôi. Giết gà thì dùng dao mổ gà, giết trâu thì dùng dao mổ trâu.
Nếu cần mở tập tin đã biết đường dẫn (vd. được chọn trong ComboBox, có được sau khi đã tìm kiếm ở lần chạy code trước và được nhớ ở biến sPath chẳng hạn v...v) thì chạy code trong bài #711 chứ ai lại dùng code #716 để bắt người dùng nhọc công chọn cái tập tin mà đường dẫn đã được xác định? Còn nếu chưa xác định và cần phải chọn thì chạy code #716. Tùy việc mà chọn công cụ chứ nói cái này ưu điểm vì thay được cái kia thì không đúng.

Em thì không được học bài bản, nhưng vọc thì rất chịu vọc (có lúc bị treo máy lên treo máy xuống đó chứ), em thường thử nhiều trường hợp cho các thủ tục mới, rồi đo lường thời gian cho dữ liệu nhiều, nếu code nào chạy đúng nhất, nhanh nhất là em dùng cái đó, không cần biết thủ tục đó dài (nhiều dòng) hay nó ngắn (ít dòng).

Cứ tổng quát một chút và hiệu quả một chút là em khoái, không câu nệ là gà hay trâu!

Nhớ một câu chuyện vui về các giai thoại của Anhxtanh (Albert Einstein), ông có nuôi 2 con chó, 1 con chó lớn và 1 con chó nhỏ. Ông làm cái nhà cho 2 con chó ở chung, sau khi làm cái cửa lớn cho con chó lớn xong, ông lại nghĩ cần có thêm 1 cái cửa nhỏ nữa để cho con chó nhỏ, thế là ông lại cưa thêm một cái lỗ nhỏ nữa! (lời bàn: chỉ cần một cửa lớn là 2 con chó cùng ra vào được!)
 
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom