Import số liệu từ nhiều sheet (1 người xem)

Liên hệ QC

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

tuan.1985

Thành viên chính thức
Tham gia
25/3/13
Bài viết
77
Được thích
2
Em có code import số liệu từ nhiều file vào file tổng hợp như bên dưới
Vấn đề e gặp phải là phải khai báo tất cả các cột ở các file cần phải import vào file tổng, vì file em rất nhiều trường nên việc khai báo này mất rất nhiều time, nên post lên đây nhờ các anh chị giúp em có cách nào đơn giản hơn ah

Em cám ơn

Mã:
Option Explicit



Sub import_data()
    
    Dim DVKH As Worksheet, sh As Worksheet
    Dim wk As Workbook
    Dim strFolderPath As String
    Dim selectedFiles As Variant
    Dim iFileNum As Integer, iLastRowReport As Integer, iNumberOfRowsToPaste As Integer
    Dim strFileName As String
    Dim rDomain As Range, rInside As Range
    Dim iCurrentLastRow As Integer, iRowStartToPaste As Integer
    Dim startTime As Double
    Dim rep
     
    rep = MsgBox("Ban co muon lam moi du lieu khong?", vbYesNo)
    If rep = vbYes Then Sheet1.Range("A2:AH1000000").ClearContents
 
    getSpeed (True)
    Set DVKH = ActiveWorkbook.Sheets("PU")
    
    strFolderPath = ActiveWorkbook.Path
    
    ChDrive strFolderPath
    ChDir strFolderPath
    
    On Error GoTo NoFileSelected
    selectedFiles = Application.GetOpenFilename( _
                    filefilter:="Excel Files (*.xls*),*.xlsx*", MultiSelect:=True)
                    
    startTime = Timer
    
    For iFileNum = LBound(selectedFiles) To UBound(selectedFiles)
        strFileName = selectedFiles(iFileNum)
        
        
        Set wk = Workbooks.Open(strFileName)
        For Each sh In wk.Sheets
            If sh.Name Like "PU" Then
                With sh
                    iLastRowReport = .Range("A" & Rows.Count).End(xlUp).Row
                    iNumberOfRowsToPaste = iLastRowReport - 2 + 1
                    
                    Set rDomain = .Range("A2:A" & iLastRowReport)
                    Set rInside = .Range("B2:C" & iLastRowReport)
              
                    
                    With DVKH
                            iCurrentLastRow = .Range("A" & Rows.Count).End(xlUp).Row
                            iRowStartToPaste = iCurrentLastRow + 1
                        
                        .Range("A" & iRowStartToPaste).Resize(iNumberOfRowsToPaste, 1) = rDomain.Value2
                        .Range("C" & iRowStartToPaste).Resize(iNumberOfRowsToPaste, 1) = rInside.Value2
                    End With
                    
                End With
            End If
        Next sh
        wk.Close
    Next
    
    MsgBox "Done in " & Int(Timer - startTime) & " s."
    getSpeed (False)
NoFileSelected:
    MsgBox "Chua co file nao duoc chon!"
End Sub


Function getSpeed(doIt As Boolean)
    Application.ScreenUpdating = Not (doIt)
    Application.EnableEvents = Not (doIt)
    Application.Calculation = IIf(doIt, xlCalculationManual, xlCalculationAutomatic)
End Function
 
Rất cám ơn a hpkhuong em đã làm được rồi ah
Tuy nhiên khi chạy nó báo lỗi phải debug nhưng end nó vẫn pass value e vào
Em gửi file đính kèm anh xem thử ah

P/S:
Em mới học nên hơi chậm có gì thiếu sót mong anh thông cảm
Bữa giờ anh hpkhuong hỗ trợ em nhiều, em rất mong được gặp anh để gửi lời cảm ơn đến anh được hok ah
 

File đính kèm

Upvote 0
Dạ vâng
Đúng như ý em rồi ah
Em cám ơn anh nhiều lắm
 
Upvote 0
Sau thời gian chạy tuần này em làm báo cáo thì phát sinh thêm một nhu cầu nữa nhờ anh chị hỗ trợ em với ah:


Hiện tại như sau:


1. File DVKH_RP là để tổng hợp số liệu từ rất nhiều file và em gửi 2 file đính kèm ví dụ là DVKH_1 và file DVKH_2
2. Với code hiện tại như file đính kèm, mỗi lần report em chỉ click vào nút RP trên sheet thì số liệu đổ về để em làm báo cáo


Như vậy đã giải quyết vấn đề, nhưng giờ chạy thực tế thì phát sinh nhu cầu là:


1. Khi cần report Click nút RP trên sheet của file DVKH_RP thì dữ liệu tự động đổ về và:
2. Những dữ liệu nào mà ở trường Domain của file DVKH_RP đã có (trùng) thì không nhập vào nữa chỉ nhập những dữ liệu nào mà trường Domain của file DVKH_RP không trùng lặp


