Xin giúp đỡ: các thao tác trên workbook ?

Liên hệ QC

hiallhiall

Thành viên mới
Tham gia
24/2/22
Bài viết
7
Được thích
5
Lời đầu tiên xin chào các bác.
Em mới tập code vba nên có một số thắc mắc mà tìm hoài không thấy trên mạng, mong các bác giúp đỡ ạ
Em đang viết dc 1 marco kiểm tra, thay đổi dữ liệu của workbook A, copy 1 phần dữ liệu ở workbook A cho sang workbook B => về cơ bản e đã làm được chạy OK nhưng còn 1 số vấn đề cần cải thiện để cho nhanh hơn
1. Ở câu lệnh Workbooks.Close thì workbook B do được thay đổi thì nó không đóng ngay, mà nó sẽ hiện thông báo 1645721189188.png rất bất tiện, làm thế nào để nó tự động chọn save, không hiện thông báo nữa

2. Khi code em đang để ở workbook A, sau khi mở workbook B và copy dữ liệu vào workbook B thì em lại không thể sắp xếp được dữ liệu ở workbook B bằng câu lệnh Workbooks("B.xlsx").Worksheets("Sheet1").Range("A2", Range("I" & Rows.Count).End(xlUp)).Sort [C2], xlAscending
Có cách nào khác để sắp xếp trong trường hợp này không ạ ?
Em xử lý việc này bằng cách tắt workbook A, mở workbook B chạy code Range("A2", Range("I" & Rows.Count).End(xlUp)).Sort [C2], xlAscending :D

