Tương tác Excel: _ Trang tính hay Trang tính?


76

Tôi hiện đang viết về kiểu nhập động và tôi đang đưa ra một ví dụ về phép tương tác trong Excel. Tôi hầu như không thực hiện bất kỳ tương tác Office nào trước đây và nó hiển thị. Các MSDN Văn phòng Interop hướng dẫn cho C # 4 sử dụng _Worksheetgiao diện, nhưng cũng có một Worksheetgiao diện. Tôi không biết sự khác biệt là gì.

Trong ứng dụng demo đơn giản đến mức ngớ ngẩn của tôi (được hiển thị bên dưới) hoặc hoạt động tốt - nhưng nếu phương pháp hay nhất ra lệnh cho cái này hay cái khác, tôi muốn sử dụng nó một cách thích hợp.

using System;
using System.Linq;
using Excel = Microsoft.Office.Interop.Excel;

class DynamicExcel
{
    static void Main()
    {
        var app = new Excel.Application { Visible = true };
        app.Workbooks.Add();

        // Can use Excel._Worksheet instead here. Which is better?
        Excel.Worksheet workSheet = app.ActiveSheet;

        Excel.Range start = workSheet.Cells[1, 1];
        Excel.Range end = workSheet.Cells[1, 20];
        workSheet.get_Range(start, end).Value2 = Enumerable.Range(1, 20)
                                                           .ToArray();
    }
}

Tôi đang cố gắng tránh đi sâu vào khả năng tương tác của COM hoặc Office, chỉ làm nổi bật các tính năng mới của C # 4 - nhưng tôi không muốn làm bất cứ điều gì thực sự, thực sự ngớ ngẩn.

(Có thể có điều gì đó thực sự, thực sự ngớ ngẩn trong đoạn mã trên, trong trường hợp đó, vui lòng cho tôi biết. Việc sử dụng các ô bắt đầu / kết thúc riêng biệt thay vì chỉ "A1: T1" là có chủ ý - dễ thấy rằng đó thực sự là một phạm vi trong số 20 ô. Bất kỳ điều gì khác có thể là ngẫu nhiên.)

Vì vậy, tôi nên sử dụng _Worksheethoặc Worksheet, và tại sao?


5
Jon, ngoài những câu trả lời tuyệt vời được đưa ra ở đây, tôi muốn nói thêm rằng, nói chung, khi làm việc với Excel thông qua tương tác, hãy sử dụng tên lớp như nó thường xuất hiện trong Excel. Điều này có nghĩa là sử dụng 'Worksheet' thay vì '_Worksheet' và sử dụng 'Application' thay vì 'ApplicationClass'. (Một cuộc thảo luận ở đây giải thích lý do tại sao không sử dụng 'Lớp ứng dụng': blog.msdn.com/ptorr/archive/2004/02/05/67872.aspx. ) Nếu bạn không quen với mô hình đối tượng Excel khi tiếp xúc với COM, thì điều này có thể phức tạp hơn, nhưng tôi nghĩ hầu hết thời gian đều phải rõ ràng.
Mike Rosenblum

May mắn thay, tôi đang làm rất ít với Office - thực sự chỉ đang cố gắng hiển thị các tính năng mới. Cảm ơn rất nhiều vì liên kết - rất hữu ích!
Jon Skeet

Tôi xin lỗi nhưng phải hỏi - Tính năng mới của C # 4 mà bạn đang làm nổi bật là gì?
Oskar

Đối với trường hợp cụ thể này, đó là kiểu nhập động - các kiểu trả về của các lệnh gọi / thuộc tính phương thức khác nhau có hiệu quả là "động", do đó thiếu phôi mà nếu không thì sẽ được yêu cầu.
Jon Skeet

Câu trả lời:


77

Nếu tôi nhớ chính xác - và trí nhớ của tôi về điều này hơi mờ, đã lâu rồi tôi không tách Excel PIA ra - nó như thế này.

Sự kiện về cơ bản là một phương thức mà một đối tượng gọi khi có điều gì đó xảy ra. Trong .NET, các sự kiện là đại biểu, đơn giản và dễ hiểu. Nhưng trong COM, rất phổ biến là tổ chức một loạt các cuộc gọi lại sự kiện vào các giao diện. Do đó, bạn có hai giao diện trên một đối tượng nhất định - giao diện "đến", các phương thức bạn mong đợi người khác gọi cho mình và giao diện "đi", các phương thức mà bạn mong đợi để gọi người khác khi sự kiện xảy ra.

Trong siêu dữ liệu không được quản lý - thư viện loại - đối với một đối tượng có thể tạo, có các định nghĩa cho ba thứ: giao diện đến, giao diện đi và lớp, cho biết "Tôi là đối tượng có thể tạo triển khai giao diện đến này và cái này giao diện gửi đi ”.

Bây giờ khi thư viện kiểu được tự động dịch thành siêu dữ liệu, đáng buồn là những mối quan hệ đó vẫn được bảo toàn. Sẽ tốt hơn nếu có một PIA được tạo thủ công làm cho các lớp và giao diện phù hợp hơn với những gì chúng ta mong đợi trong thế giới được quản lý, nhưng đáng buồn là điều đó đã không xảy ra. Do đó, Office PIA chứa đầy những sự trùng lặp có vẻ kỳ quặc này, trong đó mọi đối tượng có thể tạo dường như có hai giao diện được liên kết với nó, với cùng một thứ trên chúng. Một trong các giao diện đại diện cho giao diện của lớp và một trong số chúng đại diện cho giao diện đến của lớp đó.