ví dụ:


DVKH_1 tuần 1 có dữ liệu là


Domain Tên KH
11 11


DVKH_2 tuần 1 có dữ liệu là


Domain Tên KH
22 22


Tuần 1 em import dữ liệu vào file tổng thành
Domain Tên KH
11 11
22 22


Sang tuần 2 các bạn nhập liệu tiếp vào như sau


DVKH_1 tuần 2 có dữ liệu là


Domain Tên KH
11 11
111 111


DVKH_2 tuần 2 có dữ liệu là


Domain Tên KH
22 22
222 222


Tuần 2 em import dữ liệu vào file tổng thành
Domain Tên KH
11 11
22 22
111 111
222 222
 

File đính kèm

Upvote 0
Nói thật là anh chàng chủ topic muốn gì nữa mình cũng không hiểu nổi. Nhưng trong code đã có câu lệnh này trước khi vào vòng lặp thì nó đã xóa bắn cái dữ liệu cũ rồi còn gì:
Mã:
WsMain.[A2:I65000].ClearContents
Chả hiểu nỗi anh chàng đó muốn gì...--=0--=0--=0
ôi bạn thật chu đáo . Tôi còn chưa tải file về xem nữa , chỉ phản xạ trả lời thôi
 
Upvote 0
tại vì sau khi tổng hợp từ các bạn team DVKH về thì một team QA sẽ lấy thông tin đổ về này làm việc ở những cột tiếp theo trong file tổng hợp

