Giúp đỡ về macro chạy không ổn định khi coppy từ file này sang file khác

Liên hệ QC

fukagawa

Thành viên mới
Tham gia
3/10/19
Bài viết
24
Được thích
4
Chào cả nhà
- Do nhu cầu công việc em cần macro nhân viên phải nhập dữ liệu trong cột F thì file mới mở lock cho nhân viên nhập nội dung vào cột A,B,C,D,E, nếu xoá dữ liệu trong cột F đi file sẽ lock cột A,B,C,D,E lại. Em lên diễn đàn tham khảo và sửa công thức theo nhu cầu của em, khi thử trên file excel tạo mới thì macro chạy ổn nhưng khi em coppy công thức vào file làm việc chính thì nó lại bị tình trạng khi em xoá nội dung trong cột F thì file không lock lại cột A,B,C,D,E. Do file chính là file làm việc chung trong file có công thức của người khác tạo để làm việc nên không thể lấy file excel tạo mới để thay được
- Em đính kèm lên 2 file, file ok là file excel em tạo mới test công thức chạy ổn và file not ok là file làm việc chính công thức chưa ổn. Mong mọi người giúp đỡ
- Cám ơn mọi người
 

File đính kèm

  • not ok.xlsm
    59.4 KB · Đọc: 4
  • ok.xlsm
    52 KB · Đọc: 4
Chào cả nhà
- Do nhu cầu công việc em cần macro nhân viên phải nhập dữ liệu trong cột F thì file mới mở lock cho nhân viên nhập nội dung vào cột A,B,C,D,E, nếu xoá dữ liệu trong cột F đi file sẽ lock cột A,B,C,D,E lại. Em lên diễn đàn tham khảo và sửa công thức theo nhu cầu của em, khi thử trên file excel tạo mới thì macro chạy ổn nhưng khi em coppy công thức vào file làm việc chính thì nó lại bị tình trạng khi em xoá nội dung trong cột F thì file không lock lại cột A,B,C,D,E. Do file chính là file làm việc chung trong file có công thức của người khác tạo để làm việc nên không thể lấy file excel tạo mới để thay được
- Em đính kèm lên 2 file, file ok là file excel em tạo mới test công thức chạy ổn và file not ok là file làm việc chính công thức chưa ổn. Mong mọi người giúp đỡ
- Cám ơn mọi người
Bạn nên đổi tiêu đề về chữ thường cho phù hợp Nội quy nhé.
 
Chào cả nhà
- Do nhu cầu công việc em cần macro nhân viên phải nhập dữ liệu trong cột F thì file mới mở lock cho nhân viên nhập nội dung vào cột A,B,C,D,E, nếu xoá dữ liệu trong cột F đi file sẽ lock cột A,B,C,D,E lại. Em lên diễn đàn tham khảo và sửa công thức theo nhu cầu của em, khi thử trên file excel tạo mới thì macro chạy ổn nhưng khi em coppy công thức vào file làm việc chính thì nó lại bị tình trạng khi em xoá nội dung trong cột F thì file không lock lại cột A,B,C,D,E. Do file chính là file làm việc chung trong file có công thức của người khác tạo để làm việc nên không thể lấy file excel tạo mới để thay được
- Em đính kèm lên 2 file, file ok là file excel em tạo mới test công thức chạy ổn và file not ok là file làm việc chính công thức chưa ổn. Mong mọi người giúp đỡ
- Cám ơn mọi người
Bạn đâu có chép code sự kiện Worksheet_Change vào file làm việc chính của bạn đâu mà lock cell chạy được
 
Bạn đâu có chép code sự kiện Worksheet_Change vào file làm việc chính của bạn đâu mà lock cell chạy được
- Dạ em có thêm rồi anh xem dùm em công thức này có vần đề gì không ạ:

PHP:
Option Explicit



Private Sub Worksheet_Change(ByVal Target As Range)

If Not Intersect(Target, Range("F4:F100")) Is Nothing Then

Call locked

End If

End Sub

Public Sub locked()

Dim Rng As Range, Cll As Range, Tem As Variant

ActiveSheet.Unprotect "8581"

With Sheet2

Set Rng = .Range(.[F4], .[F100].End(xlUp))

    Tem = ""

End With

    For Each Cll In Rng

        With Cll.Offset(, -5).Resize(, 5)

            If Cll.Value = Tem Then

                .locked = True

            Else

                .locked = False

            End If

        End With

    Next

Set Rng = Nothing

ActiveSheet.Protect "8581"

End Sub
 
- Dạ em có thêm rồi anh xem dùm em công thức này có vần đề gì không ạ:

PHP:
Option Explicit



Private Sub Worksheet_Change(ByVal Target As Range)

