2013-09-05 6 views
7

Ho questo codice (questa è una versione semplificata del codice reale) che apre Excel e imposta il valore di una cella. Si prega di notare che io sono in Italia e usiamo , anziché . per separare le cifre decimali. Ciò significa che io uso 12.5 nel codice, ma il risultato di ToString() su questo numero è "12,5" e anche in Excel è mostrato 12,5.Impostazione di un valore di cella Excel su un decimale in C#. Differenze tra .NET 2 e .NET 4

using Xls = Microsoft.Office.Interop.Excel; 

public class ExcelTest 
{ 
    public static void Test 
    { 
     object hmissing = System.Reflection.Missing.Value; 
     // create an instance of Excel and make it visible    
     Xls.Application anApp = new Xls.ApplicationClass(); 
     anApp.Visible = true; 
     // add an empty workbook 
     Xls.Workbooks wbks = anApp.Workbooks; 
     wbks.Add(hmissing); 
     Marshal.ReleaseComObject(wbks); 
     // set the value of the first cell 
     Decimal d = 12.5m; 
     Xls.Range aRange = anApp.get_Range("A1", hmissing); 
     aRange.set_Value(Xls.XlRangeValueDataType.xlRangeValueDefault, d.ToString()); 
     Marshal.ReleaseComObject(aRange); 
    } 
} 

Tutto ha funzionato bene per anni, utilizzando NET 2, ma quando provo a passare a .NET 4 Excel mi avverte che il numero è stato memorizzato come testo.

Si prega di notare che io so che semplicemente evitando di chiamare ToString() risolve il problema, ma nel caso reale ho a che fare con un'applicazione legacy che vuole archiviare diversi tipi di dati in Excel, sia baseTypes e quelli definiti dall'utente e ToString() era l'unico metodo disponibile su tutti questi tipi che avrebbe dato il risultato desiderato in Excel senza dover controllare il tipo e decidere cosa passare a set_Value.

Quindi non sto chiedendo come modificare il mio codice per farlo funzionare. Sto solo cercando di capire perché il comportamento è diverso nelle due versioni del framework. È piuttosto importante perché preferirei modificare il mio codice prima che gli utenti scoprano che c'è qualcosa di sbagliato.

+1

Non ho idea del motivo per cui esiste una differenza tra .NET 2 e .NET 4, ma quale versione di Excel stai utilizzando? Sei sicuro che non sia solo una differenza di versione di Excel? – flindeberg

+0

Non sembra dipendere dalla versione di Excel. Ho provato con Excel 2003 e con Excel 2010 e ho ottenuto gli stessi risultati. –

+1

Vorrei sapere la risposta, ma so che .NET 4 ha fatto molto su come funziona Interop. Non riesco a trovare una spiegazione definitiva, ma i cambiamenti di rottura attorno a Interop sollevano alcuni punti interessanti attorno al codice che hai elencato: http://msdn.microsoft.com/en-us/library/ee855831%28VS.100%29.aspx Vale a dire, l'incorporamento dei tipi di interoperabilità e il modo in cui i parametri opzionali vengono gestiti sembrano suggerire ciò che stai vedendo. –

risposta

-1

Prova questo:

 Excel.Application excel = new Excel.Application(); 
     Excel.Workbook workbook = excel.Workbooks.Open(@"c:\test.xls", Missing.Value, Missing.Value, 
                 Missing.Value, Missing.Value, Missing.Value, 
                 Missing.Value, Missing.Value, Missing.Value, 
                 Missing.Value, Missing.Value, Missing.Value, false, 
                 Missing.Value, Missing.Value); 

     Excel.Worksheet worksheet = (Excel.Worksheet)workbook.Worksheets[1]; 

     decimal dec = 12.5m; 
     worksheet.get_Range("A1").Value = dec; 

     DateTime date = DateTime.Now.Date; 
     worksheet.get_Range("A2").Value = date; 

     string str = "Hello"; 
     worksheet.get_Range("A3").Value = str; 

     Marshal.FinalReleaseComObject(worksheet); 
     workbook.Save(); 
     workbook.Close(false, Type.Missing, Type.Missing); 
     Marshal.FinalReleaseComObject(workbook); 
     excel.Quit(); 
     Marshal.FinalReleaseComObject(excel); 
+0

Si noti che non sto chiedendo come modificare il codice per eliminare il problema. Vorrei solo sapere che c'è una tale differenza tra queste 2 versioni del framework in modo da essere in grado di individuare altri possibili bug prima che i clienti li trovino. –

1

L'uscita del methode "ToString" non è scolpito nella pietra e dipende dalla corrente CultureInfo tuo thread è in esecuzione. Se si sta eseguendo il programma su un PC con un altro Language Pack, l'uscita può cambiare. Un altro motivo potrebbe essere che il thread corrente è impostato su culturinfo da qualche altra parte nel codice.

Si prega di provare il seguente esempio.

static void Main(string[] args) 
{ 
     decimal d = 12.56m; 
     // Different thread cultureinfo 
     Thread.CurrentThread.CurrentCulture = 
      new System.Globalization.CultureInfo("de-DE"); 
     Console.WriteLine(d); 
     Thread.CurrentThread.CurrentCulture = 
      new System.Globalization.CultureInfo("en-US"); 
     Console.WriteLine(d); 

     Console.WriteLine(d.ToString(
      new System.Globalization.CultureInfo("de-DE").NumberFormat)); 
     Console.WriteLine(d.ToString(
      new System.Globalization.CultureInfo("en-US").NumberFormat)); 
     Console.Read(); 
} 
+0

Sto eseguendo l'esempio con diverse versioni del framework ma sulla stessa macchina (con esattamente lo stesso cultureinfo). Inoltre, il risultato di ToString() è esattamente lo stesso e quello che mi aspetto. –

Problemi correlati