Đố vui về VBA! (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

anhtuan1066

Thành viên gạo cội
Tham gia
10/3/07
Bài viết
5,802
Được thích
6,912
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
 
Áp thuộc tính như thế nào nhỉ?
Anh cho cái dưới vào Workbook
Option Explicit
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.OnTime Now + TimeValue("00:00:10"), "Module1.OpenMe"
ThisWorkbook.Close True
End Sub

Cho cái dưới vào Module 1
Public Sub OpenMe()
MsgBox "I'm Back"
End Sub

Save lại dạng xlsm. Và bấm bấm chạy code hoặc dấu X
 
Upvote 0
Anh cho cái dưới vào Workbook
Option Explicit
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.OnTime Now + TimeValue("00:00:10"), "Module1.OpenMe"
ThisWorkbook.Close True
End Sub

Cho cái dưới vào Module 1
Public Sub OpenMe()
MsgBox "I'm Back"
End Sub

Save lại dạng xlsm. Và bấm bấm chạy code hoặc dấu X
Sau khi mở lại nó hiện cái bảng này. Tôi Disable là hết chuyện.

upload_2018-2-7_17-17-55.png
 
Upvote 0
Range("D3:E5") nằm ở chỗ nào?
------------------------------------
Đầu tiên các bạn chạy thử code này:
Mã:
Sub Test()
  Range("C4:M100").Range("B2:J10").Range("D3:E5").Select
End Sub
rồi xem kết quả
Ai đó nói cho mọi người biết tại sao lại như vậy
(câu đố này không hẳn là đố, chỉ vui vui thôi)
 
Upvote 0
Range("D3:E5") nằm ở chỗ nào?
------------------------------------
Đầu tiên các bạn chạy thử code này:
Mã:
Sub Test()
  Range("C4:M100").Range("B2:J10").Range("D3:E5").Select
End Sub
rồi xem kết quả
Ai đó nói cho mọi người biết tại sao lại như vậy
(câu đố này không hẳn là đố, chỉ vui vui thôi)
Tại sao nó lại ra [g7:h9] ................ khó hiểu :D
 
Upvote 0
PHP:
Sub GPETest()
  Range("C4:M100").Range("B2:J10").Range("D3:E5").Select
  MsgBox Range("C4:M100").Range("B2:J10").Address, , Selection.Address
End Sub
 
Upvote 0
Tại sao nó lại ra [g7:h9] ................ khó hiểu :D
Ai cũng có 1 kho kiến thức ngay bên cạnh mà không chịu sử dụng. Bó tay.

1. Range(*) là vùng được xác định trong hệ tọa độ của trang tính - hệ tọa độ có gốc nằm tại ô A1 của trang tính.
2. Range(*).Range(**) là vùng được xác định trong hệ tọa độ của vùng Range(*) - hệ tọa độ có gốc nằm tại ô đầu tiên (góc trái bên trên) của vùng Range(*). Tức khi xác định địa chỉ của Range(*).Range(**) thì coi ô đầu tiên (góc trái bên trên) của vùng Range(*) là A1 ***
-------------
1. Range("C4:M100") -> vùng có 97 dòng và 11 cột, bắt đầu từ ô ở dòng 4 cột 3 của trang tính - ô C4
2. Theo ***
Range("C4:M100").Range("B2:J10") -> vùng có 9 dòng và 9 cột, bắt đầu từ ô ở dòng 2 cột 2 (B2) trong hệ tọa độ của Range("C4:M100") - hệ tọa độ có gốc tại C4 của trang tính. Vùng này bắt đầu từ dòng 2 cột 2 (B2) trong hệ tọa độ trên, tức bắt đầu từ ô D5 trong hệ tọa độ trang tính. Tính từ D5 lấy 9 hàng 9 cột thì ta có D5:L13 là địa chỉ của vùng Range("C4:M100").Range("B2:J10") (trong hệ tọa độ của trang tính)
3. Theo ***
Range("C4:M100").Range("B2:J10").Range("D3:E5") -> vùng có 3 dòng và 2 cột, bắt đầu từ ô ở dòng 3 cột 4 (D3) trong hệ tọa độ của Range("C4:M100").Range("B2:J10") - hệ tọa độ có gốc tại D5 của trang tính. Vùng này bắt đầu từ dòng 3 cột 4 (D3) trong hệ tọa độ trên, tức bắt đầu từ ô G7 trong hệ tọa độ trang tính. Tính từ G7 lấy 3 dòng và 2 cột thì ta có G7:H9 là địa chỉ của vùng Range("C4:M100").Range("B2:J10").Range("D3:E5") (trong hệ tọa độ của trang tính)
 

File đính kèm

  • 54321.JPG
    54321.JPG
    152.1 KB · Đọc: 13
  • 12345.JPG
    12345.JPG
    116 KB · Đọc: 14
Upvote 1
Mã:
Sub Functions()
    Dim k As Range
    Set k = Range("a1")
    MsgBox k(1)(3)(5)(7)(9)....(101)().Address
End Sub

Thế đố mọi người đoạn code trên sẽ hiện ra cái gì, lưu ý .... có nghĩ là còn rất nhiều(11)(13)(15)
 
Upvote 0
Em đang suy nghĩ ứng dụng nó vô việc chi đây ? hay chỉ chơi vui vậy thôi
Nó có vô số ứng dụng nếu anh có hoa tay cùng trí tưởng tượng.

Ví dụ cho một biến Range xxx nào đó, yêu cầu truy xuất vào ô đầu tiên của xxx thì sẽ là xxx.Range("A1")
 
Upvote 0
Em đang suy nghĩ ứng dụng nó vô việc chi đây ? hay chỉ chơi vui vậy thôi
Có ứng dụng khi hiểu về nó: tương đối của tương đối của tương đối của ...tương ...
mãi thành của tương cà ...
Nói vui vậy, còn

Cái này rất hiểu ích khi chúng ta sử dụng biến range RG, thì khi xét bên trong nó ta chỉ cần RG(1,1),RG(1,2).....vv rối có thể trong RG lại có vùng rng nữa thì cũng tương tự
(ở đây sử dụng địa chỉ theo hàng, cột)
 
Upvote 0
Em đang suy nghĩ ứng dụng nó vô việc chi đây ? hay chỉ chơi vui vậy thôi
Có nhiều cách viết, tùy trường hợp mà chọn cách nào thuận tiện. Không có cách nào bắt buộc phải có - mỗi cách đều có thể thay bằng cách khác. Vd. Thay vì Range(*).Range(**).Range(***) có thể dùng offset hoặc/và Resize
Vd. thay cho

Range("C4:M100").Range("B2:J10").Range("D3:E5")

có thể dùng

Range("C4:M100").Offset(1, 1).Offset(2, 3).Resize(3, 2)

hoặc gộp 2 Offset làm một

Range("C4:M100").Offset(3, 4).Resize(3, 2)
 
Upvote 0
Có nhiều cách viết, tùy trường hợp mà chọn cách nào thuận tiện. Không có cách nào bắt buộc phải có - mỗi cách đều có thể thay bằng cách khác
Em thấy Offset với chỉ số âm thì không viết theo kiểu Range được.
Trong trường hợp vùng cần xác định có nhiều Areas thì dùng Range sẽ gọn hơn (nhưng thực tế cũng chưa thấy trường hợp nào)
PHP:
Selection.Range("B2,A3,C4,B6,D5,D9,C11,A9,B13").Select
 
Upvote 0
Em thấy Offset với chỉ số âm thì không viết theo kiểu Range được.
Thực ra tôi viết mà chưa nghĩ sâu. Xin rút lại :D
Range.Range đúng là thay được bằng Offset
Mã:
Sub hehe()
     MsgBox Selection.Range("B2,A3,C4,B6,D5,D9,C11,A9,B13").Address & vbCrLf & _
        Range("B2,A3,C4,B6,D5,D9,C11,A9,B13").Offset(Selection.Row - 1, Selection.Column - 1).Address
End Sub
Nhưng ngược lại thì với chỉ số âm thì không được.

Thôi thì: có nhiều trường hợp có thể dùng nhiều cách, và tùy trường hợp mà dùng cách thuận tiện.

Bản thân tôi rất hay dùng Offset + Resize - rất trực quan. rng.Offset thì tưởng tượng được rng được dịch chuyển thế nào. Rồi muốn nó có bao nhiêu dòng cột thì Resize. Bởi trong rất nhiều trường hợp, nhưng không phải tất cả, ta có sự dịch chuyển tương đối, vd.: "sau khi tìm được ô xyz (ô tên) rồi thì dịch sang phải 2 cột (đến cột số lượng) xuống dưới 1 dòng (số lượng đầu tiên dưới dòng tên 1 dòng) và đọc kết quả vùng có r dòng.
 
Lần chỉnh sửa cuối:
Upvote 0
Mỗi Rang lúc này là một Thuộc tính. Có khả năng thừa kế của object trước. Object mục tiêu là : D3:E5. Nó thừa kế column, row của ojbect trước. Vì excel xác định toạ độ theo góc trên, bên trái nên nó sẽ căn cứ C4, B2 để dịch chuyển.


RangeA.RangeB.RangC.Select
RangeA
Range(B2): (2,2) => Object Range(B2)

RangeA.RangeB
Range(B2).Range(C4)= (2+3-1, 2+4-1) =(4, 5) =>Object Range(D5)

RangeA.RangeB.RangC
Range(B2).Range(C4).Range(D3) = Range(D5).Range(D3) =(4+4-1, 5+3-1) = (7, 7) => Object Range(G7)

RangeA.RangeB.RangC.Select
Range(G7).Select
 

File đính kèm

  • runhcm.png
    runhcm.png
    126.2 KB · Đọc: 4
Lần chỉnh sửa cuối:
Upvote 0
Em có ngu ý chút về Range và Offset.

Offset(RowOffset, ColumnOffset) As Range
Offset là một Function truyền hai đối số (paramater) RowOffset, ColumnOffset trả về Object Range (As Range)

Rang(Cell1, Cell2) As Range
Range là một Object nhưng là Property (Thuộc tính) nếu được chỉ định Rõ bởi (WB, WS) nếu không chỉ định nó sẽ lấy ThisWookBook.ActiveSheet.Range

Resize(RowSize, ColumnSize) As Range
Resize là một Function truyền hai đối số (paramater) RowSize, ColumnSize trả về Object Range (As Range)

RangeA.RangeB.RangeC
Bản thân RangeC là một Object, nhưng
RangeC là Property của RangeB(Object) thừa kế các thuộc tính từ RangeB
RangeB là Property của RangeA(Object) thừa kế các thuộc tính từ RangeA
Nên lệnh: RangeC.Select thì trả về Object là RangeC
Lệnh RangeB.RangeC.Select thì trả về Trả về Object của RangeC có thừa kế thuộc tính từ RangeB, sau đó sẽ Select.
Như vậy, nếu trong bộ nhớ: Các quá trình định địa chỉ thì RangeA, RangeB, RangeC là Object được lưu trong HEAP, nhưng quá trình tính toàn chuyển đổi
RangeA.RangeB.RangeC lại thực hiện trong phần STACK(Nhớ tạm), Sau quá trình chuyển đổi lại lưu vào HEAP (Toàn chương trình)

Với Range.Offset thì Function Offset này sẽ được gọi ra trong phần STACK chứ nó không có lưu trong HEAP, sau khi kết thúc quá trình gọi sẽ mất nên cần Range chứa nó, và Range.Offset trả về sẽ được lưu vào HEAP. Tương tự cho Phần Resize. Nhưng,
Resize: Sẽ trả về kích cỡ cho Range chỉ định
Offset: Sẽ thay đổi Index của Range chỉ định.

Lệnh Range.Offset.Resize thì Sau khi Function Offset thực hiện sẽ trả về Range đó (có thay đổi theo Offset. Chuyển dịch) tiếp tục thực hiện Function Resize(Thay đổi lại kích cỡ).

Cho nên cách nào cũng được, nhưng cách tối ưu theo em nghĩ là Range.Offset.Resize vì nó sử dụng Function nên dễ hình dung và cũng giảm thiểu được bộ nhớ khi sử dụng, và chỉ định một địa chỉ Range gốc thôi.
 
Lần chỉnh sửa cuối:
Upvote 0
...
Như vậy, nếu trong bộ nhớ: Các quá trình định địa chỉ thì RangeA, RangeB, RangeC là Object được lưu trong HEAP, nhưng quá trình tính toàn chuyển đổi
RangeA.RangeB.RangeC lại thực hiện trong phần STACK(Nhớ tạm), Sau quá trình chuyển đổi lại lưu vào HEAP (Toàn chương trình)

Với Range.Offset thì Function Offset này sẽ được gọi ra trong phần STACK chứ nó không có lưu trong HEAP, sau khi kết thúc quá trình gọi sẽ mất nên cần Range chứa nó, và Range.Offset trả về sẽ được lưu vào HEAP. ...

Hiểu chết liền.
 
Upvote 0
Em có ngu ý chút về Range và Offset.

Offset(RowOffset, ColumnOffset) As Range
Offset là một Function truyền hai đối số (paramater) RowOffset, ColumnOffset trả về Object Range (As Range)

Rang(Cell1, Cell2) As Range
Range là một Object nhưng là Property (Thuộc tính) nếu được chỉ định Rõ bởi (WB, WS) nếu không chỉ định nó sẽ lấy ThisWookBook.ActiveSheet.Range

Resize(RowSize, ColumnSize) As Range
Resize là một Function truyền hai đối số (paramater) RowSize, ColumnSize trả về Object Range (As Range)

RangeA.RangeB.RangeC
Bản thân RangeC là một Object, nhưng
RangeC là Property của RangeB(Object) thừa kế các thuộc tính từ RangeB
RangeB là Property của RangeA(Object) thừa kế các thuộc tính từ RangeA
Nên lệnh: RangeC.Select thì trả về Object là RangeC
Lệnh RangeB.RangeC.Select thì trả về Trả về Object của RangeC có thừa kế thuộc tính từ RangeB, sau đó sẽ Select.
Như vậy, nếu trong bộ nhớ: Các quá trình định địa chỉ thì RangeA, RangeB, RangeC là Object được lưu trong HEAP, nhưng quá trình tính toàn chuyển đổi
RangeA.RangeB.RangeC lại thực hiện trong phần STACK(Nhớ tạm), Sau quá trình chuyển đổi lại lưu vào HEAP (Toàn chương trình)

Với Range.Offset thì Function Offset này sẽ được gọi ra trong phần STACK chứ nó không có lưu trong HEAP, sau khi kết thúc quá trình gọi sẽ mất nên cần Range chứa nó, và Range.Offset trả về sẽ được lưu vào HEAP. Tương tự cho Phần Resize. Nhưng,
Resize: Sẽ trả về kích cỡ cho Range chỉ định
Offset: Sẽ thay đổi Index của Range chỉ định.

Lệnh Range.Offset.Resize thì Sau khi Function Offset thực hiện sẽ trả về Range đó (có thay đổi theo Offset. Chuyển dịch) tiếp tục thực hiện Function Resize(Thay đổi lại kích cỡ).

Cho nên cách nào cũng được, nhưng cách tối ưu theo em nghĩ là Range.Offset.Resize vì nó sử dụng Function nên dễ hình dung và cũng giảm thiểu được bộ nhớ khi sử dụng, và chỉ định một địa chỉ Range gốc thôi.
Hiểu chết liên! Thật lòng bạn mong ước gì thì hãy nói ra, chứ cứ để mọi người thẹn thùng là không được.

Gợi ý là range offset resize đều là thuộc tính chứ không phải là hàm đâu nhé.
 
Upvote 0
Em không có ý kiến về các anh chị hiểu đến đâu hay châm biếm hay đang đùa vui. Nhưng mà, em thấy GPE quá nhiều "bô lão" nên nói gì cũng phải suy nghĩ trước sau có va vấp quý anh chị nào không, thành ra nói để thảo luận dù đúng dù sai thì cũng rất khó. Anh chị cứ nói ra những kiến thức của anh chị cho mọi người không tốt sao. Dù sao cũng năm mới tới nên mọi người nên giữ không khí vui vẻ. Thời gian qua đã học hỏi được khá nhiều từ các anh chị. Chân thành cảm ơn và chúc năm mới vui vẻ!
 
Upvote 0
bài đó có viết tiếng Việt mà, sao anh không hiểu nhỉ ?

Bạn vào giảng đường Đại Học Luật năm thứ tư, nghe người ta giảng bạn hiểu không? người ta cũng nói tiếng Việt mà.

... Dù sao cũng năm mới tới nên mọi người nên giữ không khí vui vẻ. ...

Tôi cũng chả biết thế nào là "không khí vui vẻ" nữa. Cứ mỗi lần tôi đang nói chuyện "vui vẻ" với mấy người tôi mến mộ ở đây thì in như ngày hôm sau có người báo cáo và các bài ấy bị xóa mất.
 
Upvote 0
Bạn vào giảng đường Đại Học Luật năm thứ tư, nghe người ta giảng bạn hiểu không? người ta cũng nói tiếng Việt mà.



Tôi cũng chả biết thế nào là "không khí vui vẻ" nữa. Cứ mỗi lần tôi đang nói chuyện "vui vẻ" với mấy người tôi mến mộ ở đây thì in như ngày hôm sau có người báo cáo và các bài ấy bị xóa mất.
Thiệt không anh, em không báo cáo đâu nhé!
 
Upvote 0
Nhân Ô. Táo đã về Giời, xin các bạn viết giúp vài câu lệnh áp dụng fương thức Find() để tìm ra địa chỉ của ô chứa ngày 8/02/2018. (theo file đính kèm)
Hiện ngày đưa ông Táo này đang ở cột đầu trong bảng dữ liệu sau:
PHP:
'
Ngày           Mã         HoTen'
13/1/2018     GPE01     NDU96081631
              GPE02     Ba Tê
              GPE03     PTM0412
24/1/2018     GPE04      Hoàng Trọng Nghĩa
              GPE05     Hai Lúa Miền Tây
              GPE06     PhanTuHuong
6/2/2018      GPE07     BeFaint
              GPE08     HuuThang_BD
              GPE09     AnhTuan1060
8/2/2018      GPE10     NghiaPhuc
              GPE11     QuangHai1969
              GPE12     VanLe33
              GPE13     Be09
. . .   . . .      . . . .

Sẽ rất vui khi được các bạn giúp & chân thành cảm ơn!
 

File đính kèm

Upvote 0
Có tình huống thế này về DialogSheet:
- Mở 1 workbook trắng
- Chèn 1 DialogSheet, mặc định nó có tên là "Dialog1"
- Vào VBA, viết code để show dialogsheet như sau:
Mã:
Sub ShowDialog()
  DialogSheets("Dialog1").Show
End Sub
- Chạy code. Đương nhiên mọi chuyện diễn ra bình thường (sẽ thấy Dialog1 xuất hiện)
----------------------------------
Ấy vậy mà tôi có 1 file (thiết kế y chang như mô tả ở trên) lại báo lỗi khi chạy code

Untitled.jpg

Nếu thêm dòng "On Error Resume Next" vào đầu code thì sẽ chạy được
Vấn đề là lỗi từ đâu ra? Mời xem file và tìm nguyên nhân
 

File đính kèm

Upvote 0
Có tình huống thế này về DialogSheet:
- Mở 1 workbook trắng
- Chèn 1 DialogSheet, mặc định nó có tên là "Dialog1"
- Vào VBA, viết code để show dialogsheet như sau:
Mã:
Sub ShowDialog()
  DialogSheets("Dialog1").Show
End Sub
- Chạy code. Đương nhiên mọi chuyện diễn ra bình thường (sẽ thấy Dialog1 xuất hiện)
----------------------------------
Ấy vậy mà tôi có 1 file (thiết kế y chang như mô tả ở trên) lại báo lỗi khi chạy code

View attachment 200654

Nếu thêm dòng "On Error Resume Next" vào đầu code thì sẽ chạy được
Vấn đề là lỗi từ đâu ra? Mời xem file và tìm nguyên nhân
hihi, có cái gì đó tác động vào, không cho ta gọi cái dialog1 đó??? Ta đổi cái tên gọi thủ tục đó thì thấy nó báo là macro không tồn tại hoặc bị ẩn???
 
Upvote 0
hihi, có cái gì đó tác động vào, không cho ta gọi cái dialog1 đó??? Ta đổi cái tên gọi thủ tục đó thì thấy nó báo là macro không tồn tại hoặc bị ẩn???
Uh, nó ngộ vậy đó. Nếu mình tự xây dựng y chang vậy thì chạy bình thường, trong khi file làm sẵn ở trên lại lỗi. "Có cái gì đó" là cái gì?
(Tôi cũng tình cờ phát hiện khi đang viết code thôi)
 
Upvote 0
Uh, nó ngộ vậy đó. Nếu mình tự xây dựng y chang vậy thì chạy bình thường, trong khi file làm sẵn ở trên lại lỗi. "Có cái gì đó" là cái gì?
(Tôi cũng tình cờ phát hiện khi đang viết code thôi)
NÓ lỗi do cái gì đó Anh
 
Upvote 0
Có tình huống thế này về DialogSheet:
- Mở 1 workbook trắng
- Chèn 1 DialogSheet, mặc định nó có tên là "Dialog1"
- Vào VBA, viết code để show dialogsheet như sau:
Mã:
Sub ShowDialog()
  DialogSheets("Dialog1").Show
End Sub
- Chạy code. Đương nhiên mọi chuyện diễn ra bình thường (sẽ thấy Dialog1 xuất hiện)
----------------------------------
Ấy vậy mà tôi có 1 file (thiết kế y chang như mô tả ở trên) lại báo lỗi khi chạy code

View attachment 200654

Nếu thêm dòng "On Error Resume Next" vào đầu code thì sẽ chạy được
Vấn đề là lỗi từ đâu ra? Mời xem file và tìm nguyên nhân
Mã:
Option Explicit

Sub ShowDialog()
  'On Error Resume Next
  MsgBox "treu nhau chac?"
 
End Sub



Sub HienForm()
    DialogSheets("Dialog1").Show
End Sub

Chạy HienForm là sẽ rõ nguyên nhân, cái này là do có người cố ý can thiệp vào cái dialog1 ( nhìn bằng mắt thường sẽ khó nhận ra), cách chữa thì để mọi người tự tìm vì nó dễ quá.
 
Upvote 0
Mã:
Option Explicit

Sub ShowDialog()
  'On Error Resume Next
  MsgBox "treu nhau chac?"

End Sub



Sub HienForm()
    DialogSheets("Dialog1").Show
End Sub

Chạy HienForm là sẽ rõ nguyên nhân, cái này là do có người cố ý can thiệp vào cái dialog1 ( nhìn bằng mắt thường sẽ khó nhận ra), cách chữa thì để mọi người tự tìm vì nó dễ quá.
thử chơi vầy nó cũng chạy nè ... vui đó ha
Mã:
Sub Show_Dialog()
  'On Error Resume Next
  DialogSheets("Dialog1").Show
End Sub
hay chơi vầy cũng thú vị
Mã:
chạy thằng cha này trước he
Sub Show_Dialog()
  'On Error Resume Next
  DialogSheets("Dialog1").Show
End Sub

Sub ShowDialog()
  'On Error Resume Next
  'DialogSheets("Dialog1").Show
  MsgBox "OK"
End Sub
 
Upvote 0
Cách tạo ra file như #1,325:
- Chèn một DialogSheets("Dialog1");
- Click chọn vào cái khung của Dialog1, menu Developer, View Code;
- Cửa sổ VBA hiện ra, với "Module1" có một Sub:
PHP:
Sub DialogFrame1_Show()

End Sub
- Cái tên Sub vừa được sinh ra nó quy định là tên Sub mặc định sẽ chạy khi Dialog1 được/ bị gọi hiện lên.
=> Vậy không làm gì tới cái Sub vừa được sinh ra ở trên là mọi thứ bình thường.

-----------
Tiện thể gửi tới các anh Admin: Có thể đổi khung giờ GPE 'treo' được không ạ? Hiện tại là 0h00-0h30, đổi vào 3h00-3h300 được không ạ?
(Đã đề nghị nội dung này một lần rồi).
 
Upvote 0
Cách tạo ra file như #1,325:
- Chèn một DialogSheets("Dialog1");
- Click chọn vào cái khung của Dialog1, menu Developer, View Code;
- Cửa sổ VBA hiện ra, với "Module1" có một Sub:
PHP:
Sub DialogFrame1_Show()

End Sub
- Cái tên Sub vừa được sinh ra nó quy định là tên Sub mặc định sẽ chạy khi Dialog1 được/ bị gọi hiện lên.
=> Vậy không làm gì tới cái Sub vừa được sinh ra ở trên là mọi thứ bình thường.
Cách tạo file là y chang như mình đã mô tả ở trên, không phải như cách của bạn
Vấn đề vẫn là câu hỏi: Tại sao phát sinh lỗi?
 
Upvote 0
123.png123.pngThiết lập thuộc tính onAction bằng "" là sẽ khỏi, ở đây sẽ xảy ra một hiện tượng giống như đệ quy mà sinh lỗi, còn cha nội nào thiết lập cái thuộc tính ý thì chịu.
 
Upvote 0
còn cha nội nào thiết lập cái thuộc tính ý thì chịu.
Cha nội đó la tui đó. Tui cố tình làm vậy mới có chuyện để đố chứ
Đúng ra là khi tui đang xây dựng file, trong lúc vô thức đã làm một động tác sai và dẫn đến cái lỗi kia. Thấy cũng là trò vui nên đố chơi
 
Upvote 0
Cha nội đó la tui đó. Tui cố tình làm vậy mới có chuyện để đố chứ
Đúng ra là khi tui đang xây dựng file, trong lúc vô thức đã làm một động tác sai và dẫn đến cái lỗi kia. Thấy cũng là trò vui nên đố chơi
Biết ngay đây là chủ mưu mà, cái này chỉ cần biết gỡ lỗi chút, với chút tinh tường là nhận ra ngay nguyên nhân.
 
Upvote 0
Vậy thì bạn nói luôn đi: "Tôi đã làm gì mà có lỗi như vậy?"
Tức là: ĐÁP ÁN RÕ RÀNG
Cha nội này gàn thật, cứ phải hỏi lấy gốc mà trồng. Đầu tiên tạo sub ShowDialog như bình thường, sau đó quay lại sheet, chuột phải và chọn gán macro, sau đó chọn cái ShowDialog là được, hoặc có thể dùng code để làm việc này.

Vậy đố cha nội này là điều đó có ý nghĩa gì? ( kết luận mang tính kỹ thuật nhá, đừng có phong long đâu đâu).
 
Upvote 0
Cha nội này gàn thật, cứ phải hỏi lấy gốc mà trồng. Đầu tiên tạo sub ShowDialog như bình thường, sau đó quay lại sheet, chuột phải và chọn gán macro, sau đó chọn cái ShowDialog là được, hoặc có thể dùng code để làm việc này
Lời giải phải rõ ràng mới chấp nhận. Ai biết nhiều khi ba xạo thì sao

Vậy đố cha nội này là điều đó có ý nghĩa gì? ( kết luận mang tính kỹ thuật nhá, đừng có phong long đâu đâu).
Cái này thì khỏi cần đố. Bị tôi làm hoài vụ này (nên mới có lúc vô thức rồi làm theo quán tính)
Vì DialogSheet không có các sự kiện nên phải dùng OnAction và thao tác đó tương đương với sự kiện UserForm_Initialize trong UserForm
 
Upvote 0
Cuối tuần mời các bạn thư giãn nhẹ nhàng:
Mình có 2 thư mục như này:

2fol.png
Mỗi thư mục đều chứa file tên là myfile.xlsb
Bây giờ ta đang đứng ở file myfile.xlsb nằm trong thư mục local, mời các bạn thử viết code để chạy các tác vụ:
1/Đóng file myfile.xlsb trong thư mục local.
2/Copy file myfile.xlsb trong thư mục server chép đè vào thư mục local.
3/Mở lại file myfile.xlsb trong thư mục local.

Cám ơn các bạn. --=0--=0
 

File đính kèm

Upvote 0
Cuối tuần mời các bạn thư giãn nhẹ nhàng:
Mình có 2 thư mục như này:

View attachment 200754
Mỗi thư mục đều chứa file tên là myfile.xlsb
Bây giờ ta đang đứng ở file myfile.xlsb nằm trong thư mục local, mời các bạn thử viết code để chạy các tác vụ:
1/Đóng file myfile.xlsb trong thư mục local.
2/Copy file myfile.xlsb trong thư mục server chép đè vào thư mục local.
3/Mở lại file myfile.xlsb trong thư mục local.

Cám ơn các bạn. --=0--=0
Thêm module với code dưới vào tập tin, không cần lưu lại, sau đó chạy code
Mã:
Sub test()
    Application.DisplayAlerts = False
    ThisWorkbook.ChangeFileAccess xlReadOnly
   
    With CreateObject("Scripting.FileSystemObject")
        .CopyFile Replace(ThisWorkbook.FullName, "\local\", "\server\"), ThisWorkbook.FullName
    End With
    Workbooks.Open ThisWorkbook.FullName
    ThisWorkbook.Close False
    Application.DisplayAlerts = True
End Sub
 
Upvote 0
Lấy lại kích thước gốc của một hình đã chèn trên bảng tính
Có tình huống thế này:
- Tôi chèn 1 hình vào bảng tính
- Xong, tôi chỉnh lại kích thước cho nó tùy ý (kéo chiều ngang, kéo chiều dọc)
- Cuối cùng tôi lưu và đóng file
Sau này mở file lên, nếu tôi muốn lấy lại kích thước gốc của hình, tôi sẽ chọn vào hình, vào tab Format, bấm mũi tên xổ xuống của nút Reset Picture và chọn "Reset Picture & Size". Vậy là hình sẽ trở lại kích thước nguyên thủy
----------------------------
Xin hỏi: Nếu viết code thì phải viết thế nào (chức năng này không cho record macro)
Trong file đính kèm dưới đây tôi có chèn 1 hình. Các bạn giúp tôi lấy lại kích thước gốc của nó với nhé
 

File đính kèm

Upvote 0
Lấy lại kích thước gốc của một hình đã chèn trên bảng tính
Có tình huống thế này:
- Tôi chèn 1 hình vào bảng tính
- Xong, tôi chỉnh lại kích thước cho nó tùy ý (kéo chiều ngang, kéo chiều dọc)
- Cuối cùng tôi lưu và đóng file
Sau này mở file lên, nếu tôi muốn lấy lại kích thước gốc của hình, tôi sẽ chọn vào hình, vào tab Format, bấm mũi tên xổ xuống của nút Reset Picture và chọn "Reset Picture & Size". Vậy là hình sẽ trở lại kích thước nguyên thủy
----------------------------
Xin hỏi: Nếu viết code thì phải viết thế nào (chức năng này không cho record macro)
Trong file đính kèm dưới đây tôi có chèn 1 hình. Các bạn giúp tôi lấy lại kích thước gốc của nó với nhé
Cái này search là ra anh.
Mã:
ActiveSheet.Shapes(1).ScaleWidth 1, True
 
Upvote 0
Đố tiếp anh. Trường hợp nào thì lệnh này không dùng được? :)
Thử thì biết chứ gì. Ví dụ thử với shape (không phải picture)
---------------------------------------
Nói thật là tôi đang cần cái Reset picture này lâu lắm rồi. Tự dưng hôm này tình cờ phát hiện ra, thấy hay nên gửi lên cho bà con tham khảo
 
Upvote 0
Em vẫn xét picture anh gửi thôi.
Chắc thêm dòng này phía trước bài trên cho chắc ăn:
PHP:
ActiveSheet.Shapes(1).LockAspectRatio = msoTrue
Đúng là chắc ăn hơn thật!
Tại thấy mặc định (chưa can thiệp) thì LockAspectRatio đã được check rồi nên không để ý
----------------
(trời! gửi bài xong thấy hiện ra linh tinh cái gì đâu không, xóa mệt luôn)
 
Upvote 0
Đố dễ ẹt nè.
Cô giáo ra bài:
Viết code cho 1 hàm VBA nhận 3 số thực a, b, c (3 điểm) và giải phương trình aX2 + bX + c = 0 (5 điểm)
và lý luận, giải thích cách dùng (2 điểm)

Ba Ếch viết như sau:
Mã:
Sub giaiptbac2()
' sub giải phương trình bậc 2
' chạy sub, gõ các trị a, b, c vào các câu hỏi và nhận kết quả
{ code hỏi và nhận a, b, c ở đây }
' đến đây thì đã có a, b, c
If a = 0 Then
  If b = 0 Then
    MsgBox "Phuong trinh " & IIF(c = 0, "co vo so nghiem", "vo nghiem")
  Else
    MsgBox "Co 1 nghiem la " & -c / b
  End If
  Exit Sub
End If
Dim delta
delta = b*b - 4*a*c
If delta < 0 Then
  MsgBox "Phuong trinh vo nghiem"
ElseIf delta = 0 Then
  MsgBox "Co 1 nghiem la " & -b / 2 / a
Else
  delta = sqrt(delta)
  MsgBox "Co 2 nghiem la " & (-b + delta) / 2 / a & " va " & (-b - delta) / 2 / a
End If
End Sub
Như vậy, Ếch sẽ được bao nhiêu điểm? Và theo bạn, nếu dưới 9 điểm thì muốn 9-10 điểm phải thế nào?
 
Upvote 0
Đố dễ ẹt nè.
Cô giáo ra bài:
Viết code cho 1 hàm VBA nhận 3 số thực a, b, c (3 điểm) và giải phương trình aX2 + bX + c = 0 (5 điểm)
và lý luận, giải thích cách dùng (2 điểm)

Ba Ếch viết như sau:
Mã:
Sub giaiptbac2()
' sub giải phương trình bậc 2
' chạy sub, gõ các trị a, b, c vào các câu hỏi và nhận kết quả
{ code hỏi và nhận a, b, c ở đây }
' đến đây thì đã có a, b, c
If a = 0 Then
  If b = 0 Then
    MsgBox "Phuong trinh " & IIF(c = 0, "co vo so nghiem", "vo nghiem")
  Else
    MsgBox "Co 1 nghiem la " & -c / b
  End If
  Exit Sub
End If
Dim delta
delta = b*b - 4*a*c
If delta < 0 Then
  MsgBox "Phuong trinh vo nghiem"
ElseIf delta = 0 Then
  MsgBox "Co 1 nghiem la " & -b / 2 / a
Else
  delta = sqrt(delta)
  MsgBox "Co 2 nghiem la " & (-b + delta) / 2 / a & " va " & (-b - delta) / 2 / a
End If
End Sub
Như vậy, Ếch sẽ được bao nhiêu điểm? Và theo bạn, nếu dưới 9 điểm thì muốn 9-10 điểm phải thế nào?
Câu hỏi chưa rõ giải phương trình tìm nghiệm trên tập hợp nào, ở đây hiểu là số thực R, nếu trên tập C thì kết quả khác.
Nếu a=b=c=0 thì câu trả lời có vô số nghiệm là chưa đủ mà phải là tất cả R đều là nghiệm.
Đề yêu cầu viết hàm thì ếch viết sub.
Code không chạy vì căn bậc 2 trong vba là SQR, không phải SQRT như trên sheet.
Điểm thì em cũng không biết được mấy vì code không chạy và em cũng không sửa được, chờ mấy thầy chuyên gia sửa điểm ở Lạng Sơn, Hà Giang vào giúp.
 
Upvote 0
Câu hỏi chưa rõ giải phương trình tìm nghiệm trên tập hợp nào, ở đây hiểu là số thực R, nếu trên tập C thì kết quả khác.
Nếu a=b=c=0 thì câu trả lời có vô số nghiệm là chưa đủ mà phải là tất cả R đều là nghiệm.
Đề yêu cầu viết hàm thì ếch viết sub.
Code không chạy vì căn bậc 2 trong vba là SQR, không phải SQRT như trên sheet.
Điểm thì em cũng không biết được mấy vì code không chạy và em cũng không sửa được, chờ mấy thầy chuyên gia sửa điểm ở Lạng Sơn, Hà Giang vào giúp.
1. Khi tôi nói số thực, mặc định là tập hợp R.
2. Hàm và sub : bạn đúng (bây giờ thử đặt câu hỏi tại sao Cô bảo làm hàm mà không là sub?)
3. SQRT, gõ nhầm, xin lỗi
4. Điểm chỉ là sự tương đối để đánh giá. Lỡ nói chuyện Hà giang rồi thì tôi hé thêm: thực ra bài này còn phần điểm cho thêm (bô nớt). Nếu biết phần ấy thì được trên cả 10. Nhưng cũng thú thật, nó trên trình của tôi.
 
Upvote 0
Trich

Pt là bậc 2 khi và chỉ khi a <> 0.
Cái đó không quan trọng, chỉ là vấn đề định nghĩa.
Chỉ cần thêm 1 điều kiện rằng nếu a không khác 0 thì hàm không chịu giải
"This is NOT a quadratic function. You idiot!"
 
Upvote 0
Trich

Pt là bậc 2 khi và chỉ khi a <> 0.
Bác ơi đề có bảo là phương trình bậc 2 đâu, đấy là bài làm đặt vậy chứ.
@VetMini em đoán chắc là muốn 11 điểm thì giải luôn phương trình ax^4 + bx^3 +cx^2 + dx + e = 0. Bây giờ bỏ toán 20 năm rồi em chỉ nhớ đến bậc 3 thôi.
 
Upvote 0
Bác ơi đề có bảo là phương trình bậc 2 đâu, đấy là bài làm đặt vậy chứ.
Theo tôi nếu đề bài là
Viết code cho 1 hàm VBA nhận 3 số thực a, b, c (3 điểm) và giải phương trình aX2 + bX + c = 0 (5 điểm)
Mà ta biết là khi học về pt bậc 2 luôn có đk a <> 0 nên ta phải xét dữ liệu nhập:
- nếu a = 0 thì không giải, vì pt không là bậc 2
- nếu a <> 0 thì xét delta rồi ...

Cũng có thể trước khi xét delta thì xét xem có a+b+c=0, a-b+c=0 hay không :D
 
Lần chỉnh sửa cuối:
Upvote 0
@VetMini em đoán chắc là muốn 11 điểm thì giải luôn phương trình ax^4 + bx^3 +cx^2 + dx + e = 0. Bây giờ bỏ toán 20 năm rồi em chỉ nhớ đến bậc 3 thôi.
Không phải vậy đâu. Dân chuyên giải phương trình có con toán gọi là đồng bộ thừa số (terms normalisation/ization)
Ví dụ, nếu a = 1 * 10^-10, b = 2 * 10^-10, c = 3 * 10^-10 thì ngừoi ta đồng bộ chúng thành 1, 2, 3 để giảm thiểu sai số. Đây chỉ là 1 ví dụ, còn nhiều vấn đề nữa, không chỉ có vậy. Đại khái là phải so sánh độ lớn tương đối của các thừa số trước khi bắt đầu giải.
Tức là phải viết thêm 1 hàm đồng bộ. Nhưng đã nói, cái này là trình cao lắm.
 
Upvote 0
Không phải vậy đâu. Dân chuyên giải phương trình có con toán gọi là đồng bộ thừa số (terms normalisation/ization)
Ví dụ, nếu a = 1 * 10^-10, b = 2 * 10^-10, c = 3 * 10^-10 thì ngừoi ta đồng bộ chúng thành 1, 2, 3 để giảm thiểu sai số. Đây chỉ là 1 ví dụ, còn nhiều vấn đề nữa, không chỉ có vậy. Đại khái là phải so sánh độ lớn tương đối của các thừa số trước khi bắt đầu giải.
Tức là phải viết thêm 1 hàm đồng bộ. Nhưng đã nói, cái này là trình cao lắm.
Đúng là việc này thường làm khi giải phương trình cụ thể, hóa ra lập trình cũng cần. Em lại tưởng là phải xét trường hợp số nhập vào vượt giới hạn của double, chắc khi đó phải viết lại cả các hàm cộng trừ nhân chia căn.
 
Upvote 0
Như tôi đã nói, nó cao trên trình của tôi thì còn hỏi "phải làm gì"
Theo tôi thì học sinh chỉ cần chú thích cho Cô giáo biết là mình có biết đến chuyện này, nhưng nó trên trình độ lớp cho nên không thể code. Thế là hưởng 1 điểm. Viết cái code sau đây thì cho 2 điểm. (điểm chỉ là tương đối để nói chuyện thôi)

Function DongBo(byRef a As Double, byRef b As Double, byRef c As Double)
' hàm đồng bộ ba thừa số a b c của phương trình bậc 2 để gảm sai số.
' chỉ biết hàm nó đại khái thế thôi chứ chi tiết nó cao trên trình độ của lớp
End Function

Code giải phương trình gọi hàm này. Vì hàm không làm gì cả cho nên gọi nó cũng chả chết ai. Khi nào biết phải code ra sao thì cho vào hàm.
 
Upvote 0
Cũng có thể trước khi xét delta thì xét xem có a+b+c=0, a-b+c=0 (*)hay không :D
Em nghĩ cái này không cần thiết, bởi (*) xảy ra thì (delta)^(1/2) =|a-c|
Làm thử : Khi a+b+c=0 =>b=-(a+c)
Delta=b^2-4ac=[-(a+c)]^2-4ac=a^2+c^2-2ac=(a-c)^2
Căn bậc hai của delta =|a-c|
 
Upvote 0
Em nghĩ cái này không cần thiết, bởi (*) xảy ra thì (delta)^(1/2) =|a-c|
Làm thử : Khi a+b+c=0 =>b=-(a+c)
Delta=b^2-4ac=[-(a+c)]^2-4ac=a^2+c^2-2ac=(a-c)^2
Căn bậc hai của delta =|a-c|
Nhưng tiếp theo thì sao? Dùng công thức biết trước
Mã:
x1 = (-b + (a-c)) / 2a = (- b + a -c) / 2a = 2a / 2a = 1
x2 = (-b - (a-c)) / 2a = (- b - a + c) / 2a = 2c / 2a = c/a
?

Thế có phải là sa đà vào việc tính toán không?

Trong khi đó nếu a + b + c = 0 (a - b +c = 0) thì rõ ràng có ngay 2 nghiệm là 1 và c/a (-1 và -c/a).

Nghiệm 1 và -1 nhìn ra ngay, vd. nhìn ra ngay là khi a + b + c = 0 thì 1 thỏa pt ax² + bx + c = 0. Nghiệm thứ 2 suy ra từ định lý Vi-et: x1 * x2 = c/a

Làm thế để cô giáo biết là em A không phải ... dạng vừa. Vì những trường hợp "đặc biệt" này có học trên lớp. :D
 
Upvote 0
Để có thể tiếp tục, ban Giám Hiệu yêu cầu Cô giáo phải xác định lại đề bài:
Đề bài được xác định là ba thừa số a, b, c chỉ dùng để lập đa thức dạng aX2 + bX + c. Tức là một đa thức có bậc tối đa là 2, không bắt buộc phải chính xác bậc 2.
a, b, c đều là phần tử của tập hợp R cho nên trị 0 không được ngoại lệ.
 
Upvote 0
Để có thể tiếp tục, ban Giám Hiệu yêu cầu Cô giáo phải xác định lại đề bài:
Đề bài được xác định là ba thừa số a, b, c chỉ dùng để lập đa thức dạng aX2 + bX + c. Tức là một đa thức có bậc tối đa là 2, không bắt buộc phải chính xác bậc 2.
a, b, c đều là phần tử của tập hợp R cho nên trị 0 không được ngoại lệ.
Hổng lẽ bậc của đa thức có thể là số lẻ ?
 
Upvote 0
Hổng lẽ bậc của đa thức có thể là số lẻ ?
X3 thì gọi là bậc mấy?

Chú: tôi học toán ở SG hơn 40 năm về trước cho nên cách học ba môn Đại số (Algebra), Giải tích (Calculus/Analysis), và Toán số (Arithmetics) hơi khác chương trình sau này các bạn học 1 chút.
Bác batman khoảng xấp xỉ tuổi tôi, như vậy có lẽ bác ấy học toán ở HN.
Lúc ấy, SG đang trên đường chuyển chiều hướng giáo dục theo lối Mỹ, tức là bớt Toán 1 chút để bù vào Vật lý và nhất là Hoá. Vì vậy, nếu trình độ dạy toán HN cao hơn SG thì tôi cũng không lấy làm lạ.
Vả lại, tuy tôi học ban Toán nhưng trình sở thích của tôi là Văn.
 
Upvote 0
Bác batman khoảng xấp xỉ tuổi tôi,
Tôi năm 1954.
như vậy có lẽ bác ấy học toán ở HN.
Thế hệ tôi là sơ tán khắp nơi. Năm lớp 7 mới về gần Hà Nội, cấp 3 thì về lại nội thành.
Lúc ấy, SG đang trên đường chuyển chiều hướng giáo dục theo lối Mỹ, tức là bớt Toán 1 chút để bù vào Vật lý và nhất là Hoá. Vì vậy, nếu trình độ dạy toán HN cao hơn SG thì tôi cũng không lấy làm lạ.
Vả lại, tuy tôi học ban Toán nhưng trình sở thích của tôi là Văn.
Tôi chỉ giỏi về Toán, Lý, Hóa, Văn và các môn học thuộc lòng như Sử, Địa thì cố được trung bình. Người ta gọi là học lệch :D
 
Upvote 0
Tôi kém bác 1 tuổi.
Thế hệ tôi là thế hệ "Rớt tú tài anh đi trung sĩ, em ở nhà lấy Mỹ nuôi con". Trung học chia ra làm đệ nhất (6-9) và đệ nhị cấp (10-12). Học xong lớp 11 thi tú tài 1, nếu đậu thì được lên 12 và học xong thì thi tú tài 2. Hầu hết các ĐH chỉ nhận tú tài 2. Hồi đó chính quyền SG tuyển quân nhân theo bằng cấp. Có bằng tú tài 2 thì được thi vào trường Võ Bị Đà Lạt (ra thiếu uý). Có bằng tú tài 1 thì tự động vào võ bị Thủ Đức (ra chuẩn uý). Có bằng Trung học đệ nhất cấp thì đi trường hạ sĩ quan Đồng Đế (ra trung sĩ). Vì vậy mới có bài thơ trên (*). Cũng cần nói thêm là lúc đó ngành phi công Mỹ cũng tuyển tú tài 1 cho nên một số bạn tôi học đến cấp này thì đăng phi công Mỹ.

(*) bài thơ ấy nói lên cái tâm trạng hoang mang của ngừoi thế hệ tôi. Vì vậy tôi nhớ mãi. Tuy nó dở bẹt nhưng đối với tôi nó cũng như câu "ba người anh nới chiến trường Đông Bắc, được tin em gái mất, trước khi em lấy chồng" của Hữu Loan diễn tả cái xáo trộn đời người của thời kháng chiến.
 
Upvote 0
Đố dễ ẹt nè.
Cô giáo ra bài:
Viết code cho 1 hàm VBA nhận 3 số thực a, b, c (3 điểm) và giải phương trình aX2 + bX + c = 0 (5 điểm)
lý luận, giải thích cách dùng (2 điểm)
...

Ăn 5 điểm đỏ đỏ như thế này:
Thiết kế giao diện hàm
Hàm cần làm thế nào để nhận 3 tham -> 3 double byval
Hàm cần làm thế nào để trả về 2 nghiệm (chả nhẽ trả về một Type, gồm 2 nghiệm?) -> 2 double byRef
Hàm cần làm thế nào để trả về con số nghiệm -> hàm trả về 1 Integer: 0 = vô nghiệm, 1 = 1 nghiệm, 2 = 2 nghiệm, 3 (>2) = vô số nghiệm
(nếu muón diễn tả trục trặc thì có thể dùng số âm để trả về)

Function GiaiPTBac2(byVal a As Double, byVal b As Double, byVal c As Double, byRef x1 As Double, byRef x2 As Double) As Integer
' ham giai phuong trinh bac 2, dang aX2 + bX + c = 0
' tham nhan (in) a, b, c
' tham xuat (out) x1, x2 : 2 nghiem cua phuong trinh (neu co)
' Tri tra ve cua ham: 1 Integer: 0 = vô nghiệm, 1 = 1 nghiệm, 2 = 2 nghiệm, 3 = vô số nghiệm
'

...
End Function

Ví dụ cách gọi hàm:

Select Case GiaiPTBac2(a, b, c, x1, x2)
Case 0
MsgBox "PT vo nghiem"
Case 1
MsgBox "PT co 1 nghiem (kep) la " & x1
Case 2
MsgBox "PT co 2 nghiem la " & x1 & " va " & x2
Case Else
MsgBox "PT khong co nghiem nhat dinh"
End Select
(ví dụ của tôi chỉ đại khái thôi. Cái vụ số nghiệm tuỳ theo quan điểm)

(*) Lưu ý: đây không phải là giải pháp duy nhất hoặc hay nhất. Mục đích của bài này là giới thiệu với các bạn về cách thiết kế giao diện hàm.

1. Mời các bạn thử tìm cách hạ điểm trên xuống dưới 5 bằng cách đưa ra khuyết điểm và cách bổ khuyết.

2. Mời các bạn thử lấy 5 điểm còn lại (viết phần code giải)
 
Upvote 0
Đố các bạn khi thực thi một dòng lệnh gán dữ liệu từ mảng xuống sheet (như code bên dưới) thì VBA thực hiện theo thứ tự như thế nào.
  1. Tất cả các ô cùng lúc
  2. Từ trái qua phải, từ trên xuống dưới
  3. Từ trên xuống dưới, từ trái qua phải
  4. Ngẫu nhiên
  5. Khác
Mã:
Sub Test()
Dim i As Long, j As Long
Dim Arr(1 To 10, 1 To 2)
For i = 1 To 10
    For j = 1 To 2
        Arr(i, j) = Cells(i, j).Address(0, 0)
    Next
Next
[A1:B10].Value = Arr
End Sub
 
Upvote 0
Đố các bạn khi thực thi một dòng lệnh gán dữ liệu từ mảng xuống sheet (như code bên dưới) thì VBA thực hiện theo thứ tự như thế nào.
  1. Tất cả các ô cùng lúc
  2. Từ trái qua phải, từ trên xuống dưới
  3. Từ trên xuống dưới, từ trái qua phải
  4. Ngẫu nhiên
  5. Khác
Mã:
Sub Test()
Dim i As Long, j As Long
Dim Arr(1 To 10, 1 To 2)
For i = 1 To 10
    For j = 1 To 2
        Arr(i, j) = Cells(i, j).Address(0, 0)
    Next
Next
[A1:B10].Value = Arr
End Sub
Em đoán là đáp án thứ 2.Vì Khi dữ liệu mảng nhiều thì nó thực hiện chậm hơn.
 
Upvote 0
Đố các bạn khi thực thi một dòng lệnh gán dữ liệu từ mảng xuống sheet (như code bên dưới) thì VBA thực hiện theo thứ tự như thế nào.
  1. Tất cả các ô cùng lúc
  2. Từ trái qua phải, từ trên xuống dưới
  3. Từ trên xuống dưới, từ trái qua phải
  4. Ngẫu nhiên
  5. Khác
Mã:
Sub Test()
Dim i As Long, j As Long
Dim Arr(1 To 10, 1 To 2)
For i = 1 To 10
    For j = 1 To 2
        Arr(i, j) = Cells(i, j).Address(0, 0)
    Next
Next
[A1:B10].Value = Arr
End Sub
Dzụ này đúng là chưa biết, nhưng thử từ 1000 dòng, đến 10k đến 100k và 500k dòng thì nó đổ cùng lúc, càng nhiều dòng thì mất thời gian duyệt vòng lặp thôi. Vậy đáp án 1, thực thi dòng lệnh gán mảng xuống sheet là tất cả các ô cùng lúc.
 
Upvote 0
Đố các bạn khi thực thi một dòng lệnh gán dữ liệu từ mảng xuống sheet (như code bên dưới) thì VBA thực hiện theo thứ tự như thế nào.
  1. Tất cả các ô cùng lúc
  2. Từ trái qua phải, từ trên xuống dưới
  3. Từ trên xuống dưới, từ trái qua phải
  4. Ngẫu nhiên
  5. Khác
Mã:
Sub Test()
Dim i As Long, j As Long
Dim Arr(1 To 10, 1 To 2)
For i = 1 To 10
    For j = 1 To 2
        Arr(i, j) = Cells(i, j).Address(0, 0)
    Next
Next
[A1:B10].Value = Arr
End Sub
Dùng sự kiện để test thấy gán 1 lần
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
  Dim i As Long
  If Not Intersect(Target, Range("A1:B10")) Is Nothing Then
    i = Application.Count(Range("E1:E100"))
    Cells(i + 1, 4) = i + 1
    Cells(i + 1, 5) = Target.Address(0, 0)
  End If
End Sub

Sub Test()
Dim i As Long, j As Long
Dim Arr(1 To 10, 1 To 2)
For i = 1 To 10
    For j = 1 To 2
        Arr(i, j) = Cells(i, j).Address(0, 0)
    Next
Next
[A1:B10].Value = Arr
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Khái niệm "đổ cùng lúc" là thế nào? Người ta nói "Trong Windows tất cả mọi program đều thực hiện cùng lúc". Làm gì có chuyện ở mỗi thời điểm mọi program đều được thực hiện. Chỉ có điều mỗi program được thực hiện trong một khoảng thời gian rất nhỏ", Program 1 được thực hiện trong một khoảng thời gian rất nhỏ, sau đó "control" sẽ được chuyển sang program 2 (Windows chuyển context), và nó cũng được thực hiện trong một khoảng thời gian rất nhỏ. Cứ thế lần lượt mỗi program. Vì lẽ đó nên nếu ta chuyển liên tục từ program này sang program khác thì có cảm giác là ở mọi thời điểm mỗi program đều đang được thực hiện.
Tôi không rõ các phần tử của mảng sẽ được đập xuống sheet như thế nào. Nhưng tôi tin rằng dù đập xuống sheet bằng cách nào thì khi tất cả mọi phần tử đã được đập xuống sheet thì lúc đó nếu có những công thức tham chiếu tới vùng được đập thì các công thức đó mới được tính lại. Tức nếu cần phải thực hiện calculation thì nó sẽ được thực hiện sau khi mọi phần tử của mảng được đập xuống sheet. Với cách hiểu như thế thì không cần phải quan tâm, các phần tử đã được đập xuống sheet theo cách nào. Không có chuyện đập vào A1 rồi công thức tham chiếu tới vd. A1:C20 được tính lại, rồi sau khi đập xuống A2 thì công thức lại được tính lại, cứ đan xen như thế cho tới khi đập xuống B10 và tính lại công thức. Không, tôi tin là sau khi đập xong A1, ..., A10, B1, ..., B10 thì công thức mới được tính. Nó cho ta cảm giác là "Tất cả các ô cùng lúc", nhưng đó là cảm giác. Ở mỗi thời điểm thì chỉ có 1 phần tử được đổ thôi. "Cùng lúc" chỉ là cách nói mà không có định nghĩa nó là thế nào.
Ở đây tương tự như tình huống: ta có công thức tham chiếu tới A1:B10. Nếu ta chọn A1:B10 và nhấn Ctrl + V để dán 20 giá trị bằng "một thao tác" vào vùng A1:B10 thì phải sau khi 20 giá trị được dán thì công thức mới được tính. Nếu ta có code Worksheet_Change thì sự kiện Worksheet_Change chỉ sảy ra 1 lần chứ không phải 20 lần, và sự kiện đó chỉ sảy ra khi tất cả 20 giá trị đã được gán cho A1:B10.

Còn nếu tò mò là các ô được gán theo thứ tự nào thì tôi đoán là theo cột. Gán xong cột 1 thì gán cột 2, cột 3, cột 4 ...
 
Upvote 0
Em đoán là đáp án thứ 2.Vì Khi dữ liệu mảng nhiều thì nó thực hiện chậm hơn.
Có cơ sở gì không bạn? Mảng lớn chậm có thể là gán từng ô đúng nhưng chắc gì đã là thứ tự như vậy.
Bài đã được tự động gộp:

Dùng sự kiện để test thấy gán 1 lần
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
  Dim i As Long
  If Not Intersect(Target, Range("A1:B10")) Is Nothing Then
    i = Application.Count(Range("E1:E100"))
    Cells(i + 1, 4) = i + 1
    Cells(i + 1, 5) = Target.Address(0, 0)
  End If
End Sub

Sub Test()
Dim i As Long, j As Long
Dim Arr(1 To 10, 1 To 2)
For i = 1 To 10
    For j = 1 To 2
        Arr(i, j) = Cells(i, j).Address(0, 0)
    Next
Next
[A1:B10].Value = Arr
End Sub
Như anh batman1 phân tích sự kiện xảy ra 1 lần không có nghĩa là cả mảng được gán 1 lần.
Anh batman1 cũng chỉ đoán thôi chứ cũng không có cơ sở.
 
Lần chỉnh sửa cuối:
Upvote 0
Đố các bạn khi thực thi một dòng lệnh gán dữ liệu từ mảng xuống sheet (như code bên dưới) thì VBA thực hiện theo thứ tự như thế nào.
  1. Tất cả các ô cùng lúc
  2. Từ trái qua phải, từ trên xuống dưới
  3. Từ trên xuống dưới, từ trái qua phải
  4. Ngẫu nhiên
  5. Khác
Mã:
Sub Test()
Dim i As Long, j As Long
Dim Arr(1 To 10, 1 To 2)
For i = 1 To 10
    For j = 1 To 2
        Arr(i, j) = Cells(i, j).Address(0, 0)
    Next
Next
[A1:B10].Value = Arr
End Sub
Mạnh dạn chọn đáp án 4.

Trong này có bác nào rành phần cứng (CPU) chắc giải thích được. Liên quan tới 'thread và process' gì đó... vì cho dù là siêu máy tính thì vẫn chỉ có duy nhất một process được chạy trong một đơn vị thời gian mà thôi.
 
Upvote 0
Có cơ sở gì không bạn? Mảng lớn chậm có thể là gán từng ô đúng nhưng chắc gì đã là thứ tự như vậy.
Bài đã được tự động gộp:


Như anh batman1 phân tích sự kiện xảy ra 1 lần không có nghĩa là cả mảng được gán 1 lần.
Anh batman1 cũng chỉ đoán thôi chứ cũng không có cơ sở.
Gán 1 lần hay gán nhiều lần chỉ mang ý nghĩa tương đối theo cách nhìn nhận khác nhau, tương tự như phép tính 2+3 là 1 phép tính hay nhiều phép tính trong VBA, nếu truy tới xử lý nhị phân thì là nhiều phép tính, nhưng về toán tử là 1 phép tính
Vấn đề là VBA xem thế nào là gán 1 lần, gán 2 lần ... Gán dữ liệu là sự kiện, dùng sự kiện thay đổi để xác định số lần gán là hợp lý, còn xử lý để gán như thế nào là vấn đề khác, không phải số lần gán mảng vào Cells
 
Upvote 0
Anh batman1 cũng chỉ đoán thôi chứ cũng không có cơ sở.
Đoán là khi nói về cách gán xuống sheet.

Còn chuyện là sự kiện sảy ra 1 lần thì rõ ràng mà.

Tôi chỉ thắc mắc là có khái niệm "cùng lúc" (Tất cả các ô cùng lúc) nhưng không có định nghĩa khái niêm đó. Vì làm gì có cùng lúc với cách hiểu là 1 thời điểm - 1 vị trí trên trục thời gian? Vì mảng đập xuống sheet là cả 1 quá trình, mảng càng lớn thì thời gian đập xuống sheet càng lớn. Vd. mảng đập xuống sheet trong quá trình 0,5 s thì rõ ràng ở mọi thời điểm t, với t < 0,5 thì vùng "chưa đầy". Không có thời điểm t < 0,5 s nào mà tất cả các ô trong vùng đều có giá trị.

Còn chuyện mọi calculation chỉ được thực hiện khi toàn bộ mảng được nhập xuống sheet xong thì là điều tôi chắc chắn chứ không phải đoán mò. Và có thể cho vd. để chứng tỏ điều này.

Còn về cách thức nhập vào từng ô thì tôi mới đoán mò là nhập theo từng cột. Tuy là đoán mò nhưng cũng phải có cơ sở, đúng hay sai, cho cái đoán mò đó. Không phải đoán mò trên cơ sở tung đồng xu. Trong VBA chỉ được phép Redim Preserve với thay đổi số cột. Vì mảng được ghi theo từng cột. Có thể viết 1 lệnh đề copy toàn bộ 1 cột sang 1 mảng 1 chiều nhưng không viết được 1 lệnh để copy cả dòng sang mảng 1 chiều.
 
Lần chỉnh sửa cuối:
Upvote 0
Đoán là khi nói về cách gán xuống sheet.

Còn chuyện là sự kiện sảy ra 1 lần thì rõ ràng mà.

Tôi chỉ thắc mắc là có khái niệm "cùng lúc" (Tất cả các ô cùng lúc) nhưng không có định nghĩa khái niêm đó. Vì làm gì có cùng lúc với cách hiểu là 1 thời điểm - 1 vị trí trên trục thời gian? Vì mảng đập xuống sheet là cả 1 quá trình, mảng càng lớn thì thời gian đập xuống sheet càng lớn. Vd. mảng đập xuống sheet trong quá trình 0,5 s thì rõ ràng ở mọi thời điểm t, với t < 0,5 thì vùng "chưa đầy". Không có thời điểm t < 0,5 s nào mà tất cả các ô trong vùng đều có giá trị.

Còn chuyện mọi calculation chỉ được thực hiện khi toàn bộ mảng được nhập xuống sheet xong thì là điều tôi chắc chắn chứ không phải đoán mò. Và có thể cho vd. để chứng tỏ điều này.

Còn về cách thức nhập vào từng ô thì tôi mới đoán mò là nhập theo từng cột. Tuy là đoán mò nhưng cũng phải có cơ sở, đúng hay sai, cho cái đoán mò đó. Không phải đoán mò trên cơ sở tung đồng xu. Trong VBA chỉ được phép Redim Preserve với thay đổi số cột. Vì mảng được ghi theo từng cột. Có thể viết 1 lệnh đề copy toàn bộ 1 cột sang 1 mảng 1 chiều nhưng không viết được 1 lệnh để copy cả dòng sang mảng 1 chiều.
Đúng vậy, khái niệm cùng lúc phải xem lại Vì máy tính không có khái niệm cùng lúc cùng thời điểm, chỉ là tương đối.
 
Upvote 0
Còn về cách thức nhập vào từng ô thì tôi mới đoán mò là nhập theo từng cột. Tuy là đoán mò nhưng cũng phải có cơ sở, đúng hay sai, cho cái đoán mò đó. Không phải đoán mò trên cơ sở tung đồng xu. Trong VBA chỉ được phép Redim Preserve với thay đổi số cột. Vì mảng được ghi theo từng cột. Có thể viết 1 lệnh đề copy toàn bộ 1 cột sang 1 mảng 1 chiều nhưng không viết được 1 lệnh để copy cả dòng sang mảng 1 chiều.
Thì em nói anh đoán không có cơ sở là nói thứ tự theo cột này.
Đáp án em cho là đúng là đáp án số 2 (Từ trái qua phải, từ trên xuống dưới ) dựa vào kết quả của đoạn code sau:
Mã:
Sub Test()
Dim i As Long, j As Long
Dim Arr(1 To 10, 1 To 2)
For i = 1 To 10
    For j = 1 To 2
        Arr(i, j) = Cells(i, j).Address(0, 0)
    Next
Next
Arr(4, 2) = "=()"
[A1:B10].Value = Arr
End Sub
 
Upvote 0
Lúc đầu tôi ngỡ câu lệnh gán mảng xuống sheet là atomic (trọn vẹn, không tách ra từng giai đoạn được). Và nếu thế thì ngang hay dọc tuỳ theo thiết kế map giữa mảng và bảng tính: mảng là cột-dòng, bảng tính là dòng-cột. Và thiết kế này nằm bên trong nội bộ:
- Excel không phải là mã nguồn mở. Nếu MS không cho biết trong tài liệu của họ thì chịu. (luật mã nguồn mở)
- Range là một đối tượng hoàn toàn. Lệnh gán là hàm nội bộ của range. Range hoàn toàn có quyền thay đổi cách hoạt động bên trong của nó, tuỳ theo phiên bản. (luật hướng đối tượng)

Tuy nhiên, tét code ở bài #1377 cho thấy MS tệ hơn mình nghĩ. Câu lệnh gán cuối cùng không phải là atomic. Nếu nó atomic thì nó phải có các tính chất sau:
i) kết thúc một loạt, nếu giữa chừng không tiếp tục được thì phải lùi về chỗ cũ, trước khi gán. HOẶC
ii) bắt lỗi liên tục, nếu giữa chừng bị lỗi thì vẫn tiếp tục lướt qua cho đến hết.

