Nhờ khắc phục lỗi không hiển thị giá trị trên một ô

Liên hệ QC

Nguyen Rem

Tất cả chỉ là đưa ra quyết định đúng đắn
Tham gia
23/2/22
Bài viết
211
Được thích
30
Giới tính
Nữ
Em chào các Anh/Chị
Em có 1 file excel. Em muốn các Anh/Chị Vào Modul có tên là "Show" trong file ở dưới và chạy Sub "hello"
Nhập 1 số bất kỳ vào form và nhấn ok .
Câu hỏi :
Cho em hỏi là tại sao ô A10 nó không hiện giá trị mình vừa điền ạ . Có thể cho em cách khắc phục thì càng tốt ạ
Em cảm ơn rất nhiều <3
 

File đính kèm

  • userform.xlsm
    25.2 KB · Đọc: 9
Lần chỉnh sửa cuối:
Nôm na như bài #24 đã nói, là bạn nhập dữ liệu vào đâu thì sẽ lấy dữ liệu từ đó gán xuống ô A1, cụ thể là bạn nhập vào txttuoi thì sẽ lấy từ txttuoi để gán xuống ô A1, do đó sau dấu bằng không phải là Me.txttuoi thì ô A1 sẽ không nhận được dữ liệu mà bạn nhập vào txttuoi.
Anh ơi! Nhưng mà tại sao Age lại không được ạ chẳng phải mình đang code trên userform đấy sao với mình cũng đã đặt tên userform đó là Age rồi . Cái thuộc tính getage nó cũng là txttuoi.Value rồi . Nếu như anh bảo sao mình không viết là txttuoi.getage đi . Nếu viết như thế sẽ bị trùng đúng không ạ nên chắc chắn cái Age và Me nó đều biểu thị cho userform . Nhưng khác nhau của 2 đứa naỳ là thế nào ạ . Mong anh giải thích kĩ giúp em với
 
Upvote 0
Anh ơi! Nhưng mà tại sao Age lại không được ạ chẳng phải mình đang code trên userform đấy sao với mình cũng đã đặt tên userform đó là Age rồi . Cái thuộc tính getage nó cũng là txttuoi.Value rồi . Nếu như anh bảo sao mình không viết là txttuoi.getage đi . Nếu viết như thế sẽ bị trùng đúng không ạ nên chắc chắn cái Age và Me nó đều biểu thị cho userform . Nhưng khác nhau của 2 đứa naỳ là thế nào ạ . Mong anh giải thích kĩ giúp em với
Đoạn này thì ngoài khả năng của mình mất rồi. Bạn chịu khó chờ xem có thành viên nào nắm được sẽ giải thích cho bạn, hoặc bạn thử tìm tài liệu nghiên cứu thêm vậy.
 
Upvote 0
Đoạn này thì ngoài khả năng của mình mất rồi. Bạn chịu khó chờ xem có thành viên nào nắm được sẽ giải thích cho bạn, hoặc bạn thử tìm tài liệu nghiên cứu thêm vậy.
Dạ vâng ạ . Em cảm ơn anh nhiều . Để mai em đặt câu hỏi mới ^^
 
Upvote 0
Vậy mình cũng cố gắng kiên nhẫn giải thích cho bạn.
- Khi bạn nhập các ký tự là nhập vào TextBox có tên là txttuoi chứ không phải là nhập vào userfom có tên là age, sau đó dữ liệu đó được gán từ txttuoi xuống ô A1 trong trang tính.
Bạn giải thích như thế không đúng. Nhập dữ liệu thì đúng là nhập vào textbox txttuoi rồi nhưng khi ghi xuống sheet thì người ta đọc từ THUỘC TÍNH getAge mà người ta tạo ra cho đối tượng Age. Mà THUỘC TÍNH getAge lấy giá trị từ textbox txttuoi chứ lấy từ đâu.
Mã:
Public Property Get getAge() As Variant
 getAge = txttuoi.Value
End Property
 
Lần chỉnh sửa cuối:
Upvote 0
Tại sao không dùng Age được ở đây. Rõ ràng em đặt tên cho userform nó là Age rồi mà
Mình đang dùng code ở trên userform thì cái Me cũng đồng nghĩa với Age luôn mà anh . Em sai ở đâu ạ ^^
Anh ơi! Nhưng mà tại sao Age lại không được ạ chẳng phải mình đang code trên userform đấy sao với mình cũng đã đặt tên userform đó là Age rồi . Cái thuộc tính getage nó cũng là txttuoi.Value rồi . Nếu như anh bảo sao mình không viết là txttuoi.getage đi . Nếu viết như thế sẽ bị trùng đúng không ạ nên chắc chắn cái Age và Me nó đều biểu thị cho userform . Nhưng khác nhau của 2 đứa naỳ là thế nào ạ . Mong anh giải thích kĩ giúp em với
Cái sai của bạn như tôi trình bầy kỹ ở bên dưới. Nói tóm tắt thì là bạn không hiển thị form Age. Bạn tạo 1 phiên bản của Age (frm As New Age) rồi hiển thị nó (frm.Show). Bạn nhập dữ liệu vào textbox của "phiên bản" khác của Age nên trong textbox đó có dữ liệu. Nhưng khi nhập xuống sheet thì bạn không lấy từ <phiên bản>.getAge mà bạn lấy từ Age.getAge, mà bản thân Age không được hiển thị (chỉ phiên bản frm được hiển thị), textbox trên Age RỖNG, vậy không có gì được nhập xuống sheet. Dễ hiểu. Nếu thay vì Age.getAge mà bạn dùng Me.getAge thì khi frm được hiển thị thì Me.getAge = frm.getAge, khi form Age được hiển thị thì Me.getAge = Age.getAge. Tức dùng Me.getAge thì luôn là đọc từ texbox txttuoi của Form HIỆN HÀNH.
------------
Ta xét code của bạn ở tập tin #1.

