Cần giúp đỡ về VBA

Liên hệ QC

vovanthanh2602

Thành viên chính thức
Tham gia
29/10/19
Bài viết
83
Được thích
3
Giới tính
Nam
Đề bài.
1 là nhập data vào cột A gồm chuỗi kí tự dài 3 và 5 kí tự , nếu khác thì se báo" sai data", và phát âm thanh.
2 là nêu nhập data vào cột A mà trùng thì sẽ báo "trùng data".và phát âm thanh, ( 1 âm thanh dùng chung cho 2 trường hợp)
-em lam dc như vậy rồi . nhưng bị sai 1 số điểm.
Giup em phan nay voi.
-Sau khi nhap data dung vao cột A thi kich chuot cho nao no cung bao "sai data" het .
-Giup em dieu chinh lai la khi bao "sai data" minh nhan enter thi chuot tu nhay ve lai o do de minh nhap lai => hien tai khi minh nhan enter thi chuot no nhay xuong o ke tiep. ( trung data thi ok roi)
- em co vi du o sheet3 ve viec phat am thanh. ma ko bik long ghep sao de no vo duoc cung 1 sheet. giup e nha. thanks.
 

File đính kèm

  • Test1.xlsm
    19.9 KB · Đọc: 13
if Len(temp) <> 5 And Len(temp) <> 3
Thì điều kiện này luôn đúng dùng len(temp) có giá trị bằng bao nhiều
Và xem lại
- Chọn sự kiện là worksheet_change (không dùng Worksheet_SelectionChange)
- có cần sử dụng DIC không?
- cần xem xét tắt mở Application.EnableEvents không?
 
Lần chỉnh sửa cuối:
if Len(temp) <> 5 And Len(temp) <> 3
Thì điều kiện này luôn đúng
Và xem lại
- Chọn sự kiện là worksheet_change (không dùng Worksheet_SelectionChange)
- có cần sử dụng DIC không?
- cần xem xét tắt mở Application.EnableEvents không?


Bạn ơi, bạn có thể giúp mình dc ko. tại mình ko bik về VBA , minh cũng chỉ copy trên mạng vè thôi. mà ko bik chỉnh sửa. nên bạn giúp mình nhé. cảm ơn bạn nhìu .
 
1. Code theo yêu cầu phải phản ứng sau khi nhập liệu trong mỗi ô chứ không phải khi chọn ô. Vì thế phải dùng Worksheet_Change chứ không phải Worksheet_SelectionChange.

2. Code theo yêu cầu chỉ phản ứng khi nhập dữ liệu vào cột A. Vậy thì trước khi chơi cần kiểm tra xem vùng (vì có thể thay đổi nhiều ô cùng lúc bằng cách dán hàng loat) vừa thay đổi có là 1 ô hay không (ta phản ứng khi thay đổi 1 ô. Cái này là do thống nhất với nhau thôi) và có nằm trong cột A hay không. Nếu không thỏa thì không dọn đồ chơi ra chơi.
Vùng vừa có sự thay đổi chính là Target. Không phải nhờ vả gì anh ActiveCell để xác định.

3. Nếu đi tiếp thì:
- kiểm tra độ dài của ô vừa thay đổi và thông báo lỗi nếu cần.

- kiểm tra trùng lặp và thông báo nếu cần.

Để kiểm tra trùng lặp thì có thể dùng hàm Application.CountIf.

Code không làm việc gì lâu nên Application.ScreenUpdating = False không cần thiết. Tôi không xóa mà chỉ biến nó thành chú thích.

4. Mới học VBA thì nên học khai báo từng biến, và viết tường minh. Đừng học thói quen xấu của người khác. Vd. temp.Value thay cho temp.
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim lastRow As Long, badValue As Boolean, rng As Range
'On Error GoTo thoat
'    Application.ScreenUpdating = False
    
'    neu nhieu o thay doi hoac thay doi khong o cot A thi nghi choi
    If Target.Count > 1 Or Target.Column > 1 Then Exit Sub
'    neu la xoa du lieu thi nghi choi. Phai cho phap nguoi nhap kha nang xoa du lieu
    If IsEmpty(Target.Value) Then Exit Sub
'    kiem tra do dai chuoi
    If Len(Target.Value) <> 5 And Len(Target.Value) <> 3 Then
'        o vua thay doi co do dai khac 3 va 5. Thong bao
        MsgBox " SAI DATA"
        badValue = True
    End If
'    kiem tra trung lap
    With Sheet1
'        dong cuoi cung co du lieu
        lastRow = .Range("A" & Rows.Count).End(xlUp).Row
'        neu lastRow = 1 thi khong kiem tra vi chi co 1 du lieu nen khong co chuyen trung lap
        If lastRow > 1 Then