Nên với đoạn code
Mã:
[COLOR=#000000][I]WsMain.[A2:I65000].ClearContents[/I][/COLOR]

Thì khi import số liệu vào thì các cột làm việc của bạn QA trước đây sẽ không khớp với dữ liệu củ đưa về

Do vậy mình chỉ muốn mỗi khi import vào thì dữ liệu củ vẫn dữ nguyên đúng dòng đã import trước đó, dữ liệu mới import vào nếu giống dữ liệu củ thì hok import chỉ import những dòng giữ liệu mà không giống vs dữ liệu củ.

Việc giống, hok giống giữ liệu củ được lấy bằng trường Domain làm chuẩn
 
Upvote 0
Em có code import số liệu từ nhiều file vào file tổng hợp như bên dưới
Vấn đề e gặp phải là phải khai báo tất cả các cột ở các file cần phải import vào file tổng, vì file em rất nhiều trường nên việc khai báo này mất rất nhiều time, nên post lên đây nhờ các anh chị giúp em có cách nào đơn giản hơn ah

Em cám ơn

Mã:
Option Explicit



Sub import_data()
    
    Dim DVKH As Worksheet, sh As Worksheet
    Dim wk As Workbook
    Dim strFolderPath As String
    Dim selectedFiles As Variant
    Dim iFileNum As Integer, iLastRowReport As Integer, iNumberOfRowsToPaste As Integer
    Dim strFileName As String
    Dim rDomain As Range, rInside As Range
    Dim iCurrentLastRow As Integer, iRowStartToPaste As Integer
    Dim startTime As Double
    Dim rep
     
    rep = MsgBox("Ban co muon lam moi du lieu khong?", vbYesNo)
    If rep = vbYes Then Sheet1.Range("A2:AH1000000").ClearContents
 
    getSpeed (True)
    Set DVKH = ActiveWorkbook.Sheets("PU")
    
    strFolderPath = ActiveWorkbook.Path
    
    ChDrive strFolderPath
    ChDir strFolderPath
    
    On Error GoTo NoFileSelected
    selectedFiles = Application.GetOpenFilename( _
                    filefilter:="Excel Files (*.xls*),*.xlsx*", MultiSelect:=True)
                    
    startTime = Timer
    
    For iFileNum = LBound(selectedFiles) To UBound(selectedFiles)
        strFileName = selectedFiles(iFileNum)
        
        
        Set wk = Workbooks.Open(strFileName)
        For Each sh In wk.Sheets
            If sh.Name Like "PU" Then
                With sh
                    iLastRowReport = .Range("A" & Rows.Count).End(xlUp).Row
                    iNumberOfRowsToPaste = iLastRowReport - 2 + 1
                    
                    Set rDomain = .Range("A2:A" & iLastRowReport)
                    Set rInside = .Range("B2:C" & iLastRowReport)
              
                    
                    With DVKH
                            iCurrentLastRow = .Range("A" & Rows.Count).End(xlUp).Row
                            iRowStartToPaste = iCurrentLastRow + 1
                        
                        .Range("A" & iRowStartToPaste).Resize(iNumberOfRowsToPaste, 1) = rDomain.Value2
                        .Range("C" & iRowStartToPaste).Resize(iNumberOfRowsToPaste, 1) = rInside.Value2
                    End With
                    
                End With
            End If
        Next sh
        wk.Close
    Next
    
    MsgBox "Done in " & Int(Timer - startTime) & " s."
    getSpeed (False)
NoFileSelected:
    MsgBox "Chua co file nao duoc chon!"
End Sub


Function getSpeed(doIt As Boolean)
    Application.ScreenUpdating = Not (doIt)
    Application.EnableEvents = Not (doIt)
    Application.Calculation = IIf(doIt, xlCalculationManual, xlCalculationAutomatic)
End Function
Đây là code nguyên bản của bạn ĐT Nguyễn [Excel] trên youtube mà. Bạn mà xem hết clip đó, chắc chắn bạn sửa đc theo ý bạn. Bạn chịu khó xem hết clip đi nhé.
 
Upvote 0
tại vì sau khi tổng hợp từ các bạn team DVKH về thì một team QA sẽ lấy thông tin đổ về này làm việc ở những cột tiếp theo trong file tổng hợp

Nên với đoạn code
Mã:
[COLOR=#000000][I]WsMain.[A2:I65000].ClearContents[/I][/COLOR]

Thì khi import số liệu vào thì các cột làm việc của bạn QA trước đây sẽ không khớp với dữ liệu củ đưa về

Do vậy mình chỉ muốn mỗi khi import vào thì dữ liệu củ vẫn dữ nguyên đúng dòng đã import trước đó, dữ liệu mới import vào nếu giống dữ liệu củ thì hok import chỉ import những dòng giữ liệu mà không giống vs dữ liệu củ.

Việc giống, hok giống giữ liệu củ được lấy bằng trường Domain làm chuẩn

dữ liệu các file con thật ra khoảng bao nhiêu dòng ? 10 000 , 20 000 , 100 000 ?
 
Upvote 0
mỗi bạn 1 tháng tầm 2k dòng mà có 20 bạn như vậy ah
 
Upvote 0
mỗi bạn 1 tháng tầm 2k dòng mà có 20 bạn như vậy ah
lấy về xài thử
Mã:
Public Sub hello()
Dim arr, r As Long, i As Byte, lr As Long, lrA As Long, filenames, Dic As Object
Dim Adr As String, fso As Object, k As Long, c As Byte, dArr(1 To 500000, 1 To 9)
With Sheet1
    lrA = .[A65000].End(xlUp).Row + 1
    Set Dic = CreateObject("scripting.dictionary")
    Set fso = CreateObject("Scripting.FileSystemObject")
    arr = .Range("A2:A" & lrA).Value
    If lrA > 2 Then
        For r = 1 To UBound(arr) - 1 Step 1
            Dic(arr(r, 1)) = 1
        Next
    End If
    filenames = .Range("K2:K" & .[K65000].End(xlUp).Row + 1).Value
    .Range("BA1").Resize(10000, 9).ClearContents
    For i = 1 To UBound(filenames) - 1 Step 1
        Adr = "'" & fso.GetParentFolderName(filenames(i, 1)) & "\[" & _
              fso.GetFileName(filenames(i, 1)) & "]PU'!"
        .[BA1] = "=IFERROR(LOOKUP(2,1/(" & Adr & "A1:A10000<>""""),ROW(A1:A10000)),0)"
        lr = .[BA1]
        If lr > 1 Then
            .Range("BA2").Resize(lr - 1, 9).FormulaArray = "=if(" & Adr & "A2:I" & lr & _
                "="""",""""," & Adr & "A2:I" & lr & ")"
            arr = .Range("BA2").Resize(lr - 1, 9).Value
            For r = 1 To UBound(arr) Step 1
                If Not Dic.exists(arr(r, 1)) Then
                    k = k + 1
                    For c = 1 To 9 Step 1
                        dArr(k, c) = arr(r, c)
                    Next
                End If
            Next
            .Range("BA1").Resize(lr, 9).ClearContents
        End If
    Next
    If k > 0 Then
        .Range("A" & lrA).Resize(k, 9).Value = dArr
    End If
End With
End Sub
 
Upvote 0
Có chút gì đó không ổn chăng?:

1. Hiện cửa sổ chọn file, chọn xong. Hỏi lại 2 lần cửa sổ ấy nữa
2. Thêm dữ liệu tiếp theo vào file nguồn....Chạy code và có hiện tượng này với dữ liệu mới thêm...Từ cột B trở đi là #REF!
#REF! Dấu hiệu không tốt...--=0--=0--=0

ồ cám ơn bạn , mình rất thích nghe những ý kiến chê bai , chỉ trích (thân lừa ưa nặng mà)
code ở trên cơ bản là không có dòng nào dùng để bắn lên cửa sổ chọn file cả
chữ #REF nghĩa là gì bạn biết rồi đó , nghĩa là đường dẫn nằm ở cột K không có thật
điều đó nằm ngoài khả năng viết code của người thiết kế
Nếu như đường dẫn ở cột K là có thật và file đó có sheet PU mà vẫn báo lỗi #REF thì xin bạn up file đó lên đây để mình xem lại
 
Upvote 0
Không đê ý vụ dường dẫn. Mới test lại đường dẫn.

1. Thử làm 2 FIle con khi import lần đầu ok. Dữ liệu file thứ 1 điền vào, tiếp theo là dữ liệu của file thứ 2
2. Giờ Thử thêm dữ liệu ở 1 file con dầu tiên. Tiến hành chạy code thì báo lỗi ngày dòng có công thức mảng: FormulaArray

haha......Thánh soi ...--=0--=0--=0

mình vẫn đang nghe đây bạn . bạn cho mình xin các file chạy bị lỗi đi bạn
 
Upvote 0
Vâng đúng như ý em rồi ah

Với code như vậy giúp ích em rất nhiều trong công việc hiện tại của em

Em rất muốn được hậu tạ các anh chị

Em sẽ inbox các anh chị mong anh chị nhận lời cám ơn của em
 
Upvote 0
Vâng đúng như ý em rồi ah

Với code như vậy giúp ích em rất nhiều trong công việc hiện tại của em

Em rất muốn được hậu tạ các anh chị

Em sẽ inbox các anh chị mong anh chị nhận lời cám ơn của em

tỏ thái độ cảm ơn là được , tôi không câu nệ hình thức , và càng không viết code vì mục đích để nhận hậu tạ của ai cả
bạn cảm thấy đã được giúp đỡ cho công việc thì sau này khi có ai cần bạn giúp , bạn hãy nhớ đến ngày hôm nay . Vậy thôi
 
Upvote 0
doveandrose giúp mình file này , chuyển từ bảng một sang bảng rút gọn bằng VBA
 
Upvote 0
lấy về xài thử
Mã:
Public Sub hello()
Dim arr, r As Long, i As Byte, lr As Long, lrA As Long, filenames, Dic As Object
Dim Adr As String, fso As Object, k As Long, c As Byte, dArr(1 To 500000, 1 To 9)
With Sheet1
    lrA = .[A65000].End(xlUp).Row + 1
    Set Dic = CreateObject("scripting.dictionary")
    Set fso = CreateObject("Scripting.FileSystemObject")
    arr = .Range("A2:A" & lrA).Value
    If lrA > 2 Then
        For r = 1 To UBound(arr) - 1 Step 1
            Dic(arr(r, 1)) = 1
        Next
    End If
    filenames = .Range("K2:K" & .[K65000].End(xlUp).Row + 1).Value
    .Range("BA1").Resize(10000, 9).ClearContents
    For i = 1 To UBound(filenames) - 1 Step 1
        Adr = "'" & fso.GetParentFolderName(filenames(i, 1)) & "\[" & _
              fso.GetFileName(filenames(i, 1)) & "]PU'!"
        .[BA1] = "=IFERROR(LOOKUP(2,1/(" & Adr & "A1:A10000<>""""),ROW(A1:A10000)),0)"
        lr = .[BA1]
        If lr > 1 Then
            .Range("BA2").Resize(lr - 1, 9).FormulaArray = "=if(" & Adr & "A2:I" & lr & _
                "="""",""""," & Adr & "A2:I" & lr & ")"
            arr = .Range("BA2").Resize(lr - 1, 9).Value
            For r = 1 To UBound(arr) Step 1
                If Not Dic.exists(arr(r, 1)) Then
                    k = k + 1
                    For c = 1 To 9 Step 1
                        dArr(k, c) = arr(r, c)
                    Next
                End If
            Next
            .Range("BA1").Resize(lr, 9).ClearContents
        End If
    Next
    If k > 0 Then
        .Range("A" & lrA).Resize(k, 9).Value = dArr
    End If
End With
End Sub

Anh ơi code này đã đáp ứng nhu cầu của em, nhưng khi chạy vào thực tế thì em lại phát sinh nhu cầu nữa ah, cụ thể em mô tả như sau:

Với đoạn code này thì trong file tổng hợp khi import số liệu từ các file khác (file con) vào thì dòng nào ở cột Domain có giá trị rồi thì sẽ không import dòng đó vào file tổng hợp

Bây giờ lại phát sinh nhu cầu nữa là:

file tổng hợp khi import số liệu từ các file khác (file con) vào thì dòng nào ở cột Domain có giá trị rồi thì sẽ đè giá trị mới nhất của dòng đó ở file con đúng ngay dòng đó vào file tổng hợp

Em ví dụ trong file đính kèm ah

Nhờ các anh hỗ trợ giúp em với ah
 

File đính kèm

Upvote 0
Web KT

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

Back
Top Bottom