Chuyên mục xử lý, gỡ rối code VBA (1 người xem)

Liên hệ QC

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

Status
Không mở trả lời sau này.

ndu96081631

Huyền thoại GPE
Thành viên BQT
Super Moderator
Tham gia
5/6/08
Bài viết
30,703
Được thích
53,954
Đầu tiên hết thì kiểm soát hàm đệ quy.

Ngoại trừ trường hợp hàm đệ quy ra, có 3 lý do chính để một chương trình bị phình ra và "out of memory". Đây là danh sách có sự sắp xếp, cần làm theo đúng thứ tự.

1/ dùng mảng quá lớn. Sửa bằng cách reset mảng lại sau khi dùng. Với VBA thì có thêm trường hợp string bị phình, cần set lại thành "".

2/ dùng quá nhiều objects lớn. Dùng xong thì Set chúng lại thành nothing.

3/ riêng đối với Excel, mở nhiều files có màu mè mẫu mã cũng bị tốn bộ nhớ.
3.1 đối với trường hợp nhiều code, tránh màu mè mẫu mã và shapes trong file và tránh ba cái mớ dialog box màu mè.
3.2 đóng bớt các files đã dùng xong
3.3 nếu code có dùng các objects chuyên về dữ liệu như ADO thì phải coi chừng connection và recordset.
3.4 nếu làm mọi thứ mà vẫn không được thì canh cứ khoảng vài giây, cho code save file lại. Khi được save, Excel sẽ nhả những phần memory mà nó chứa trong cache.
#1/ Hiện tại em không dùng Array nhiều, chỉ dùng Đệ quy nhiều. Vấn đề phình String em chưa nghiên cứu nhưng em sẽ thử set lại "" (Em có đọc đâu đó nên set vbNullString tốt hơn)

#2/ Đúng là để code trực quan hơn em có dùng một số Object Workbook, Worksheet, Mail Object. Nhưng những cái nào ít dùng em đang cố gắng dùng dạng trực tiếp. Riêng việc Set = Nothing em đang sử dụng nhưng cũng chưa rõ khi set về Nothing thì bộ nhớ đã được clear hay chưa.

#3/ Phần màu mè không có nhiều vì em chỉ load data chứ không dùng condition formatting.
#3.1 Shapes, Dialog thì cũng không có (có một số megbox thông báo thôi)

#3.2 Em đóng file APP nhưng nó không tắt hẳn.
#3.3 Em chưa học ADO nên không có dùng
#3.4 Em sẽ thử dùng cách này của anh.