If Not Intersect(Target, Range("F4:F100")) Is Nothing Then

Call locked

End If

End Sub

Public Sub locked()

Dim Rng As Range, Cll As Range, Tem As Variant

ActiveSheet.Unprotect "8581"

With Sheet2

Set Rng = .Range(.[F4], .[F100].End(xlUp))

    Tem = ""

End With

    For Each Cll In Rng

        With Cll.Offset(, -5).Resize(, 5)

            If Cll.Value = Tem Then

                .locked = True

            Else

                .locked = False

            End If

        End With

    Next

Set Rng = Nothing

ActiveSheet.Protect "8581"

End Sub
Như trong file Not_ok của bạn thì đã có sẵn code Worksheet_Change rồi nên bạn cần đưa 3 dòng này vào cuối của thủ tục
If Not Intersect(Target, Range("F4:F100")) Is Nothing Then
Call locked
End If


Còn sub locked thì chép nguyên.
 
Như trong file Not_ok của bạn thì đã có sẵn code Worksheet_Change rồi nên bạn cần đưa 3 dòng này vào cuối của thủ tục
If Not Intersect(Target, Range("F4:F100")) Is Nothing Then
Call locked
End If


Còn sub locked thì chép nguyên.
Da em chưa hiểu khúc này, anh hướng dẫn thêm với. Em cám ơn
 
Da em chưa hiểu khúc này, anh hướng dẫn thêm với. Em cám ơn
Bạn có sẵn sub Worksheet_Change trong cái sheet title của file Not_ok rồi. Sub đó làm gì thì tôi không xem nhưng vì nó phải có tác dụng gì đó. Do vậy cần phải giữ các dòng code đó lại, chép 3 dòng mình muốn vào cuối sub (trước End Sub)
 
Bạn có sẵn sub Worksheet_Change trong cái sheet title của file Not_ok rồi. Sub đó làm gì thì tôi không xem nhưng vì nó phải có tác dụng gì đó. Do vậy cần phải giữ các dòng code đó lại, chép 3 dòng mình muốn vào cuối sub (trước End Sub)
Anh, em làm vẫn không được, thậm chí em thử xoá hết sub có sẵn trong file để 1 mình code của em ở sheet 2 mà vẫn không được, em thử ở ô F4 thì thấy A4,B4,C4,D4,E4 dòng này công thức unlock và lock lại chạy ổn định, không biết sub của em có vấn đề gì về khoảng thực hiện của công thức không
 
Anh, em làm vẫn không được, thậm chí em thử xoá hết sub có sẵn trong file để 1 mình code của em ở sheet 2 mà vẫn không được, em thử ở ô F4 thì thấy A4,B4,C4,D4,E4 dòng này công thức unlock và lock lại chạy ổn định, không biết sub của em có vấn đề gì về khoảng thực hiện của công thức không
À, tôi nhầm sheet2 với sheet1 (title). Để tôi xem lại code.

Giờ bạn mô tả lại, lấy 1 cell F8 làm ví dụ:
Nếu xóa dữ liệu tại F8 thì từ A8:E8 bị lock và khi điền dữ liệu vào F8 thì A8:E8 sẽ unlock? Hay là thế nào?
 
Lần chỉnh sửa cuối:
Bây giờ thế này nhé:
1. Xóa hoặc vô hiệu hóa code của sheet2.
2. UnProtect Sheet (mật khẩu là 8581) > quét chọn vùng từ A4:EXX (XX là dòng bất kỳ lớn hơn khối dữ liệu của bạn) > Format Cells > tại thẻ Protection chọn Locked.
3. Protect Sheet lại với MK 8581.
4. Gõ 1 ký tự bất kỳ vào cell FYY (miễn sao YY nhỏ hơn XX)
5. Chép lại hoặc cho code sheet2 có hiệu lực. Xong!

Việc gài ký tự bất kỳ đó tại 4 là tác giả code làm cho cả vùng A4:YY chịu tác động của code (nếu không có thì code chạy sai), còn việc đó hay dở thế nào tôi không bàn.
 
Bây giờ thế này nhé:
1. Xóa hoặc vô hiệu hóa code của sheet2.
2. UnProtect Sheet (mật khẩu là 8581) > quét chọn vùng từ A4:EXX (XX là dòng bất kỳ lớn hơn khối dữ liệu của bạn) > Format Cells > tại thẻ Protection chọn Locked.
3. Protect Sheet lại với MK 8581.
4. Gõ 1 ký tự bất kỳ vào cell FYY (miễn sao YY nhỏ hơn XX)
5. Chép lại hoặc cho code sheet2 có hiệu lực. Xong!

