2014-06-04 19 views
7

Ho qualche codice C# esistente che vorrei esporre tramite com interop in modo che possa essere chiamato da Excel VBA. Poiché eseguirò molte operazioni di aggiornamento batch nidificate, devo supportare le transazioni e per ridurre al minimo il refactoring richiesto a livello C#, vorrei utilizzare l'approccio TransactionScope:Avvio di TransactionScope da Excel VBA?

Implementazione di una transazione implicita utilizzando Transaction Scope
http://msdn.microsoft.com/en-us/library/ms172152.aspx

la classe TransactionScope fornisce un modo semplice per marcare un blocco di codice come partecipare a una transazione, senza la necessità di interagire con la transazione stessa. Un ambito di transazione può selezionare e gestire automaticamente la transazione ambientale. A causa della facilità di utilizzo ed efficienza di , si consiglia di utilizzare la classe TransactionScope durante lo sviluppo di un'applicazione di transazione.

Inoltre, non è necessario elencare risorse esplicitamente con la transazione . Qualsiasi gestore di risorse System.Transactions (come SQL Server 2005) può rilevare l'esistenza di una transazione ambientale creata dall'ambito e arruolarsi automaticamente.

La mia domanda è: è possibile avviare il TransactionScope all'interno del codice VBA (o chiamare il metodo aC# tramite interoperabilità COM per istanziare e restituire un oggetto TransactionScope), e quindi procedere a chiamare i vari altri oggetti C# tramite COM Interop, che parteciperà automaticamente alla transazione singola radice?

+0

No, non è possibile farlo in VBA. –

+0

Potresti elaborare (spero di non essere un tipo che ti chiede di dimostrare un negativo) – tbone

+0

Ho cancellato la mia risposta perché non penso che siamo sulla stessa pagina, capendo che cos'è TransactionScope per C# e cosa sarebbe in VBA. ADODB implementa il meccanismo per il rollback delle modifiche durante una Transazione ma non è possibile eseguire il wrapping di un blocco di qualsiasi codice VBA in TransactionScope e ripristinarlo se la Transazione non riesce ... –

risposta

1

Non vedo alcun problema con il tuo approccio. Non è necessario using in VBA, in modo da avere per simulare da

  • utilizzando un gestore di errori e
  • facendo molta attenzione a non lasciare il metodo senza disporre l'TransactionScope in un modo o nell'altro.

Per esempio, diciamo che in C# applicazione, è necessario fornire i seguenti metodi:

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

si compila il C# DLL e fornirlo al Excel VBA tramite l'interoperabilità COM. In VBA, si esegue i metodi come segue:

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 

nota, però, che i dati di accesso che si esibirà con codice VBA (tra il DoSomeWork chiama) sarà di fuori l'ambito della transazione, dal momento che TransactionScope non è compatibile con ADO o DAO classici.

+0

Mi dispiace che possa essermi frainteso qualcosa qui, ma qual è il punto di tutto questo, dal momento che se si utilizza C# per gestire le transazioni e solo chiamandolo esplicitamente da VBA. Puoi anche gestire l'intero processo di transazione in C# e avere solo un metodo per restituire il risultato. Perché esporre tutto a VBA poiché può essere facilmente gestito da C#? –

+0

@mehow: 1. Grazie per aver individuato l'errore, corretto. 2. Forse ha bisogno di eseguire il codice VBA tra le varie chiamate 'DoSomeWork'? Comunque, è una buona domanda, ma probabilmente è meglio mirare all'OP che a me. – Heinzi

+0

sì, non si deve usare in VBA ma si ha 'con ' 'end with'. Non funziona allo stesso modo di "usare" in C#, ma sono in qualche modo correlati, suppongo. Il mio punto qui è che non è possibile impostare un TransactionScope in VBA perché VBA utilizza VB6 Virtual Machine come runtime e non consente di eseguire il rollback del proprio codice se ciò ha senso (* mi dispiace difficile spiegare *). –