Mã:
Sub hello()
Dim frm As New Age
frm.Show
If frm.Cancel = True Then
MsgBox "Cancelled"
Else
Debug.Print frm.getAge
End If
End Sub

Mã:
Public Property Get getAge() As Variant
 getAge = txttuoi.Value
End Property

Private Sub Ok_Click_Click()
ThisWorkbook.Sheets("Sheet1").Range("A10").Value = Age.getAge
Me.Hide
End Sub
Về mặt cú pháp và lôgíc thì nhìn qua thấy được. Ta xét hoạt động.

Có một cái khuôn mẫu là Age. Khi chạy Sub hello thì một "người em sinh đôi" của Age được tạo (frm As New Age) và hiển thị. Nó không phải là Age mà là một "phiên bản" của Age. Ta gọi tạm là "một phiên bản của Age". Chỉ có "một phiên bản của Age" được hiển thị chứ bản thân Age không được hiển thị. Khi "một phiên bản của Age" đang hiển thị và bạn nhập "Ngày mai em đi" rồi nhấn OK thì cái gì sảy ra? Bạn nhập "Ngày mai em đi" vào textbox của "một phiên bản của Age", còn textbox của Age thì vẫn trống vì chỉ "một phiên bản của Age" hiển thị chứ Age có hiển thị đâu.

Age.getAge = Age.txttuoi.Value = "". Do Age.textbox trống nên A10 = "RỖNG".

Thế nếu sửa thành
Private Sub Ok_Click_Click()
ThisWorkbook.Sheets("Sheet1").Range("A10").Value = Me.getAge
Me.Hide
End Sub
thì sao?

Me luôn ám chỉ class (module) mà ở đó từ khóa ME được sử dụng. Vd. trong module của Sheet13 thì Me chính là Sheet13 - Me.Range("A7") có nghĩa là Sheet13.Range("A7"). Trong mudule của đối tượng Age thì Me chính là Age - Me.getAge có nghĩa là Age.getAge. Trong mudule của đối tượng frm ("một phiên bản của Age") thì Me chính là frm - Me.getAge có nghĩa là frm.getAge. Do bạn nhập "Ngày mai em đi" vào textbox của frm nên Me.getAge = frm.getAge = frm.txttuoi.Value = "Ngày mai em đi". Vậy A10 = "Ngày mai em đi". Thế thôi.

Thực ra bạn tạo thuộc tính getAge cho Age cũng được nhưng không tạo cũng được. Lúc đó thay cho Me.getAge thì là Me.txttuoi.Value.

Mà tôi không hiểu dụng ý bạn dùng frm As New Age để làm gì. Nếu không dùng frm thì thay frm.Show bằng Age.Show thôi.
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn giải thích như thế không đúng. Nhập dữ liệu thì đúng là nhập vào textbox txttuoi rồi nhưng khi ghi xuống sheet thì người ta đọc từ THUỘC TÍNH getAge mà người ta tạo ra cho đối tượng Age. Mà THUỘC TÍNH getAge lấy giá trị từ textbox txttuoi chứ lấy từ đâu.
Mã:
Public Property Get getAge() As Variant
 getAge = txttuoi.Value
End Property
Dạ, cảm ơn anh ạ.
 
Upvote 0
Cái sai của bạn như tôi trình bầy kỹ ở bên dưới. Nói tóm tắt thì là bạn không hiển thị form Age. Bạn tạo 1 phiên bản của Age (frm As New Age) rồi hiển thị nó (frm.Show). Bạn nhập dữ liệu vào textbox của "phiên bản" khác của Age nên trong textbox đó có dữ liệu. Nhưng khi nhập xuống sheet thì bạn không lấy từ <phiên bản>.getAge mà bạn lấy từ Age.getAge, mà bản thân Age không được hiển thị (chỉ phiên bản frm được hiển thị), textbox trên Age RỖNG, vậy không có gì được nhập xuống sheet. Dễ hiểu. Nếu thay vì Age.getAge mà bạn dùng Me.getAge thì khi frm được hiển thị thì Me.getAge = frm.getAge, khi form Age được hiển thị thì Me.getAge = Age.getAge. Tức dùng Me.getAge thì luôn là đọc từ texbox txttuoi của Form HIỆN HÀNH.
------------
Ta xét code của bạn ở tập tin #1.

Mã:
Sub hello()
Dim frm As New Age
frm.Show
If frm.Cancel = True Then
MsgBox "Cancelled"
Else
Debug.Print frm.getAge
End If
End Sub

Mã:
Public Property Get getAge() As Variant
 getAge = txttuoi.Value
End Property

Private Sub Ok_Click_Click()
ThisWorkbook.Sheets("Sheet1").Range("A10").Value = Age.getAge
Me.Hide
End Sub
Về mặt cú pháp và lôgíc thì nhìn qua thấy được. Ta xét hoạt động.

Có một cái khuôn mẫu là Age. Khi chạy Sub hello thì một "người em sinh đôi" của Age được tạo (frm As New Age) và hiển thị. Nó không phải là Age mà là một "phiên bản" của Age. Ta gọi tạm là "một phiên bản của Age". Chỉ có "một phiên bản của Age" được hiển thị chứ bản thân Age không được hiển thị. Khi "một phiên bản của Age" đang hiển thị và bạn nhập "Ngày mai em đi" rồi nhấn OK thì cái gì sảy ra? Bạn nhập "Ngày mai em đi" vào textbox của "một phiên bản của Age", còn textbox của Age thì vẫn trống vì chỉ "một phiên bản của Age" hiển thị chứ Age có hiển thị đâu.

Age.getAge = Age.txttuoi.Value = "". Do Age.textbox trống nên A10 = "RỖNG".

Thế nếu sửa thành

thì sao?

