Câu hỏi liên quan đến nội dung buổi sinh hoạt đầu tiên của VEC?

Liên hệ QC

anktdn

Thành viên chính thức
Tham gia
18/6/06
Bài viết
72
Được thích
77
Nghề nghiệp
acc
Anh Duyệt hay anh tedaynui ơi, cho em xin code của thủ tục gọi 1 chương trình khác khi đang thao tác trên bảng tính excel mà hôm qua em có trình bày với 2 anh. thanks !
 
Chào bạn
Để gọi 1 chương trình khác từ Excel, bạn có thể dùng cú pháp sau :
Call Shell(Full_Path)

Ví dụ để gọi NotePad :
Call Shell("C:\WINDOWS\NOTEPAD.EXE")

Thân!
 
Cảm ơn anh tedaynui nha, để em thử xem
 
Em tham khảo đoạn code sau:

Mã:
Public Sub SendKeyTest()
'Khai báo biến
Dim ReturnValue As Double
'Mở Notepad
ReturnValue = Shell("NOTEPAD.EXE", vbNormalFocus)
'Chọn Notepad
Call AppActivate(ReturnValue)
'Đưa vào nội dung: [B]Copy Data.xls c:\[/B]
Application.SendKeys "Copy Data.xls c:\", True

Application.SendKeys "~", True
'Lưu lại, [B]%FA[/B]: có nghĩa là chọn File/Save As với tên là [B]BATCH[/B]
Application.SendKeys "%FABATCH~", True
End Sub

Chú ý rằng em thực thi đoạn code trên bằng cách từ màn hình Excel, Alt+F8, chọn thủ tục trên và Run xem sao.

Chúc thành công.

Lê Văn Duyệt
 
Phương thức OnKey của đối tượng Application cũng thường được sử dụng:
Bạn hãy xem đoạn code sau

Mã:
Public Sub AssignDown()
    Application.OnKey "{Down}", "DownTen"
End Sub
Public Sub DownTen()
    ActiveCell.Offset(10, 0).Select
End Sub
Public Sub ClearDown()
    Application.OnKey "{Down}"
End Sub
Với phương thức OnKey sẽ giúp bạn gán phím nóng cho các thủ tục. Ví dụ ở trên khi bạn thực hiện thủ tục AssignDown, thì khi bạn nhấn phím mủi tên xuống, nó sẽ thực hiện thủ tục DownTen (Tức là di chuyển xuống 10 ô từ ô hiện hành).
Với việc gán phím nóng như vậy sẽ có tác dụng cho tất cả các workbook và chỉ trong Excel mà thôi.
Để xóa phím nóng gán cho thủ tục trên bạn phải thực hiện thủ tục ClearDown.

Ví dụ bạn muốn vô hiệu hóa tổ hợp phím để CopyCtrl + C bạn dùng thủ tục sau:
Mã:
Sub StopCopyShortCut()
Application.OnKey "^c", ""
End Sub

Còn muốn phục hồi lại tổ hợp phím Ctrl + C bạn thực hiện thủ tục sau:
Mã:
Sub ClearCopyShortCut()
Application.OnKey "^c"
End Sub

Chúc thành công.

Lê Văn Duyệt
 
Một lỗi các bạn thường gặp khi dùng hàm VBA IIF.
Cấu trúc của hàm này như sau:

IIF(expr, truepart, falsepart)

_ expr: biểu thức bạn muốn kiểm tra.
_ truepart: giá trị khi biểu thức expr đúng.
_ falsepart: giá trị khi biểu thức expr sai.

Bạn hãy thử đoạn code sau:
Mã:
Sub test()
    Dim n As Integer
    n = 0
    MsgBox IIf(n = 0, 1, 1 / n)
End Sub
Bạn sẽ thấy báo lỗi, đúng không ạ?

LoiChia0.jpg


Tại sao vậy? Vấn đề là đối số thứ ba (falsepart) luôn luôn được evaluated (đánh giá), ngay cả nếu biểu thức expr là đúng.
Chính vì vậy khi bạn thực hiện đoạn code trên báo lỗi sẽ xãy ra.

Lê Văn Duyệt
 
