2010-09-28 66 views
6

Trước tiên, tôi muốn nói rằng tôi đang ở trên nước sâu ở đây, vì tôi chỉ thực hiện một số thay đổi đối với mã được viết bởi người khác trong công ty, sử dụng OleDbDataAdapter để "nói chuyện" với Excel và tôi không quen thuộc với điều đó. Có một lỗi ở đó tôi không thể làm theo.Vấn đề với việc sử dụng OleDbDataAdapter để lấy dữ liệu từ một trang tính Excel

Tôi đang cố gắng sử dụng OleDbDataAdapter để đọc trong một tệp excel với khoảng 450 dòng.

Trong đoạn mã nó được thực hiện như thế này:

connection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source='" + path + "';" + "Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1;\""); 
connection.Open(); 
OleDbDataAdapter objAdapter = new OleDbDataAdapter(objCommand.CommandText, connection); 
objAdapter.Fill(objDataSet, "Excel"); 

foreach (DataColumn dataColumn in objTable.Columns) { 
    if (dataColumn.Ordinal > objDataSet.Tables[0].Columns.Count - 1) { 
    objDataSet.Tables[0].Columns.Add(); 
    } 
    objDataSet.Tables[0].Columns[dataColumn.Ordinal].ColumnName = dataColumn.ColumnName; 
    objImport.Columns.Add(dataColumn.ColumnName); 
} 

foreach (DataRow dataRow in objDataSet.Tables[0].Rows) { 
    ... 
} 

Tất cả mọi thứ dường như được làm việc tốt, ngoại trừ một điều. Cột thứ hai được làm đầy với số lượng chủ yếu là bốn chữ số như 6739, 3920 và một, nhưng các hàng liên kết có các giá trị chữ và số như 8201NO và 8205NO. Năm ô này được báo cáo là có nội dung trống thay vì nội dung chữ và số của chúng. Tôi đã kiểm tra trong excel, và tất cả các tế bào trong các cột này được đánh dấu là văn bản.

Đây là tệp xls bằng cách này chứ không phải xlsx.

Có ai có bất kỳ đầu mối nào vì sao các ô này được hiển thị dưới dạng trống trong DataRow, nhưng các ô số được hiển thị không? Có các cột khác có nội dung chữ và số được hiển thị tốt.

+0

Nhờ tất cả vì đã giúp tôi ra với vấn đề này. Bạn đã làm cho tôi hiểu tại sao điều này xảy ra, vì vậy tôi có thể tìm ra giải pháp thích hợp. Tôi vẫn nghĩ cách nó hoạt động khá khủng khiếp, nhưng đó là một câu chuyện khác :) –

Trả lời

8

Điều đang xảy ra là excel đang cố gắng chỉ định loại dữ liệu cho cột bảng tính dựa trên một số giá trị đầu tiên trong cột đó. Tôi nghi ngờ rằng nếu bạn nhìn vào các thuộc tính trong cột đó, nó sẽ nói nó là một cột số.

Sự cố xảy ra khi bạn bắt đầu cố truy vấn bảng tính đó bằng máy bay phản lực. Khi nó nghĩ rằng nó đối phó với một cột số và nó tìm thấy một giá trị varchar nó lặng lẽ trả về không có gì. Thậm chí không phải là một thông báo lỗi khó hiểu để tắt.

Khi có thể, bạn có thể di chuyển một trong các giá trị số alpha sang hàng dữ liệu đầu tiên và sau đó thử phân tích cú pháp. Tôi nghi ngờ bạn sẽ bắt đầu nhận được giá trị cho các hàng số alpha sau đó ...

Hãy xem this article. Nó đi vào chi tiết hơn về vấn đề này. nó cũng nói về một tác phẩm có thể xung quanh đó là:

Tuy nhiên, theo tài liệu JET, chúng tôi có thể ghi đè lên các thiết lập qua các chuỗi kết nối registry, nếu chúng ta đặt IMEX = 1 (là một phần của Extended Thuộc tính), JET sẽ đặt loại cột tất cả như UNICODE VARCHAR hoặc ADVARWCHAR không phân biệt 'ImportMixedTypes' chìa khóa value.hey

+0

Tôi đã thử nghiệm điều này ngay bây giờ, và thực sự nếu tôi đặt hàng chữ số đầu tiên, sau đó nó hoạt động như mong đợi. Vấn đề của tôi là tôi không thể thực hiện điều này một quy tắc chung, vì khách hàng sẽ đọc trong tờ của riêng họ. Tuy nhiên, giải pháp của tôi là "gian lận", để tôi thay đổi HDR = Không trong chuỗi kết nối để đảm bảo rằng tiêu đề chữ và số được đọc để tạo cột chữ và số, sau đó tôi cắt dòng đầu tiên của DataTable kết quả. Nó khá khó chịu, nhưng tôi không thấy bất kỳ lựa chọn nào khác ở đây. Cảm ơn bạn rất nhiều vì đã giúp tôi đi đúng hướng. –

+0

Rất lén lút. Nếu nó hoạt động nó hoạt động! –

1

IMEX=1 có nghĩa là "đọc dữ liệu hỗn hợp dưới dạng văn bản."

Tuy nhiên, có một số gotchas. Máy bay phản lực sẽ chỉ sử dụng một vài hàng để xác định liệu dữ liệu có bị trộn hay không và nếu có thì các hàng này đều là số, bạn sẽ nhận được hành vi này.

Xem connectionstrings.com để biết chi tiết:

Kiểm tra các [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel] nằm registry REG_DWORD "TypeGuessRows". Đó là chìa khóa để không cho phép Excel chỉ sử dụng 8 hàng đầu tiên để đoán loại dữ liệu cột. Đặt giá trị này thành 0 để quét tất cả các hàng. Điều này có thể làm tổn thương hiệu suất.Cũng xin lưu ý rằng việc thêm tùy chọn IMEX = 1 có thể khiến tính năng IMEX được đặt sau chỉ 8 hàng. Sử dụng IMEX = 0 để chắc chắn buộc đăng ký TypeGuessRows = 0 (quét tất cả các hàng) để hoạt động.

+0

Tôi không biết Jet được hiển thị như thế nào trong Excel, nhưng trong Access, bạn có thể thay đổi những thứ như vậy trong thời gian chạy trong phiên bản hiện tại của công cụ Jet db mà không phải thay đổi sổ đăng ký và khởi động lại Access. –

+0

Cảm ơn thông tin này. Nó hoạt động nhưng đáng ngạc nhiên là chậm, vì vậy tôi phải đi với mẹo "đọc và vứt bỏ tiêu đề" thay thế. –

1

Tôi khuyên bạn không nên sử dụng công cụ cung cấp dữ liệu OleDb để truy cập Excel nếu bạn có thể trợ giúp. Tôi đã không có gì ngoài vấn đề, vì chính xác những lý do mà những người khác đã chỉ ra. Hiệu suất có xu hướng xấu xa khi bạn đang xử lý các bảng tính lớn.

Bạn có thể thử giải pháp mã nguồn mở này: http://exceldatareader.codeplex.com/

+0

Tôi hoàn toàn đồng ý với bạn Mark. Tôi nghĩ rằng nó khá khủng khiếp, nhưng trong trường hợp này tôi không có bất kỳ tùy chọn nào khi tôi được chỉ định sửa chữa lỗi này trong một chương trình hiện có và không được bỏ thời gian để thực hiện bất kỳ phép cấu trúc lại lớn nào. Tôi sẽ giữ liên kết của bạn trong tâm trí nếu tôi cần phải làm điều này từ đầu sau này. –

Các vấn đề liên quan