Việc gài ký tự bất kỳ đó tại 4 là tác giả code làm cho cả vùng A4:YY chịu tác động của code (nếu không có thì code chạy sai), còn việc đó hay dở thế nào tôi không bàn.
- Dạ không được anh ơi, chắc em đổi phương án, nghiên cứu khi cột B,C,D có dữ liệu mà không nhập cột F khi tắt file sẽ hiện msgbox báo cột F chưa nhập dữ liệu xem được không
- Cám ơn anh
 
chắc em đổi phương án,
Có chắc chưa? Lần cuối cùng đổi rồi chứ? :)

khi cột B,C,D có dữ liệu mà không nhập cột F khi tắt file sẽ hiện msgbox báo cột F chưa nhập dữ liệu

PHP:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
    Dim varCheck as variant
    varCheck  = KiemTraCotF(sheet1, "B2:F1000")
if not varCheck  = true then
msgbox varCheck , vbinformation
Cancel =true
End if
End Sub
PHP:
Function KiemTraCotF(byval ws as worksheets, byval strVungDulieu as string) as variant
'Tra ve True nếu thỏa điều kiện, ngược lại trả về thông báo dòng thuộc cột F chưa nhập dữ liệu'
'ws là worksheet có bảng dữ liệu cần kiểm tra'
'strVungDulieu là vùng dữ liệu cần kiểm tra'
KiemTraCotF =True

Dim data as variant, i as long, strCotF as string, bolBCD as boolean, iCol as long
Dim startRow as long
data =ws.range(strVungDulieu ).value2
startRow = ws.range(strVungDulieu ).cells(1,1).row
For i=1 to ubound(data,1)
bolBCD = False
For iCol = 1 to 3 'xét cột B,C,D'
if len(data(i, icol)) >0 Then
bolBCD = True
Exit for
end if
Next iCol

if bolBCD = True then 'Nếu 1 trong 3 cột B,C,D có dữ liệu thì xét tiếp cột F'
if len(data(i, 4)) = 0  Then 'Nếu cột F chưa NHẬP'
KiemTraCotF = "Dong " & i - startRow + 1 & "chua nhap du lieu!"
Exit function
End if
End if
Next i
End function
 
- Dạ không được anh ơi, chắc em đổi phương án, nghiên cứu khi cột B,C,D có dữ liệu mà không nhập cột F khi tắt file sẽ hiện msgbox báo cột F chưa nhập dữ liệu xem được không
- Cám ơn anh
Chắc bạn làm sai thứ gì đó chứ tôi làm được tại file Not_ok của bạn. Bạn xem file
 

File đính kèm

  • LockCells_Notok_fukagawa.xlsm
    57.2 KB · Đọc: 4
Có chắc chưa? Lần cuối cùng đổi rồi chứ? :)



PHP:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
    Dim varCheck as variant
    varCheck  = KiemTraCotF(sheet1, "B2:F1000")
if not varCheck  = true then
msgbox varCheck , vbinformation
Cancel =true
End if
End Sub
PHP:
Function KiemTraCotF(byval ws as worksheets, byval strVungDulieu as string) as variant
'Tra ve True nếu thỏa điều kiện, ngược lại trả về thông báo dòng thuộc cột F chưa nhập dữ liệu'
'ws là worksheet có bảng dữ liệu cần kiểm tra'
'strVungDulieu là vùng dữ liệu cần kiểm tra'
KiemTraCotF =True

Dim data as variant, i as long, strCotF as string, bolBCD as boolean, iCol as long
Dim startRow as long
data =ws.range(strVungDulieu ).value2
startRow = ws.range(strVungDulieu ).cells(1,1).row
For i=1 to ubound(data,1)
bolBCD = False
For iCol = 1 to 3 'xét cột B,C,D'
if len(data(i, icol)) >0 Then
bolBCD = True
Exit for
end if
Next iCol

if bolBCD = True then 'Nếu 1 trong 3 cột B,C,D có dữ liệu thì xét tiếp cột F'
if len(data(i, 4)) = 0  Then 'Nếu cột F chưa NHẬP'
KiemTraCotF = "Dong " & i - startRow + 1 & "chua nhap du lieu!"
Exit function
End if
End if
Next i
End function
dạ để em thử thêm cách này
Chắc bạn làm sai thứ gì đó chứ tôi làm được tại file Not_ok của bạn. Bạn xem file
dạ chắc em làm sai gì đó ở bước coppy 3 dòng code sub Worksheet_Change của em vào công thức sẵn có. để em làm thêm cách theo bộ code của anh befaint cho ông sếp lựa
Cám ơn 2 anh đã hỗ trợ
 
Có chắc chưa? Lần cuối cùng đổi rồi chứ? :)



