sửa lỗi VBA gộp nhiều sheet thành 1 sheet

Liên hệ QC

thanhhong.hr

Thành viên chính thức
Tham gia
5/2/15
Bài viết
50
Được thích
1
Giới tính
Nữ
Nghề nghiệp
Nhân viên nhân sự
mọi người cho em hỏi chút ạ, em dùng VBA gộ nhiều sheet có cấu trúc giống nhau thành 1 sheet, nhưng khi gộp lại thì nó thành 1 file giống như dạng ảnh, không dùng được các thao tác trên thanh công cụ. Mong mng giúp đỡ em với ạ, thanks all!!!! (Code như bên dưới ạ)
Sub MergeSheets()
Const NHR = 1

Dim MWS As Worksheet
Dim AWS As Worksheet
Dim FAR As Long
Dim LR As Long

Set AWS = ActiveSheet

For Each MWS In ActiveWindow.SelectedSheets
If Not MWS Is AWS Then
FAR = AWS.UsedRange.Cells(AWS.UsedRange.Cells.Count).Row + 1
LR = MWS.UsedRange.Cells(MWS.UsedRange.Cells.Count).Row
MWS.Range(MWS.Rows(NHR + 1), MWS.Rows(LR)).Copy AWS.Rows(FAR)
End If
Next MWS
End Sub
 
Tôi có thấy nó bị cái gì đâu.
Code của bạn bắt buôc phải select 1 nhóm sheets trước khi chạy. Sau khi chạy xong thì bạn phải de-select thì mới làm việc tiếp được.
(click đại vào tab của 1 sheet nào đó, trừ activesheet)
 
Upvote 0
Tôi có thấy nó bị cái gì đâu.
Code của bạn bắt buôc phải select 1 nhóm sheets trước khi chạy. Sau khi chạy xong thì bạn phải de-select thì mới làm việc tiếp được.
(click đại vào tab của 1 sheet nào đó, trừ activesheet)
Bác ơi, bác có thể sửa code này để tổng hợp 1 số file cụ thể được không hở bác
Cháu cảm ơn bác nhé!
 
Upvote 0
Bác ơi, bác có thể sửa code này để tổng hợp 1 số file cụ thể được không hở bác
Cháu cảm ơn bác nhé!
Code này là một trong những code rác rưởi nhất mà tôi từng đọc qua. Sửa làm gì cho mệt.
Ở diễn đàn này có cả đống code tổng hợp files. Cứ tìm và chọn lấy 1. Nếu bạn nêu rõ code ở đâu ra thì người ta sẽ sẵn sàng sửa giùm.
 
Upvote 0
PHP:
Sub MergeSheets()
 Const NHR = 1  '???  '
 Dim MWS As Worksheet, AwS As Worksheet
 Dim fAR As Long, lR As Long

 Set AwS = ThisWorkbook.Worksheets("GPE")
 For Each MWS In ThisWorkbook.Worksheets
    If MWS.Name <> "GPE" Then
        fAR = AwS.UsedRange.Cells(AwS.UsedRange.Cells.Count).Row + 1
        lR = MWS.UsedRange.Cells(MWS.UsedRange.Cells.Count).Row
        MWS.Range(MWS.Rows(NHR + 1), MWS.Rows(lR)).Copy AwS.Rows(fAR)
    End If
 Next MWS
End Sub
 
Upvote 0
PHP:
Sub MergeSheets()
Const NHR = 1  '???  '
Dim MWS As Worksheet, AwS As Worksheet
Dim fAR As Long, lR As Long

Set AwS = ThisWorkbook.Worksheets("GPE")
For Each MWS In ThisWorkbook.Worksheets
    If MWS.Name <> "GPE" Then
        fAR = AwS.UsedRange.Cells(AwS.UsedRange.Cells.Count).Row + 1
        lR = MWS.UsedRange.Cells(MWS.UsedRange.Cells.Count).Row
        MWS.Range(MWS.Rows(NHR + 1), MWS.Rows(lR)).Copy AwS.Rows(fAR)
    End If
Next MWS
End Sub
Cháu cảm ơn bác
 
