2014-06-04 15 views
7

Ich habe einige vorhandene C# -Code, die ich über COM-Interop freigeben möchte, so dass es von Excel VBA aufgerufen werden kann. Da ich viele geschachtelte Batch-Update-Operationen durchführen werde, muss ich Transaktionen unterstützen und um das Refactoring auf C# -Ebene zu minimieren, möchte ich den TransactionScope-Ansatz verwenden:Initiieren eines TransactionScope von Excel VBA?

Implementieren einer impliziten Transaktion mithilfe des Transaktionsbereichs
http://msdn.microsoft.com/en-us/library/ms172152.aspx

die Transaction-Klasse bietet eine einfache Möglichkeit, einen Block von Code wie die Teilnahme an einer Transaktion zu markieren, ohne Sie zu Interaktion mit der Transaktion selbst zu erfordern. Ein Transaktionsbereich kann auswählen und die Ambient-Transaktion automatisch verwalten. Aufgrund seiner Benutzerfreundlichkeit und Effizienz empfiehlt es sich, bei der Entwicklung einer Transaktionsanwendung die TransactionScope-Klasse zu verwenden.

Darüber hinaus müssen Sie keine Ressourcen explizit mit der -Transaktion registrieren. Jeder System.Transactions-Ressourcenmanager (z. B. SQL Server ) kann das Vorhandensein einer Umgebungstransaktion erkennen, die vom Gültigkeitsbereich erstellt und automatisch registriert wird.

Meine Frage ist: ist es möglich, die Transaction im VBA-Code initiieren (oder C# Methode über COM-Aufruf Interop ein Transaction Objekt zu instanziiert und zurück), und fahren Sie dann verschiedene andere C# Objekte nennen über COM Interop, die alle automatisch an der einzelnen Root-Transaktion teilnehmen?

+0

Nein, das können Sie definitiv nicht in VBA tun. –

+0

Könnten Sie (hoffentlich werde ich Sie nicht bitten, ein Negativ zu beweisen) – tbone

+0

Ich habe meine Antwort gelöscht, da ich glaube nicht, dass wir auf der gleichen Seite verstehen, was das TransactionScope für C# ist und was es in VBA wäre. ADODB implementiert den Mechanismus, um alle Änderungen während einer Transaktion rückgängig zu machen, aber Sie können keinen Block eines VBA-Codes in ein TransactionScope umbrechen und es wird zurückgesetzt, wenn die Transaktion fehlgeschlagen ist ... –

Antwort

1

Ich sehe kein Problem mit Ihrem Ansatz. Sie haben noch using in VBA, so dass Sie es von

  • mit einem Fehlerhandler und
  • nicht die Methode sehr vorsichtig müssen simulieren lassen, ohne die Transaction in einer oder anderen Weise zu entsorgen.

Zum Beispiel lassen Sie uns sagen, dass # Anwendung in Ihrem C, können Sie die folgenden Methoden zur Verfügung stellen:

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() { ... } 

Sie Ihre C# DLL kompilieren und zu Excel VBA über COM-Interop liefern. In VBA führen Sie die Methoden wie folgt:

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 

Beachten Sie jedoch, dass alle Daten zugreifen, die Sie VBA-Code (zwischen der DoSomeWork nennt) durchführen wird außerhalb der Transaktionsbereich sein, da Transaction ist nicht kompatibel mit klassischen ADO oder DAO.

+0

Es tut mir leid, dass ich hier etwas falsch verstanden habe, aber was ist der Sinn von all dem, wenn Sie C# verwenden, um die Transaktionen zu behandeln und nur explizit von VBA aus aufzurufen. Sie können auch den gesamten Transaktionsprozess in C# verarbeiten und haben nur eine Methode, um das Ergebnis zurückzugeben. Warum sollte alles mit VBA in Verbindung gebracht werden, da es leicht von C# aus gehandhabt werden kann? –

+0

@mehow: 1. Danke für die Erkennung des Tippfehlers, behoben. 2. Vielleicht muss er zwischen den verschiedenen "DoSomeWork" -Aufrufen VBA-Code ausführen? Wie auch immer, es ist eine gute Frage, aber es ist wahrscheinlich besser auf das OP als auf mich gerichtet. – Heinzi

+0

yeah haben Sie nicht 'using' in VBA, aber Sie haben' mit '' end with'. Es funktioniert nicht so wie 'using' in C#, aber irgendwie haben sie etwas damit zu tun. Mein Punkt hier ist, dass Sie kein TransactionScope in VBA einrichten können, weil VBA VB6 Virtual Machine als Laufzeit verwendet und es Ihnen nicht erlaubt, Ihren eigenen Code zurückzusetzen, wenn das Sinn macht (* tut mir leid, das ist schwer zu erklären *). –