3. Có cách nào để chạy 1 macro cho lần lượt từng workbook ko, kiểu như chạy workbook 1 xong, đóng workbook 1rồi chạy đến workbook 2.... ? Do bây giờ số lượng workbook khá nhiều, khoảng hơn 200 workbook , hiện giờ e đang làm thủ công, mở workbook => dán code=> bấm chạy => đóng workbook => rồi lại mở rất mất thời gian :((
Các workbook của e nằm ở các folder khác nhau, nhưng lại ở trong 1 folder mẹ kiểu folder mẹ=>folder con 1=> folder con 2=> workbook
 
Lần chỉnh sửa cuối:
Lời đầu tiên xin chào các bác.
Em mới tập code vba nên có một số thắc mắc mà tìm hoài không thấy trên mạng, mong các bác giúp đỡ ạ
Em đang viết dc 1 marco kiểm tra, thay đổi dữ liệu của workbook A, copy 1 phần dữ liệu ở workbook A cho sang workbook B => về cơ bản e đã làm được chạy OK nhưng còn 1 số vấn đề cần cải thiện để cho nhanh hơn
1. Ở câu lệnh Workbooks.Close thì workbook B do được thay đổi thì nó không đóng ngay, mà nó sẽ hiện thông báo View attachment 272442 rất bất tiện, làm thế nào để nó tự động chọn save, không hiện thông báo nữa

2. Khi code em đang để ở workbook A, sau khi mở workbook B và copy dữ liệu vào workbook B thì em lại không thể sắp xếp được dữ liệu ở workbook B bằng câu lệnh Workbooks("B.xlsx").Worksheets("Sheet1").Range("A2", Range("I" & Rows.Count).End(xlUp)).Sort [C2], xlAscending
Có cách nào khác để sắp xếp trong trường hợp này không ạ ?
Em xử lý việc này bằng cách tắt workbook A, mở workbook B chạy code Range("A2", Range("I" & Rows.Count).End(xlUp)).Sort [C2], xlAscending :D

3. Có cách nào để chạy 1 macro cho lần lượt từng workbook ko, kiểu như chạy workbook 1 xong, đóng workbook 1rồi chạy đến workbook 2.... ? Do bây giờ số lượng workbook khá nhiều, khoảng hơn 200 workbook , hiện giờ e đang làm thủ công, mở workbook => dán code=> bấm chạy => đóng workbook => rồi lại mở rất mất thời gian :((
Các workbook của e nằm ở các folder khác nhau, nhưng lại ở trong 1 folder mẹ kiểu folder mẹ=>folder con 1=> folder con 2=> workbook
Bạn phải đưa tập tin lên thì mới biết cot ket của bạn thế nào chứ,hoặc là viết code vao đâu chứ.
 
Upvote 0
code chính e viết chạy OK rồi bác ạ, bây giờ chỉ cần thêm 1 số tính năng cho đỡ vất vả thôi bác ạ
code e viết ngay trong sheet1
View attachment 272449
Hãy làm như anh @befaint đã hướng dẫn ở bài #4. Nếu chưa có thì thêm để tắt các thông báo

Mã:
Sub......
Dim....
Application.DisplayAlerts=false
.....

Workbooks.Close SaveChange:= True
.....
Application.DisplayAlerts=true
end sub
Mà tại sao bạn không gửi tập tin giả định lên nhỉ? Có quá nhiều bí mật không thể tiết lộ hay sao?
3. Có cách nào để chạy 1 macro cho lần lượt từng workbook ko, kiểu như chạy workbook 1 xong, đóng workbook 1rồi chạy đến workbook 2.... ? Do bây giờ số lượng workbook khá nhiều, khoảng hơn 200 workbook , hiện giờ e đang làm thủ công, mở workbook => dán code=> bấm chạy => đóng workbook => rồi lại mở rất mất thời gian :((
Các workbook của e nằm ở các folder khác nhau, nhưng lại ở trong 1 folder mẹ kiểu folder mẹ=>folder con 1=> folder con 2=> workbook"

Nếu các Folder ấy đều có một điểm gì đó giống nhau ví dụ : Nhap \năm 2022\Thang........Và Xuat\nam2022\thang...... thì có thể sẽ làm được.
Thêm nữa là Code sao lại viết ở Sheet mà không viết ở modul? Nếu ai vô tình mà xóa Sheet có code ấy thì tèo luôn.
 
Lần chỉnh sửa cuối:
Upvote 0
Hãy làm như anh @befaint đã hướng dẫn ở bài #4. Nếu chưa có thì thêm để tắt các thông báo

Mã:
Sub......
Dim....
Application.DisplayAlerts=false
.....

Workbooks.Close SaveChange:= True
.....
Application.DisplayAlerts=true
end sub
Mà tại sao bạn không gửi tập tin giả định lên nhỉ? Có quá nhiều bí mật không thể tiết lộ hay sao?
3. Có cách nào để chạy 1 macro cho lần lượt từng workbook ko, kiểu như chạy workbook 1 xong, đóng workbook 1rồi chạy đến workbook 2.... ? Do bây giờ số lượng workbook khá nhiều, khoảng hơn 200 workbook , hiện giờ e đang làm thủ công, mở workbook => dán code=> bấm chạy => đóng workbook => rồi lại mở rất mất thời gian :((
Các workbook của e nằm ở các folder khác nhau, nhưng lại ở trong 1 folder mẹ kiểu folder mẹ=>folder con 1=> folder con 2=> workbook"

Nếu các Folder ấy đều có một điểm gì đó giống nhau ví dụ : Nhap \năm 2022\Thang........Và Xuat\nam2022\thang...... thì có thể sẽ làm được.
Thêm nữa là Code sao lại viết ở Sheet mà không viết ở modul? Nếu ai vô tình mà xóa Sheet có code ấy thì tèo luôn.
Thực ra e mới học vba được 3-4 hôm, nên còn gà lắm chưa hiểu rõ sheet với modul. Em chỉ cần chạy lại dữ liệu đó, ko cần lưu code lại trên file
e đã làm theo bác trên nhưng nó báo lỗi, dù làm ví dụ đơn giản 1645757296432.png

Nhưng h em đã khắc phục được bằng cách Workbooks("1.xlsx").Save Workbooks("2.xlsx").Save Workbooks("1.xlsx").Close Workbooks("2.xlsx").Close thì nó đã ko hiện thông báo lưu nữa là hiện dòng: Be careful! Parts of your document may include personal information that can't be removed by the Document Inspector. :((
3. Đúng là nó có cấu trúc như bác nói năm=>tháng=>ngày=> workbook

Đây là code của e viết trên sheet, mong các bác góp ý ạ
Mã:
Sub sualoi()
Sheet1.Range("B2:D99").NumberFormat = "@"
Dim i As Integer
Dim thaydoi As Integer
Dim ngayden, thangden, namden, thogianden As Long
Dim thoigian As Long
Dim dem As Integer
Dim dongcat, dongccuoi As Integer
Dim chuyenfile As Integer

Range("A2", Range("I" & Rows.Count).End(xlUp)).Sort [C2], xlAscending
giothem = 18
chuyenfile = 0
For i = 1 To 99
    If Cells(i, 6) = "az-112" Then
        If Left(Cells(i, 4), 2) > 65 And Left(Cells(i, 4), 2) < 77 Then
            Cells(i, 3) = Format(DateAdd("h", giothem, Cells(i, 3)), "yyyy-mm-dd hh:mm:ss")
            Cells(i, 4) = Replace(Cells(i, 4), Left(Cells(i, 4), 2), Left(Cells(i, 4), 2) + giothem, 1, 1)
            chuyenfile = 1
        End If
    End If
Next
Sheet1.Range("B2:D99").NumberFormat = "General"
If chuyenfile = 1 Then
    Range("A2", Range("I" & Rows.Count).End(xlUp)).Sort [C2], xlAscending
    dongcuoi = Cells(Rows.Count, 2).End(xlUp).Row
    thoigian = Mid(ActiveWorkbook.Name, 1, 8)
    For dem = 2 To dongcuoi
        thoigianden = Mid(Cells(dem, 3), 1, 4) + Mid(Cells(dem, 3), 6, 2) + Mid(Cells(dem, 3), 9, 2)
        If thoigianden > thoigian Then
           dongcat = dem
           namden = Mid(Cells(dem, 3), 1, 4)
           thangden = Mid(Cells(dem, 3), 6, 2)
           ngayden = Mid(Cells(dem, 3), 9, 2)
           Workbooks.Open ("C:\Users\zz\Desktop\New folder\Output\" & namden & "\" & thangden & "\" & ngayden & "\" & thoigianden & "_Data Output.xlsx")
           Workbooks(thoigian & "_Data Output.xlsx").Worksheets("Sheet1").Range("A" & dongcat & ":" & "I" & dongcuoi).Cut Workbooks(thoigianden & "_Data Output.xlsx").Worksheets("Sheet1").Range("A40")
           Workbooks(thoigian & "_Data Output.xlsx").Close SaveChange:=True
           Workbooks(thoigianden & "_Data Output.xlsx").Close SaveChange:=True
        Exit For
        End If
    Next
End If
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Tình hình nhờ 2 bác trên em đã giải quyết dc vấn đề 1 bằng câu lệnh
Mã:
Sub aa()
           Application.DisplayAlerts = False
           Cells(1, 1) = 1
           Cells(1, 2) = 2
           Workbooks.Open ("C:\222\2.xlsx")
           Workbooks("1.xlsx").Worksheets("Sheet1").Range("A1:B1").Cut Workbooks("2.xlsx").Worksheets("Sheet1").Range("A1")
           Workbooks("2.xlsx").Save
           Workbooks("2.xlsx").Close
           Workbooks("1.xlsx").Save
           Workbooks("1.xlsx").Close
           Application.DisplayAlerts = True
End Sub
 
Upvote 0
1.
Workbooks("B.xlsx").Close True
Hoặc
Workbooks("B.xlsx").Close SaveChanges:= True
(@befaint thiếu sờ)
2.
Workbooks("B.xlsx").Worksheets("Sheet1").Range("A2", Range("I" & Rows.Count).End(xlUp)).Sort .[C2], xlAscending
(thiếu những dấu chấm)
3.
Dùng vòng lặp, với điều kiện phải có list 200 file, nếu 200 file cùng 1 thư mục phải dùng File System Object
 
Lần chỉnh sửa cuối:
Upvote 0
Thực ra e mới học vba được 3-4 hôm, nên còn gà lắm chưa hiểu rõ sheet với modul. Em chỉ cần chạy lại dữ liệu đó, ko cần lưu code lại trên file
e đã làm theo bác trên nhưng nó báo lỗi, dù làm ví dụ đơn giản View attachment 272451

Nhưng h em đã khắc phục được bằng cách Workbooks("1.xlsx").Save Workbooks("2.xlsx").Save Workbooks("1.xlsx").Close Workbooks("2.xlsx").Close thì nó đã ko hiện thông báo lưu nữa là hiện dòng: Be careful! Parts of your document may include personal information that can't be removed by the Document Inspector. :((
3. Đúng là nó có cấu trúc như bác nói năm=>tháng=>ngày=> workbook

Đây là code của e viết trên sheet, mong các bác góp ý ạ
Mã:
Sub sualoi()
Sheet1.Range("B2:D99").NumberFormat = "@"
Dim i As Integer
Dim thaydoi As Integer
Dim ngayden, thangden, namden, thogianden As Long
Dim thoigian As Long
Dim dem As Integer
Dim dongcat, dongccuoi As Integer
Dim chuyenfile As Integer

Range("A2", Range("I" & Rows.Count).End(xlUp)).Sort [C2], xlAscending
giothem = 18
chuyenfile = 0
For i = 1 To 99
    If Cells(i, 6) = "az-112" Then
        If Left(Cells(i, 4), 2) > 65 And Left(Cells(i, 4), 2) < 77 Then
            Cells(i, 3) = Format(DateAdd("h", giothem, Cells(i, 3)), "yyyy-mm-dd hh:mm:ss")
            Cells(i, 4) = Replace(Cells(i, 4), Left(Cells(i, 4), 2), Left(Cells(i, 4), 2) + giothem, 1, 1)
            chuyenfile = 1
        End If
    End If
Next
Sheet1.Range("B2:D99").NumberFormat = "General"
If chuyenfile = 1 Then
    Range("A2", Range("I" & Rows.Count).End(xlUp)).Sort [C2], xlAscending
    dongcuoi = Cells(Rows.Count, 2).End(xlUp).Row
    thoigian = Mid(ActiveWorkbook.Name, 1, 8)
    For dem = 2 To dongcuoi
        thoigianden = Mid(Cells(dem, 3), 1, 4) + Mid(Cells(dem, 3), 6, 2) + Mid(Cells(dem, 3), 9, 2)
        If thoigianden > thoigian Then
           dongcat = dem
           namden = Mid(Cells(dem, 3), 1, 4)
           thangden = Mid(Cells(dem, 3), 6, 2)
           ngayden = Mid(Cells(dem, 3), 9, 2)
           Workbooks.Open ("C:\Users\zz\Desktop\New folder\Output\" & namden & "\" & thangden & "\" & ngayden & "\" & thoigianden & "_Data Output.xlsx")
           Workbooks(thoigian & "_Data Output.xlsx").Worksheets("Sheet1").Range("A" & dongcat & ":" & "I" & dongcuoi).Cut Workbooks(thoigianden & "_Data Output.xlsx").Worksheets("Sheet1").Range("A40")
           Workbooks(thoigian & "_Data Output.xlsx").Close SaveChange:=True
           Workbooks(thoigianden & "_Data Output.xlsx").Close SaveChange:=True
        Exit For
        End If
    Next
End If
End Sub
Mới học VBA được 3-4 ngày mà có trình độ cao siêu thế. Để viết được Code như bạn đã trình bày thì mất ít ra cũng phải 3-4 năm cật lực học và hỏi (đấy là kể cả có người hướng dẫn)
1. Bạn làm như anh @SA_DQ đã hướng dẫn. và xem kết quả thế nào.
Vấn đề "..hiện dòng: Be careful! Parts of your document may include personal information that can't be removed by the Document Inspector."
bạn mở Workbook vào Thẻ File\Info nhìn sang bên cạnh có thấy mục Inspect Workbook , tìm dòng Allow..... (ở phía cuối), nháy chuột vào đó là được.
2."3. Đúng là nó có cấu trúc như bác nói năm=>tháng=>ngày=> workbook...."
Cái này Bạn phải đưa file giả định lên thì mới hy vọng có người giúp được bạn. chứ nhìn vào code xong lại đoán bên Sheet có những gì, rồi lại phải tạo Sheet, rồi chay thử sai đúng thế nào.....Tôi tin là trên diễn đàn này không có người có khả năng vậy, mà nếu có thì họ cũng không có thời gian để đoán mò ý định của bạn rồi giúp bạn.
 
Upvote 0
Mới học VBA được 3-4 ngày mà có trình độ cao siêu thế. Để viết được Code như bạn đã trình bày thì mất ít ra cũng phải 3-4 năm cật lực học và hỏi (đấy là kể cả có người hướng dẫn)
1. Bạn làm như anh @SA_DQ đã hướng dẫn. và xem kết quả thế nào.
Vấn đề "..hiện dòng: Be careful! Parts of your document may include personal information that can't be removed by the Document Inspector."
bạn mở Workbook vào Thẻ File\Info nhìn sang bên cạnh có thấy mục Inspect Workbook , tìm dòng Allow..... (ở phía cuối), nháy chuột vào đó là được.
2."3. Đúng là nó có cấu trúc như bác nói năm=>tháng=>ngày=> workbook...."
Cái này Bạn phải đưa file giả định lên thì mới hy vọng có người giúp được bạn. chứ nhìn vào code xong lại đoán bên Sheet có những gì, rồi lại phải tạo Sheet, rồi chay thử sai đúng thế nào.....Tôi tin là trên diễn đàn này không có người có khả năng vậy, mà nếu có thì họ cũng không có thời gian để đoán mò ý định của bạn rồi giúp bạn.
thanks bác, sau nhiều ngày tìm hiểu, tham khảo trên mạng e đã giải quyết được vấn đề rùi.
Dưới đây là code của em ( thực ra phần lớn là đi copy :D ) cho yêu cầu: Chỉnh sửa rất nhiều workbook có trong folder, subfolder ( bao nhiêu cấp cũng được)


Mã:
Sub ListFiles()
    Application.ScreenUpdating = False
    Dim path As String
    Dim dem As Integer
    path = "C:\New folder"                      'đường dẫn đến thư mục mẹ
    Cells.Clear
    Call GetFiles(path)
End Sub

Private Sub GetFiles(ByVal path As String)
    Application.ScreenUpdating = False
    Dim FSO As Object, Fldr As Object, subF As Object, file As Object, extn As String
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Set Fldr = FSO.GetFolder(path)
    For Each subF In Fldr.SubFolders
        GetFiles (subF.path)
    Next subF

    For Each file In Fldr.Files
        On Error Resume Next
        If Err.Number = 0 Then
            Range("A" & Rows.Count).End(xlUp).Offset(1, 0) = file.Name     ' dòng này để ghi lại xem đã duyệt qua những workbook nào
            Workbooks.Open (file.path)
                
                ' copy code chỉnh sửa từng workbook vào đây
            
        End If
        On Error GoTo 0
    Next file
    
    Set FSO = Nothing
    Set Fldr = Nothing
    Set subF = Nothing
    Set file = Nothing
End Sub
 
Upvote 0
thanks bác, sau nhiều ngày tìm hiểu, tham khảo trên mạng e đã giải quyết được vấn đề rùi.
Dưới đây là code của em ( thực ra phần lớn là đi copy :D ) cho yêu cầu: Chỉnh sửa rất nhiều workbook có trong folder, subfolder ( bao nhiêu cấp cũng được)


Mã:
Sub ListFiles()
    Application.ScreenUpdating = False
    Dim path As String
    Dim dem As Integer
    path = "C:\New folder"                      'đường dẫn đến thư mục mẹ
    Cells.Clear
    Call GetFiles(path)
End Sub

Private Sub GetFiles(ByVal path As String)
    Application.ScreenUpdating = False
    Dim FSO As Object, Fldr As Object, subF As Object, file As Object, extn As String
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Set Fldr = FSO.GetFolder(path)
    For Each subF In Fldr.SubFolders
        GetFiles (subF.path)
    Next subF

    For Each file In Fldr.Files
        On Error Resume Next
        If Err.Number = 0 Then
            Range("A" & Rows.Count).End(xlUp).Offset(1, 0) = file.Name     ' dòng này để ghi lại xem đã duyệt qua những workbook nào
            Workbooks.Open (file.path)
               
                ' copy code chỉnh sửa từng workbook vào đây
           
        End If
        On Error GoTo 0
    Next file
   
    Set FSO = Nothing
    Set Fldr = Nothing
    Set subF = Nothing
    Set file = Nothing
End Sub
Đó, cứ cố gắng từng tý một là dần tự viết được code cho nhu cầu làm việc của mình.
Bạn có nền tảng gì trước không mà mới học VBA có 3-4 ngày mà đã đạt đến trình độ siêu thế. Hay bạn là một siêu nhân theo đúng nghĩa.
 
Upvote 0
Đó, cứ cố gắng từng tý một là dần tự viết được code cho nhu cầu làm việc của mình.
Bạn có nền tảng gì trước không mà mới học VBA có 3-4 ngày mà đã đạt đến trình độ siêu thế. Hay bạn là một siêu nhân theo đúng nghĩa.
Nào có siêu j đâu bác, toàn đi góp nhặt code trên mạng :D
Em học ngành điện, trước đi học thì được học qua 1 môn lập trình nhúng bằng C rồi bác
 
Upvote 0
Web KT

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

Back
Top Bottom