Một số thuộc tính thường dùng của đối tượng Application
_ DisplayAlerts: Hệ thống sẽ hiện thông báo khi thực hiện một Macro. Ví dụ khi bạn thực hiện một marco xóa một worksheet, một thông báo sẽ xuát hiện và bạn phải nhấn OK để tiếp tục.
Mã:
Application.DisplayAlerts = False
ActiveSheet.Delete
Application.DisplayAlerts = True
Thông thường khi các bạn gán cho thuộc tính này là True thì bạn phải gán lại là False. Nếu lở bạn quên gán lại là False thì sao? Thực sự ra VBA sẽ tự làm điều này cho bạn, tức là tự gán lại sau mỗi lần thực hiện Macro. Nhưng tốt hơn, để tạo thói quen lập trình tốt chúng ta nên trả về True như đoạn code ở trên.

_ ScreenUpdating: Nó sẽ giúp cho bạn tránh việc nhìn thấy màn hình thay đổi, hoặc bị chớp chớp khi thực hiện Macro. Ví dụ như khi các bạn thực hiện đoạn code sau:
Mã:
    Application.ScreenUpdating = False
    Worksheets("Sheet1").Select
    Worksheets("Sheet2").Select
    Application.ScreenUpdating = False
Với việc thiết lập giá trị ScreenUpdating = False sẽ giúp chương trình bạn thực hiện rất nhanh (Tôi chắc chắn rằng các bạn ít nhiều cũng có kinh nghiệm về việc này! Nếu chưa có thì hãy thử xem!)
Khi trong đoạn mã của các bạn có việc cho hiện Form người dùng, hoặc hộp thoại của bạn, bạn phải chắc chắn rằng ScreenUpdating = True
Có nhiều bạn cho rằng, tôi không cần thiết lập là True thì tôi thực hiện vẫn bình thường chứ có sao đâu?! Các bạn hãy thử đoạn code sau, khi hiện ra form các bạn hãy thử kéo rê xung quanh, các bạn sẽ thấy gì?
Mã:
Sub test()
    Application.ScreenUpdating = False
    UserForm1.Show
    Application.ScreenUpdating = True
End Sub
Các bạn sẽ thấy như hình sau
ScreenUpdating.jpg


_ StatusBar: Thuộc tính này cho phép bạn gán chuổi (để thông báo, hoặc cho mục đích khác) ở thanh tình trạng của Excel. Đây là cách đơn giản nhằm cập nhật thông tin cho người dùng ngay cả khi bạn gán thuộc tính
Mã:
    Application.ScreenUpdating = False

các bạn hãy thử thủ tục sau:
Mã:
Public Sub ShowStatus()
Application.ScreenUpdating = False
Dim I As Long
For I = 0 To 10000000
If I Mod 1000000 = 0 Then
Application.StatusBar = "Processing Record" & I
End If
Next I
Application.StatusBar = False
Application.ScreenUpdating = True
End Sub
Các bạn phải gán Application.StatusBar = False vào cuối thủ tục của các bạn nhằm trả lại tình trạng bình thường cho thanh trạng thái.

_ Caller: là thuộc tính của đối tượng Application nhằm tham chiếu đến đối tượng đã gọi hay thực hiện macro (macro procedure). Nó được sử dụng nhiều trong Excel 5 và Excel 95, nơi mà nó được sử dụng với Menucontrols trong dialog sheets. Từ Excel 95, commandbars và ActiveX controls trên Form đã thay thế cho Menu và control trong dialog sheets.
Caller vẫn còn áp dụng cho Forms toolbar controls(các control trên thanh công cụ), drawing object(đối tượng drawing) có gắn liền với macro và hàm người dùng. Nó có ít, khi cho chúng ta biết ô nào đã gọi hàm người dùng.

WorksheetNameFunc.jpg


và kết quả là:

WorksheetNameFuncResult.jpg


Hy vọng vài thông tin trên sẽ giúp ít cho bạn.

Lê Văn Duyệt
 
Khi mới bước vào "con đường lập trình VBA", thông thường chúng ta phải thực hiện từng bước để kiểm tra lỗi. Vậy thì tôi xin liệt kê ra đây các câu lệnh, dòng lệnh thường dùng các bạn hãy giúp tôi giải thích nha !

Mã:
Debug.Print
Debug.Assert

Các khai báo kiểu
Mã:
#Const Tracing = True
#Const UseEventLog = False
Hoặc
Mã:
#If UseEventLog Then
#Else
Debug.Print "Source: " & Source & " Message: " & Message
#End If
Hoặc
Mã:
#If Tracing Then
Call DebugPrint(Source, Message)
#End If
Bẫy lỗi:
Mã:
On Error Goto Line Number
On Error Resume Next
On Error Goto 0