Upvote 0
Bác ơi, bác có thể sửa code này để tổng hợp 1 số file cụ thể được không hở bác
Cháu cảm ơn bác nhé!
Vào Tìm kiếm gõ cụm từ "gộp nhiều file vào 1 file" có cả đống, đây là nguyên nhân tôi đã từng góp ý cho các thành viên khi mở Topic nên đặt tiêu đề cụ thể, rõ ràng để thuận tiện cho các thành viên khác tìm cái cần cho công việc.

A_Tim.JPG
 
Upvote 0
Bác ơi, bác có thể sửa code này để tổng hợp 1 số file cụ thể được không hở bác
Cháu cảm ơn bác nhé!
Bạn có thể tham khảo code bên dưới, gộp nhiều sheet có đk,
nếu không có điều kiện thì bỏ dòng này đi
If (Arr_N(i, 1) = Kh) Then tất nhiên phải bỏ end if nữa
Mã:
Sub InHoandon05(Sh As Worksheet, Arr_D(), K As Long)
Dim i As Long
Dim Kh As String
Dim DongCuoi As Long
Dim Arr_N()
Kh = Sheet7.Range("C4")
DongCuoi = Sh.Range("A10000").End(xlUp).Row
Arr_N = Sh.Range("A2:I" & DongCuoi)
For i = 1 To UBound(Arr_N, 1)
    If (Arr_N(i, 1) = Kh) Then
        K = K + 1
        Arr_D(K, 1) = Arr_N(i, 5)
        Arr_D(K, 2) = Arr_N(i, 2)
        Arr_D(K, 3) = Arr_N(i, 3)
        Arr_D(K, 4) = Arr_N(i, 8)
        Arr_D(K, 5) = Arr_N(i, 9)
        Arr_D(K, 6) = Arr_N(i, 7)
    End If
Next
End Sub

Sub main()
Dim K As Long
Dim Arr_D(1 To 10000, 1 To 7)
    K = 0
    Call InHoandon05(Sheet1, Arr_D, K)
    Call InHoandon05(Sheet8, Arr_D, K)
    Call InHoandon05(Sheet9, Arr_D, K)
    Call InHoandon05(Sheet10, Arr_D, K)
    Call InHoandon05(Sheet11, Arr_D, K)
    Sheet7.Range("A9:Z1000").Clear
    Sheet7.Range("A9").Resize(K, 1).NumberFormat = "dd/mm/yyyy"
    Sheet7.Range("A9").Resize(K, 6) = Arr_D
    Sheet7.Range("D9").Resize(K, 3).NumberFormat = "#,##0.0"
    Sheet7.Range("A9").Resize(K + 1, 7).Borders.LineStyle = 1
   Sheet7.Range("C9").Offset(K, 1).Value = "Total"
   Sheet7.Range("A9").Offset(K, 0).Resize(1, 7).Interior.ColorIndex = 15
End Sub
 

File đính kèm

Upvote 0
Bạn có thể tham khảo code bên dưới, gộp nhiều sheet có đk,
nếu không có điều kiện thì bỏ dòng này đi
If (Arr_N(i, 1) = Kh) Then tất nhiên phải bỏ end if nữa
Mã:
Sub InHoandon05(Sh As Worksheet, Arr_D(), K As Long)
Dim i As Long
Dim Kh As String
Dim DongCuoi As Long
Dim Arr_N()
Kh = Sheet7.Range("C4")
DongCuoi = Sh.Range("A10000").End(xlUp).Row
Arr_N = Sh.Range("A2:I" & DongCuoi)
For i = 1 To UBound(Arr_N, 1)
    If (Arr_N(i, 1) = Kh) Then
        K = K + 1
        Arr_D(K, 1) = Arr_N(i, 5)
        Arr_D(K, 2) = Arr_N(i, 2)
        Arr_D(K, 3) = Arr_N(i, 3)
        Arr_D(K, 4) = Arr_N(i, 8)
        Arr_D(K, 5) = Arr_N(i, 9)
        Arr_D(K, 6) = Arr_N(i, 7)
    End If