Me luôn ám chỉ class (module) mà ở đó từ khóa ME được sử dụng. Vd. trong module của Sheet13 thì Me chính là Sheet13 - Me.Range("A7") có nghĩa là Sheet13.Range("A7"). Trong mudule của đối tượng Age thì Me chính là Age - Me.getAge có nghĩa là Age.getAge. Trong mudule của đối tượng frm ("một phiên bản của Age") thì Me chính là frm - Me.getAge có nghĩa là frm.getAge. Do bạn nhập "Ngày mai em đi" vào textbox của frm nên Me.getAge = frm.getAge = frm.txttuoi.Value = "Ngày mai em đi". Vậy A10 = "Ngày mai em đi". Thế thôi.

Thực ra bạn tạo thuộc tính getAge cho Age cũng được nhưng không tạo cũng được. Lúc đó thay cho Me.getAge thì là Me.txttuoi.Value.

Mà tôi không hiểu dụng ý bạn dùng frm As New Age để làm gì. Nếu không dùng frm thì thay frm.Show bằng Age.Show thôi.
Dạ vâng ạ ! Em cảm ơn anh batman1 nhiều lắm .
Thật ra việc em tạo một "Phiên bản khác của Age" cũng chỉ là em muốn thử . Em muốn được gặp lỗi (em muốn code mình tạo ra không chạy) càng nhiều càng tốt ^^
Câu hỏi:
(1) Nhưng mà anh ơi! . Khi mà mình đang code trên userform . Thì mình dùng từ khóa Me trên userform thì nó ám chỉ cả việc dùng cho userform Age và một phiên bản khác của Age đúng không ạ .
1649293115188.png
(2) Nếu mà khi tạo một phiên bản khác của userform Age thì tất cả các bảng điều khuyển mà mình sử dụng trong userform Age (textBox , commandBox) đều có "Name" giống nhau nhưng mà thật ra có có 2 phiên bản đúng không ạ hay nói cách khác . Việc mình tạo ra một phiên bảng khác của userform Age ( Dim frm As New Age ) thì tất cả bảng điều khuyển ở trong Age cũng có một phiên bản khác nhưng tên giống nhau . Điều này có đúng không ạ
 
Upvote 0
(1) Nhưng mà anh ơi! . Khi mà mình đang code trên userform . Thì mình dùng từ khóa Me trên userform thì nó ám chỉ cả việc dùng cho userform Age và một phiên bản khác của Age đúng không ạ .
Đúng rồi. Thực ra cái code mà bạn viết có thể hiểu là "mẫu" là "khuôn". Khi chạy code thì trên cơ sở "mẫu" hay "khuôn" đó ĐỐI TƯỢNG mới được tạo. "Mẫu" thì chỉ có 1 nhưng trong run-time bạn có thể tạo rất rất nhiều ĐỐI TƯỢNG. Bạn có thể hiểu nôm na code nó như là công thức làm bánh ấy: bao nhiêu bột, bột gì, bột nở gì, dầu thơm, đường, nho khô ... Từ công thức đó có thể tạo ra 100 chiếc bánh - 100 ĐỐI TƯỢNG. Vd. code của Dictionary chỉ có 1, nó nằm trong thư viện từ khi cài hệ điều hành Windows cơ, nhưng chả có ĐỐI TƯỢNG nào được tạo. Chỉ tới khi chạy code của bạn thì code đó mới tạo ra vd. 100 ĐỐI TƯỢNG Dictionary.
Code trong module Form cũng thế. Bạn dùng Me nhưng nó là gì thì phải đợi tới khi form đượ̣c hiển thị. Nếu form đang hiển thị là Age thì Me ám chỉ Age, còn nếu form đang hiển thị là frm thì Me ám chỉ frm.
------------
Thì tôi đã viết rõ rồi mà
Trong mudule của đối tượng Age thì Me chính là Age - Me.getAge có nghĩa là Age.getAge. Trong mudule của đối tượng frm ("một phiên bản của Age") thì Me chính là frm - Me.getAge có nghĩa là frm.getAge. Do bạn nhập "Ngày mai em đi" vào textbox của frm nên Me.getAge = frm.getAge = frm.txttuoi.Value = "Ngày mai em đi". Vậy A10 = "Ngày mai em đi". Thế thôi.

Bạn sửa lại code trong form Age
Mã:
Private Sub Ok_Click_Click()
    MsgBox Me.Caption
    Unload Me
End Sub

và thêm code ở module Show sub hichic
Mã:
Sub hello()
Dim frm As New Age
    frm.Caption = "Toi la frm"
    frm.Show
End Sub

Sub hichic()
    Age.Caption = "Toi la Age"
    Age.Show
End Sub

Bây giờ bạn test:

1. Chạy sub hello -> nhấn OK -> bạn nhìn thấy thông báo: "Toi là frm". Tại sao? Bởi form HIỆN HÀNH, form ĐANG HIỂN THỊ chính là frm.

2. Chạy sub hichic -> nhấn OK -> bạn nhìn thấy thông báo: "Toi là Age". Tại sao? Bởi form HIỆN HÀNH, form ĐANG HIỂN THỊ chính là Age.

Như vậy tùy theo form đang hiển thị thì Me nó là frm hay Age.

Nếu bạn sửa thành
Mã:
Private Sub Ok_Click_Click()
    MsgBox Age.Caption
    Unload Me
End Sub

thì là LUÔN LUÔN hiển thị Caption của Age, bất luận bạn chạy hello hay hichic:

2. Chạy hichic -> nhấn OK -> bạn nhìn thấy thông báo: "Toi là Age". Tại sao? Bởi bạn lấy Caption của đích thân Age (MsgBox Age.Caption), mà Caption đó được thiết lập là "Toi là Age" trong hichic.