'            vung du lieu can kiem tra
            Set rng = .Range("A1:A" & lastRow)
'            neu co trung thi thuc hien
            If Application.CountIf(rng, Target.Value) > 1 Then
'                du lieu vua nhap da xuat hien. Thong bao
                MsgBox " TRUNG DATA"
                badValue = True
            End If
        End If
    End With
    If badValue Then
'        du lieu vua nhap sai hoac trung. Vay xoa du lieu
'        "Tat" phuc vu su kien Change vi neu khong thi khi xoa du lieu nhap sai hoac trung thi lai say ra
'        su kien Change -> code lai duoc thuc hien.
        Application.EnableEvents = False
        Target.Value = Empty
        Application.EnableEvents = True
    End If
    
'    Application.ScreenUpdating = True
End Sub
 
1. Code theo yêu cầu phải phản ứng sau khi nhập liệu trong mỗi ô chứ không phải khi chọn ô. Vì thế phải dùng Worksheet_Change chứ không phải Worksheet_SelectionChange.

2. Code theo yêu cầu chỉ phản ứng khi nhập dữ liệu vào cột A. Vậy thì trước khi chơi cần kiểm tra xem vùng (vì có thể thay đổi nhiều ô cùng lúc bằng cách dán hàng loat) vừa thay đổi có là 1 ô hay không (ta phản ứng khi thay đổi 1 ô. Cái này là do thống nhất với nhau thôi) và có nằm trong cột A hay không. Nếu không thỏa thì không dọn đồ chơi ra chơi.
Vùng vừa có sự thay đổi chính là Target. Không phải nhờ vả gì anh ActiveCell để xác định.

3. Nếu đi tiếp thì:
- kiểm tra độ dài của ô vừa thay đổi và thông báo lỗi nếu cần.

- kiểm tra trùng lặp và thông báo nếu cần.

Để kiểm tra trùng lặp thì có thể dùng hàm Application.CountIf.

Code không làm việc gì lâu nên Application.ScreenUpdating = False không cần thiết. Tôi không xóa mà chỉ biến nó thành chú thích.

4. Mới học VBA thì nên học khai báo từng biến, và viết tường minh. Đừng học thói quen xấu của người khác. Vd. temp.Value thay cho temp.
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim lastRow As Long, badValue As Boolean, rng As Range
'On Error GoTo thoat
'    Application.ScreenUpdating = False
  
'    neu nhieu o thay doi hoac thay doi khong o cot A thi nghi choi
    If Target.Count > 1 Or Target.Column > 1 Then Exit Sub
'    neu la xoa du lieu thi nghi choi. Phai cho phap nguoi nhap kha nang xoa du lieu
    If IsEmpty(Target.Value) Then Exit Sub
'    kiem tra do dai chuoi
    If Len(Target.Value) <> 5 And Len(Target.Value) <> 3 Then
'        o vua thay doi co do dai khac 3 va 5. Thong bao
        MsgBox " SAI DATA"
        badValue = True
    End If
'    kiem tra trung lap
    With Sheet1
'        dong cuoi cung co du lieu
        lastRow = .Range("A" & Rows.Count).End(xlUp).Row
'        neu lastRow = 1 thi khong kiem tra vi chi co 1 du lieu nen khong co chuyen trung lap
        If lastRow > 1 Then
'            vung du lieu can kiem tra
            Set rng = .Range("A1:A" & lastRow)
'            neu co trung thi thuc hien
            If Application.CountIf(rng, Target.Value) > 1 Then
'                du lieu vua nhap da xuat hien. Thong bao
                MsgBox " TRUNG DATA"
                badValue = True
            End If
        End If
    End With
    If badValue Then
'        du lieu vua nhap sai hoac trung. Vay xoa du lieu
'        "Tat" phuc vu su kien Change vi neu khong thi khi xoa du lieu nhap sai hoac trung thi lai say ra
'        su kien Change -> code lai duoc thuc hien.
        Application.EnableEvents = False
        Target.Value = Empty
        Application.EnableEvents = True
    End If
  
'    Application.ScreenUpdating = True
End Sub

Cảm ơn bạn đã chiếu cố.
Nhưng mình muốn khi nhập sai data bảng thông báo hiện ra sau đó mình nhấn enter thì con chuột về lại ô vừa nhập để mình nhập tiếp vào ô đó chứ ko muốn trỏ chuột nhảy xuống ô kế tiếp,như vậy mất công mình phải đưa chuột về lại ô vừa nhập sai. bạn giup mình lun được ko. thanks.
 