Next
End Sub

Sub main()
Dim K As Long
Dim Arr_D(1 To 10000, 1 To 7)
    K = 0
    Call InHoandon05(Sheet1, Arr_D, K)
    Call InHoandon05(Sheet8, Arr_D, K)
    Call InHoandon05(Sheet9, Arr_D, K)
    Call InHoandon05(Sheet10, Arr_D, K)
    Call InHoandon05(Sheet11, Arr_D, K)
    Sheet7.Range("A9:Z1000").Clear
    Sheet7.Range("A9").Resize(K, 1).NumberFormat = "dd/mm/yyyy"
    Sheet7.Range("A9").Resize(K, 6) = Arr_D
    Sheet7.Range("D9").Resize(K, 3).NumberFormat = "#,##0.0"
    Sheet7.Range("A9").Resize(K + 1, 7).Borders.LineStyle = 1
   Sheet7.Range("C9").Offset(K, 1).Value = "Total"
   Sheet7.Range("A9").Offset(K, 0).Resize(1, 7).Interior.ColorIndex = 15
End Sub
Em cảm ơn anh ạ
 
Upvote 0
Bạn có thể tham khảo code bên dưới, gộp nhiều sheet có đk,
nếu không có điều kiện thì bỏ dòng này đi
If (Arr_N(i, 1) = Kh) Then tất nhiên phải bỏ end if nữa
Mã:
Sub InHoandon05(Sh As Worksheet, Arr_D(), K As Long)
...
Tôi nhớ không lầm thì bạn là từng nói mình viết code C/C++ phải không?
Người kinh nghiệm C/C++ thường bảo Function trả về trị cần thiết.
Trường hợp bạn cần thiết trả về trị qua tham (vd, nhiều hơn 1) thì cũng khai tường minh rằng nó là tham biến (byRef). Cho dù điều kiện byRef có mặc định hay không. Lý do là người khác nhìn vào dòng này thì hiểu ngay cái tham byRef kia sẽ chứa trị quan trọng trả về.

Bài này thì chỉ trả về 1 trị dạng đơn giản cho nên dùng Function là tốt nhất

Function InHoandon05(Sh As Worksheet, Arr_D(), byVal K As Long) As Long
...
InHoandon05 = K
End Function

Sub main()
...
K = InHoandon05(Sheet1, Arr_D, 0)
K = InHoandon05(Sheet8, Arr_D, K)
K = InHoandon05(Sheet9, Arr_D, K)
K = InHoandon05(Sheet10, Arr_D, K)
K = InHoandon05(Sheet11, Arr_D, K)
...
End Sub
Hoặc
K = 0
For Each Sh In Array(Sheet1, Sheet8, Sheet9, Sheet10, Sheet11)
K = InHoandon05(Sheet1, Arr_D, K)
Next Sh

(*) Nếu Arr_D không bị thay đổi thì ta đã có thể pipe luôn lệnh gọi:
K = InHoandon05(Sheet11, Arr_D, _
InHoandon05(Sheet10, Arr_D, _
InHoandon05(Sheet9, Arr_D, _
InHoandon05(Sheet8, Arr_D, _
InHoandon05(Sheet1, Arr_D, 0 )))))
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi nhớ không lầm thì bạn là từng nói mình viết code C/C++ phải không?
Người kinh nghiệm C/C++ thường bảo Function trả về trị cần thiết.
Trường hợp bạn cần thiết trả về trị qua tham (vd, nhiều hơn 1) thì cũng khai tường minh rằng nó là tham biến (byRef). Cho dù điều kiện byRef có mặc định hay không. Lý do là người khác nhìn vào dòng này thì hiểu ngay cái tham byRef kia sẽ chứa trị quan trọng trả về.

Bài này thì chỉ trả về 1 trị dạng đơn giản cho nên dùng Function là tốt nhất

Function InHoandon05(Sh As Worksheet, Arr_D(), byVal K As Long) As Long
...
InHoandon05 = K
End Function