1. Chạy hello -> nhấn OK -> bạn nhìn thấy thông báo: "Your Age". Tại sao? Bởi bạn lấy Caption của đích thân Age (MsgBox Age.Caption), mà Caption đó được thiết lập trong design-time bằng tay là "Your Age" (trong hello bạn thiết lập Caption cho frm, Caption của Age vẫn là Your Age)

Tóm lại:
1. Nếu trong code của form dùng Age thì LUÔN LUÔN là Age cho dù form đang hiển thị có là Age hay chỉ là "phiên bản của Age"
2. Nếu trong code của form dùng Me thì nó là Age khi form đang hiển thị là Age, hoặc là "phiên bản của Age" nếu form đang hiển thị là "phiên bản của Age".

Tức Me luôn là form HIỆN HÀNH đang HIỂN THỊ. Do "từ xưa tới nay" nhiều người chả bao giờ tạo và hiển thị "phiên bản" của Age nên nhiều người nghĩ là Age.getAge và Me.getAge là như nhau, dùng cái nào cũng được. Nhưng bạn đã thấy là nếu bạn lúc dùng Age lúc thì dùng "phiên bản của Age" thì code trong form: Age.getAge và Me.getAge là 2 cái hoàn toàn khác nhau. Cái đầu luôn là truy cập đích thân tới form cụ thể là Age bất luận form đang hiển thị có là Age hay không, trong khi đó cái thứ 2 luôn truy cập tới form hiện hành đang hiển thị. Tùy cái đang hiển thị là gì thì truy cập tới nó.

Nếu bạn vẫn không hiểu thì tôi chịu.
------------
Giả sử bạn có
Mã:
Private Sub Ok_Click_Click()
    MsgBox Age.Caption
    Unload Me
End Sub
Khi bạn chạy hichic thì chỉ có 1 form là Age, 1 textbox txttuoi và 1 OK trên Age.

Khi bạn chạy hello thì có 2 form: form đang hiển thị là frm. Nhưng khi nhấn OK thì do có truy cập tới thuộc tính (Caption) của Age - Age.Caption, nên đối tượng kiểu Age được tạo nhưng bị ẩn. Tức trong trường hợp này ở thời điểm hiển thị form thì chỉ có frm. Nhưng ở thời điểm nhấn OK thì Age được tạo nhưng bị ẩn (chả có chỗ nào có Age.Show). Trên frm có 1 textbox txttuoi và 1 OK, trên Age đang bị ẩn cũng tương tự có 1 textbox txttuoi và 1 OK. Tức tổng cộng ở thời điểm click OK trên frm có 2 textbox txttuoi và 2 OK - 1 textbox txttuoi và 1 OK trên frm đang hiển thị và 1 textbox txttuoi và 1 OK trên Age đang bị ẩn.
(2) Nếu mà khi tạo một phiên bản khác của userform Age thì tất cả các bảng điều khuyển mà mình sử dụng trong userform Age (textBox , commandBox) đều có "Name" giống nhau nhưng mà thật ra có có 2 phiên bản đúng không ạ hay nói cách khác . Việc mình tạo ra một phiên bảng khác của userform Age ( Dim frm As New Age ) thì tất cả bảng điều khuyển ở trong Age cũng có một phiên bản khác nhưng tên giống nhau . Điều này có đúng không ạ
1. Nếu bạn có Age.Show thì chỉ có 1 form là Age và 1 textbox txttuoi và 1 OK trên Age.

2. Nếu bạn có frm.Show thì ở thời điểm hiển thị frm thì chỉ có 1 đối tượng là frm được tạo và trên nó có 1 textbox txttuoi và 1 OK. Nếu trong code không có chỗ nào truy cập đích thân tới Age thì tới tận khi đóng frm thì vẫn chỉ có 1 đối tượng frm với 1 textbox txttuoi và 1 OK trên nó. Nhưng nếu có 1 chỗ nào đó truy cập tới thuộc tính hay gọi phương thức của Age, vd. Age.txttuoi, thì ở thời điểm truy cập tới thuộc tính hay gọi phương thức của Age ở "chỗ ấy" thì đối tượng Age được tạo nhưng ở trạng thái ẩn. Và từ lúc đó trở đi có 2 đối tượng là frm (đang hiển thị) và Age (ẩn) và 2 textbox txttuoi và 2 OK.

Nếu muốn truy cập tới textbox của form HIỆN HÀNH bất luận nó là frm hay Age thì bắt buộc phải dùng Me.txttuoi.Value. Thế thôi.
 
Upvote 0
...
Thật ra việc em tạo một "Phiên bản khác của Age" cũng chỉ là em muốn thử . Em muốn được gặp lỗi (em muốn code mình tạo ra không chạy) càng nhiều càng tốt ^^
...
Do đâu bạn có cái ý tưởng là "càng nhiều càng tốt"?

Muốn thử, muốn học nhanh thì học cách debug code, cách đổ stack và heap memory ra xem. Có như vậy, bạn mới thức ngộ được những cái như "Me" là cái gì, lúc nào thì đối tượng nào đang nắm tiền tố.
 
Upvote 0
Đúng rồi. Thực ra cái code mà bạn viết có thể hiểu là "mẫu" là "khuôn". Khi chạy code thì trên cơ sở "mẫu" hay "khuôn" đó ĐỐI TƯỢNG mới được tạo. "Mẫu" thì chỉ có 1 nhưng trong run-time bạn có thể tạo rất rất nhiều ĐỐI TƯỢNG. Bạn có thể hiểu nôm na code nó như là công thức làm bánh ấy: bao nhiêu bột, bột gì, bột nở gì, dầu thơm, đường, nho khô ... Từ công thức đó có thể tạo ra 100 chiếc bánh - 100 ĐỐI TƯỢNG. Vd. code của Dictionary chỉ có 1, nó nằm trong thư viện từ khi cài hệ điều hành Windows cơ, nhưng chả có ĐỐI TƯỢNG nào được tạo. Chỉ tới khi chạy code của bạn thì code đó mới tạo ra vd. 100 ĐỐI TƯỢNG Dictionary.
Code trong module Form cũng thế. Bạn dùng Me nhưng nó là gì thì phải đợi tới khi form đượ̣c hiển thị. Nếu form đang hiển thị là Age thì Me ám chỉ Age, còn nếu form đang hiển thị là frm thì Me ám chỉ frm.
------------
Thì tôi đã viết rõ rồi mà


