2009-02-11 16 views
45

मैं वर्तमान में Excel में एक श्रृंखला के लिए वस्तुओं की एक सरणी, जहां objData बस तार की एक सरणी है निम्नलिखित कोड का उपयोग करने से डेटा लिखने के लिए कोशिश कर रहा हूँ:लिखें

private object m = System.Type.Missing; 
object[] objData = getDataIWantToWrite(); 

Range rn_Temp; 
rn_Temp = (Range)XlApp.get_Range(RangeName, m); 
rn_Temp = rn_Temp.get_Resize(objData.GetUpperBound(), 1); 
rn_Temp.value2 = objData; 

यह बहुत लगभग काम करता है, समस्या यह है कि सीमा भर जाती है लेकिन प्रत्येक सेल को objData में पहले आइटम का मूल्य मिलता है।

उलटा काम करता है, अर्थात

private object m = System.Type.Missing; 
object[] objData = new object[x,y] 

Range rn_Temp; 
rn_Temp = (Range)XlApp.get_Range(RangeName, m); 
rn_Temp = rn_Temp.get_Resize(objData.GetUpperBound(), 1); 
objData = (object[])rn_Temp.value2; 

कार्यपत्रक से सभी मान युक्त एक सरणी वापस आएगा, तो मैं क्यों पढ़ने और काम काम अलग ढंग से यकीन नहीं है।

क्या किसी ने कभी भी इसे सफलतापूर्वक किया है? मैं वर्तमान में सेल द्वारा सरणी कक्ष लिख रहा हूं, लेकिन इसे पंक्तियों (> 50,000) पंक्तियों से निपटने की ज़रूरत है और इसलिए यह बहुत समय ले रहा है।

+7

चयनित जवाब इसलिए यदि किसी और कभी भी इस समस्या, संक्षेप में है, समाधान है, इसे तुरंत स्पष्ट नहीं है एक अच्छा दिन है: यहाँ कोड का एक उदाहरण है कि आपको एक 2 डी सरणी ('ऑब्जेक्ट [,]') असाइन करने की आवश्यकता है, भले ही आपका डेटा केवल एक आयाम पर फिट हो। – zneak

+1

