Hỏi đáp về VBA (các vấn đề căn bản nhất)

Liên hệ QC

havietchuong

Thành viên tiêu biểu
Tham gia
16/6/09
Bài viết
490
Được thích
570
Giới tính
Nam
Nghề nghiệp
Giáo viên tiểu học.
Tôi không biết đặt đặt câu hỏi này nơi nào cho đúng, xin gởi vào đây. Nếu có sai xin thông cảm cho người mới học VBA.
Trong 1 cửa sổ Module có thể ghi nhiều nhiều Macro và mỗi macro có thể ứng với 1 tổ hợp phím nào đó được không?
Tôi thử nhiều lần thì khi được khi không. Không biết nó thế nào? Trong tập tin sau có lỗi gì không trong cách ghi Macro? Cám ơn.
 

File đính kèm

  • baitap1.xls
    28 KB · Đọc: 244
Lần chỉnh sửa cuối:
Anh cho em ví dụ cụ thể được khộng! em cảm ơn.
Thôi đã có bài của thầy ptm0412, Thầy ptm0412 nói nếu loại trừ ít, như vậy nếu loại trừ nhiều thì giải quyết như thế nào ạ!
Nhiều là nhiều cở bao nhiêu? Bạn thử cho ví dụ xem
Nếu nhiều quá, ta có thể cho mấy thằng loại trừ ấy vào Dictionary, xong dùng phương thức Dic.Exists để xem biến chạy i có tồn tại trong Dic hay không... đại khái thế
 
Upvote 0
Nếu nhiều quá, ta có thể cho mấy thằng loại trừ ấy vào Dictionary, xong dùng phương thức Dic.Exists để xem biến chạy i có tồn tại trong Dic hay không... đại khái thế

Hì hì em thấy Dictionary và phương thức Dic.Exists còn cao quá đối với em.
Không biết có bài nào đơn giản & dễ hiểu về Dictionary thì thầy chỉ giùm, em có thấy các bài trên mạng nhưng còn khó hiểu quá! em cảm ơn.
 
Upvote 0
Hì hì em thấy Dictionary và phương thức Dic.Exists còn cao quá đối với em.
Không biết có bài nào đơn giản & dễ hiểu về Dictionary thì thầy chỉ giùm, em có thấy các bài trên mạng nhưng còn khó hiểu quá! em cảm ơn.
"Không có việc gì khó, chỉ sợ lòng không bền"
Chẳng nhẽ bạn thấy khó rồi xin rút lui sao? phải lao vào mới tiến bộ được chứ
MÌnh nói với bạn Dictionary rất hay và không khó hiểu lắm đâu (mình cũng mới học đây thôi) các anh chị sẵn sàng giúp bạn, khó đến đâu cứ hỏi
Tham khảo Link: http://www.giaiphapexcel.com/forum/showthread.php?60643-Tổng-quan-về-Dictionary
 
Lần chỉnh sửa cuối:
Upvote 0
Hì hì em thấy Dictionary và phương thức Dic.Exists còn cao quá đối với em.
Không biết có bài nào đơn giản & dễ hiểu về Dictionary thì thầy chỉ giùm, em có thấy các bài trên mạng nhưng còn khó hiểu quá! em cảm ơn.

Bạn có thể tập một ví dụ đơn giản về Dictionary là bạn lấy 1 bảng dữ liệu gồm nhiều cái tên ra, xong bạn dùng Dic để lọc thành những tên duy nhất. Như vậy bạn chỉ cần thực hiện các thao tác là
1/ Duyệt bảng, lấy từng phần tử đem ra coi trong Dic đã tồn tại chưa, bằng phương thức Exists
2/ Nếu tồn tại thì không làm gì, nếu không tồn tại thì cho vào Dic bằng phương thức Add
3/ Xuất Dic ra bằng cách xuất mảng Keys của nó.

Mình nghĩ ba bước cơ bản như vậy cũng rất dễ làm bạn à, bạn thử xem.
 