Bạn sửa lại code trong form Age
Mã:
Private Sub Ok_Click_Click()
    MsgBox Me.Caption
    Unload Me
End Sub

và thêm code ở module Show sub hichic
Mã:
Sub hello()
Dim frm As New Age
    frm.Caption = "Toi la frm"
    frm.Show
End Sub

Sub hichic()
    Age.Caption = "Toi la Age"
    Age.Show
End Sub

Bây giờ bạn test:

1. Chạy sub hello -> nhấn OK -> bạn nhìn thấy thông báo: "Toi là frm". Tại sao? Bởi form HIỆN HÀNH, form ĐANG HIỂN THỊ chính là frm.

2. Chạy sub hichic -> nhấn OK -> bạn nhìn thấy thông báo: "Toi là Age". Tại sao? Bởi form HIỆN HÀNH, form ĐANG HIỂN THỊ chính là Age.

Như vậy tùy theo form đang hiển thị thì Me nó là frm hay Age.

Nếu bạn sửa thành
Mã:
Private Sub Ok_Click_Click()
    MsgBox Age.Caption
    Unload Me
End Sub

thì là LUÔN LUÔN hiển thị Caption của Age, bất luận bạn chạy hello hay hichic:

2. Chạy hichic -> nhấn OK -> bạn nhìn thấy thông báo: "Toi là Age". Tại sao? Bởi bạn lấy Caption của đích thân Age (MsgBox Age.Caption), mà Caption đó được thiết lập là "Toi là Age" trong hichic.

1. Chạy hello -> nhấn OK -> bạn nhìn thấy thông báo: "Your Age". Tại sao? Bởi bạn lấy Caption của đích thân Age (MsgBox Age.Caption), mà Caption đó được thiết lập trong design-time bằng tay là "Your Age" (trong hello bạn thiết lập Caption cho frm, Caption của Age vẫn là Your Age)

Tóm lại:
1. Nếu trong code của form dùng Age thì LUÔN LUÔN là Age cho dù form đang hiển thị có là Age hay chỉ là "phiên bản của Age"
2. Nếu trong code của form dùng Me thì nó là Age khi form đang hiển thị là Age, hoặc là "phiên bản của Age" nếu form đang hiển thị là "phiên bản của Age".

Tức Me luôn là form HIỆN HÀNH đang HIỂN THỊ. Do "từ xưa tới nay" nhiều người chả bao giờ tạo và hiển thị "phiên bản" của Age nên nhiều người nghĩ là Age.getAge và Me.getAge là như nhau, dùng cái nào cũng được. Nhưng bạn đã thấy là nếu bạn lúc dùng Age lúc thì dùng "phiên bản của Age" thì code trong form: Age.getAge và Me.getAge là 2 cái hoàn toàn khác nhau. Cái đầu luôn là truy cập đích thân tới form cụ thể là Age bất luận form đang hiển thị có là Age hay không, trong khi đó cái thứ 2 luôn truy cập tới form hiện hành đang hiển thị. Tùy cái đang hiển thị là gì thì truy cập tới nó.

Nếu bạn vẫn không hiểu thì tôi chịu.
------------
Giả sử bạn có
Mã:
Private Sub Ok_Click_Click()
    MsgBox Age.Caption
    Unload Me
End Sub
Khi bạn chạy hichic thì chỉ có 1 form là Age, 1 textbox txttuoi và 1 OK trên Age.

Khi bạn chạy hello thì có 2 form: form đang hiển thị là frm. Nhưng khi nhấn OK thì do có truy cập tới thuộc tính (Caption) của Age - Age.Caption, nên đối tượng kiểu Age được tạo nhưng bị ẩn. Tức trong trường hợp này ở thời điểm hiển thị form thì chỉ có frm. Nhưng ở thời điểm nhấn OK thì Age được tạo nhưng bị ẩn (chả có chỗ nào có Age.Show). Trên frm có 1 textbox txttuoi và 1 OK, trên Age đang bị ẩn cũng tương tự có 1 textbox txttuoi và 1 OK. Tức tổng cộng ở thời điểm click OK trên frm có 2 textbox txttuoi và 2 OK - 1 textbox txttuoi và 1 OK trên frm đang hiển thị và 1 textbox txttuoi và 1 OK trên Age đang bị ẩn.

1. Nếu bạn có Age.Show thì chỉ có 1 form là Age và 1 textbox txttuoi và 1 OK trên Age.

2. Nếu bạn có frm.Show thì ở thời điểm hiển thị frm thì chỉ có 1 đối tượng là frm được tạo và trên nó có 1 textbox txttuoi và 1 OK. Nếu trong code không có chỗ nào truy cập đích thân tới Age thì tới tận khi đóng frm thì vẫn chỉ có 1 đối tượng frm với 1 textbox txttuoi và 1 OK trên nó. Nhưng nếu có 1 chỗ nào đó truy cập tới thuộc tính hay gọi phương thức của Age, vd. Age.txttuoi, thì ở thời điểm truy cập tới thuộc tính hay gọi phương thức của Age ở "chỗ ấy" thì đối tượng Age được tạo nhưng ở trạng thái ẩn. Và từ lúc đó trở đi có 2 đối tượng là frm (đang hiển thị) và Age (ẩn) và 2 textbox txttuoi và 2 OK.