Lần chỉnh sửa cuối:
Cảm ơn bạn đã chiếu cố.
Nhưng mình muốn khi nhập sai data bảng thông báo hiện ra sau đó mình nhấn enter thì con chuột về lại ô vừa nhập để mình nhập tiếp vào ô đó chứ ko muốn trỏ chuột nhảy xuống ô kế tiếp,như vậy mất công mình phải đưa chuột về lại ô vừa nhập sai. bạn giup mình lun được ko. Cảm ơn.
Có gì đâu bạn. Nhiệm vụ của tôi là phải chiếu cố bạn vì gia đình bạn là gia đình có công với cách mạng mà. :D

Sau dòng
Mã:
Target.Value = Empty
thì thêm dòng
Mã:
Target.Select
 
Lần chỉnh sửa cuối:
Sau dòng
Mã:
Target.Value = Empty
thì thêm dòng
Mã:
Target.Select


Bạn ơi. Mình rất cần code này.nhưng thiếu cái cảnh báo âm thanh. Nếu bạn giúp mình code này ok .mình sẽ hậu tạ.
Sau dòng
Mã:
Target.Value = Empty
thì thêm dòng
Mã:
Target.Select


Bạn ơi. Mình rất cần code này.nhưng thiếu cái cảnh báo âm thanh. Nếu bạn giúp mình code này ok .mình sẽ hậu tạ.
khi bảng thông báo hiện lên thì đi kèm phát âm thanh cảnh báo .
Sau dòng
Mã:
Target.Value = Empty
thì thêm dòng
Mã:
Target.Select


bạn ơi.mình rất cần doạn code này. bạn giúp mình thêm phần đi kèm bảng thông báo hiện lên thì phát 1 âm thanh cảnh báo . 1 âm thanh dùng chung cho cả 2 trường hợp trên. nếu ok mình sẽ hậu tạ . bạn giúp mình nha , cam on ban nhiu
 
Nội dung âm thanh là gì? Bạn có 1 tập tin âm thanh nào đó?
 
Thế này có được không? Text "Bad data" bạn có thể thay bằng đoạn text khác.

Sau Target.Select thêm Application.Speech.Speak "Bad data"

Hoặc dùng hàm API PlaySound hoặc mciSendString

Đối với bạn đơn giản nhất là speak ở trên.
 
Lần chỉnh sửa cuối:
Thế này có được không? Text "Bad data" bạn có thể thay bằng đoạn text khác.

Sau Target.Select thêm Application.Speech.Speak "Bad data"


Doạn text ntn là nó đọc như thế đó hả bạn. Tại mình muốn phát 1 âm có đuôi.wav lun. Giống trong file mình gửi trong sheet 3 có đoạn code phát âm thanh ak. Như vậy là được
Bài đã được tự động gộp:

Doạn text ntn là nó đọc như thế đó hả bạn. Tại mình muốn phát 1 âm có đuôi.wav lun. Giống trong file mình gửi trong sheet 3 có đoạn code phát âm thanh ak. Như vậy là được

Bạn ơi mình muốn khi bảng thông báo hiện lên là nó phát âm thanh lun. chứ ko phải đợi mình nhấn enter để tắt bảng thông báo nó ms phát âm thanh.( vì khi mình nhập mình ko cần nhìn màn hình , khi nào nhập sai nó phát âm báo để mình bik để mình nhập lại ak)
 
Lần chỉnh sửa cuối:
Doạn text ntn là nó đọc như thế đó hả bạn.
Những cái gì bạn tự kiểm tra được thì đừng hỏi
Tại mình muốn phát 1 âm có đuôi.wav lun. Giống trong file mình gửi trong sheet 3 có đoạn code phát âm thanh ak. Như vậy là được
Nếu muốn thế thì sau Target.Select thêm dòng
Mã:
Call sndPlaySound32("C:\Windows\Media\Windows Logon.wav", 1)

Ở trên cùng thì có như Sheet3, tức
Mã:
Private Declare Function sndPlaySound32 Lib "winmm.dll" _
Alias "sndPlaySoundA" (ByVal lpszSoundName _
As String, ByVal uFlags As Long) As Long
 
Những cái gì bạn tự kiểm tra được thì đừng hỏi

Nếu muốn thế thì sau Target.Select thêm dòng
Mã:
Call sndPlaySound32("C:\Windows\Media\Windows Logon.wav", 1)

Ở trên cùng thì có như Sheet3, tức
Mã:
Private Declare Function sndPlaySound32 Lib "winmm.dll" _
Alias "sndPlaySoundA" (ByVal lpszSoundName _
As String, ByVal uFlags As Long) As Long