Giao diện _Workbook là giao diện đến trên lớp sổ làm việc. Giao diện Workbook là giao diện đại diện cho chính lớp, và do đó kế thừa từ _Workbook.

Tóm lại, tôi sẽ sử dụng Workbook nếu bạn có thể làm như vậy một cách thuận tiện; _Workbook là một chút chi tiết triển khai.


Đó là Worksheet / _Worksheet mà chúng ta đang nói đến ở đây ... bạn đã đọc sai giống như JP, nhưng như anh ấy chỉ ra, tình hình về cơ bản là tương đương. ;)
Noldorin

25

Nếu bạn nhìn vào lắp ráp PIA (Microsoft.Office.Interop.Excel) trong Reflector , Workbookgiao diện có định nghĩa này ...

public interface Workbook : _Workbook, WorkbookEvents_Event

Workbook_Workbooknhưng thêm các sự kiện. Giống vớiWorksheet (xin lỗi, chỉ nhận thấy rằng bạn không nói về Workbooks) ...

public interface Worksheet : _Worksheet, DocEvents_Event

DocEvents_Event ...

[ComVisible(false), TypeLibType((short) 0x10), ComEventInterface(typeof(DocEvents),
                     typeof(DocEvents_EventProvider))]
public interface DocEvents_Event
{
    // Events
    event DocEvents_ActivateEventHandler Activate;
    event DocEvents_BeforeDoubleClickEventHandler BeforeDoubleClick;
    event DocEvents_BeforeRightClickEventHandler BeforeRightClick;
    event DocEvents_CalculateEventHandler Calculate;
    event DocEvents_ChangeEventHandler Change;
    event DocEvents_DeactivateEventHandler Deactivate;
    event DocEvents_FollowHyperlinkEventHandler FollowHyperlink;
    event DocEvents_PivotTableUpdateEventHandler PivotTableUpdate;
    event DocEvents_SelectionChangeEventHandler SelectionChange;
}

Tôi sẽ nói rằng tốt nhất là nên sử dụng Worksheet, nhưng đó là sự khác biệt.


8

Lớp học và Giao diện Chỉ sử dụng Nội bộ

Tránh sử dụng trực tiếp bất kỳ lớp và giao diện nào sau đây, được sử dụng nội bộ và thường không được sử dụng trực tiếp.

Lớp / Giao diện: Ví dụ

classid Class: ApplicationClass (Word hoặc Excel), WorksheetClass (Excel)

classid Sự kiện x _SinkHelper: ApplicationEvents4_SinkHelper (Word), WorkbookEvents_SinkHelper (Excel)

_classid : _Application (Word hoặc Excel), _Worksheet (Excel)

Sự kiện classid x: ApplicationEvents4 (Word), AppEvents (Excel)

Tôi classid Sự kiện x: IApplicationEvents4 (Word), IAppEvents (Excel)

http://msdn.microsoft.com/en-gb/library/ms247299(office.11).aspx

chỉnh sửa: (re: format of this answer) không thể định dạng chính xác dấu gạch dưới thoát ngay sau đó là văn bản in nghiêng. Hiển thị chính xác trong bản xem trước nhưng bị hỏng khi đăng

edit2: hoạt động nếu bạn làm cho dấu gạch dưới nghiêng, điều này thật kinh khủng về mặt khái niệm nhưng trông giống nhau, tôi cho là vậy


7

Tôi đã xem và viết khá nhiều mã C # / Excel COM Interop trong vài năm qua và tôi đã thấy Trang tính được sử dụng trong hầu hết mọi trường hợp. Tôi chưa bao giờ thấy bất cứ điều gì dứt khoát từ Microsoft về chủ đề này.


Cảm ơn. Không quan tâm, bạn đã cập nhật những cải tiến trong C # 4 chưa? Họ âm thanh như họ muốn tạo sự khác biệt lớn về văn phòng interop, nhưng không có kinh nghiệm mà tôi đang thực sự chỉ là đoán (aka bluffing, khi nói đến việc viết cuốn sách ...)
Jon Skeet

Các cải tiến Dynamic / COM Interop có vẻ hữu ích khi bạn phải sử dụng COM, nhưng tôi khá chắc chắn rằng tôi sẽ không sử dụng tính năng động cho nhiều hơn thế. Những thứ tôi thực sự mong đợi ở C # 4 / .NET 4 là các hợp đồng mã và Thư viện song song tác vụ.
Joe Erickson

6

MSDN cho thấy rằng Worksheetgiao diện chỉ đơn giản là kế thừa từ các giao diện _WorksheetDocEvents_Event. Có vẻ như người ta chỉ đơn giản là cung cấp các sự kiện mà một đối tượng trang tính có thể nâng cao bổ sung cho mọi thứ khác. Theo như tôi thấy, Worksheetkhông cung cấp bất kỳ thành viên nào khác của riêng nó. Vì vậy, bạn cũng có thể tiếp tục sử dụng Worksheetgiao diện trong mọi trường hợp, vì bạn không mất gì bởi nó và có thể cần những sự kiện mà nó thể hiện.


4
Jon Skeet hỏi một câu hỏi ?? Tôi đã phải lấy cơ hội hiếm có này để đáp lại! :)
Noldorin

(Ngoài ra, tôi có thể chỉ chọn sử dụng Bảng tính vì gạch dưới đó trông rất xấu xí ở đó ... Nhưng nghiêm túc mà nói, có vẻ như không có lý do gì để không làm như vậy.)
Noldorin
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.