Em có một vấn đề thế này, không biết anh có thể cho em lời khuyên không ạ.
Vấn đề 1: Không tắt hẳn file, dẫn tới lỗi out of memory.
Em có 2 file, file APP.xlsm và file DATA.xlsm. Em dùng file APP để đăng nhập và gọi xác nhận dữ liệu từ file DATA. Sau khi kiểm tra đăng nhập hợp lệ, sẽ nạp dữ liệu login và load dữ liệu theo user login lên trong sheet TIMESHEET của file DATA.xlsm.
Vấn đề ở chỗ mỗi file em đều có một Module dùng để quản lý biến như bên dưới. Và khi login xong, em đóng cái file APP lại, nhưng nó không tắt hẳn trong cửa sổ VBA, thành ra, những biến nó đã khai báo vẫn còn tốn bộ nhớ (em đang nghĩ vậy). Và file DATA, APP có kha khá biến tương đồng :(
Hiện tại nếu chạy file APP gọi file DATA thì bị lỗi "Out of Memory" nhưng nếu chạy trực tiếp file DATA thì không bị vấn đề trên.

Vấn đề 2:
File của em có khá nhiều biến, vì để cho code trở nên dễ đọc, và có khá nhiều Sub nên các biến được sử dụng khá nhiều, thành ra em đang tạm quản lý ở một Module dạng Public. Điều này khiến em lo lắng vì sẽ tốn khá nhiều bộ nhớ lưu trữ.

Mã:
Option Explicit
Public wb As Workbook
Public wb_App As Workbook

Public ws As Worksheet
Public ws_Login As Worksheet, ws_MemData As Worksheet, ws_TimeSheet As Worksheet
Public ws_Record As Worksheet, ws_OffData As Worksheet, ws_Confirm As Worksheet, ws_DateTime As Worksheet, ws_Manager As Worksheet

Public rng As Range
'Declare ranges in the APP file
Public btn_InfoLogin As Range, btn_Contact As Range, btn_BackInfo As Range, btn_ForgetPW As Range, btn_Login As Range, btn_AppInfo As Range, frm_UserID As Range, frm_UserPW As Range
'Declare ranges in the DATA file
Public rng_UserID As Range, rng_UserName As Range, rng_PubKey As Range, rng_Manager As Range, rng_DataTittle As Range
Public rng_EnDays As Range, rng_EnHours As Range, rng_EnMins As Range
Public rng_OutDays As Range, rng_OutHours As Range, rng_OutMins As Range
Public rng_FromDate As Range, rng_ToDate As Range, rng_FromTime As Range, rng_ToTime As Range, rng_Notes As Range

'Declare object
Public OutApp As Object, OutMail As Object

Public icnt As Long, jcnt As Long, lng_lastRow As Long

'Public int_UsedDays As Integer, int_UsedHours As Integer, int_UsedMins As Integer
'Public int_EnDOff As Integer, int_EnHOff As Integer, int_EnNOff As Integer, int_AsEnNOff As Integer

Public Cancel As Boolean

Public Const strPATH As String = "\\A\B\"
Public Const strDATA As String = "offworkDATA.xlsm"
Public Const strAPP As String = "offworkAPP.xlsm"
Public Const strPubPW As String = "XYZ"
Public answer As String
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn có nhiều vấn đề quá. Khong thể giải quyết tất cả cùng 1 lúc. Làm tham lam tức là tự phình -> tự mình bị "out of memory"
Trước mắt cứ lo vấn đề #1. Mấy cái khác tính sau.
a/ hàm đệ quy rất khó debug. Bạn có thể tìm hiểu cách kiểm soát xem nó được gọi bao nhiêu lần.
b/ string thì xem lại những chỗ lập string bằng biểu thức kiểu s = s & abc, và kiểm soát độ lớn của nó.
ví dụ:
If (Len(s) Mod 1000 = 0) Then MsgBox "Đã phình ra thêm 1000 ký tự: " & Len(s)
 
Upvote 0
Bạn có nhiều vấn đề quá. Khong thể giải quyết tất cả cùng 1 lúc. Làm tham lam tức là tự phình -> tự mình bị "out of memory"
Trước mắt cứ lo vấn đề #1. Mấy cái khác tính sau.
a/ hàm đệ quy rất khó debug. Bạn có thể tìm hiểu cách kiểm soát xem nó được gọi bao nhiêu lần.
b/ string thì xem lại những chỗ lập string bằng biểu thức kiểu s = s & abc, và kiểm soát độ lớn của nó.
ví dụ:
If (Len(s) Mod 1000 = 0) Then MsgBox "Đã phình ra thêm 1000 ký tự: " & Len(s)
Vấn đề của em nằm ở chỗ cái file APP của em không hoàn toàn được đóng trong VBE, như bình luận của anh Werner Mittrup.
https://archive.sap.com/discussions/thread/3514553
 

File đính kèm

  • errorvba.png
    errorvba.png
    66.9 KB · Đọc: 13
Upvote 0
Các anh cho em hỏi sao code trong file sao không sumifs được
Cám các anh nhiều.
 

File đính kèm

Upvote 0
Các anh cho em hỏi sao code trong file sao không sumifs được
Cám các anh nhiều.
Code bạn sai hoàn toàn thì tính tổng là sao bạn, mà tôi có thấy code bạn dùng Sumifs chổ nào đâu. Mục đích của bạn là gì có thể giải thích để anh em giúp cho.
 
Upvote 0
Code bạn sai hoàn toàn thì tính tổng là sao bạn, mà tôi có thấy code bạn dùng Sumifs chổ nào đâu. Mục đích của bạn là gì có thể giải thích để anh em giúp cho.
Cám ơn Anh nhiều
Em muốn áp dụng giống code giống link sau nhưng thêm điều kiện ở cột E
http://www.giaiphapexcel.com/dienda...f-để-giảm-dung-lượng-file.101899/#post-828952
Em gửi lại file kết quả mong muốn giống cột J.
 

File đính kèm

Upvote 0
Cám ơn Anh nhiều
Em muốn áp dụng giống code giống link sau nhưng thêm điều kiện ở cột E
http://www.giaiphapexcel.com/diendan/threads/code-thay-thế-hàm-sumif-để-giảm-dung-lượng-file.101899/#post-828952
Em gửi lại file kết quả mong muốn giống cột J.
Bạn xem lại 2 chỗ ghi chú trong code:
PHP:
Private Sub CommandButton1_Click()
Dim Dic As Object, sArr(), dArr(), I As Long, Tem As String
Set Dic = CreateObject("Scripting.Dictionary")
sArr = Range([C8], [C8].End(xlDown)).Resize(, 6).Value2
ReDim dArr(1 To UBound(sArr, 1), 1 To 1)
For I = 1 To UBound(sArr, 1)
    Tem = sArr(I, 1) & sArr(I, 3) '<-------Chỗ này---------'
    If Not Dic.Exists(Tem) Then
        Dic.Add Tem, sArr(I, 6)
    Else
        Dic.Item(Tem) = Dic.Item(Tem) + sArr(I, 6)
    End If
Next I
For I = 1 To UBound(sArr, 1)
    dArr(I, 1) = Dic.Item(sArr(I, 1) & sArr(I, 3)) '<------và chỗ này-------------'
Next I
[I8].Resize(I - 1) = dArr
Set Dic = Nothing
End Sub
 
Upvote 0
Bạn có nhiều vấn đề quá. Khong thể giải quyết tất cả cùng 1 lúc. Làm tham lam tức là tự phình -> tự mình bị "out of memory"
Trước mắt cứ lo vấn đề #1. Mấy cái khác tính sau.
a/ hàm đệ quy rất khó debug. Bạn có thể tìm hiểu cách kiểm soát xem nó được gọi bao nhiêu lần.
b/ string thì xem lại những chỗ lập string bằng biểu thức kiểu s = s & abc, và kiểm soát độ lớn của nó.
ví dụ:
If (Len(s) Mod 1000 = 0) Then MsgBox "Đã phình ra thêm 1000 ký tự: " & Len(s)
Em đã giải quyết được vấn đề của mình. Lỗi ở 1 dòng code khiến nó không hoạt động được như ý.
Do em thiết lập cái Application.EnableEvents = False đầu tiên và Application.EnableEvents =True tận cuối tất cả code nên đã gây lỗi. Giờ em bỏ cả hai luôn chạy như ý rồi. Dù sao thì em cũng cảm ơn anh nhiều vì đã giúp em mở rộng kiến thức và cho em lời khuyên khi gặp vấn đề :)
 
