Mọi người cho mình hỏi cách để chèn Sendkeys vào vòng lặp với.
Mình có macro như sau: (xem thêm ảnh hoặc file)
Sub TestSendkeysLoop()
Cells(1, 1).CurrentRegion.Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues
a = 2
b = 2
Cells(a, b).Select
While Cells(a, b) <> ""
While Cells(a, b) <> ""
SendKeys "{f2}"
SendKeys "{enter}"
a = a + 1
Wend
a = 2
b = b + 1
Wend
End Sub
Khi viết macro thì mình tính là
từ ô B2 sẽ nhấn F2 rồi Enter,
cho đến ô B6 là ô trống thì sẽ chuyển lên ô C2 rồi lại F2 Enter cho đến ô C6,
rồi sẽ này lên ô D2 nhưng ô D2 là ô trắng nên macro sẽ dừng lại.
Nhưng khi chạy macro thì vòng lặp While đếm được 8 giá trị cho đến khi kết thúc
và F2 Enter được chạy 8 lần và macro kết thúc ở ô B10.
Mọi người cho mình hỏi cách để chèn Sendkeys vào vòng lặp với.
Mình có macro như sau: (xem thêm ảnh hoặc file)
Sub TestSendkeysLoop()
Cells(1, 1).CurrentRegion.Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues
a = 2
b = 2
Cells(a, b).Select
While Cells(a, b) <> ""
While Cells(a, b) <> ""
SendKeys "{f2}"
SendKeys "{enter}"
a = a + 1
Wend
a = 2
b = b + 1
Wend
End Sub
Khi viết macro thì mình tính là
từ ô B2 sẽ nhấn F2 rồi Enter,
cho đến ô B6 là ô trống thì sẽ chuyển lên ô C2 rồi lại F2 Enter cho đến ô C6,
rồi sẽ này lên ô D2 nhưng ô D2 là ô trắng nên macro sẽ dừng lại.
Nhưng khi chạy macro thì vòng lặp While đếm được 8 giá trị cho đến khi kết thúc
và F2 Enter được chạy 8 lần và macro kết thúc ở ô B10.
Tò mò là đúng. Vì trong trường hợp này bài #2 giải quyết được. Nhưng ở những bài khác bắt buộc phải dùng SendKeys, While, Do ... thì sao? Giả sử không có cách khác thì sao? Các bài trên GPE được viết không chỉ dành cho người hỏi mà còn cho rất nhiều người âm thầm đọc và học tập.
Trước tiên tôi chỉ ra cái sai rõ nhất của bạn.
Lỗi không phải do bỏ qua tham số thứ 2 của SendKeys. Dù thêm TRUE hay FALSE thì vẫn y nguyên thế thôi. Lỗi không ở chỗ đó. Mỗi người có thể tự kiểm nghiệm là thêm tham số thứ 2 chả giải quyết được gì.
Ở thời điểm chào buổi sáng thì code chọn B2: Cells(a, b).Select. SELECT chỉ được dùng 1 lần duy nhất trước khi vào vòng lặp. Sau đó là Chuỗi 8 (F2 + ENTER), mỗi lần ENTER là tự xuống ô bên dưới. Ở thời điểm b = 2, a = 6 có Cells(a, b) = Cells(6, 2) = B6 = "" (B6 đang được chọn) nên vòng lặp TRONG kết thúc -> a = 2, b = b + 1 = 3. Do Cells(a, b) = Cells(2,3) = C2 <> "" nên vào lại vòng lặp NGOÀI -> thực hiện Enter. Nhưng do không có SELECT nữa nên ô đang chọn vẫn đang là B6. Vì thế khi Enter thì xuống B7, tiếp theo lại Enter nên xuống B8, B9, B10.
Tóm lại ở thời điểm vào cột mới, tức B2, C2, D2, ... phải dùng SELECT để chọn các ô đó. Chọn B2 và do 4 Enter nên xuống các ô B3, B4, B5, B6, tiếp theo chọn C2 thì do 4 Enter nên lại xuống C3, C4, C5, C6.
Vậy phải chuyển Cells(a, b).Select vào sau vòng lặp NGOÀI và trước vòng lặp TRONG
Ta xét code
Mã:
Sub TestSendkeysLoop()
Cells(1, 1).CurrentRegion.Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues
a = 2
b = 2
While Cells(a, b) <> ""
Cells(a, b).Select
While Cells(a, b) <> ""
SendKeys "{f2}"
SendKeys "{enter}"
a = a + 1
Wend
a = 2
b = b + 1
Wend
End Sub
Để kiểm nghiệm các kết luận ở trên thì ta bắt xử lý ngay lập tức bằng cách dùng DoEvents.
Mã:
Sub TestSendkeysLoop()
Cells(1, 1).CurrentRegion.Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues
a = 2
b = 2
While Cells(a, b) <> ""
Cells(a, b).Select
While Cells(a, b) <> ""
SendKeys "{f2}"
SendKeys "{enter}"
DoEvents
a = a + 1
Wend
a = 2
b = b + 1
Wend
End Sub
Tò mò là đúng. Vì trong trường hợp này bài #2 giải quyết được. Nhưng ở những bài khác bắt buộc phải dùng SendKeys, While, Do ... thì sao? Giả sử không có cách khác thì sao? Các bài trên GPE được viết không chỉ dành cho người hỏi mà còn cho rất nhiều người âm thầm đọc và học tập.
Trước tiên tôi chỉ ra cái sai rõ nhất của bạn.
Lỗi không phải do bỏ qua tham số thứ 2 của SendKeys. Dù thêm TRUE hay FALSE thì vẫn y nguyên thế thôi. Lỗi không ở chỗ đó. Mỗi người có thể tự kiểm nghiệm là thêm tham số thứ 2 chả giải quyết được gì.
Ở thời điểm chào buổi sáng thì code chọn B2: Cells(a, b).Select. SELECT chỉ được dùng 1 lần duy nhất trước khi vào vòng lặp. Sau đó là Chuỗi 8 (F2 + ENTER), mỗi lần ENTER là tự xuống ô bên dưới. Ở thời điểm b = 2, a = 6 có Cells(a, b) = Cells(6, 2) = B6 = "" (B6 đang được chọn) nên vòng lặp TRONG kết thúc -> a = 2, b = b + 1 = 3. Do Cells(a, b) = Cells(2,3) = C2 <> "" nên vào lại vòng lặp NGOÀI -> thực hiện Enter. Nhưng do không có SELECT nữa nên ô đang chọn vẫn đang là B6. Vì thế khi Enter thì xuống B7, tiếp theo lại Enter nên xuống B8, B9, B10.
Tóm lại ở thời điểm vào cột mới, tức B2, C2, D2, ... phải dùng SELECT để chọn các ô đó. Chọn B2 và do 4 Enter nên xuống các ô B3, B4, B5, B6, tiếp theo chọn C2 thì do 4 Enter nên lại xuống C3, C4, C5, C6.
Vậy phải chuyển Cells(a, b).Select vào sau vòng lặp NGOÀI và trước vòng lặp TRONG
Ta xét code
Mã:
Sub TestSendkeysLoop()
Cells(1, 1).CurrentRegion.Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues
a = 2
b = 2
While Cells(a, b) <> ""
Cells(a, b).Select
While Cells(a, b) <> ""
SendKeys "{f2}"
SendKeys "{enter}"
a = a + 1
Wend
a = 2
b = b + 1
Wend
End Sub
Để kiểm nghiệm các kết luận ở trên thì ta bắt xử lý ngay lập tức bằng cách dùng DoEvents.
Mã:
Sub TestSendkeysLoop()
Cells(1, 1).CurrentRegion.Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues
a = 2
b = 2
While Cells(a, b) <> ""
Cells(a, b).Select
While Cells(a, b) <> ""
SendKeys "{f2}"
SendKeys "{enter}"
DoEvents
a = a + 1
Wend
a = 2
b = b + 1
Wend
End Sub
macro thứ 2 bạn ghi cho tôi không chạy đúng như ý muốn
nhưng tôi đã học được là có thể dùng Doevents để khiến sendkeys chạy theo thứ tự trong vòng lặp.
điều này thật sự rất hữu ích.
từ giờ tôi sẽ có thể tìm hiểu thêm cách hoạt động của sendkeys và luyện tập
macro thứ 2 bạn ghi cho tôi không chạy đúng như ý muốn
nhưng tôi đã học được là có thể dùng Doevents để khiến sendkeys chạy theo thứ tự trong vòng lặp.
điều này thật sự rất hữu ích.
từ giờ tôi sẽ có thể tìm hiểu thêm cách hoạt động của sendkeys và luyện tập