Lại báo lỗi VBA...

Thảo luận trong 'Ứng dụng Excel' bắt đầu bởi levanduyet, 1 Tháng một 2000.

4,771 lượt xem

  1. levanduyet

    levanduyet Welcome

    Bài viết:
    535
    Đã được thích:
    11
    Giới tính:
    Nam
    Nơi ở:
    HCM
    Chào SHM,
    Chắc có lẻ bạn chưa test !!! Vẫn có lỗi đấy thôi !!!
    Dù sao về cấu trúc của bạn thì quá Pro rồi.
    Thân,
    Lê Văn Duyệt
    PS: SHM, có tìm được e-book về ADO chưa? Giúp mình với, mình cần! Cám ơn bạn trước.
     
    #1
  2. adam_tran

    adam_tran Steel Partner

    Bài viết:
    1,373
    Đã được thích:
    32
    Nơi ở:
    Goooogle
    Tớ có 1 cái form trong đó có nhiều checkbox, tớ tạo 1 cái button gọi là reset Button và gán code sau:

    Sub ResetButton_Click()
    Dim C As CheckBox
    For Each C In UserForm1
    Set C.Value = False
    Next C
    End Sub

    Mục đích là sau khi check nhiều checkbox, muốn bỏ chọn đi một lượt chỉ nhấn 1 nút Reset, nhưng nó cứ báo lỗi "Object doens't support this method..." làm thế nào để đáp ứng yêu cầu tương tự??? :wall:
     
    #2
  3. levanduyet

    levanduyet Welcome

    Bài viết:
    535
    Đã được thích:
    11
    Giới tính:
    Nam
    Nơi ở:
    HCM
    Hì hì hì,
    Em phải khai báo là Control chứ không phải Checkbox. Sau đó em quét qua các control rồi xét nếu là Checkbox thì làm theo ý của em.
    Thân,
    Lê Văn Duyệt
     
    #3
  4. adam_tran

    adam_tran Steel Partner

    Bài viết:
    1,373
    Đã được thích:
    32
    Nơi ở:
    Goooogle
    Hey hey hey, em không biết code đâu, không sách không thầy, đang mò... Kiểm tra If Cotrol is checkbox thì làm gì.... :wall:
     
    #4
  5. SA_DQ

    SA_DQ Thành viên thân thiết

    Bài viết:
    431
    Đã được thích:
    37
    Nơi ở:
    HCM city
    Kiểu du kích đây, tới đi!

    Thử đi, OK?! :atom:
     
    #5
  6. adam_tran

    adam_tran Steel Partner

    Bài viết:
    1,373
    Đã được thích:
    32
    Nơi ở:
    Goooogle
    Macro không ghi lại cái gì cả!
    Tức là, gán Ancellerator không record lại được.
     
    Last edited: 30 Tháng tám 2005
    #6
  7. SA_DQ

    SA_DQ Thành viên thân thiết

    Bài viết:
    431
    Đã được thích:
    37
    Nơi ở:
    HCM city
    => View=>Toolbar=> chọn Form & vẽ 1 cái nút lệnh; Nhập lên nó cái tên, VT "Test" (nhớ là có gạch dưới chữ T);
    Bây chừ mới mở NewMacro & ghi lại hành động bạn sửa lại là không gạch dưới chữ T nữa mà viết hoa & gạch dưới chữ "e";
    Được nha!
     
    #7
  8. StonyHeartedMan

    StonyHeartedMan Thành viên sơ cấp

    Bài viết:
    306
    Đã được thích:
    2
    Nơi ở:
    Hà nội
    Public Function SetAllCheckBoxValue(ByRef objForm As Form, ByVal blnValue As Boolean) As Boolean
    On Error GoTo SetAllCheckBoxValue_ERR:
    Dim objControl As Control '// or Object

    '// Assume function fails
    SetAllCheckBoxValue = False​

    For Each objControl In objForm
    '// Tớ viết "chay" đoạn code này vì lâu lắm ko viết code nên ko nhớ lệnh nữa :)
    If TypeOf objControl Is CheckBox Then
    '//If objControl.Enabled Then objControl.Value = Val(blnValue) '// Check if control is enabled before assigning property's value​
    If objControl.Enabled Then objControl.Value = Abs(blnValue) '// Check if control is enabled before assigning property's value​

    End If

    Next objControl​

    '// All's well done, return True
    SetAllCheckBoxValue = True​

    SetAllCheckBoxValue_DONE:
    If Not objControl Is Nothing Then Set objControl = Nothing
    Exit Function
    SetAllCheckBoxValue_ERR:

    '// Your Error Handle here such as rise error msgbox, log error,...
    '// ...​
    Resume SetAllCheckBoxValue_DONE​

    End Function

    -----------------------------
    How to use this function
    -----------------------------

    Dim oForm as Form, iRet As Boolean

    Set oForm = UserForm1 '// UserForm1 must loaded!
    '// Nếu gọi hàm này từ 1 form và muốn áp dụng ngay cho form đó thì:
    '// Set oForm = Me '// UserForm1 must loaded!

    iRet = SetAllCheckBoxValue(oForm, True)
    '// Nếu ko dùng oForm mà dùng ngay form hiện thời thì:
    '// iRet = SetAllCheckBoxValue(Me, True) // Chú ý, ko thể viết code này lúc Form Load (Event) vì lúc đó Form chưa Loaded và tồn tại trong memory.

    If not iRet then '// Goto Error Handle - Raise Error handle
    ....

    Set oForm = Nothing
    ....


    Hope this helps!

    P/S: Tớ chưa test thử code trên đâu nhé, chỉ là code "chay" để các bạn lấy ý tưởng lập trình thôi.
     
    Last edited: 30 Tháng tám 2005
    #8
  9. StonyHeartedMan

    StonyHeartedMan Thành viên sơ cấp

    Bài viết:
    306
    Đã được thích:
    2
    Nơi ở:
    Hà nội
    Có 4 cái lỗi ở đây:
    1. Không phải control nào cũng có property là Value, vì thế phải kiểm tra kiểu của control object (nếu ko thì phải cho cái bẫy lỗi là On Error Resume Next :))
    2. Set C.Value = False là sai vì người ta chỉ dùng lệnh Set với các object (ví dụ như font chẳng hạn, cũng là property nhưng lại là object), còn gán giá trị cho các property không phải dạng object thì chỉ là lệnh gán bình thường (=). Như vậy đúng ra phải là: C.Value = False
    3. Bao giờ trong lập trình cũng phải cố gắng vét cạn hết các trường hợp xảy ra để xử lý hết các lỗi. Ví dụ trong trường hợp này, giả sử các CheckBox Controls trên form đã bị .Enable = False (hoặc .Visible = False) thì việc gán giá trị cho các thuộc tính của control sẽ ko thực hiện được (lỗi xảy ra). Vì vậy, các bạn phải kiểm tra nếu Enable = True (If theControl.Enable Then ...) trước khi gán giá trị cho thuộc tính. (Cũng giống như việc trước khi Delete (hay Move) File, Folder, Record... thì phải kiểm tra sự tồn tại, thuộc tính (Read, Write,...) của File, Folder hay Record đó rồi mới thực hiện lệnh Delete (Move)... (Dĩ nhiên là phải thực hiện sau khi đã nhắc nhở người dùng trước khi thực hiện lệnh)
    4. Trong lập trình, nhất là lập trình C, Delphi trong windows, một khi đã sử dụng các resources của hệ thống thì phải giải phóng hết memory. Việc bạn sử dụng Object (Control, form, recordset, connection, v.v...) cũng vậy, phải Kill Object(s) sau khi đã dùng xong. Bạn cũng đừng tin là các chương trình viết bằng VB sau khi thoát khỏi chương trình sẽ tự động giải phóng resources. Hãy cứ lập trình theo phong cách chuyên nghiệp.
    Ví dụ:
    If Not objObject Is Nothing Then
    '// Nếu có thể close được thì close object (ví dụ, object là recordset, connection, v.v...)
    If objObject.Open Then objObject.Close '// Tùy theo loại object mà viết các phương thức tương ứng
    If Not objObject Is Nothing Then Set objObject = Nothing
    '// Chú ý: Tại sao lại cứ phải check các trang thái open, nothing trước khi thực hiện: Vì những lệnh check đó thường sẽ làm code chạy nhanh hơn (trong trường hợp phủ định của lệnh check, như ở trên, trường hợp đó là Object đang close hay là nothing sẵn rồi thì nó sẽ bỏ qua lệnh close hay set = nothing - những lệnh này thường chậm hơn lệnh kiểm tra). Ai đã từng viết object như activeX control... rồi thì thì sẽ hiểu cách giải thích (hơi dài dòng) trên :)).
    End If

    5. Suggestion: Trong mọi trường hợp nên viết Error handle, Comments phải đầy đủ cho từng dòng lệnh (nếu có thể) hoặc từng Code Block...
    6. Nên "đóng gói" (viết thành object, thủ tục, hàm dùng chung,...) tất cả những gì bạn thấy có thể reuse lại được.
    7. Tài liệu hóa nếu có thể

    ---------------------------
    Trên đây chỉ là một vài chia sẻ kinh nghiệm viết code với các bạn. Hy vọng các bạn có thể viết nhiều chương trình với những dòng code thật "đẹp"
     
    Last edited: 30 Tháng tám 2005
    #9
  10. adam_tran

    adam_tran Steel Partner

    Bài viết:
    1,373
    Đã được thích:
    32
    Nơi ở:
    Goooogle
    To SA QD:
    Vấn đề là các control nằm trên UserForm chứ không phải là 1 cái shape của sheet, tức là Parent của nó là Form, với các Method và Properties được định nghĩa sẳn.
    To StonyHeartMan:
    Cám ơn anh, cái mà em bí là ko biết diễn giải ý tưởng thành ngôn ngữ VB, không biết cái if cotrol is checkbox kìa.
    Các lỗi:
    1. Em đã khai báo là checkbox, nên em nghỉ checkbox có property Value
    2. Đầu tiên em không dùng "Set", nhưng cũng cứ bị lỗi
    3 - 7: Đây là những kiến thức về lập trình, em hiểu.
     
    #10
  11. StonyHeartedMan

    StonyHeartedMan Thành viên sơ cấp

    Bài viết:
    306
    Đã được thích:
    2
    Nơi ở:
    Hà nội
    --> Stony cũng ko nhớ chính xác :), nhưng stony biết cách vào MSDN để search ra cái lệnh này :) (Ví dụ: Search: "Check Control Type in Visual Basic", vậy cái này có cần kinh nghiệm ko hay chỉ là biết tiếng anh thôi?). Nhớ tất cả những cái đó vào đầu làm gì cho mệt.

    --> Nghĩ thế (Dim C As CheckBox) ... vẫn sai. Trong trường hợp adam_tran thử xóa hết (các) checkbox control(s) trong Form đi sẽ thấy lỗi nó như thế nào. (Đây là cách nghĩ vét cạn nhé (trong trường hợp viết tổng quát áp dụng cho mọi form), ko nên nói là biết chắc form đó có checkbox rồi thì mới viết thế :). Nếu ko có control nào là checkbox trên form thì nó báo lỗi ngay từ cái dòng For Each...

    --> Đấy, phải hiểu "Set" nghĩa là gì, dùng nó khi nào... mới đem ra dùng, chắc giờ đã hiểu rồi nhỉ? :)

    --> Tuyệt quá! vì ko phải ai cũng biết là cách viết code "đẹp" có ý nghĩa như thế nào đâu. Nào là coding conventions, nào là change requests mgnt, bug fixes, v.v...
     
    Last edited: 30 Tháng tám 2005
    #11
  12. workman

    workman Thành viên hoạt động

    Bài viết:
    372
    Đã được thích:
    0
    Nơi ở:
    Ho Chi Minh
    Cái này mình chịu. Xài đỡ cách củ chuối của mình xem sao.

    Tôi assume là Adam sử dụng tên default của VB, tức là CheckBox1, CheckBox2...

    Xài đỡ cái này: for each control in userform1

    if control.name like "CheckBox*" then control.value=false

    next control

    Đừng cười cách làm thô thiển, trình độ của tôi chỉ đến thế.

    Thế nhé. Chúc bạn vui.
     
    #12
  13. StonyHeartedMan

    StonyHeartedMan Thành viên sơ cấp

    Bài viết:
    306
    Đã được thích:
    2
    Nơi ở:
    Hà nội
    Xử lý xong rồi còn xử lý lại làm gì nữa?????? :). Nói vậy thôi, Code của tớ bài trước là quá chuẩn & pro rồi (Chỉ việc Copy & Paste vào chương trình của mọi người thôi). Tớ test rồi, yên tâm đi. Ko phải nghĩ ra cách khác nữa đâu :)
     
    #13
  14. workman

    workman Thành viên hoạt động

    Bài viết:
    372
    Đã được thích:
    0
    Nơi ở:
    Ho Chi Minh
    Ờ, tôi overlook thôi. Đúng là dân lập trình chuyên nghiệp có khác, nhìn code là thấy mê rồi, có cả đoạn xử lý lỗi nữa.

    Cám ơn bạn nhiều về bài viết hướng dẫn rất chi tiết.
     
    #14
  15. StonyHeartedMan

    StonyHeartedMan Thành viên sơ cấp

    Bài viết:
    306
    Đã được thích:
    2
    Nơi ở:
    Hà nội
    YES! :biggrin:

    Here is the code: (just a small amendment: "Go to" --> "Goto", ".Enable" --> ".Enabled", "Val" --> "Abs") SetCheckBoxValue SourceCode

    Cài MSDN của bộ Visual Studio 6 lên :) (Hoặc là vào www.microsoft.com/msdn mà search)
     
    Last edited: 31 Tháng tám 2005
    #15

Chia sẻ trang này