Upvote 0
Tại sheet HD em muốn xóa các cell và khối cell : "B11:B14", "F3", "A3", "B19", "E29", "C31"
Em có viết code như sau, nhưng nó báo lỗi, nhờ các anh/chị giúp đỡ
PHP:
Sub XoaSoLieu()
    Sheets("HD").Select
    Range("B11:B14", "F3", "A3", "B19", "E29", "C31").Select
    Selection.ClearContents
    Range("F1").Select
End Sub
Em cảm ơn
 
Upvote 0
Tại sheet HD em muốn xóa các cell và khối cell : "B11:B14", "F3", "A3", "B19", "E29", "C31"
Em có viết code như sau, nhưng nó báo lỗi, nhờ các anh/chị giúp đỡ
PHP:
Sub XoaSoLieu()
    Sheets("HD").Select
    Range("B11:B14", "F3", "A3", "B19", "E29", "C31").Select
    Selection.ClearContents
    Range("F1").Select
End Sub
Em cảm ơn
Dòng này:
Range("B11:B14", "F3", "A3", "B19", "E29", "C31")
Thử bỏ các dấu nháy kép giữa chỉ chừa lại 2 dấu đầu và cuối thôi.
 
Upvote 0
Em có file tính dùng VBA dùng được rồi, bài toán em đặt ra là cần tách file dữ liệu (data) thành 1 file riêng. Nhưng em không rõ phải sửa code VBA như thế nào.
Các bác hỗ trợ em với.
File đính kèm có 2 sheet thì em cần tách sheet "Data_cable" thành file riêng tên là e-data.xls
 

File đính kèm

Upvote 0
Em có file tính dùng VBA dùng được rồi, bài toán em đặt ra là cần tách file dữ liệu (data) thành 1 file riêng. Nhưng em không rõ phải sửa code VBA như thế nào.
Các bác hỗ trợ em với.
File đính kèm có 2 sheet thì em cần tách sheet "Data_cable" thành file riêng tên là e-data.xls
Trong ổ D, tạo 1 Folder mới với tên là DIEN_2018.
Tại sheet Cable cho nó một Shapes rồi gán code sau vào thử xem:
Lưu ý: Tại K4 của sheet Data_Cable bạn gõ tên File cần lưu.

Mã:
Sub ThuXuatFile_Moi()
    Dim Path As String
    Dim filename As String
    Dim FileMoi
 
    Path = "D:\DIEN_2018\"
    filename = Sheet1.Range("K4") 'gõ tên File càn luu vào K4
    Set FileMoi = Workbooks.Add
    Sheet1.Copy Before:=FileMoi.Sheets(1)
 
    ActiveWorkbook.SaveAs filename:=Path & filename & ".xls", FileFormat:=xlNormal
    ActiveWindow.Close