mình thêm vào mà nó báo lỗi. mình gửi bạn file. bạn sửa giúp mình nha.
với lại mình muốn khi bảng thông báo hiện lên là nó phát âm thanh lun. chứ ko phải đợi mình nhấn enter để tắt bảng thông báo nó ms phát âm thanh.( vì khi mình nhập mình ko cần nhìn màn hình , khi nào nhập sai nó phát âm báo để mình bik để mình nhập lại ak)
 

File đính kèm

  • Test1.xlsm
    15.4 KB · Đọc: 5
Bạn ơi mình muốn khi bảng thông báo hiện lên là nó phát âm thanh lun. chứ ko phải đợi mình nhấn enter để tắt bảng thông báo nó ms phát âm thanh.( vì khi mình nhập mình ko cần nhìn màn hình , khi nào nhập sai nó phát âm báo để mình bik để mình nhập lại ak)
Hoặc là phát âm thanh trước hoặc sau MsgBox chứ khi hiện MsgBox thì code dừng ở đó cho tới tận khi bạn nhấn Enter nó mới đi tiếp nên không có chuyện phát âm thanh sau khi hiện MsgBox nhưng trước khi bạn nhấn Enter. Mà nếu không muốn nhìn màn hình thì bỏ MsgBox đi thôi.
Nếu muốn phát âm thanh trước MsgBox thì chuyển Application.Speech.Speak "Bad data" hoặc Call sndPlaySound32("C:\Windows\Media\Windows Logon.wav", 1) lên trước dòng có MsgBox (ở 2 chỗ). Thế thôi.
Bài đã được tự động gộp:

mình thêm vào mà nó báo lỗi. mình gửi bạn file. bạn sửa giúp mình nha.
 

File đính kèm

  • moinhatTest1.xlsm
    13.1 KB · Đọc: 15
Lần chỉnh sửa cuối:
Hoặc là phát âm thanh trước hoặc sau MsgBox chứ khi hiện MsgBox thì code dừng ở đó cho tới tận khi bạn nhấn Enter nó mới đi tiếp nên không có chuyện phát âm thanh sau khi hiện MsgBox nhưng trước khi bạn nhấn Enter. Mà nếu không muốn nhìn màn hình thì bỏ MsgBox đi thôi.
Nếu muốn phát âm thanh trước MsgBox thì chuyển Application.Speech.Speak "Bad data" hoặc Call sndPlaySound32("C:\Windows\Media\Windows Logon.wav", 1) lên trước dòng có MsgBox (ở 2 chỗ). Thế thôi.
Bài đã được tự động gộp:

thanks bạn nha. ban cho minh xin so dt minh gui ban card dt nha. dùng mạng j lun.
 
Có câu chuyện thế này về chuyện "nhập sai thì phát âm thanh"

Phòng nọ có cô đòi hỏi cái phần mềm vô dữ liệu nó phải "bíp" một cái khi cô ta nhập sai. Người viết phần mềm này là bạn tôi.
Được một thời gian sau, cả phòng cùng làm việc với cô ta phát khùng luôn vì cứ đến lúc cô ta bắt tay vào việc thì cứ vài giây lại "bíp" một cái, chả cho ai yên ổn cả. Họ năn nỉ cô ta tắt cái ấy đi nhưng cô nhất định không với lý do "nếu tôi gõ sai, ai chịu trách nhiệm?"

Được một thời gian sau, chính cô ta lại nhờ người bạn tôi gỡ cái "bíp" ấy ra. Lý do: các người khác trong phòng dùng tiếng "bíp" để biết được là cô ta đang làm việc hay đang lướt mạng.
 
Không cần thiết đâu. Tôi đã viết rồi mà.

Bạn ơi. Cho mình hỏi . Thay vì mình nhập data vào cột A. Thì giờ mình nhập vào cột B . Nhưng mình thay đổi công thức từ A sang B xong mình nhập vào A nó vẫn chạy .bạn giúp mình nha.
 
Lần chỉnh sửa cuối:
Bạn ơi. Cho mình hỏi . Thay vì mình nhập data vào cột A. Thì giờ mình nhập vào cột B . Nhưng mình thay đổi công thức từ A sang B xong mình nhập vào A nó vẫn chạy .bạn giúp mình nha.
Máy tôi bị chặn từ đêm 2/11 đến hôm nay mới vào được.

Bạn sửa tổng cộng ở 3 dòng thành
Mã:
If Target.Count > 1 Or Target.Column <> 2 Then Exit Sub
...
lastRow = .Range("B" & Rows.Count).End(xlUp).Row
...
Set rng = .Range("B1:B" & lastRow)

Trong dòng đầu luôn có 1. Có 2 là do cột B có chỉ số 2. Cột A có chỉ số 1, cột C có chỉ số 3 v...v Lần sau đổi cột khác thì sửa cả 2 thành chỉ số cột cần thao tác.
 
Web KT
Back
Top Bottom