HKNHKN
HKNHKN PRO
Thảo luận 6 thảo luận
Vỗ tay 0 vỗ tay
Lượt xem 388 lượt xem

Tôi có sub chạy copy dữ liệu từ sheet này sang sheet khác gọi là Sub

Tôi có sub chạy copy dữ liệu từ sheet này sang sheet khác gọi là Sub Tonghop (gán Macro vào một shape để run). Trong Sub này ngoài hỏi các thông tin đầu vào thì tôi có Call 1Sub Copy. Tuy nhiên khi kiểm tra kết quả thì thấy không có copy. Nhưng nếu tôi chạy tuần tự bằng phím F8 trong cửa sổ VBA thì nó thực hiện copy được. Ngoài ra Nếu tôi chạy lại Sub Tonghop với thay đổi thông tin đầu vào, thì khi copy nó lại ra dữ liệu của lần chạy trước không thành công. Rất mong được hỗ trợ. Cảm ơn.
Thảo luận 6 câu trả lời
Lượt xem 388 lượt xem
Vỗ tay vỗ tay
Dương Mạnh Quân [Chuyên gia] 14:05 - May 29, 2020
bạn gửi cả code nhé, vì không rõ code sẽ không biết bạn sai ở chỗ nào.
Thường khi lấy dữ liệu từ sheet này sang sheet khác (hay từ file này sang file khác) chúng ta sẽ không dùng lệnh copy paste mà dùng phương pháp lấy giá trị trực tiếp của đối tượng
sheet1.range(...).value = sheet2.range(...).value
Vấn đề bạn gặp phải có thể do quy trình lấy dữ liệu = copy paste diễn ra không đúng
Vỗ tay vỗ tay
HKNHKN 09:05 - May 30, 2020
Thầy nói đúng rồi. Đây là lần đầu tiên tôi viết VBA (chưa qua trường lớp nào cả, chỉ học trên Gitiho) mà lại lao vào 1 yêu cầu khó quá nên xảy ra trục trặc. Tôi dùng copy và paste, trong đó chỉ paste special giá trị value từ sheet này sang sheet khác. Tôi sẽ gửi đoạn lệnh và mong thầy chỉ cách tốt hơn và hiệu quả hơn.
Sub ChuyenDuLieuEvent() 'Xu ly o bang Input
'Xoa cac vung du lieu cu o bang Input
Sheets("Input").Range("A15:D1000").ClearContents
Sheets("Input").Range("L15:L1000").ClearContents
'Copy Date
Sheets("Temporary").ListObjects("Event").ListColumns("Date").DataBodyRange.Copy
Sheets("Input").Range("A15").PasteSpecial xlPasteValues
'Copy Time
Sheets("Temporary").ListObjects("Event").ListColumns("Time").DataBodyRange.Copy
Sheets("Input").Range("B15").PasteSpecial xlPasteValues
'Copy Event
Sheets("Temporary").ListObjects("Event").ListColumns("Event").DataBodyRange.Copy
Sheets("Input").Range("C15").PasteSpecial xlPasteValues
'Copy Event no.
Sheets("Temporary").ListObjects("Event").ListColumns("Event no.").DataBodyRange.Copy
Sheets("Input").Range("D15").PasteSpecial xlPasteValues
'Copy Shift
Sheets("Temporary").ListObjects("Event").ListColumns("Shift").DataBodyRange.Copy
Sheets("Input").Range("L15").PasteSpecial xlPasteValues
Application.CutCopyMode = False
End Sub
Vỗ tay vỗ tay
Dương Mạnh Quân [Chuyên gia] 10:05 - May 30, 2020
Sub ChuyenDuLieuEvent()
'Gán các biến worksheet để tránh nhầm lẫn
Dim ws1 as worksheet, ws2 as worksheet
Set ws1 = Sheets("Input")
Set ws2 = Sheets("Temporary")

'Xóa dữ liệu trước khi cập nhật nội dung mới
ws1.Range("A15:D1000").ClearContents
ws2.Range("L15:L1000").ClearContents

'Xác định phạm vi dữ liệu cần lấy
Dim lr as long
lr = ws2.cells("A" & rows.count).end(xlup).row
Dim PhamVi as long, DongDau as long
DongDau = 5 'Thay số 5 bằng dòng bắt đầu của bảng Temporary. Ở đây lấy ví dụ là giá trị = 5
PhamVi = lr - DongDau

'Lấy dữ liệu
ws1.range("A15:D" & 15 + PhamVi - 1).value = ws2.range("A" & DongDau & ":D" & lr).Value
ws1.range("L15:L" & 15 + PhamVi - 1).value = ws2.range("L" & DongDau & ":L" & lr).Value