Sub main()
...
K = InHoandon05(Sheet1, Arr_D, 0)
K = InHoandon05(Sheet8, Arr_D, K)
K = InHoandon05(Sheet9, Arr_D, K)
K = InHoandon05(Sheet10, Arr_D, K)
K = InHoandon05(Sheet11, Arr_D, K)
...
End Sub
Hoặc
K = 0
For Each Sh In Array(Sheet1, Sheet8, Sheet9, Sheet10, Sheet11)
K = InHoandon05(Sheet1, Arr_D, K)
Next Sh

(*) Nếu Arr_D không bị thay đổi thì ta đã có thể pipe luôn lệnh gọi:
K = InHoandon05(Sheet11, Arr_D, _
InHoandon05(Sheet10, Arr_D, _
InHoandon05(Sheet9, Arr_D, _
InHoandon05(Sheet8, Arr_D, _
InHoandon05(Sheet1, Arr_D, 0 )))))
Dạ cảm ơn anh nhiều, em đã rõ vấn đề rồi ạ, sau này em sẽ khai báo tường minh, vì code trong VBA mặc định là tham biến, mà những biết kia có thay đổi hay không thì cũng không quan trọng, chỉ có k là cần thay đổi thôi, nên em khai báo hơi cẩu thả một tí là khai báo kiểu tham biến luôn. hihi
 
Upvote 0
1. Viết code đơn giản dịch yêu cầu thành ra nhóm lệnh và code là công việc sơ đẳng, giành cho người mới bắt đầu.
2. Viết code sử dụng các đối tượng và tiện nghi hệ thóng (các APIs, và Objects) là công việc của hackers

Lập trình thực thụ phải gồm thêm hai phần chính: giải thuật và quản lý code (architecture).
Ở diễn đàn này chỉ thấy viết code giải quyết công việc tại chỗ cho nên phần quản lý bị bỏ rơi, gần như hoàn toàn không ai lý tới.
Phần quan trọng nhất của quản lý code là cách phân các công việc ra thành từng Function/Sub nhỏ để dễ quản lý. Những Sub/Function nhỏ ấy liên lạc với nhau qua giao diện, tức là cái parameter list của Function/Sub (*). Một khi bạn tạo được thói quen tách riêng công việc rồi thì sẽ thấu hiểu tầm quan trọng của giao diện.
Rất tiếc là ở diễn đàn này hầu hết đều muốn tiến theo con đường 2. ở trên (hacker) cho nên cơ hội để các thành viên học code tiến theo con đường lập trình chân chính gần như 0%.

(*) những ngôn ngữ cho phép viết hàm chồng (như C++) dùng chính sách xào tên (name mangling) và dùng cái parameter list để phân biệt hàm chính thức được gọi cho nên những ngôn ngữ này gọi cái parameter list là "dấu ấn/chữ ký" (signature) của hàm.

(**) hầu hết các phần mềm hổ trợ lập trình (như Visual Studio) đều có cách tạo comments ngay đầu hàm theo kiểu XML để người sử dụng hàm có thể theo dõi giao diện hàm.

@phihndhsp:
Tôi viết những lời trên chủ yếu cho bạn, vì thấy bạn là giáo viên. Tuy bạn không cần phải dạy học viên như thế, nhưng nếu một dịp nào đó gặp được một học viên có năng khiếu lập trình thì những lời khuyên trên sẽ giúp cho học viên ấy tiến xa.
 
Upvote 0
1. Viết code đơn giản dịch yêu cầu thành ra nhóm lệnh và code là công việc sơ đẳng, giành cho người mới bắt đầu.
2. Viết code sử dụng các đối tượng và tiện nghi hệ thóng (các APIs, và Objects) là công việc của hackers

Lập trình thực thụ phải gồm thêm hai phần chính: giải thuật và quản lý code (architecture).
Ở diễn đàn này chỉ thấy viết code giải quyết công việc tại chỗ cho nên phần quản lý bị bỏ rơi, gần như hoàn toàn không ai lý tới.
Phần quan trọng nhất của quản lý code là cách phân các công việc ra thành từng Function/Sub nhỏ để dễ quản lý. Những Sub/Function nhỏ ấy liên lạc với nhau qua giao diện, tức là cái parameter list của Function/Sub (*). Một khi bạn tạo được thói quen tách riêng công việc rồi thì sẽ thấu hiểu tầm quan trọng của giao diện.
Rất tiếc là ở diễn đàn này hầu hết đều muốn tiến theo con đường 2. ở trên (hacker) cho nên cơ hội để các thành viên học code tiến theo con đường lập trình chân chính gần như 0%.