Nếu muốn truy cập tới textbox của form HIỆN HÀNH bất luận nó là frm hay Age thì bắt buộc phải dùng Me.txttuoi.Value. Thế thôi.
Đọc bài viết của anh thật sự rất lâu . Nhưng nó rất xứng đáng và thật sự rất hứng thú . Nhưng em vẫn muốn anh kiểm tra những lời em nói sau đây để cho chắc ^^ .
Em cảm ơn anh nhiều lắm <3

Giả sử mình có
Mã:
Private Sub Ok_Click_Click()
    MsgBox Me.Caption
    Unload Me
    MsgBox Age.Caption
End Sub

có Sub hello:

Mã:
Sub hello()
Dim frm As New Age
    frm.Caption = "Toi la frm"
    frm.Show
End Sub

Các dòng code bên trong sub hello là "Mẫu" , "Khuôn" hay "Công Thức" .
Sau Khi chạy xong Sub hello thì cái đối tượng Me bên trong sub Ok_Click_Click nó mới được tạo nhờ "Công Thức" đó . Tại Thời điểm mình nhấn nút Ok thì sự kiện Click xảy ra . Đối tượng Me đã được thay bằng frm :

Mã:
Private Sub Ok_Click_Click()
    MsgBox frm.Caption
    Unload frm
    MsgBox Age.Caption
End Sub

Cũng tại thời điểm sau khi nhấn nút Ok thì hiện tại mình có 2 form
Một là : frm và trong đó có 1 textbox txttuoi và 1 OK
Hai là : Age và trong có cũng có 1 textbox txttuoi và 1 OK nhưng bị ẩn
Bài đã được tự động gộp:

Do đâu bạn có cái ý tưởng là "càng nhiều càng tốt"?

Muốn thử, muốn học nhanh thì học cách debug code, cách đổ stack và heap memory ra xem. Có như vậy, bạn mới thức ngộ được những cái như "Me" là cái gì, lúc nào thì đối tượng nào đang nắm tiền tố.
Em cảm ơn anh ạ . Em là người mới nên chắc cách đổ stack và heap memory thì để một thời gian sau đi ạ . Bởi vì bây giờ em nghe tên vẫn còn chưa biết là gì nữa
 
Lần chỉnh sửa cuối:
Upvote 0
Đọc bài viết của anh thật sự rất lâu . Nhưng nó rất xứng đáng và thật sự rất hứng thú . Nhưng em vẫn muốn anh kiểm tra những lời em nói sau đây để cho chắc ^^ .
Em cảm ơn anh nhiều lắm <3

Giả sử mình có
Mã:
Private Sub Ok_Click_Click()
    MsgBox Me.Caption
    Unload Me
    MsgBox Age.Caption
End Sub

có Sub hello:

Mã:
Sub hello()
Dim frm As New Age
    frm.Caption = "Toi la frm"
    frm.Show
End Sub

Các dòng code bên trong sub hello là "Mẫu" , "Khuôn" hay "Công Thức" .
Sau Khi chạy xong Sub hello thì cái đối tượng Me bên trong sub Ok_Click_Click nó mới được tạo nhờ "Công Thức" đó . Tại Thời điểm mình nhấn nút Ok thì sự kiện Click xảy ra . Đối tượng Me đã được thay bằng frm :

Mã:
Private Sub Ok_Click_Click()
    MsgBox frm.Caption
    Unload frm
    MsgBox Age.Caption
End Sub

Cũng tại thời điểm sau khi nhấn nút Ok thì hiện tại mình có 2 form
Một là : frm và trong đó có 1 textbox txttuoi và 1 OK
Hai là : Age và trong có cũng có 1 textbox txttuoi và 1 OK nhưng bị ẩn
Bài đã được tự động gộp:


Em cảm ơn anh ạ . Em là người mới nên chắc cách đổ stack và heap memory thì để một thời gian sau đi ạ . Bởi vì bây giờ em nghe tên vẫn còn chưa biết là gì nữa
Trong bóng đá người ta gọi là lối đá đeo bám, pressing toàn sân đây.
 
Upvote 0
Đọc bài viết của anh thật sự rất lâu .
Kiến thức rộng mà giải thích một phần thì bạn không hiểu nên tôi phải viết dài.

Những dòng code chẳng qua là những "dòng chữ". Chả có đối tượng nào tự dưng được tạo từ những "dòng chữ" đó. Điều đó có nghĩa là gì? Bạn mở tập tin ra và làm việc liên tục 1 ngày. Trong 1 ngày này bạn chỉ nhập liệu vào sheet, chèn ảnh, ngắm gái đẹp. Không một lần nào bạn nhấn hello thì trong bộ nhớ chả có đối tượng form được tạo. Đối tượng đó không được tạo TỰ ĐỘNG thôi. Tôi ví là "mẫu" để cho bạn hiểu là khi được tạo thì đối tượng được tạo như thế nào, rõ ràng phải có "khuôn", "mẫu" để trên cơ sở đó "đúc" ra những đối tượng. Bạn không biết lập trình nên tôi phải ví von, mà có thể ví von không sát không chuẩn. Rõ ràng có những dòng code có trong module của form nhưng suốt 1 ngày không có đối tượng form được tạo. Muốn tạo thì phải truy cập (gọi) các thuộc tính hoặc gọi các phương thức của class form. Nếu bạn lập trình trong vd. Delphi thì những code nguồn chúng nằm trong CLASS. Khi cần tạo OBJECT thì phải gọi code để tạo nó, và lúc đó OBJECT được tạo thế nào, với những thuộc tính mặc định nào thì chính là phụ thuộc vào những "chi tiết" có trong CLASS.

Trong VBA giả sử bạn có form HopDong. Chả có form - object HopDong nào được tạo TỰ ĐỘNG cho tới tận khi chạy 1 code nào đó mà code đó dùng Load, truy cập tới thuộc tính hoặc gọi phương thức của HopDong. Chỉ ở thời điểm đó form mới được tạo.

