Cách tối ưu lấy dữ liệu từ workbook sang workbook khác?

Liên hệ QC

LearnExcel

Thành viên thường trực
Tham gia
7/8/06
Bài viết
292
Được thích
519
Chào các anh chị. Tôi đang viết một ứng dụng làm báo cáo sản xuất như sau:
Một báo cáo ca (mỗi tháng 1 book, ngày gồm 3 ca = 93 sheets).
Một báo cáo tổng hợp hàng ngày (mỗi tháng 1 book, ngày gồm 1 tờ = 31 sheets).
Vì dữ liệu khá nhiều nên không thiết kế dạng Form mà trình bày dạng Worksheet Form (cũng là Report luôn). Cũng vì lý do trên nên việc tổ chức CSDL chưa làm được.

Khi làm báo cáo tổng hợp từ 3 ca sang 1 ngày thì có vài phương pháp lấy dữ liệu từ BC ca sang BC ngày như sau:
  • Sử dụng ADODB (file nguồn vẫn đóng)
  • Sử dụng XLMMacro (file nguồn vẫn đóng)
  • Sử dụng chức năng mở file nguồn lấy dữ liệu dán qua file đích rồi đóng lại.

Câu hỏi : Làm cách nào trong 3 cách trên tối ưu nhất (tốc độ cao, tốn ít tài nguyên, code đơn giản, dễ bảo dưỡng sửa chữa...)? Còn cách nào tốt hơn mấy cách trên?

Cảm ơn anh/ chị quan tâm và cho ý kiến!
 

File đính kèm

__________________
Thành viên sau cảm ơn LearnExcel về bài viết này:
Tom Cruise, Mat Damon, Sylvester Stallone, Angelina Jolie,Pierce Brosnan,Dr. No,Casino Royale,Quantum of Solace, Die Another Day
oh, LearnExcel dùng chữ ký lạ quá - cứ tưởng nhầm nhiều người cảm ơn!!! hix
.

  • Sử dụng ADODB (file nguồn vẫn đóng)
  • Sử dụng XLMMacro (file nguồn vẫn đóng)
  • Sử dụng chức năng mở file nguồn lấy dữ liệu dán qua file đích rồi đóng lại.

Sử dụng ADODB,XLMMacro -> cho phép không cần mở file -> dường như nhanh hơn, nhưng lại phải thiết lập các thông tin truyền cho ADO , hay phân tích cấu trúc XML --> vì thế cách này sẽ hiệu quả nếu file workbook có nhiều DL cần copy (kiểu sử dụng dao phay mổ bò đó), bên cạnh đó CODE cũng k đơn giản và phụ thuộc nhiều vào sự kết nối -> vì thế nếu dữ liệu, Project lớn mới đáng bát gạo

trái lại mở trực tiếp Workbook -> mất thời gian mở đóng file, nhưng code đơn giản và trực tiếp cho excel quản lý (-> kết nối nhanh hơn) ==> vì thế hiệu quả ứng dụng cho các file nhỏ và project nhỏ và vừa

một vài ý vậy bạn nhé
 
Lần chỉnh sửa cuối:
Upvote 0
Theo tôi nghĩ thì tùy dữ liệu mà dùng trong 3 cách trên. Ví dụ: nếu dữ liệu lớn trên 10.000 dòng thì nên dùng cách một thì tốc độ mới nhanh được, ở công ty của tôi dữ liệu dưới 1000 dòng nên tôi dùng cách 3 là hay nhất.

Bạn hỏi có cách khác không, thì có đó là dùng phần mền chuyên nghiệp về nó, cách này phải mua phần mềm rất tốn tiền, nhưng mà bảo đảm nhanh nhất.
 
Upvote 0
Hi !

Theo Tôi cách 1 là tối hay nhất vì chiếm rất ít tài nguyên máy khi làm việc.
Hiện tại tôi còn đang còn bị vưóng ở chỗ, nếu dữ liệu file nguồn có chứa nhiều tham chiếu thì khi lấy sang file đích sẽ bị mất ô chứa dữ liệu, mà vẫn chưa có cách khắc phục.

Thân.
 
Upvote 0
Adodb???

Hi !

Theo Tôi cách 1 là tối hay nhất vì chiếm rất ít tài nguyên máy khi làm việc.
Hiện tại tôi còn đang còn bị vưóng ở chỗ, nếu dữ liệu file nguồn có chứa nhiều tham chiếu thì khi lấy sang file đích sẽ bị mất ô chứa dữ liệu, mà vẫn chưa có cách khắc phục.

Thân.

ADODB có lẽ thích hợp cho việc lấy một mảng dữ liệu VD 50 hàng x 20 cột (liên tục)

Tất nhiên có thể lấy một cell thôi (khai biến sRange chỉ định 1 cell, VD "A1:A1"), nhưng khoảng 20 cell nằm rải rác trên Form Report thì có lẽ dùng XLMMacro nhẹ hơn ADODB chăng?