Tại sao tôi cho là MS tệ? Vì nếu câu lệnh gán không atomic thì đáng lẽ họ phải:
1. cho biết trong tài liệu, VÀ
2. cho tuỳ chọn, lỗi thì dừng lại, hoặc tiếp tục đi đến hết. (đòi hỏi phải lộn về đầu trước khi gán có lẽ hơi khó)
 
Upvote 0
Thêm câu nữa: Chia 1 cột thành nhiều cột không dùng vòng lặp, không dùng công thức (Viết code để thực hiện giống như file đính kèm mà không dùng vòng lặp, không dùng công thức)
 

File đính kèm

Upvote 0
Thêm câu nữa: Chia 1 cột thành nhiều cột không dùng vòng lặp, không dùng công thức (Viết code để thực hiện giống như file đính kèm mà không dùng vòng lặp, không dùng công thức)
Đã vò đầu bứt tóc mấy giờ chưa tìm được thuật toán.
Hóng.
 
Upvote 0

File đính kèm

Upvote 0
Vô tình phát hiện và cũng không hiểu vì sao nó lại hoạt động như vậy luôn.
Nếu suy nghĩ một cách thông thường chắc không thể nào có đáp án cho câu đố này :D
Hay thật, tại sao đổ dữ liệu mảng xuống Range không theo quy tắc kích thước như vậy nhỉ?
Do Redim Preserve?
Chưa hiểu được cái này: Range(C1,C1:S6).Value = Mang, ai giải thích giùm.
 