(*) những ngôn ngữ cho phép viết hàm chồng (như C++) dùng chính sách xào tên (name mangling) và dùng cái parameter list để phân biệt hàm chính thức được gọi cho nên những ngôn ngữ này gọi cái parameter list là "dấu ấn/chữ ký" (signature) của hàm.

(**) hầu hết các phần mềm hổ trợ lập trình (như Visual Studio) đều có cách tạo comments ngay đầu hàm theo kiểu XML để người sử dụng hàm có thể theo dõi giao diện hàm.

@phihndhsp:
Tôi viết những lời trên chủ yếu cho bạn, vì thấy bạn là giáo viên. Tuy bạn không cần phải dạy học viên như thế, nhưng nếu một dịp nào đó gặp được một học viên có năng khiếu lập trình thì những lời khuyên trên sẽ giúp cho học viên ấy tiến xa.

Em muốn được anh @VetMini chỉ giúp thêm về vấn đề này trong bài này luôn, em xin cảm ơn anh trước
xét về code hôm trước của em là như vậy (em có tiếp thu phần anh chỉ dẫn và có code theo kiểu function như anh em thấy rất ok và lấy làm tư liệu cho việc hướng dẫn). Tạm thời em muốn mổ xẻ code này một tí mong anh giúp đỡ, tạm thời em không đề cập đến cách call sao cho nó gọn, tạm thời em cứ call bình thường
Mã:
Sub InHoandon01(ByVal Sh As Worksheet, ByRef Arr_D(), ByRef k As Long)
Dim i As Long
Dim j As Long
Dim Kh As String
Dim DongCuoi As Long
Dim Arr_N()
Kh = Sheet7.Range("C4")
DongCuoi = Sh.Range("A10000").End(xlUp).Row
Arr_N = Sh.Range("A2:I" & DongCuoi)
For i = 1 To UBound(Arr_N, 1)
    If (Arr_N(i, 1) = Kh) Then
        k = k + 1
        Arr_D(k, 1) = Arr_N(i, 5)
        Arr_D(k, 2) = Arr_N(i, 2)
        Arr_D(k, 3) = Arr_N(i, 3)
        Arr_D(k, 4) = Arr_N(i, 8)
        Arr_D(k, 5) = Arr_N(i, 9)
        Arr_D(k, 6) = Arr_N(i, 7)
    End If
Next
End Sub
Sub main()
Dim k As Long
k = 0
    Dim Arr_D(1 To 10000, 1 To 7)
    Call InHoandon01(Sheet1, Arr_D, k)
    Call InHoandon01(Sheet10, Arr_D, k)
    Call InHoandon01(Sheet11, Arr_D, k)
    Call InHoandon01(Sheet4, Arr_D, k)
    Sheet7.Range("A9:Z1000").Clear
    Sheet7.Range("A9").Resize(k, 1).NumberFormat = "dd/mm/yyyy"
    Sheet7.Range("A9").Resize(k, 6) = Arr_D
    Sheet7.Range("D9").Resize(k, 3).NumberFormat = "#,##0.0"
    Sheet7.Range("A9").Resize(k + 1, 7).Borders.LineStyle = 1
   Sheet7.Range("C9").Offset(k, 1).Value = "Total"
   Sheet7.Range("A9").Offset(k, 0).Resize(1, 7).Interior.ColorIndex = 15
End Sub
Code này mà dùng sub em thấy cũng khá ổn, nhưng có một vấn đề là Arr_D() mình phải khai chết vì trong VBA nó chỉ cho thay đổi chiều cuối cùng của mảng, nên bài này mình phải gán chết số dòng cho Arr_D(), mà gán chết như vậy nó rất cứng nhắc
nên em có code lại bài này
Mã:
Type DanhMuc
  Ngay As Long
  Ten As String
  Soluong As Long
  DonGia As Long
  ThanhTien As Long
  Ship As Long