tất nhiên 2 cách này lấy dữ liệu từ file không cài mật khẩu.

Còn có cài MK thì phải Open rồi Close thôi.

PHP:
'Read data from a closed workbook using ADO

'The following code reads data from closed Excel workbooks using ADO with an ODBC driver.

'Purpose     :  Extracts data from a closed workbook to an array
'Inputs      :  sSourceFile                     The path and file name of the workbook to read data from.
'               sRange                          The range reference (or named range) to read the data from.
'               [sSheetName]                    The name of the sheet to return the data from. If not specified returns
'                                               data from first sheet.
'               [bReturnHeadings]               If True returns the Column Headings (i.e. the first row in the range).
'                                               Note: This alters the shape of the output array to an array in an array.
'Outputs     :  Returns a 2d variant array containing the values in the specified range.
'Notes       :  Requires a reference to the Microsoft ActiveX Data Objects library
'               Could also use OLEDB JET 4.0 Driver "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & sSourceFile & ";Extended Properties=""Excel 8.0;HDR=Yes"""


Function WorkbookReadRange(sSourceFile As String, sRange As String, Optional sSheetName As String, Optional bReturnHeadings As Boolean) As Variant
    Dim conWkb As ADODB.Connection, rsWkbCells As ADODB.Recordset, sConString As String
    Dim lThisField As Long, avResults As Variant, avHeadings As Variant

    On Error GoTo ErrFailed
    sConString = "DRIVER={Microsoft Excel Driver (*.xls)};ReadOnly=1;DBQ=" & sSourceFile
    Set conWkb = New ADODB.Connection
    'open connection
    conWkb.Open sConString
    If Len(sSheetName) Then
        'Get data from specified sheet
        Set rsWkbCells = conWkb.Execute("Select * from " & Chr(34) & sSheetName & "$" & sRange & Chr$(34))
    Else
        'Get data from first sheet
        Set rsWkbCells = conWkb.Execute("Select * from " & sRange)
    End If
    If rsWkbCells.EOF Then
        'Return a 1d array
        'Get headings
        ReDim avHeadings(0 To 0, 0 To rsWkbCells.Fields.Count - 1)
        For lThisField = 0 To rsWkbCells.Fields.Count - 1
            avHeadings(0, lThisField) = rsWkbCells.Fields(lThisField).Name
        Next
        WorkbookReadRange = avHeadings
    Else
        'Return a 2d array
        If bReturnHeadings Then
            'Get cells
            avResults = rsWkbCells.GetRows
            'Get headings
            ReDim avHeadings(0 To rsWkbCells.Fields.Count - 1, 0 To 0)
            For lThisField = 0 To rsWkbCells.Fields.Count - 1
                avHeadings(lThisField, 0) = rsWkbCells.Fields(lThisField).Name
            Next
            WorkbookReadRange = Array(avHeadings, avResults)
        Else
            'Get cells
            WorkbookReadRange = rsWkbCells.GetRows
        End If
    End If
    'Disconnect and destroy DB objects
    rsWkbCells.Close
    conWkb.Close
    Set rsWkbCells = Nothing
    Set conWkb = Nothing
    On Error GoTo 0
    Exit Function

ErrFailed:
    'Return error message
    WorkbookReadRange = Err.Description

    If conWkb.State <> adStateClosed Then
        conWkb.Close
    End If

    Set rsWkbCells = Nothing
    Set conWkb = Nothing
End Function

'Demonstration Routine
Sub TestADO()
    Dim avCellValues As Variant, vThisCell As Variant
    avCellValues = WorkbookReadRange("F:\My Documents\Papakinkin\HomeWorks\PX1-TC-05.2008.xls", "A1:L10000", "A.01.05.2008-FM")
    If IsArray(avCellValues) Then
        Sheets(1).Range("A1:L10000") = avCellValues
    End If
End Sub
 
Upvote 0
To LearnExcel

Cảm ơn bạn, bạn cho mình file mẫu nhen.

Thân.
 
Upvote 0
Với chừng bấy nhiêu dữ liệu trên file ID.xls thì việc lấy dữ liệu trên file CALCULATOR như thế nào là hiệu quả nhất?
Việc tổ chức sắp xiếp dữ liệu trên file ID như vậy có tối ưu chưa? làm sao để khi thay đổi số liệu cũng như cập nhật thêm ID sẽ trở nên dễ dàng hơn. do có nhiều workbook và nhiều người sử dụng khác nhau lấy thông tin trên ID nhưng đảm bảo tính nhất quán tại mỗi thời điểm.
Xin các thành viên có kinh nghiệm góp ý để việc tính toán được tối ưu.
Mọi ý kiến xin được cảm ơn!
 

File đính kèm

Upvote 0
Web KT

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

Back
Top Bottom