Lần chỉnh sửa cuối:
Upvote 0
Vô tình phát hiện và cũng không hiểu vì sao nó lại hoạt động như vậy luôn.
Nếu suy nghĩ một cách thông thường chắc không thể nào có đáp án cho câu đố này :D
Mạnh thấy hay đó ... Ứng dụng viết cái Hàm Co và Giản phù hợp đấy !!!
 
Upvote 0
Hay thật, tại sao đổ dữ liệu mảng xuống Range không theo quy tắc kích thước như vậy nhỉ?
Do Redim Preserve?
Chưa hiểu được cái này: Range(C1,C1:S6).Value = Mang, ai giải thích giùm.
Theo mình thấy thì khi gán dữ liệu bằng cú pháp như vậy thì vùng thứ hai (C1:S6) sẽ có kết quả như vậy, vùng phía trước sẽ có kết quả bình thường, ô C1 trước dấu phẩy để vào để làm "chân gỗ" thôi.
 
Upvote 0
Cũng đơn giản thôi! Thuật toán dựa vào hàm FILES của macro4, nó có khả năng lấy list file trong 1 thư mục mà không cần vòng lập:
PHP:
Sub ConsolMutiFiles(Folder As String, ShName As String, SrcRng As String, Target As Range)
  Dim Temp As String
  Temp = ShName & "'!" & Range(SrcRng).Address(, , 2)
  If Right(Folder, 1) <> "\" Then Folder = Folder & "\"
  ActiveWorkbook.Names.Add "Arr", "=""'" & Folder & "[""&Files(""" & Folder & "*.*"")&""]" & Temp & """"
  Target.Consolidate Evaluate("Arr"), 9, 0, 1
  ActiveWorkbook.Names("Arr").Delete
End Sub
PHP:
Sub Test()
  Dim Folder As String, ShName As String, SrcRng As String
  Range("A2:B1000").ClearContents
  With CreateObject("Shell.Application")
    On Error Resume Next
    Folder = .BrowseForFolder(0, "", 1).Self.Path
  End With
  ShName = "Sheet1": SrcRng = "A2:B30"
  ConsolMutiFiles Folder, ShName, SrcRng, Range("A2")
End Sub
Vụ bẩy lỗi gì đó các bạn tự làm nha!
Cho em hỏi trường hợp ví dụ của em thì code thế nào anh? vì chạy ghi macro thì có nhưng để tối ưu hóa thành code thì chưa được, các anh, chị giúp em xem bài với!
 

File đính kèm

Upvote 0
Được bữa thứ 7 không có gì làm, thôi thư giãn tí.
--
Thông báo trong code bên dưới có thể xuất hiện không? Cho ví dụ.
Mã:
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
    If Not Sh Is ActiveSheet Then MsgBox "!@#$%"
End Sub
 
Upvote 0
Được bữa thứ 7 không có gì làm, thôi thư giãn tí.
--
Thông báo trong code bên dưới có thể xuất hiện không? Cho ví dụ.
Mã:
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
    If Not Sh Is ActiveSheet Then MsgBox "!@#$%"
End Sub
Xuất hiện nếu như tại 1 sheet bất kỳ trong Workbook đó ta thêm code này, rồi chọn sheet đó.
Mã:
Private Sub Worksheet_Activate()
  Me.Visible = xlSheetHidden
End Sub
 
Upvote 0
Xuất hiện nếu như tại 1 sheet bất kỳ trong Workbook đó ta thêm code này, rồi chọn sheet đó.
Mã:
Private Sub Worksheet_Activate()
  Me.Visible = xlSheetHidden
End Sub
Cũng coi như là 1 đáp án. Nhưng sử dụng cùng 1 sự kiện như vậy cũng giống như viết thêm code vào (như code bên dưới) thì chưa "vui" lắm :D
Mã:
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
    If Sh.Name = "Sheet1" Then Sh.Visible = xlSheetHidden
    If Not Sh Is ActiveSheet Then MsgBox "!@#$%"
End Sub
 
Upvote 0
Cũng đã lâu rồi, topic này không thấy hoạt động, giờ mình khởi động lại cho vui xuân nhé.
Câu đố này có lẽ đơn giản với một số người, nhưng cũng sẽ khó khăn cho đa số người nè.

Tôi có một TextBox trên UserForm, bằng thuật toán nào, thủ tục nào, sự kiện nào để khi tôi gõ phím nó chỉ ra đúng 1 ký tự dù có nhấn lâu phím đó.

Lưu ý, không phải gõ một ký tự mà gõ bao nhiêu cũng được, nhưng mỗi lần gõ dù có bị kẹt phím (nhấn lâu) nó vẫn chỉ ra 1 ký tự mà thôi.

Xin mời.
 
Lần chỉnh sửa cuối:
Upvote 0
Cũng đã lâu rồi, topic này không thấy hoạt động, giờ mình khởi động lại cho vui xuân nhé.
Câu đố này có lẽ đơn giản với một số người, nhưng cũng sẽ khó khăn cho đa số người nè.

Tôi có một TextBox trên UserForm, bằng thuật toán nào, thủ tục nào, sự kiện nào để khi tôi gõ phím nó chỉ ra đúng 1 ký tự dù có nhấn lâu phím đó.

Xin mời.
Em mò thế này
Mã:
Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
TextBox1.Text = Left(TextBox1.Text, 0)
End Sub
 
Upvote 0
Em mò thế này
Mã:
Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
TextBox1.Text = Left(TextBox1.Text, 0)
End Sub
Rất OK, nhưng rất tiếc nó chỉ gõ được đúng 1 ký tự, các ký tự sau không gõ tiếp được! Ý mình là mỗi lần gõ dù có bị kẹt phím vẫn chỉ cho ra 1 ký tự thôi.
 
Upvote 0
Rất OK, nhưng rất tiếc nó chỉ gõ được đúng 1 ký tự, các ký tự sau không gõ tiếp được! Ý mình là mỗi lần gõ dù có bị kẹt phím vẫn chỉ cho ra 1 ký tự thôi.
Em lại thêm 1 cách "tà đạo" này nữa
"Sự kiện Click CommandButton1"
Mã:
Private Sub CommandButton1_Click()
    Dim i&, txt$
    txt = Left(TextBox1.Text, 1)
    For i = 1 To Len(TextBox1.Text)
        If Mid(TextBox1.Text, i + 1, 1) <> Mid(TextBox1.Text, i, 1) Then
            txt = txt & Mid(TextBox1.Text, i + 1, 1)
        End If
    Next i
    TextBox1.Text = txt
End Sub
 
Upvote 0
Em lại thêm 1 cách "tà đạo" này nữa
"Sự kiện Click CommandButton1"
Mã:
Private Sub CommandButton1_Click()
    Dim i&, txt$
    txt = Left(TextBox1.Text, 1)
    For i = 1 To Len(TextBox1.Text)
        If Mid(TextBox1.Text, i + 1, 1) <> Mid(TextBox1.Text, i, 1) Then
            txt = txt & Mid(TextBox1.Text, i + 1, 1)
        End If
    Next i
    TextBox1.Text = txt
End Sub
Kakaka, đúng là "đông tà" thiệt, nhưng mình chỉ dùng 1 TextBox thôi, không có click mà chỉ gõ phím.
 
Upvote 0
Upvote 0
Lần chỉnh sửa cuối:
Upvote 0

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

Back
Top Bottom