End Type

Sub InHoandon02(ByVal Sh As Worksheet, ByRef Arr_DM() As DanhMuc, ByRef k As Long)
Dim i As Long
Dim j As Long
Dim Kh As String
Dim DongCuoi As Long
Dim Arr_N()
Kh = Sheet7.Range("C4")
DongCuoi = Sh.Range("A10000").End(xlUp).Row
Arr_N = Sh.Range("A2:I" & DongCuoi)
For i = 1 To UBound(Arr_N, 1)
    If (Arr_N(i, 1) = Kh) Then
        k = k + 1
       ReDim Preserve Arr_DM(1 To  k)
        Arr_DM(k).Ngay = Arr_N(i, 5)
        Arr_DM(k).Ten = Arr_N(i, 2)
        Arr_DM(k).Soluong = Arr_N(i, 3)
        Arr_DM(k).DonGia = Arr_N(i, 8)
        Arr_DM(k).ThanhTien = Arr_N(i, 9)
        Arr_DM(k).Ship = Arr_N(i, 7)
    End If
Next
End Sub

Sub main()
Dim k As Long
Dim Arr_DM() As DanhMuc
Dim Arr_D()
k = 0
    Call InHoandon02(Sheet1, Arr_DM, k)
    Call InHoandon02(Sheet10, Arr_DM, k)
    Call InHoandon02(Sheet11, Arr_DM, k)
    Call InHoandon02(Sheet4, Arr_DM, k)
    ReDim Arr_D(1 To k, 1 To 6)
   For i = 1 To k
    Arr_D(i, 1) = Arr_DM(i).Ngay
    Arr_D(i, 2) = Arr_DM(i).Ten
    Arr_D(i, 3) = Arr_DM(i).Soluong
    Arr_D(i, 4) = Arr_DM(i).DonGia
    Arr_D(i, 5) = Arr_DM(i).ThanhTien
    Arr_D(i, 6) = Arr_DM(i).Ship
  Next
Sheet7.Range("A9:Z1000").Clear
Sheet7.Range("A9").Resize(k, 1).NumberFormat = "dd/mm/yyyy"
Sheet7.Range("A9").Resize(k, 6) = Arr_D
Sheet7.Range("D9").Resize(k, 3).NumberFormat = "#,##0.0"
Sheet7.Range("A9").Resize(k + 1, 7).Borders.LineStyle = 1
Sheet7.Range("C9").Offset(k, 1).Value = "Total"
Sheet7.Range("A9").Offset(k, 0).Resize(1, 7).Interior.ColorIndex = 15
End Sub
bài này ưu điểm là co giãn mảng nguồn vừa đủ nhưng nhược điểm là không sử dụng được thuộc tính .Resize, nên em muốn bun xuống sheet thì phải thông qua một bước trung gian. Anh có thể xem xét và cho em ý kiến để vấn đề được tối ưu hóa hơn, xin cảm ơn anh
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Em muốn được anh @VetMini chỉ giúp thêm về vấn đề này trong bài này luôn, em xin cảm ơn anh trước
xét về code hôm trước của em là như vậy (em có tiếp thu phần anh chỉ dẫn và có code theo kiểu function như anh em thấy rất ok và lấy làm tư liệu cho việc hướng dẫn). Tạm thời em muốn mổ xẻ code này một tí mong anh giúp đỡ, tạm thời em không đề cập đến cách call sao cho nó gọn, tạm thời em cứ call bình thường
...........................................................
bài này ưu điểm là co giãn mảng nguồn vừa đủ nhưng nhược điểm là không sử dụng được thuộc tính .Resize, nên em muốn bun xuống sheet thì phải thông qua một bước trung gian. Anh có thể xem xét và cho em ý kiến để vấn đề được tối ưu hóa hơn, xin cảm ơn anh
Anh biết em hỏi để hiểu biết thêm, nhưng anh có thắc mắc về cấu trúc:
1/ Thông thường sử dụng hóa đơn thì có số hóa đơn, nhưng ở sheet Hoa Don sao không có?
2/ Các sheet tháng sao không có cột số hóa đơn, nếu 1 khách hàng nào đó muốn in lại 1 hóa đơn nào đó thì làm thế nào để truy vấn lại và in riêng 1 hóa đơn?
 
