2014-06-04 21 views
7

Tôi có một số mã C# hiện có mà tôi muốn hiển thị qua com interop để nó có thể được gọi từ Excel VBA. Như tôi sẽ được thực hiện nhiều hoạt động cập nhật hàng loạt lồng nhau, tôi cần phải hỗ trợ giao dịch, và để giảm thiểu refactoring cần ở cấp C#, tôi muốn sử dụng cách tiếp cận TransactionScope:Bắt đầu một TransactionScope từ Excel VBA?

Thực hiện một giao dịch ngầm sử dụng Phạm vi giao dịch
http://msdn.microsoft.com/en-us/library/ms172152.aspx

lớp TransactionScope cung cấp một cách đơn giản để đánh dấu một khối mã như tham gia vào một giao dịch, mà không đòi hỏi bạn tương tác với các giao dịch riêng của mình. Phạm vi giao dịch có thể chọn và tự động quản lý giao dịch môi trường xung quanh. Do dễ sử dụng việc sử dụng và hiệu quả, bạn nên sử dụng lớp TransactionScope khi phát triển ứng dụng giao dịch.

Ngoài ra, bạn không cần phải tranh thủ tài nguyên một cách rõ ràng với giao dịch . Bất kỳ trình quản lý tài nguyên nào của System.Transactions (chẳng hạn như SQL Server 2005) có thể phát hiện sự tồn tại của một giao dịch xung quanh được tạo bởi phạm vi và tự động tranh thủ.

Câu hỏi của tôi là: là nó có thể khởi các TransactionScope trong mã VBA (hoặc gọi aC# phương pháp thông qua COM Interop để nhanh chóng và trả về một đối tượng TransactionScope), và sau đó tiến hành để gọi khác nhau khác C# đối tượng qua COM Interop, tất cả sẽ tự động tham gia vào giao dịch root đơn lẻ?

+0

Không, bạn chắc chắn không thể làm điều đó trong VBA. –

+0

Bạn có thể xây dựng (hy vọng tôi không kinda yêu cầu bạn chứng minh một tiêu cực) – tbone

+0

Tôi đã xóa câu trả lời của tôi vì tôi không nghĩ rằng chúng tôi đang trên cùng một trang hiểu những gì TransactionScope là cho C# và những gì nó sẽ được trong VBA. ADODB thực hiện cơ chế để quay trở lại bất kỳ thay đổi nào trong một Giao dịch nhưng bạn không thể bao bọc một khối của bất kỳ mã VBA nào trong một TransactionScope và có nó quay lại nếu Giao dịch thất bại ... –

Trả lời

1

Tôi không thấy sự cố với cách tiếp cận của bạn. Bạn không cần phải using trong VBA, vì vậy bạn sẽ phải mô phỏng nó bằng cách

  • sử dụng một trình xử lý lỗi và
  • là rất cẩn thận không để lại phương pháp này mà không xử lý các TransactionScope bằng cách này hay cách khác.

Ví dụ, giả sử rằng trong ứng dụng C# của bạn, bạn cung cấp các phương pháp sau:

public TransactionScope BeginTransactionScope() 
{ 
    return new TransactionScope(); 
} 

public void CommitTransactionScope(TransactionScope scope) 
{ 
    scope.Complete(); 
    scope.Dispose(); // simulates leaving the using { ... } scope 
} 

public void RollbackTransactionScope(TransactionScope scope) 
{ 
    scope.Dispose(); // simulates leaving the using { ... } scope 
} 

// Does some work using Connections and maybe nested scopes 
public void DoSomeWork1() { ... } 
public void DoSomeWork2() { ... } 
public void DoSomeWork3() { ... } 

Bạn biên dịch C# DLL và cung cấp cho nó sang Excel VBA qua COM interop. Trong VBA, bạn chạy các phương pháp như sau:

Private Sub MySub() 

    On Error Goto MyErrorHandler 

    ... 
    Dim scope As Object 
    Set scope = myCsObject.BeginTransactionScope() 
    ... 
    myCsObject.DoSomeWork1 
    ... 
    myCsObject.DoSomeWork2 
    ... 
    myCsObject.DoSomeWork3 
    ... 
    myCsObject.CommitTransactionScope scope 
    Set scope = Nothing 
    ... 

    Exit Sub 

MyErrorHandler: 
    If Not (scope Is Nothing) Then 
     myCsObject.RollbackTransactionScope scope 
    End If 
    ' Remainder of your error handler goes here 
    ... 
End Sub 

Lưu ý, mặc dù, rằng bất kỳ dữ liệu truy cập bạn thực hiện với VBA đang (ở giữa DoSomeWork gọi) sẽ ngoài phạm vi giao dịch, kể từ TransactionScope không tương thích với ADO hoặc DAO cổ điển.

+0

Tôi xin lỗi tôi có thể hiểu nhầm một cái gì đó ở đây nhưng điểm của tất cả những điều này là gì nếu bạn đang sử dụng C# để xử lý các giao dịch và chỉ cần gọi nó một cách rõ ràng từ VBA. Bạn cũng có thể xử lý toàn bộ quá trình giao dịch trong C# và chỉ có một phương thức để trả về kết quả. Tại sao phơi bày tất cả với VBA vì nó có thể dễ dàng xử lý từ C#? –

+0

@mehow: 1. Cảm ơn bạn đã phát hiện lỗi đánh máy, đã sửa. 2. Có lẽ anh ta cần thực thi mã VBA ở giữa các cuộc gọi 'DoSomeWork' khác nhau? Dù sao, đó là một câu hỏi hay, nhưng nó có lẽ tốt hơn nhắm vào OP hơn là với tôi. – Heinzi

+0

vâng bạn không có 'using' trong VBA nhưng bạn có' với '' kết thúc bằng'. Nó không hoạt động giống như 'sử dụng' trong C# nhưng chúng có liên quan đến nhau. Quan điểm của tôi ở đây là bạn không thể thiết lập một TransactionScope trong VBA vì VBA sử dụng VB6 Virtual Machine như thời gian chạy và nó không cho phép bạn khôi phục mã của riêng bạn nếu điều đó có ý nghĩa (* xin lỗi để giải thích *). –

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