Lê Văn Duyệt
 
Một vấn đề nhỏ về việc kiểm tra code của chính mình viết, tôi xin giới thiệu chức năng Review Source Code của Mz Tool cho VBA. Bài này đã có giới thiệu tôi chỉ xin nhắc lại chức năng này cho các bạn trong VEC mà thôi.
Đầu tiên các bạn download bản miễn phí tại đây:

http://www.mztools.com/v3/download.aspx
Nhấn vào nút để download
download_mztools3_vba.gif


Sau khi download xong các bạn hãy cài đặt.

Để kiểm tra đoạn code của mình, trong cửa sổ VBE các bạn di chuyển đến module, class, thủ tục, hàm ,... mình muốn kiểm tra

Luom_Hat_San1.jpg


Sau đó bạn chọn menu Review Source code như sau:
Luom_Hat_San.jpg


Các bạn sẽ nhận được kết quả kiểm tra.
Ví dụ như hình ở dưới đây báo cho tôi biết các biến tôi có khai báo mà không sử dụng.
SourceCodeReview.jpg


Sau đó các bạn chỉ việc Click vào biến (màu xanh, giống như đường link) màn hình VBE sẽ di chuyển đến nơi khai báo biến đó. Sau đó các bạn có thể xóa đi.

Chúc các bạn thành công.

Lê Văn Duyệt
 
Đúng ra là những cái này phải biết trước khi lập Code, trong khi mình chả biết gì về cái này mà lập code ào ào, giờ sai chẳng biết sai chỗ nào.
Rất chân thành cám ơn.
 
Kỹ thuật bẫy lỗi là một trong những phần chính mà người lập trình cần phải nắm rõ. Nếu bẫy lỗi tốt, đó cũng là yếu tố nói lên ứng dụng của bạn thành công hay không.
Sử dụng đối tượng DEBUG
Đối tượng Debug là đối tượng giúp chúng ta thử (testing) và gỡ lỗi (debugging)
Đối tượng này chỉ có hai phương thức. Đó là:
Mã:
Debug.Print
Debug.Assert
Phương thức Print, chỉ đơn giản là gởi chuổi thông báo cho cửa sổ Immediate. Để hiện cửa sổ này, trong cửa sổ VBE (Visual Basic Editor) chúng ta vào View/Immediate Window (Hoặc tổ hợp phím nóng Ctrl + G)

ImmediateWindow.jpg


ImmediateWindow1.jpg


Debug.Print chủ yếu sử dụng nhằm theo dõi tiến trình thực của các đoạn code bạn viết. (Mình viết thì dĩ nhiên phải tin rồi, nhưng cũng nên kiểm tra!)
Ví dụ bạn muốn in ra các giá trị khi thực hiện trong vòng lập For Next sau đây:
Mã:
Sub TestDebugPrint()
    Dim i As Long
    For i = 1 To 1000
        Debug.Print i
    Next i
End Sub

Nói chung nhằm kiểm tra các giá trị biến trong quá trình thực hiện code thì nên dùng phương thức này.