Upvote 0
Anh biết em hỏi để hiểu biết thêm, nhưng anh có thắc mắc về cấu trúc:
1/ Thông thường sử dụng hóa đơn thì có số hóa đơn, nhưng ở sheet Hoa Don sao không có?
2/ Các sheet tháng sao không có cột số hóa đơn, nếu 1 khách hàng nào đó muốn in lại 1 hóa đơn nào đó thì làm thế nào để truy vấn lại và in riêng 1 hóa đơn?
dạ mấy cái này là em làm demo để hướng dẫn thôi anh, ghi là hóa đơn vậy, chứ nó thiếu tùm lum chi tiết trong đó hết hihi
 
Upvote 0
dạ mấy cái này là em làm demo để hướng dẫn thôi anh, ghi là hóa đơn vậy, chứ nó thiếu tùm lum chi tiết trong đó hết hihi
Theo anh biết thì bất kỳ 1 hóa đơn nào đó cũng đều có số hóa đơn, vì vậy anh nêu ra để em thiết kế cho phù hợp với thực tế nhằm tránh trường hợp anh em có thắc mắc sau này.
 
Upvote 0
Em muốn được anh @VetMini ...
bài này ưu điểm là co giãn mảng nguồn vừa đủ nhưng nhược điểm là không sử dụng được thuộc tính .Resize, nên em muốn bun xuống sheet thì phải thông qua một bước trung gian. Anh có thể xem xét và cho em ý kiến để vấn đề được tối ưu hóa hơn, xin cảm ơn anh
"tối ưu" theo quan niệm của tôi nó khác với nhiều người ở đây. Vì vậy nói chuyện hơi khó.
Trước mắt thì:
Type trong VBA chỉ là một hình thức nhóm các biến lại với nhau. Trên quan điểm "nhóm" thì bạn làm vậy là đúng rồi. Nếu muốn code trông rõ hơn thì cái phần trung gian cho qua một sub khác.

Theo tôi nghĩ thì có cách cầu kỳ hơn là dùng một mảng 2 chiều và một số dòng tối thiểu (10000 dòng?). Sau đó, cứ vượt quá giới hạn này thì chép nó vào mảng khác, nới thêm 10000 nữa... Tuy nhiên, chưa có thì giờ để thử.
 
Upvote 0
...
, nhưng có một vấn đề là Arr_D() mình phải khai chết vì trong VBA nó chỉ cho thay đổi chiều cuối cùng của mảng, nên bài này mình phải gán chết số dòng cho Arr_D(), mà gán chết như vậy nó rất cứng nhắc
...

Có 2 cách:

1. dùng dòng như cột, và cột như dòng. Như vậy mỗi lần Redim Preserve thì vẫn nới được số cột.
Khi cần gán xuống sheet thì dùng hàm transpose
Khuyết điểm: hàm transpose giới hạn số cột và dòng. Tôi không nhớ rõ con số giới hạn là bao nhiêu. Bạn phải tự thử.
Hàm transpose cũng giới hạn độ dài chuỗi mõi ô là 255 ký tự - cái này cũng cần thử lại.

2. dùng Array of Array. Như vậy mỗi lần Redim Preserve thì chỉ cần redim mảng ngoài.
Khi cần gán xuống sheet thì dùng hàm Index để chuyển thành mảng 2 chiều
Khuyết điểm: cũng bị giới hạn gần giống như transpose
Trông đẹp hơn cách 1 trên nhưng rất khó làm. Lúc làm việc phải dẫn cho VBA hiểu rằng "mọi mảng trong đều có dạng giống nhau". Nếu không thì hàm Index sẽ không chịu ép kiểu.
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT

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

Back
Top Bottom