Upvote 0
Bạn có thể tập một ví dụ đơn giản về Dictionary là bạn lấy 1 bảng dữ liệu gồm nhiều cái tên ra, xong bạn dùng Dic để lọc thành những tên duy nhất. Như vậy bạn chỉ cần thực hiện các thao tác là
1/ Duyệt bảng, lấy từng phần tử đem ra coi trong Dic đã tồn tại chưa, bằng phương thức Exists
2/ Nếu tồn tại thì không làm gì, nếu không tồn tại thì cho vào Dic bằng phương thức Add
3/ Xuất Dic ra bằng cách xuất mảng Keys của nó.

Mình nghĩ ba bước cơ bản như vậy cũng rất dễ làm bạn à, bạn thử xem.




Hì hì có thể thành viên của mình đã up level rồi nên hết căn bản nhất rồi!
 
Upvote 0
Hồi trước có học lập trình cơ bản (Turbo Pascal 3.0) thầy dặn không nên thay đổi giá trị của biến điều khiển trong vòng lặp For To/Downto Do, vì thói quen này có thể dẫn đến các trường hợp bất thường.
Tôi vẫn quen dùng cách "cổ điển" khi phải nhảy băng qua các giá trị:
If i<>7 then (hoặc một điều kiện nào đó về i chẳng hạn)
... xử lý
End If
mặc dầu nó chậm hơn nhưng câu lệnh rõ ràng hơn.

Tôi cũng nghĩ là việc thay đổi i trong vòng lặp là thói quen lập trình xấu. Một vòng lặp dài mà có vài chỗ như thế thì code sẽ rất tối. Mà ai thừa hưởng nhưng code đó thì thì khổ lắm. Ông viết nhưng ông thôi việc rồii còn tôi ở lại tôi khổ mặc tôi?
Tôi không nhớ trong Turbo Pascal như thế nào nhưng trong Delphi (Object Pascal) thì không được phép thay đổi i trong vòng lặp. Nếu có thì code sẽ không compile được.
Vd. trong Delphi để nhẩy qua giá trị thì dễ thôi.
if i = 7 then continue; ' <-- vòng lặp tiếp theo
Hoặc viết như bạn.
Chắc trong Turbo Pascal cũng thế thôi.
 
Upvote 0
Cho em hỏi, Em giả sử vòng lặp For i=3 to 10 ( Nghĩa là i liên tục từ 3 đến 10) ...... Next


Còn trường hợp của em là i từ 3 đến 6 (bỏ 7) và từ 8 đến 10. Như vậy em có dùng For Next được không?
Em cảm ơn.

Tôi thường làm như vầy:

PHP:
Private Sub NhaySo()
    ''Nhay 1 so:
    For i = 3 To 10
        If i = 7 Then GoTo NextI
        Debug.Print i
NextI:
    Next
End Sub



Private Sub NhaySo1()
    ''Lay so le:
    For i = 1 To 10 Step 2
        Debug.Print i
    Next
End Sub



Private Sub NhaySo2()
    ''Lay so chan:
    For i = 2 To 10 Step 2
        Debug.Print i
    Next
End Sub



Private Sub NhaySo3()
    ''Lay 1, 2, 5, 6, 8 , 9, 10:
    For i = 1 To 10
        Select Case i
            Case 1, 2, 5, 6, 8 To 10: Debug.Print i
        End Select
    Next
End Sub

Bấm Ctrl+G để xem kết quả trong Immediate.
 
Lần chỉnh sửa cuối:
Upvote 0
Giúp em viết code: xóa phần nằm sau dấu "=" trong chuỗi
Ví dụ:
Móng: (1+2)*2 = 1
Chuyển thành:
Móng: (1+2)*2
 
Upvote 0
Giúp em viết code xoá giá trị sau dấu '="

Em gửi file bác xem giúp(sửa phần giá trị trong cột E)
Thank bác nhiều
 

File đính kèm

  • QT(mong 1).rar
    36.2 KB · Đọc: 11