Dùng Load của VBA
Mã:
- Load HopDong
object HopDong được tạo và load vào bộ nhớ (RAM) nhưng không được hiền thị.

- gọi phương thức Show của HopDong
Mã:
Sub test()
    HopDong.Show
End Sub
object HopDong được tạo và load vào bộ nhớ (RAM) và được hiển thị.

truy cập tới bất kỳ thuộc tính nào của HopDong, vd. thuộc tính Caption
Mã:
Sub test()
    MsgBox HopDong.Caption
End Sub
object HopDong được tạo và load vào bộ nhớ (RAM) nhưng không được hiền thị.

Gọi phương thức của HopDong
Mã:
Sub test()
    HopDong.Repaint
End Sub
object HopDong được tạo và load vào bộ nhớ (RAM) nhưng không được hiền thị.

Tất nhiên khi object - form đã được tạo và đang bị ẩn thì nó không được tạo nữa. Vd. khi nhấn OK mà có Me.Hide thì HopDong vẫn còn chỉ là bị ẩn. Nếu gọi code ở trên HopDong.Repaint thì HopDong không được tạo nữa vì nó đang ở trong RAM, chỉ là không được hiển thị. Nếu thay vì HopDong.Hide có Unload Me thì HopDong bị hủy hoàn toàn và khi thực hiện tiếp HopDong.Repaint thì HopDong lại được tạo.

Tôi chỉ viết thế thôi. Nếu bạn vẫn không hiểu thì tìm đọc. Tôi giải thích khúc mắc chứ không dạy lập trình.
Sub hello()
Dim frm As New Age
frm.Caption = "Toi la frm" ' (A)
frm.Show ' (B)
End Sub

Các dòng code bên trong sub hello là "Mẫu" , "Khuôn" hay "Công Thức" .

Thôi tôi rút lại câu Các dòng code bên trong sub hello là "Mẫu" , "Khuôn" hay "Công Thức".

Tôi chỉ muốn nói khác đi là trên cơ sở những dòng trên chả có object frm nào được tạo MỘT CÁCH TỰ ĐỘNG. Nếu muôn đời bạn không chạy sub hello thì muôn đời không có object frm nào được tạo.

Bây giờ ta xét xem cái gì sảy ra khi chạy hello.

Tại (A) có truy cập tới và thiết lập thuộc tính Caption nên tại thời điểm (A) object frm được tạo và load vào trong RAM nhưng không được hiển thị.

Tại thời điểm (B) bình thường thì Show sẽ tạo object frm, load vào RAM và hiển thị. Nhưng do ở thời điểm (A) object frm đã được tạo và đang nằm trong RAM tuy bị ẩn, nên Show không tạo mới object frm mà chỉ HIỂN THỊ frm đang bị ẩn.

Sau Khi chạy xong Sub hello thì cái đối tượng Me bên trong sub Ok_Click_Click nó mới được tạo nhờ "Công Thức" đó
Sau khi chạy hello? Rõ ràng trong hello có frm As New Age và frm.Show vậy cái đối tượng mà diện mạo của nó bạn đang chiêm ngưỡng nó là đối tượng FRM chứ không phải đối tượng AGE. Tôi phải giải thích đi giải thích lại như thế nào bạn mới hiểu? Nếu bạn có frm.Show thì cái mà bạn nhìn thấy là diện mạo của đối tượng frm, còn nếu bạn có Age.Show thì cái mà bạn nhìn thấy là diện mạo của đối tượng Age. Thế thôi.

Tại Thời điểm mình nhấn nút Ok thì sự kiện Click xảy ra . Đối tượng Me đã được thay bằng frm :

Private Sub Ok_Click_Click()
MsgBox frm.Caption
Unload frm
MsgBox Age.Caption
End Sub
Nếu thế thì VBA sẽ báo LỖI. frm là biến cục bộ ̣(local) được khai báo trong sub hello thì làm sao VBA biết nó là cái gì khi đang thực thi Sub Ok_Click_Click? Mà đã là biến local thì chỉ dùng được trong sub hello mà thôi.

Nếu sửa thành
Private Sub Ok_Click_Click()
MsgBox Me.Caption ' (A)
Unload Me ' (B)
MsgBox Age.Caption ' (C)
End Sub
thì ...

Nhìn vào hello thì biết là ở thời điểm (A) Me chính là FRM, vậy Me.Caption cũng có nghĩa là frm.Caption. Tại thời điểm (B) Unload Me chính là: hủy đối tượng FRM trong RAM,tức FRM đã không còn. Không còn chứ không phải chỉ bị ẩn. Nếu là Me.Hide thì mới là vẫn giữ lại nhưng ẩn đi.

Do ở thời điểm (C) có truy cập tới thuộc tính (Caption) của Age nên ở thời điểm (C) đối tượng Age được tạo và load vào RAM nhưng không được hiển thị (ẩn). Tóm lại ở thời điểm:
(A): đối tượng frm tồn tại và đang được hiển thị.
(B): đối tượng frm bị hủy. Trong RAM không tồn tại đối tượng frm vì bị hủy, không tồn tại cả đối tượng Age vì chưa từng được tạo.
(C): trong RAM chỉ có đối tượng Age nhưng đối tượng đó không được hiển thị.

Tôi dừng ở đây.
 
Lần chỉnh sửa cuối:
Upvote 0
Kiến thức rộng mà giải thích một phần thì bạn không hiểu nên tôi phải viết dài.