'Xoa bien
set ws1 = nothing
set ws2 = nothing
End Sub

Tuy nhiên trong code trên sẽ có 1 vấn đề là khi cập nhật lần sau thì dữ liệu đang có trong ws1 sẽ bị mất và thay bằng dữ liệu mới.
Nếu muốn giữ lại dữ liệu cũ và chỉ lấy thêm dữ liệu mới vào thì bạn cần dùng code như sau:

Sub ChuyenDuLieuEvent2()
'Gán các biến worksheet để tránh nhầm lẫn
Dim ws1 as worksheet, ws2 as worksheet
Set ws1 = Sheets("Input")
Set ws2 = Sheets("Temporary")

'Xác định phạm vi dữ liệu cần lấy
Dim DongCuoi as long
DongCuoi = ws1.cells("A" & rows.count).end(xlup).row
Dim lr as long
lr = ws2.cells("A" & rows.count).end(xlup).row
Dim PhamVi as long, DongDau as long
DongDau = 5 'Thay số 5 bằng dòng bắt đầu của bảng Temporary. Ở đây lấy ví dụ là giá trị = 5
PhamVi = lr - DongDau

'Lấy dữ liệu
ws1.range("A" & DongCuoi +1 & ":D" & DongCuoi + PhamVi).value = ws2.range("A" & DongDau & ":D" & lr).Value
ws1.range("L" & DongCuoi +1 & ":L" & DongCuoi + PhamVi).value = ws2.range("L" & DongDau & ":L" & lr).Value

'Xoa bien
set ws1 = nothing
set ws2 = nothing
End Sub
Vỗ tay vỗ tay
Dương Mạnh Quân [Chuyên gia] 10:05 - May 30, 2020
Bạn xem kỹ trong chương 7 nhé.
Vỗ tay vỗ tay
HKNHKN 16:05 - May 30, 2020
Cảm ơn Thầy rất nhiều. Đọan code đã hoạt động rất hiệu quả.

Tuy nhiên, cũng có 1 thắc mắc như sau: Như đoạn Code đã gửi cho Thầy lúc đầu là thực hiện Copy từ dữ liệu từ 1 Data Table, nó được tạo ra từ Power Query (xử lý dữ liệu đầu vào hàng ngày) nên nó luôn biến động. Chính vì vậy trong các dòng lệnh có ghi DataBodyRange.
Ví dụ: Sheets("Temporary").ListObjects("Event").ListColumns("Date").DataBodyRange.Copy
Tôi cũng áp dụng cấp lấy trực tiếp theo hướng dẫn của Thầy và có biến tướng 1 chút nhưng nó vẫn bị xảy ra lỗi như đoạn Code gửi Thầy ban đầu.
Vì dụ: Sheets("Input").Range("A15:A" & 15 + vDataSourceRange - 1).value = Sheets("Temporary").ListObjects("Event").ListColumns("Date").DataBodyRange.value

Ngoài ra xin hỏi Thầy về cách dữ liệu có Transpose như thế nào. Cũng lấy dữ liệu từ Sheet1 có dữ liệu dạng "Đứng" trong 1 Data Table (tạo ra từ Power Query nên nó cũng biến động số hàng) để copy sang Sheet2 có dữ liệu dạng "Ngang".
Vỗ tay vỗ tay
Dương Mạnh Quân [Chuyên gia] 09:06 - Jun 01, 2020
Thường khi sử dụng power query nên hạn chế VBA. Bởi cơ chế VBA trên các đối tượng table, pivot, query khá phức tạp.
Việc xử lý VBA trên bảng biến động thì bạn cần quản lý theo dạng mảng hoặc theo 2 biến: dòng cuối và cột cuối.
Muốn transpose thì bạn cần xác định phạm vi vùng cần copy trước, dựa trên biến động dòng cuối, cột cuối. Sau đó dán dữ liệu ra bằng phương pháp dán transpose.
---
Theo mình các thao tác xử lý cấu trúc dữ liệu nếu đã làm trên power query thì bạn nên làm toàn bộ trên query (bao gồm cả các thao tác transpose)
Còn VBA thường chỉ ở phần đưa dữ liệu đầu vào (nạp dữ liệu vào bảng, quy trình thu thập dữ liệu) chứ ít khi dùng VBA can thiệp vào cấu trúc dữ liệu.
Vỗ tay vỗ tay
Câu hỏi liên quan
@ 2020 - Bản quyền của Công ty cổ phần công nghệ giáo dục Gitiho Việt Nam
Giấy chứng nhận Đăng ký doanh nghiệp số: 0109077145, cấp bởi Sở kế hoạch và đầu tư TP. Hà Nội