End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Trong ổ D, tạo 1 Folder mới với tên là DIEN_2018.
Tại sheet Cable cho nó một Shapes rồi gán code sau vào thử xem:
Lưu ý: Tại K4 của sheet Data_Cable bạn gõ tên File cần lưu.

Mã:
Sub ThuXuatFile_Moi()
    Dim Path As String
    Dim filename As String
    Dim FileMoi
 
    Path = "D:\DIEN_2018\"
    filename = Sheet1.Range("K4") 'gõ tên File càn luu vào K4
    Set FileMoi = Workbooks.Add
    'ThisWorkbook.Sheets("Data_Cable").Copy Before:=FileMoi.Sheets(1)
    Sheet1.Copy Before:=FileMoi.Sheets(1)
 
    ActiveWorkbook.SaveAs filename:=Path & filename & ".xls", FileFormat:=xlNormal
    ActiveWindow.Close
       Sheet2.Range("J4").Select
    Set FileMoi = Nothing
End Sub
em cần 2 file đặt chung 1 folder, và không cố định đường dẫn (như bác đang là D:\Dien2018...) để có thể linh hoạt hơn trong sử dụng (share cho người khác, đặt trong folder dự án khác nhau...)
bác xem có thể sửa lại giúp em được không?
 
Upvote 0
em cần 2 file đặt chung 1 folder, và không cố định đường dẫn (như bác đang là D:\Dien2018...) để có thể linh hoạt hơn trong sử dụng (share cho người khác, đặt trong folder dự án khác nhau...)
bác xem có thể sửa lại giúp em được không?
Tại K4 của sheet Data_Cable bạn gõ tên File cần lưu, khi lưu thì nó hiện hộp thoại bạn muốn lưu chỗ nào là tùy bạn.

Mã:
Sub Luu_TuyChon()
    Dim TenFile As String
    Dim FileMoi As Object
    TenFile = Sheet1.Range("K4")
    Set FileMoi = Workbooks.Add
    Sheet1.Copy Before:=FileMoi.Sheets(1)
    Application.Dialogs(xlDialogSaveAs).Show TenFile
    ActiveWindow.Close
End Sub
 
Upvote 0
Tại K4 của sheet Data_Cable bạn gõ tên File cần lưu, khi lưu thì nó hiện hộp thoại bạn muốn lưu chỗ nào là tùy bạn.

Mã:
Sub Luu_TuyChon()
    Dim TenFile As String
    Dim FileMoi As Object
    TenFile = Sheet1.Range("K4")
    Set FileMoi = Workbooks.Add
    Sheet1.Copy Before:=FileMoi.Sheets(1)
    Application.Dialogs(xlDialogSaveAs).Show TenFile
    ActiveWindow.Close
End Sub

Em hỏi thêm chút nữa,

Nếu đã tách 2 file riêng cùng folder(1 là bảng tra, 1 là data riêng tên e-data.xls). VBA nằm ở file bảng tra thì sửa code này như thế nào để nó lấy dữ liệu để tra trong file data kia.

Mã:
ThisWorkbook.Worksheets("Data_Cable")
 
Upvote 0
Em hỏi thêm chút nữa,

Nếu đã tách 2 file riêng cùng folder(1 là bảng tra, 1 là data riêng tên e-data.xls). VBA nằm ở file bảng tra thì sửa code này như thế nào để nó lấy dữ liệu để tra trong file data kia.

Mã:
ThisWorkbook.Worksheets("Data_Cable")
Trong code trên:
- Tôi dùng Sheet1 (gọi là CodeName).
- Tôi dùng Data_Cable (gọi là Sheet Name hay Tab Sheet)

2 dòng code này sử dụng cái nào cũng được, nhưng phải gõ dấu nháy phía trước nó để bỏ đi 1 dòng code (nó hiện màu xanh), như hình.
Mã:
'ThisWorkbook.Sheets("Data_Cable").Copy Before:=FileMoi.Sheets(1)

    Sheet1.Copy Before:=FileMoi.Sheets(1)

A_LuuSheet.JPG
 
Lần chỉnh sửa cuối:
Upvote 0

File đính kèm

Upvote 0
hi bác @be09