Phương thức Assert: phương thức này thực hiện giống như sheriff (a programmer' hired gun - các bạn thử dịch xem nha). Nó được thiết kế nhằm ngừng thực thị đoạn mã trong IDE (integrated development environmen) (các bạn có thể hiểu là cửa sổ soạn code) nếu thử nghiệm truyền cho phương thức Assert bị thất bại (fails). Để hiểu được các bạn xem đoạn code của thủ tục sau:

Mã:
Public Sub DivideByZero(ByVal Numerator As Double, _
ByVal Denominator As Double)
Dim result As Double
[B]Debug.Assert Denominator <> 0[/B]
If (Denominator <> 0) Then
result = Numerator / Denominator
Else
' do something else
End If
End Sub

Khi các bạn thực thi thủ tục Test như hình dưới đây, chương trình sẽ tự động ngừng tại
Mã:
Debug.Assert Denominator <> 0

DebugAssert.jpg


Đó là lý do tại sao người ta gọi phương thức Assert của Debug giống a programmer' hired gun

Hy vọng với giải thích như trên chúng ta hiểu được hai phương thức của đối tượng Debug.

Lê Văn Duyệt
 
Bẫy lỗi
_ On Error Goto Label
_ On Error Goto 0
Trong một số thủ tục các bạn muốn rằng khi lỗi xãy ra dựa trên Err.Number mà các bạn thông báo một cách thân thiện cho người sử dụng.
Ví dụ:
Mã:
Sub ExportTbMaterials(Optional bDeleteTable As Boolean)
'Khai báo các biến

    On Error GoTo [B][COLOR="Red"]ExportTbMaterials_Error[/COLOR][/B]
    With Application
        .Calculation = xlCalculationManual
        .ScreenUpdating = False
    End With
[B][COLOR="Red"]ErrorExit:[/COLOR][/B]

    If gcnAccess.state = ObjectStateEnum.adStateOpen Then
        gcnAccess.Close
    End If

    With Application
        .Calculation = xlCalculationManual
        .ScreenUpdating = True
    End With
    Exit Sub

[B][COLOR="Red"]ExportTbMaterials_Error:[/COLOR][/B]
   
    If Err.Number <> 0 Then
        Select Case Err.Number
        Case (-) 
            MsgBox "Loi la A", vbOKOnly, "Thong bao"
        Case 3265
            MsgBox "Loi la B, vbOKOnly, "Thong bao"
        Case Else
            MsgBox "Loi la C" , vbOKOnly, "Thong bao"
        End Select
    End If
    If bCentralErrorHandler("DataUltilities", "ExportTbMaterials", , False) Then
        Stop
        Resume
    Else
        Resume ErrorExit
    End If

End Sub
Trong đoạn code trên chúng ta có hai nhãn là:
_ExportTbMaterials_Error
_ErrorExit
Khi có lỗi sẽ nhảy đến nhãn ExportTbMaterials_Error xử lý và thông báo lỗi. Sau đó mới nhảy đến nhãn ErrorExit để thực hiện các công việc trước khi thoát ra khỏi thủ tục.
Vậy trong một thủ tục, hàm chúng ta có thể có nhiều nhãn.

Còn On Error Goto 0 để làm gì?
Khai báo này nhằm tắt bất kỳ bẩy lỗi trước nó. Hay nói dễ hiểu hơn là tắt bẫy lỗi ở mức thủ tục

Các bạn hãy tham khảo hàm sau:

Mã:
Function CountUniqueValues(InputRange As Range) As Long
Dim cl As Range, UniqueValues As New Collection
    Application.Volatile
    On Error Resume Next ' ignore any errors
    For Each cl In InputRange
        UniqueValues.Add cl.Value, CStr(cl.Value) ' add the unique item
    Next cl
    [B][COLOR="Red"]On Error GoTo 0 'Lúc này bẫy lỗi On Error Resume Next sẽ không còn tác dụng[/COLOR][/B]
    CountUniqueValues = UniqueValues.Count
End Function

Lê Văn Duyệt
 
Lần chỉnh sửa cuối:
Làm việc với mảng trong VBA

Theo kinh nghiệm của nhiều người việc dùng, xử lý mảng trong VBA sẽ làm cho các đoạn mã của các bạn thực thi nhanh hơn.
Chính vì vậy tôi đã sưu tầm và tổng hợp bài này.
Các thành viên VEC có thể download và tự hoàn thiện cho bản thân.
Các bạn có thể góp ý về: levanduyet@yahoo.com

Chúc các bạn một tuần làm việc, học tập vui vẻ, hạnh phúc.

Lê Văn Duyệt
 

File đính kèm

  • Array_Study.zip
    28.6 KB · Đọc: 10,619
Cảm ơn bác nhiều, em đang mong cái này.
Để em nghiền ngẫm, nếu không hiểu thì em sẽ thắc mắc ngay (mà thường là không hiểu. Hì hì hì)

Thân!
 
Bác MrOkebab mà không hiểu thì tụi tui chắc "bò đội nón luôn".

Hè hè !!!
 
vungoc đã viết:
Bác MrOkebab mà không hiểu thì tụi tui chắc "bò đội nón luôn".

Hè hè !!!

He he he!!! May quá, may mà hôm nay đi đụng cột điện, thế là thông minh ra.+-+-+-++-+-+-++-+-+-+

Bây giờ đang hiểu một cách . . . từ từ.
Cũng bởi vì bác dùng ngôn ngữ bình dân nên em mới hiểu được.

Cảm ơn bác nhiều!!
 
Web KT
Back
Top Bottom