[बहुत उपयोगी] (http://blogs.msdn.com/b/eric_carter/archive/2004/05/04/126190.aspx) –

उत्तर

77

यह मेरी विधि से एक अंश है, जो एक डेटाटेबल (डीटी चर) को एक सरणी में परिवर्तित करता है और फिर सरणी को वर्कशीट (wsh var) पर एक रेंज में लिखता है। आप शीर्ष पंक्ति चर को भी बदल सकते हैं जो भी पंक्ति आप स्ट्रिंग की सरणी पर रखना चाहते हैं।

 object[,] arr = new object[dt.Rows.Count, dt.Columns.Count]; 
     for (int r = 0; r < dt.Rows.Count; r++) 
     { 
      DataRow dr = dt.Rows[r]; 
      for (int c = 0; c < dt.Columns.Count; c++) 
      { 
       arr[r, c] = dr[c]; 
      } 
     } 

     Excel.Range c1 = (Excel.Range)wsh.Cells[topRow, 1]; 
     Excel.Range c2 = (Excel.Range)wsh.Cells[topRow + dt.Rows.Count - 1, dt.Columns.Count]; 
     Excel.Range range = wsh.get_Range(c1, c2); 

     range.Value = arr; 
बेशक आप की तरह मैंने किया था एक मध्यवर्ती DataTable का उपयोग करने की जरूरत नहीं है के

, कोड अंश अभी प्रदर्शित करने के लिए कैसे एक सरणी एक कॉल में कार्यपत्रक में लिखा जा सकता है।

+0

दिलचस्प - यह वही है जो मैं करना चाहता हूं, लेकिन मैं रेंज ऑब्जेक्ट की वैल्यू प्रॉपर्टी तक नहीं पहुंच सकता - मैं केवल वैल्यू 2 तक पहुंच सकता हूं, और मुझे लगता है कि यह समस्या हो सकती है। कोई विचार है कि मैं मूल्य संपत्ति कैसे प्राप्त कर सकता हूं? आप किस इंटरप्ट का उपयोग कर रहे हैं? –

+0

एक्सेल की प्रकार लाइब्रेरी से आयात किया गया (मेरे मामले में Office 2003 होता है)। यानी, मैं प्राथमिक इंटरऑप असेंबली का उपयोग नहीं कर रहा हूं। मैंने बस वीएस में एक्सेल कॉम टीएलबी का संदर्भ जोड़ा। अब मुझे पीआईए का उपयोग न करने का सटीक कारण याद नहीं है, हालांकि। –

+2

मैं range.set_Value (Missing.Value, objectArray) का उपयोग करता हूं; आपको यह सुनिश्चित करने की ज़रूरत है कि सरणी रेंज के समान आकार है। –

4

आप अपना डेटा रिकॉर्डसेट में डाल सकते हैं और Excel's CopyFromRecordset Method का उपयोग कर सकते हैं - यह सेल-बाय-सेल पॉप्युलेट करने से कहीं अधिक तेज़ है।

आप this code का उपयोग कर डेटासेट से एक रिकॉर्डसेट बना सकते हैं। आपको यह देखने के लिए कुछ परीक्षण करना होगा कि इस विधि का उपयोग करना आपके द्वारा वर्तमान में किए जा रहे कार्यों से तेज़ है या नहीं।

+0

यह एक मूर्ख सवाल हो सकता है, लेकिन मुझे सी # में रिकॉर्ड्स क्लास कहां मिल सकता है ? या क्या आपको पता है कि क्या कोई और वर्ग है जिसमें मैं काम कर सकता हूं? बहुत धन्यवाद! –

+1

असेंबली एडीओडीबी संस्करण 7.0.3300.0 के संदर्भ में जोड़ें। एडीओडीबी का उपयोग करना; एडीओडीबी में "रिकॉर्ड्सेट" टाइप किया गया है –

9

पॉइंटर्स लोगों के लिए धन्यवाद - वैल्यू बनाम वैल्यू 2 तर्क ने मुझे खोज परिणामों का एक अलग सेट मिला जिसने मुझे जवाब देने में मदद की। संयोग से, मूल्य संपत्ति एक parametrized संपत्ति है, जिसे सी # में एक एक्सेसर के माध्यम से पहुंचा जाना चाहिए। इन्हें get_Value और set_Value कहा जाता है, और वैकल्पिक एनम मान लेते हैं। अगर कोई दिलचस्पी लेता है, this explains it nicely

वैल्यू 2 संपत्ति के माध्यम से असाइनमेंट करना संभव है, जो इंटरऑप दस्तावेज मेरी समझ से परे कारणों के लिए get_Value और set_Value विधियों के उपयोग के उपयोग की सिफारिश करता है।

कुंजी ऑब्जेक्ट्स की सरणी का आयाम प्रतीत होता है। काम करने के लिए कॉल के लिए सरणी को द्वि-आयामी के रूप में घोषित किया जाना चाहिए, भले ही आप केवल एक-आयामी डेटा असाइन कर रहे हों।

मैंने अपने डेटा सरणी को object[NumberofRows,1] के रूप में घोषित किया और असाइनमेंट कॉल काम किया।

+0

धन्यवाद, ऐसा लगता है कि 1 डी सरणी दी गई है, यह हमेशा क्षैतिज रूप से लिखती है (यहां तक ​​कि एक लंबवत सीमा के साथ, जिस स्थिति में यह बार-बार पहला तत्व लिखता है)। लंबवत लिखने के लिए एक सरणी प्राप्त करने के लिए, आपको ऐसा करना चाहिए जैसा आपने कहा था और इसे '[n, 1]' सरणी बनाते हैं। बहुत धन्यवाद क्योंकि मैं शायद इसे कभी नहीं खोजूंगा। –

0

किसी कारण से, 2 आयामी सरणी में कनवर्ट करना मेरे लिए काम नहीं करता था।लेकिन निम्नलिखित दृष्टिकोण किया:

public void SetRow(Range range, string[] data) 
{ 
    range.get_Resize(1, data.Length).Value2 = data; 
} 
1

सरणी परिभाषा की तरह लगता है कुंजी: मेरे मामले में यह एक दो आयाम सरणी के लिए

Defintion में बदलने के लिए है, जो 17 मदों की एक एक आयाम सरणी है कॉलम: ऑब्जेक्ट [,] ऐरे = नई ऑब्जेक्ट [17, 1];

पंक्तियों के लिए परिभाषा ऑब्जेक्ट [,] ऐरे = नई वस्तु [1,17];

मूल्य 2 के लिए कोड दोनों मामलों में Excel.Range सेल = activeWorksheet.get_Range (रेंज); सेल। वैल्यू 2 = ऐरे;

एलजी जोर्ज

1

मेरे मामले में, इस कार्यक्रम डेटाबेस जो एक DataGridView रिटर्न प्रश्नों। मैं फिर इसे एक सरणी में कॉपी करता हूं। मुझे बस बनाए गए सरणी का आकार मिलता है और फिर सरणी को Excel स्प्रेडशीट में लिखें। यह कोड लगभग दो सेकंड में डेटा की 5000 से अधिक लाइनों का उत्पादन करता है।

//private System.Windows.Forms.DataGridView dgvResults; 
dgvResults.DataSource = DB.getReport(); 

Microsoft.Office.Interop.Excel.Application oXL; 
Microsoft.Office.Interop.Excel._Workbook oWB; 
Microsoft.Office.Interop.Excel._Worksheet oSheet; 
try 
{ 
    //Start Excel and get Application object. 
    oXL = new Microsoft.Office.Interop.Excel.Application(); 
    oXL.Visible = true; 

    oWB = (Microsoft.Office.Interop.Excel._Workbook)(oXL.Workbooks.Add("")); 
    oSheet = (Microsoft.Office.Interop.Excel._Worksheet)oWB.ActiveSheet; 

    var dgArray = new object[dgvResults.RowCount, dgvResults.ColumnCount+1]; 
    foreach (DataGridViewRow i in dgvResults.Rows) 
    { 
     if (i.IsNewRow) continue; 
     foreach (DataGridViewCell j in i.Cells) 
     { 
      dgArray[j.RowIndex, j.ColumnIndex] = j.Value.ToString(); 
     } 
    } 

    Microsoft.Office.Interop.Excel.Range chartRange; 

    int rowCount = dgArray.GetLength(0); 
    int columnCount = dgArray.GetLength(1); 
    chartRange = (Microsoft.Office.Interop.Excel.Range)oSheet.Cells[2, 1]; //I have header info on row 1, so start row 2 
    chartRange = chartRange.get_Resize(rowCount, columnCount); 
    chartRange.set_Value(Microsoft.Office.Interop.Excel.XlRangeValueDataType.xlRangeValueDefault, dgArray); 


    oXL.Visible = false; 
    oXL.UserControl = false; 
    string outputFile = "Output_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xlsx"; 

    oWB.SaveAs("c:\\temp\\"+outputFile, Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookDefault, Type.Missing, Type.Missing, 
     false, false, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, 
     Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); 

    oWB.Close(); 
} 
catch (Exception ex) 
{ 
    //... 
} 
0

जब आप एक एक्सेल शीट में एक 1 डी सरणी आप इसे स्थानांतरित करने के लिए है और लिखना चाहते आप 1 कॉलम के साथ एक 2 डी सरणी बनाने के लिए के रूप में की जरूरत नहीं है ([, 1 n]) मैंने ऊपर पढ़ा है!

wSheet.Cells(RowIndex, colIndex).Resize(RowsCount,).Value = _excel.Application.transpose(My1DArray) 

, गाइल्स

संबंधित मुद्दे