Upvote 0
Em gửi file bác xem giúp(sửa phần giá trị trong cột E)
Thank bác nhiều

Bạn insert một cột phụ tại ô ở hàng 7 của cột phụ bạn đặt công thức:

=IF(ISERROR(LEFT(E7,FIND(" =",E7))),E7,LEFT(E7,FIND(" =",E7)))


Sau đó bạn chỉ việc copy giá trị của cột này rồi paste value qua cột Phần Móng.
 
Upvote 0
Hàm trên em thấy đang báo lỗi, mà nếu paste value thì sẽ mất giá trị trong các ô có tên đầu công việc (phần chỉ chứa text).
Bảng biểu khá nhiều và phải lặp lại công việc nên em muốn tạo macro cho thuận tiện (do mù mờ về code nên khó quá). Em gửi lên bác xem giúp em chèn thêm đoạn code xóa giá trị trên:
Sub TLDG()Dim i
For i = 8 To 4000
If (Cells(i, "E")) <> "" Then
If (Cells(i, "D")) = "" Then
Cells(i, "E").Select
' Doan code can them de xoa gia tri sau dau "=" trong Cell da duoc chon
Application.Run Range("Trasolieu")
End If
End If
Next i
End Sub
Đoạn code em cần có tác dụng:
Giá trị của ô được chọn (hàng i, cột E)= Giá trị của phần nằm trước dấu "=" trong chuỗi của ô được chọn (nếu có dấu "="
Hoặc nâng cao hơn, giúp e tạo macro:
Nếu đánh chuỗi giá trị có dấu '=" vào 1 ô được chọn (hàng i,cột E) thì tự đông xóa phần sau dấu "=" ngay khi nhập dữ liệu. Ví dụ:Khi đánh vào ô (hàng i, cột E)
Móng: 1+2 = 4
tự động chuyển thành:
Móng: 1+2 (xóa phần sau dấu "="
 
Lần chỉnh sửa cuối:
Upvote 0
Code này coi thế nào

Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 5 Then
Target.Replace "=*", ""
End If
End Sub
 
Upvote 0
Code này coi thế nào

Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 5 Then
Target.Replace "=*", ""
End If
End Sub
Cái này nếu để riêng thành 1 module, em bấm F5 sao lại ra bảng chọn macro (như thao tác bấm Alt+F8). Còn nếu để trong code chung thì nó báo lỗi
Sub TLDG()
Dim i
For i = 8 To 4000
If (Cells(i, "E")) <> "" Then
If (Cells(i, "D")) = "" Then
Cells(i, "E").Select
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 5 Then
Target.Replace "=*", ""
End If
End Sub
Application.Run Range("Trasolieu")
End If
End If
Next i
End Sub
 
Upvote 0
Code này coi thế nào

Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 5 Then
Target.Replace "=*", ""
End If
End Sub
Code của bac Quanghai giải quyết yêu cầu: nhập có dấu "=" thì bỏ phía sau
Còn nếu bạn muốn bỏ phần sau dấu "=" nếu cột D tương ứng rỗng thì có thể dùng cái này
PHP:
Sub GPE()
      For i = 6 To Cells(65536, 5).End(xlUp).Row    
         If Cells(i, 4) = "" Then Cells(i, 5).Replace "=*", ""
      Next
End Sub
 
Upvote 0
Cái này nếu để riêng thành 1 module, em bấm F5 sao lại ra bảng chọn macro (như thao tác bấm Alt+F8). Còn nếu để trong code chung thì nó báo lỗi

Nếu muốn viết thành 1 sub thì như thế này sẽ nhanh hơn cho dữ liệu nhiều
Nếu xử lý trên sheet thì chậm lắm

PHP:
Sub xoa_chuoi()
Dim i, kq()
kq = Range([E8], [E65536].End(3)).Offset(, -1).Resize(, 2).Value
With CreateObject("vbscript.regexp")
   .Global = True
   .Pattern = "=.*"
   For i = 1 To UBound(kq)
      If kq(i, 1) = "" Then
         If kq(i, 2) <> "" Then
            kq(i, 2) = .Replace(kq(i, 2), "")
         End If
      End If
   Next
End With
[D8].Resize(i - 1, 2) = kq
End Sub
 
Upvote 0
Nếu muốn viết thành 1 sub thì như thế này sẽ nhanh hơn cho dữ liệu nhiều
Nếu xử lý trên sheet thì chậm lắm

PHP:
Sub xoa_chuoi()
Dim i, kq()
kq = Range([E8], [E65536].End(3)).Offset(, -1).Resize(, 2).Value
With CreateObject("vbscript.regexp")
   .Global = True
   .Pattern = "=.*"
   For i = 1 To UBound(kq)
      If kq(i, 1) = "" Then
         If kq(i, 2) <> "" Then
            kq(i, 2) = .Replace(kq(i, 2), "")
         End If
      End If
   Next
End With
[D8].Resize(i - 1, 2) = kq
End Sub
Code của bác Quanghai có tốc độ giải quyết bài toán trên nhanh hơn nhiều so với code của bác dhn46.
Nhờ bác giải quyết triệt để bài toán này giúp e
Tạo ra 1 maco là tốt nhất (ưu tiến tốc độ vì bảng dữ liệu nhiều), gồm 2 tác dụng:
1. xoá phần giá trị nằm sau dấu "="
2. Trong giá trị có nhiều đoạn có nhiều "dấu cách", giúp e chuyển thành chỉ còn 1 dấu cách tại các vị trí tương ứng.
ví dụ:
Móng: 1+2 = 3 = 4 ('ban đầu, sau dấu ":" nhiều dấu cách, sau số "2" nhiều dấu cách ) (tác giả có thể hạn chế số dấu cách từ 1-9 hoặc 1-4 để ưu tiên tốc độ xử lý)
sau khi chuyển:
Móng: 1+2 ('sau dấu ":" chỉ còn 1 dấu cách, sau số 2 chỉ còn 1 dấu cách)
 
Lần chỉnh sửa cuối:
Upvote 0
Code của bác Quanghai có tốc độ giải quyết bài toán trên nhanh hơn nhiều so với code của bác dhn46.
Nhờ bác giải quyết triệt để bài toán này giúp e
Tạo ra 1 maco là tốt nhất (ưu tiến tốc độ vì bảng dữ liệu nhiều), gồm 2 tác dụng:
1. xoá phần giá trị nằm sau dấu "="
2. Trong giá trị có nhiều đoạn có nhiều "dấu cách", giúp e chuyển thành chỉ còn 1 dấu cách tại các vị trí tương ứng.
ví dụ:
Móng: 1+2 = 3 = 4 ('ban đầu, sau dấu ":" nhiều dấu cách, sau số "2" nhiều dấu cách ) (tác giả có thể hạn chế số dấu cách từ 1-9 hoặc 1-4 để ưu tiên tốc độ xử lý)
sau khi chuyển:
Móng: 1+2 ('sau dấu ":" chỉ còn 1 dấu cách, sau số 2 chỉ còn 1 dấu cách)

Chắc sợ up file lên rồi nghẽn mạng hay sao ấy.
PHP:
Sub xoa_chuoi()
Dim i, kq()
kq = Range([E8], [E65536].End(3)).Offset(, -1).Resize(, 2).Value
With CreateObject("vbscript.regexp")
   .Global = True
   .Pattern = "=.*"
   For i = 1 To UBound(kq)
      If kq(i, 1) = "" Then
         If kq(i, 2) <> "" Then
            kq(i, 2) = Trim(.Replace(kq(i, 2), "")) & " "
         End If
      End If
   Next
End With
[D8].Resize(i - 1, 2) = kq
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Xin viết code trong dự toán

Bác chỉnh giùm em để chuyển dạng dữ liệu tương tự ô E8 thành dạng dữ liệu giống ô E9
 
Upvote 0
Web KT
Back
Top Bottom