Em có mò sửa lại code file trên để tách rời 2 file: bảng tính - data.
Nhưng gặp vấn đề ở đây là file data file luôn mở khi chạy bảng tính.
Em có đọc bài này http://www.giaiphapexcel.com/vbb/sh...-liệu-từ-1-file-đang-đóng&p=260991#post260991
Nhưng không rõ áp dụng trong trường hợp của em thì nên sử dụng như thế nào?
Bác có thể hướng 1 chút giúp em được không?
Vấn đề không đơn giản như đã trình bầy ở chủ đề này - vài dòng code tách sheet sang tập tin mới..
1. Với code hiện có thì bạn tách được sheet Data_cable sang tập tin mới e-data.xls. Nhưng sheet Data_Cable vẫn tồn tại trên tập tin cũ và code hàm DK vẫn lấy giá trị từ sheet Data_Cable của tập tin cũ. Vậy tạo thêm e-data.xls để làm cảnh?
2. Bạn có thể sửa code của DK để lấy dữ liệu từ sheet Data_Cable của tập tin e-data.xls, thậm chí là lấy từ tập tin đóng, nhưng nếu vẫn để lại sheet Data_Cable trong tập tin cũ thì tách thêm nó ra tập tin mới e-data.xls để làm gì?
3. Nếu bạn đã tách Data_Cable sang tập tin e-data.xls và bỏ Data_Cable trong tập tin cũ thì bạn sẽ có thực trạng như ở tập tin Ladder size calculation vă.xls. Tức các danh sách thả trong cột E mất tác dụng. Bạn không chọn được gì khác. Nguyên nhân là các Name mà bạn có (Formulas -> Name Manager) bị lỗi hết do tham chiếu tới sheet Data_Cable mà bạn đã xóa.
4. Có thể viết code làm: tách Data_Cable sang e-data.xls -> sửa DK để lấy dữ liệu từ e-data.xls -> xóa Data_Cable trong tập tin cũ -> sửa name để tham chiếu sang e-data.xls. Nhưng lúc đó để có thể dùng danh sách thả trong cột E thì vẫn phải mở tập tin e-data.xls. Nếu tập tin đóng thì danh sách mất tác dụng, không chọn được gì mới. Nếu chấp nhận luôn luôn mở tập tin e-data.xls khi làm việc với tập tin cũ thì tại sao phải sửa thành code lấy dữ liệu từ tập tin đóng?

Tôi chỉ lưu ý để ý thức cho bạn cái mà bạn vẫn chưa nhìn thấy. Tôi không tham gia viết code.
 
Lần chỉnh sửa cuối:
Upvote 0
Vấn đề không đơn giản như đã trình bầy ở chủ đề này - vài dòng code tách sheet sang tập tin mới..
...
Tôi chỉ lưu ý để ý thức cho bạn cái mà bạn vẫn chưa nhìn thấy. Tôi không tham gia viết code.

Tks bác đã góp ý. Chúc bác năm mới an khang, thịnh vượng!
Mục đích chính của việc tách riêng Data là để gửi bảng tính cho người khác (khi họ yêu cầu file excel). Tách riêng data thì họ sẽ chỉ xem file tính mà không thể chỉnh sửa (giữ bản quyền bảng tính của em). Thực ra nếu không cần viết VBA thì tham chiếu (reference) nó dễ dàng hơn, nhưng em thấy là nếu viết bằng công thức-hàm của excel khá phức tạp, sau cần sửa đổi gì đó mất công dò lại.

Có thể viết code làm: tách Data_Cable sang e-data.xls -> sửa DK để lấy dữ liệu từ e-data.xls -> xóa Data_Cable trong tập tin cũ -> sửa name để tham chiếu sang e-data.xls. Nhưng lúc đó để có thể dùng danh sách thả trong cột E thì vẫn phải mở tập tin e-data.xls. Nếu tập tin đóng thì danh sách mất tác dụng, không chọn được gì mới. Nếu chấp nhận luôn luôn mở tập tin e-data.xls khi làm việc với tập tin cũ thì tại sao phải sửa thành code lấy dữ liệu từ tập tin đóng?[
Bác nhắc em mới để ý đến, để em sửa lại phần Name. Nếu phương án sửa tham chiếu về tập tin đóng chạy được thì em sẽ chuyển phần Name (phục vụ cho Data Validation) về chung file bảng tính chọn, file Data chỉ để thông số của dây cáp. Em cũng muốn bảng tính nó hoàn thiện dần, tốt hơn. Em cũng không kinh nghiệm nhiều về code (thời sinh viên em cũng mày mò 1 ít Matlab) nên mong các bác chỉ bảo thêm.
 
Upvote 0
Status
Không mở trả lời sau này.
Web KT

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

Back
Top Bottom