Những dòng code chẳng qua là những "dòng chữ". Chả có đối tượng nào tự dưng được tạo từ những "dòng chữ" đó. Điều đó có nghĩa là gì? Bạn mở tập tin ra và làm việc liên tục 1 ngày. Trong 1 ngày này bạn chỉ nhập liệu vào sheet, chèn ảnh, ngắm gái đẹp. Không một lần nào bạn nhấn hello thì trong bộ nhớ chả có đối tượng form được tạo. Đối tượng đó không được tạo TỰ ĐỘNG thôi. Tôi ví là "mẫu" để cho bạn hiểu là khi được tạo thì đối tượng được tạo như thế nào, rõ ràng phải có "khuôn", "mẫu" để trên cơ sở đó "đúc" ra những đối tượng. Bạn không biết lập trình nên tôi phải ví von, mà có thể ví von không sát không chuẩn. Rõ ràng có những dòng code có trong module của form nhưng suốt 1 ngày không có đối tượng form được tạo. Muốn tạo thì phải truy cập (gọi) các thuộc tính hoặc gọi các phương thức của class form. Nếu bạn lập trình trong vd. Delphi thì những code nguồn chúng nằm trong CLASS. Khi cần tạo OBJECT thì phải gọi code để tạo nó, và lúc đó OBJECT được tạo thế nào, với những thuộc tính mặc định nào thì chính là phụ thuộc vào những "chi tiết" có trong CLASS.

Trong VBA giả sử bạn có form HopDong. Chả có form - object HopDong nào được tạo TỰ ĐỘNG cho tới tận khi chạy 1 code nào đó mà code đó dùng Load, truy cập tới thuộc tính hoặc gọi phương thức của HopDong. Chỉ ở thời điểm đó form mới được tạo.

Dùng Load của VBA
Mã:
- Load HopDong
object HopDong được tạo và load vào bộ nhớ (RAM) nhưng không được hiền thị.

- gọi phương thức Show của HopDong
Mã:
Sub test()
    HopDong.Show
End Sub
object HopDong được tạo và load vào bộ nhớ (RAM) và được hiển thị.

truy cập tới bất kỳ thuộc tính nào của HopDong, vd. thuộc tính Caption
Mã:
Sub test()
    MsgBox HopDong.Caption
End Sub
object HopDong được tạo và load vào bộ nhớ (RAM) nhưng không được hiền thị.

Gọi phương thức của HopDong
Mã:
Sub test()
    HopDong.Repaint
End Sub
object HopDong được tạo và load vào bộ nhớ (RAM) nhưng không được hiền thị.

Tất nhiên khi object - form đã được tạo và đang bị ẩn thì nó không được tạo nữa. Vd. khi nhấn OK mà có Me.Hide thì HopDong vẫn còn chỉ là bị ẩn. Nếu gọi code ở trên HopDong.Repaint thì HopDong không được tạo nữa vì nó đang ở trong RAM, chỉ là không được hiển thị. Nếu thay vì HopDong.Hide có Unload Me thì HopDong bị hủy hoàn toàn và khi thực hiện tiếp HopDong.Repaint thì HopDong lại được tạo.

Tôi chỉ viết thế thôi. Nếu bạn vẫn không hiểu thì tìm đọc. Tôi giải thích khúc mắc chứ không dạy lập trình.


Thôi tôi rút lại câu Các dòng code bên trong sub hello là "Mẫu" , "Khuôn" hay "Công Thức".

Tôi chỉ muốn nói khác đi là trên cơ sở những dòng trên chả có object frm nào được tạo MỘT CÁCH TỰ ĐỘNG. Nếu muôn đời bạn không chạy sub hello thì muôn đời không có object frm nào được tạo.

Bây giờ ta xét xem cái gì sảy ra khi chạy hello.

Tại (A) có truy cập tới và thiết lập thuộc tính Caption nên tại thời điểm (A) object frm được tạo và load vào trong RAM nhưng không được hiển thị.

Tại thời điểm (B) bình thường thì Show sẽ tạo object frm, load vào RAM và hiển thị. Nhưng do ở thời điểm (A) object frm đã được tạo và đang nằm trong RAM tuy bị ẩn, nên Show không tạo mới object frm mà chỉ HIỂN THỊ frm đang bị ẩn.


Sau khi chạy hello? Rõ ràng trong hello có frm As New Age và frm.Show vậy cái đối tượng mà diện mạo của nó bạn đang chiêm ngưỡng nó là đối tượng FRM chứ không phải đối tượng AGE. Tôi phải giải thích đi giải thích lại như thế nào bạn mới hiểu? Nếu bạn có frm.Show thì cái mà bạn nhìn thấy là diện mạo của đối tượng frm, còn nếu bạn có Age.Show thì cái mà bạn nhìn thấy là diện mạo của đối tượng Age. Thế thôi.


Nếu thế thì VBA sẽ báo LỖI. frm là biến cục bộ ̣(local) được khai báo trong sub hello thì làm sao VBA biết nó là cái gì khi đang thực thi Sub Ok_Click_Click? Mà đã là biến local thì chỉ dùng được trong sub hello mà thôi.

Nếu sửa thành

thì ...

Nhìn vào hello thì biết là ở thời điểm (A) Me chính là FRM, vậy Me.Caption cũng có nghĩa là frm.Caption. Tại thời điểm (B) Unload Me chính là: hủy đối tượng FRM trong RAM,tức FRM đã không còn. Không còn chứ không phải chỉ bị ẩn. Nếu là Me.Hide thì mới là vẫn giữ lại nhưng ẩn đi.

Do ở thời điểm (C) có truy cập tới thuộc tính (Caption) của Age nên ở thời điểm (C) đối tượng Age được tạo và load vào RAM nhưng không được hiển thị (ẩn). Tóm lại ở thời điểm:
(A): đối tượng frm tồn tại và đang được hiển thị.
(B): đối tượng frm bị hủy. Trong RAM không tồn tại đối tượng frm vì bị hủy, không tồn tại cả đối tượng Age vì chưa từng được tạo.
(C): trong RAM chỉ có đối tượng Age nhưng đối tượng đó không được hiển thị.

Tôi dừng ở đây.
Em cảm ơn anh nhiều ạ ^^
 
Upvote 0
Web KT

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

Back
Top Bottom