PHP:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
    Dim varCheck as variant
    varCheck  = KiemTraCotF(sheet1, "B2:F1000")
if not varCheck  = true then
msgbox varCheck , vbinformation
Cancel =true
End if
End Sub
PHP:
Function KiemTraCotF(byval ws as worksheets, byval strVungDulieu as string) as variant
'Tra ve True nếu thỏa điều kiện, ngược lại trả về thông báo dòng thuộc cột F chưa nhập dữ liệu'
'ws là worksheet có bảng dữ liệu cần kiểm tra'
'strVungDulieu là vùng dữ liệu cần kiểm tra'
KiemTraCotF =True

Dim data as variant, i as long, strCotF as string, bolBCD as boolean, iCol as long
Dim startRow as long
data =ws.range(strVungDulieu ).value2
startRow = ws.range(strVungDulieu ).cells(1,1).row
For i=1 to ubound(data,1)
bolBCD = False
For iCol = 1 to 3 'xét cột B,C,D'
if len(data(i, icol)) >0 Then
bolBCD = True
Exit for
end if
Next iCol

if bolBCD = True then 'Nếu 1 trong 3 cột B,C,D có dữ liệu thì xét tiếp cột F'
if len(data(i, 4)) = 0  Then 'Nếu cột F chưa NHẬP'
KiemTraCotF = "Dong " & i - startRow + 1 & "chua nhap du lieu!"
Exit function
End if
End if
Next i
End function
- Anh ơi, anh có thể hoàn thành công thức vào sheet2 file em đính kèm, vùng dữ liệu cần xét: ("B4:F1000") và thêm công thức không cho save file (nếu được) nếu cố tình không nhập cột F được không ạ. Em cám ơn
 

File đính kèm

  • TEST.xlsm
    94.2 KB · Đọc: 2
Lần chỉnh sửa cuối:
Chắc bạn làm sai thứ gì đó chứ tôi làm được tại file Not_ok của bạn. Bạn xem file
Anh giúp em thêm chút nữa với, em đã khắc phục được lỗi theo hướng dẫn của anh, nhưng mà giờ nội dung trong cell A,B,C,D,E khi protect sheet em có chọn cho sử dụng các chức năng như format cell, insert row,...., thì chỉ sử dụng được 1 lần đầu. sau khi làm lại thao tác nhập và xoá nội dung trong cột F thi các chức năng format cell, insert row,.... không sử dụng được làm không chỉnh sửa size hay font chữ được. Anh có cách nào khắc phục vấn đề này không hỗ trợ em với. Em đang làm thêm cách của anh befaint mà chưa làm được nên phải làm tạm file này cho nhân viên có file làm việc trước
 
Anh giúp em thêm chút nữa với, em đã khắc phục được lỗi theo hướng dẫn của anh, nhưng mà giờ nội dung trong cell A,B,C,D,E khi protect sheet em có chọn cho sử dụng các chức năng như format cell, insert row,...., thì chỉ sử dụng được 1 lần đầu. sau khi làm lại thao tác nhập và xoá nội dung trong cột F thi các chức năng format cell, insert row,.... không sử dụng được làm không chỉnh sửa size hay font chữ được. Anh có cách nào khắc phục vấn đề này không hỗ trợ em với. Em đang làm thêm cách của anh befaint mà chưa làm được nên phải làm tạm file này cho nhân viên có file làm việc trước
Tôi sẽ xem nhưng trước hết bạn nên ghi macro việc protect sheet như mong muốn rồi lấy code đó để chỉnh sửa
 
Tôi sẽ xem nhưng trước hết bạn nên ghi macro việc protect sheet như mong muốn rồi lấy code đó để chỉnh sửa
- Dạ em cám ơn, em bổ sung code và file đính kèm
PHP:
Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("F4:F1000")) Is Nothing Then
Call locked
End If
End Sub
Public Sub locked()
Dim Rng As Range, Cll As Range, Tem As Variant
ActiveSheet.Unprotect "8581"
With Sheet2
Set Rng = .Range(.[F4], .[F1000].End(xlUp))
    Tem = ""
End With
    For Each Cll In Rng
        With Cll.Offset(, -5).Resize(, 5)
            If Cll.Value = Tem Then
                .locked = True
            Else
                .locked = False
            End If
        End With
    Next
Set Rng = Nothing
ActiveSheet.Protect "8581"
End Sub
 

File đính kèm

  • TEST.xlsm
    63.1 KB · Đọc: 2
Nếu bạn làm như tôi nói mà giải quyết được vấn đề thì mới nói, chứ giờ tôi không hiểu bạn bổ sung cái gì?!
 
Web KT
Back
Top Bottom