Option Explicit
Sub ChinhHopChap5Cua12()
Const GPE12 As String = "A12B3456C7890"
Dim j1 As Byte, J2 As Byte, J3 As Byte, J4 As Byte, J5 As Byte
For j1 = 1 To 12
For J2 = j1 + 1 To 12
For J3 = J2 + 1 To 12
For J4 = J3 + 1 To 12
For J5 = J4 + 1 To 12
With [A65500].End(xlUp).Offset(1)
.Value = Mid(GPE12, j1, 1) & Mid(GPE12, J2, 1) & Mid(GPE12, J3, 1) _
& Mid(GPE12, J4, 1) & Mid(GPE12, J5, 1)
End With
Next J5, J4, J3, J2, j1
End Sub
Hix ! Bác làm ơn xem lại hộ em một chút nhé. Bác thông cảm là nhập vào từng ô chứ không phải nhập vào cùng 1 ô đâu.PHP:Option Explicit Sub ChinhHopChap5Cua12() Const GPE12 As String = "A12B3456C7890" Dim j1 As Byte, J2 As Byte, J3 As Byte, J4 As Byte, J5 As Byte For j1 = 1 To 12 For J2 = j1 + 1 To 12 For J3 = J2 + 1 To 12 For J4 = J3 + 1 To 12 For J5 = J4 + 1 To 12 With [A65500].End(xlUp).Offset(1) .Value = Mid(GPE12, j1, 1) & Mid(GPE12, J2, 1) & Mid(GPE12, J3, 1) _ & Mid(GPE12, J4, 1) & Mid(GPE12, J5, 1) End With Next J5, J4, J3, J2, j1 End Sub
Chài ai...Hix ! Bác làm ơn xem lại hộ em một chút nhé. Bác thông cảm là nhập vào từng ô chứ không phải nhập vào cùng 1 ô đâu.
Sub ChinhHopChap5Cua12()
Const GPE12 As String = "A12B3456C7890"
Dim j1 As Byte, J2 As Byte, J3 As Byte, J4 As Byte, J5 As Byte, i As Long
For j1 = 1 To 12
For J2 = j1 + 1 To 12
For J3 = J2 + 1 To 12
For J4 = J3 + 1 To 12
For J5 = J4 + 1 To 12
With [A1:E1].Offset(i)
.Value = Array(Mid(GPE12, j1, 1), Mid(GPE12, J2, 1), Mid(GPE12, J3, 1), _
Mid(GPE12, J4, 1), Mid(GPE12, J5, 1))
i = i + 1
End With
Next J5, J4, J3, J2, j1
End Sub
Thuật toán là vậy, khi sử dụng bạn phải biết tùy biến chứ.Hix ! Bác làm ơn xem lại hộ em một chút nhé. Bác thông cảm là nhập vào từng ô chứ không phải nhập vào cùng 1 ô đâu.
Option Explicit
Sub ChinhHopChap5Cua12()
Dim j1 As Byte, J2 As Byte, J3 As Byte, J4 As Byte, J5 As Byte, i As Integer, Rng As Range
Set Rng = [A1]
For j1 = 1 To 12
For J2 = j1 + 1 To 12
For J3 = J2 + 1 To 12
For J4 = J3 + 1 To 12
For J5 = J4 + 1 To 12
i = i + 1
Set Rng = Union(Rng, Cells(i, j1), Cells(i, J2), Cells(i, J3), Cells(i, J4), Cells(i, J5))
Next J5, J4, J3, J2, j1
Rng.Value = "x"
End Sub
Xem chừng việc "thu gom" toàn bộ các cell rồi gán giá trị 1 lần cho tốc độ làm việc chậm hơn thì phảiThuật toán là vậy, khi sử dụng bạn phải biết tùy biến chứ.
PHP:Option Explicit Sub ChinhHopChap5Cua12() Dim j1 As Byte, J2 As Byte, J3 As Byte, J4 As Byte, J5 As Byte, i As Integer, Rng As Range Set Rng = [A1] For j1 = 1 To 12 For J2 = j1 + 1 To 12 For J3 = J2 + 1 To 12 For J4 = J3 + 1 To 12 For J5 = J4 + 1 To 12 i = i + 1 Set Rng = Union(Rng, Cells(i, j1), Cells(i, J2), Cells(i, J3), Cells(i, J4), Cells(i, J5)) Next J5, J4, J3, J2, j1 Rng.Value = "x" End Sub
Sub Test1()
Dim j1 As Long, J2 As Long, J3 As Long, J4 As Long, J5 As Long, i As Long
Dim TG As Double
TG = Timer
For j1 = 1 To 12
For J2 = j1 + 1 To 12
For J3 = J2 + 1 To 12
For J4 = J3 + 1 To 12
For J5 = J4 + 1 To 12
i = i + 1
Union(Cells(i, j1), Cells(i, J2), Cells(i, J3), Cells(i, J4), Cells(i, J5)) = "x"
Next J5, J4, J3, J2, j1
MsgBox Timer - TG
End Sub
Cũng dễ hiểu thôi. Trong quá trình xử lý code phải lưu một biến nhớ có dung lượng lớn (biến Rng) làm tốc độ chậm lại. Tuy nhiên, để chắc ăn phải set Calculation = Manual trước. Chạy code của bạn trong khi đang mở một file làm việc khác thời gian là 50s. Do mỗi lần gán giá trị vào cell. Các công thức lại tính toán lại một lần. Ngoài ra, các biến j1, j2,... chỉ có giá trị từ 1 đến 12 thì nên khai báo kiểu Byte là hợp lý, biến i chỉ cần kiểu Integer là đủ. Tiết kiệm tài nguyên sẽ cải thiện tốc độ.Xem chừng việc "thu gom" toàn bộ các cell rồi gán giá trị 1 lần cho tốc độ làm việc chậm hơn thì phải
Cái này nhanh hơn:
Tốc độ cực nhanh... gần như ra kết quả trong tức khắcPHP:Sub Test1() Dim j1 As Long, J2 As Long, J3 As Long, J4 As Long, J5 As Long, i As Long Dim TG As Double TG = Timer For j1 = 1 To 12 For J2 = j1 + 1 To 12 For J3 = J2 + 1 To 12 For J4 = J3 + 1 To 12 For J5 = J4 + 1 To 12 i = i + 1 Union(Cells(i, j1), Cells(i, J2), Cells(i, J3), Cells(i, J4), Cells(i, J5)) = "x" Next J5, J4, J3, J2, j1 MsgBox Timer - TG End Sub
Sub ChinhHopChap5Cua12()
Dim j1 As Byte, J2 As Byte, J3 As Byte, J4 As Byte, J5 As Byte, i As Integer, Rng As Range
Application.Calculation = xlCalculationManual
For j1 = 1 To 12
For J2 = j1 + 1 To 12
For J3 = J2 + 1 To 12
For J4 = J3 + 1 To 12
For J5 = J4 + 1 To 12
i = i + 1
Union(Cells(i, j1), Cells(i, J2), Cells(i, J3), Cells(i, J4), Cells(i, J5)).Value = "x"
Next J5, J4, J3, J2, j1
Application.Calculation = xlCalculationAutomatic
End Sub
Biến Long mới là đúng nhất và tiết kiệm nhấtNgoài ra, các biến j1, j2,... chỉ có giá trị từ 1 đến 12 thì nên khai báo kiểu Byte là hợp lý, biến i chỉ cần kiểu Integer là đủ. Tiết kiệm tài nguyên sẽ cải thiện tốc độ.
Bạn có thể cho mọi người biết nguyên nhân vì sao không?Chổ nào cũng đúng, trừ chổ này:
Biến Long mới là đúng nhất và tiết kiệm nhất
Cái này đã thuộc về "chân lý" mà cả Bill và các cao thủ trên toàn thế giới đều công nhận (tưởng bạn đã đọc qua bài viết trên GPE rồi chứ)Bạn có thể cho mọi người biết nguyên nhân vì sao không?
[B đã viết:Dailydose[/B]]...If you use the Integer data type in your code, Excel will convert it to a Long, so you might as well just use Long. It still produces an overflow error if you get outside the Integer bounds, I’ve noticed..
[B đã viết:msdn.microsoft.com[/B]]
...The Integer and Long data types can both hold positive or negative values. The difference between them is their size: Integer variables can hold values between -32,768 and 32,767, while Long variables can range from -2,147,483,648 to 2,147,483,647. Traditionally, VBA programmers have used integers to hold small numbers, because they required less memory. In recent versions, however, VBA converts all integer values to type Long, even if they are declared as type Integer. Therefore, there is no longer a performance advantage to using Integer variables; in fact, Long variables might be slightly faster because VBA does not have to convert them...
Thì ra là vậy. Từ trước đến giờ tôi cứ ngỡ Excel mượn ngôn ngữ của VB thì cũng nó cũng mang tất cả các đặc điểm của VB chứ. Đúng là sai lầm thật.Cái này đã thuộc về "chân lý" mà cả Bill và các cao thủ trên toàn thế giới đều công nhận (tưởng bạn đã đọc qua bài viết trên GPE rồi chứ)
Có thể diển giải ngắn gọn thế này: Dù rằng ta có đặt biến Byte hay Integer thì trong quá trình làm việc nó cũng sẽ được chuyển thành biến Long (chuyển xong mới làm việc)
Vì thế thay vì khai báo Byte hay Integer, ta khai báo luôn là Long (đở tốn công bác Bill)
Đã từ lâu lắm rồi, tôi quên luôn thằng Byte và Integer, cứ Long cho chắc bắp (trừ những trường hợp đặc biệt...)
Thông tin:
Option Explicit
Declare Function GetTickCount Lib "kernel32" () As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long)
Sub MmM()
Dim jJ As Byte, Ww As Byte, Kk As Byte
Dim Zz As Long, Ff As Long, iI As Long
Dim Timer_ As Double
Timer_ = GetTickCount
For jJ = 1 To 250
Do
Ww = Ww + 2: Ww = Ww - 1
If Ww > 250 Then
Kk = Kk + 1: Ww = 1
Sleep 1
End If
If Kk > 254 Then Exit For
Loop
Next jJ
[A65500].End(xlUp).Offset(1).Value = GetTickCount - Timer_
Timer_ = GetTickCount
For Zz = 1 To 250
Do
Ff = Ff + 2: Ff = Ff - 1
If Ff > 250 Then
iI = iI + 1: Ff = 1
Sleep 1
End If
If iI > 254 Then Exit For
Loop
Next Zz
[b65500].End(xlUp).Offset(1).Value = GetTickCount - Timer_
End Sub
Điều này đương nhiên sư phụ à! Bởi vậy ở trên em có nói rằng:Thứ nhất, sao có nó mà không xài;
Nên xài nó/chúng vào những việc như:
Khi không muốn xài số âm, tôi cứ Byte mà tương, một khi nó còn trong fép;
Có 1 vài đoạn code em vẫn buộc phải dùng biến Byte ---> Mà cùng lắm cũng chỉ dùng Byte và Long, chứ Integer thì hầu như em "quăng" luôn (vì nó thuộc cái hệ dở dở ương ương)Đã từ lâu lắm rồi, tôi quên luôn thằng Byte và Integer, cứ Long cho chắc bắp (trừ những trường hợp đặc biệt...)
Các trả lời và con số 792 ở trên dường như là tính tổ hợp chập 5 của 12.Em có một bài toán khó là lập các hàng chỉnh hợp chập của 5 chữ X vào 12 ô sao cho các dòng không trùng nhau. Cái này à viết tày thì mất 792 dòng kiểu này thì chết em mất. Mong các bac giúp đỡ![]()
Xin bàn ngoài lề 1 chút về đoạn code trên!Xin mời các bạn nào rỗi ta thử chạy macro này xem sao:
PHP:Option Explicit Declare Function GetTickCount Lib "kernel32" () As Long Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long) Sub MmM() Dim jJ As Byte, Ww As Byte, Kk As Byte Dim Zz As Long, Ff As Long, iI As Long Dim Timer_ As Double Timer_ = GetTickCount For jJ = 1 To 250 Do Ww = Ww + 2: Ww = Ww - 1 If Ww > 250 Then Kk = Kk + 1: Ww = 1 Sleep 1 End If If Kk > 254 Then Exit For Loop Next jJ [A65500].End(xlUp).Offset(1).Value = GetTickCount - Timer_ Timer_ = GetTickCount For Zz = 1 To 250 Do Ff = Ff + 2: Ff = Ff - 1 If Ff > 250 Then iI = iI + 1: Ff = 1 Sleep 1 End If If iI > 254 Then Exit For Loop Next Zz [b65500].End(xlUp).Offset(1).Value = GetTickCount - Timer_ End Sub