2015-03-05 7 views
9

का उपयोग कर एक्सेल में एक सेल का कॉलम इंडेक्स प्राप्त करें, मैं थोड़ी देर के लिए देख रहा हूं और ऐसा नहीं लगता कि यह कैसे किया जाए। मुझे एक्सेल शीट मिली है, जिसे मैं ओपनएक्सएमएल का उपयोग कर पढ़ रहा हूं। अब सामान्य चीजों को पंक्तियों के माध्यम से लूप करना होगा और फिर मूल्यों को प्राप्त करने के लिए कोशिकाओं के माध्यम से लूप करना होगा, जो ठीक है। लेकिन मूल्यों के साथ मुझे सेल के स्थान की आवश्यकता है, जो प्रारूप में होगा (rowindex, ColumnIndex)। मैंने पंक्ति इंडेक्स प्राप्त करने में कामयाब रहा है, लेकिन कॉलम इंडेक्स प्राप्त करने के बारे में पता लगाना प्रतीत नहीं होता है।ओपनएक्सएमएल सी #

मैंने वास्तव में सोचा कि यह आसान होने वाला था लेकिन स्पष्ट रूप से यह नहीं है।

+2

भविष्य पाठकों के लिए है, मैं [इस जवाब को देखने] सलाह देते हैं (http://stackoverflow.com/a/667902/906773)। –

उत्तर

-7

चूंकि आप Worksheet.Descendants<Cell>() का उपयोग कर पंक्ति की कोशिकाओं के माध्यम से लूप कर सकते हैं, तो आप सेल की अनुक्रमणिका निर्धारित करने के लिए बस for -loop का उपयोग कर सकते हैं।

+0

बिल्कुल सही। मुझे बस एक काउंटर चाहिए। मूर्ख में !! – QV1

+12

यदि आपके पास खाली कॉलम हैं तो यह काम नहीं करेगा क्योंकि वे XML में होने के लिए गारेन नहीं किए गए हैं। जैसा कि @ केसीडीओडी कहता है, आपको 'सेल रेफरेंस' का उपयोग करने की आवश्यकता होगी। उदा। यदि 'ए 1' और' सी 1 'में डेटा है लेकिन 'बी 1' क्या आप यह सोचने को समाप्त नहीं कर सकते कि' सी 1 'दूसरा कॉलम है और तीसरा नहीं है। – petelids

+0

@petelids आप सही हैं। यदि आपको कोई समाधान मिलता है तो कृपया हमें भी प्रदान करें। बहुत धन्यवाद –

2

उत्तर देने के लिए, मैं आपको this पर पहले देखने के लिए आमंत्रित करता हूं।

जैसा कि मैंने समझाया है कि NO पंक्ति और स्तंभ निकालने का आसान तरीका है। आपको सबसे नज़दीक मिलता है एक सेल के CellReference का निष्कर्षण जिसमें A1, B2 का रूप होगा जो वास्तव में COLUMN_ROW प्रारूप है।

आप क्या कर सकते हैं CellReference से पंक्ति और कॉलम निकालें। हां, आपको एक विधि को लागू करने की आवश्यकता होगी जहां आपको charchar द्वारा संख्याओं और तारों की पुष्टि करने के लिए जांच करने की आवश्यकता होगी।

मान लें कि आपके पास A11 है, तो जब आपको कॉलम इंडेक्स करने की आवश्यकता होती है तो आपको A निकालने की आवश्यकता होती है जो column 1 के रूप में देगी। हां यह इतना आसान नहीं है, लेकिन यह एकमात्र तरीका है जब तक आप कोशिकाओं के माध्यम से स्कैन/पुनरावृत्ति करते समय कॉलम को गिनने का विकल्प नहीं चुनते।

फिर से this प्रश्नों के उत्तर देखें जो वही काम करता है।

+0

हम्म .. ठीक है, लेकिन मुझे उस कॉलम इंडेक्स की ज़रूरत है। इसलिए अब मैं क्या सोच रहा हूं, कॉलम इंडेक्स प्राप्त करने के लिए सेल संदर्भ से पत्र को प्रतिस्थापित करने का एक तरीका ढूंढना है। – QV1

+0

जैसा कि उत्तर में बताया गया है, कोई आसान तरीका नहीं है :) बस गिनती है क्योंकि मैंने लिंक किए गए प्रश्न में इंगित किया है :) –

+0

@ QV1 क्या आपको इस प्रश्न का उत्तर मिला? या आपको अधिक स्पष्टीकरण की आवश्यकता है :) –

15

मुझे इसका उत्तर देने के लिए थोड़ा देर हो रही है, लेकिन स्वीकृत उत्तर काम नहीं करेगा यदि आपकी रुचि रखने वाली पंक्ति में रिक्त कक्ष हैं क्योंकि उन्हें XML में होने की गारंटी नहीं है, स्कीमा खाली कोशिकाओं को छोड़ा जा सकता है।

प्राप्त करने के लिए सूचकांक आप Cell वस्तु wihch एक CellReference संपत्ति है कि प्रारूप A1, B1 आदि आपको लगता है कि संदर्भ का उपयोग कर सकते स्तंभ संख्या को निकालने के लिए में संदर्भ देता है का उपयोग कर सकते हैं।

आप शायद जानते हैं, एक्सेल A = 1, B = 2 आदि में Z = 26 अप करने के लिए, जिसके आधार पर कोशिकाओं A लगी होती हैं देने के लिए AA = 27, AB = 28 आदि ध्यान दें कि AA पहले A के मामले में 26 बार के एक मूल्य है दूसरा; यानी यह "लायक" है जबकि दूसरा A कुल "27"

कॉलम इंडेक्स को काम करने के लिए आप अक्षरों को उलट सकते हैं तो पहले अक्षर का मूल्य लें और इसे जोड़ें चालू हालत में कुल। फिर दूसरे अक्षर का मूल्य लें और इसे 26 तक गुणा करें, कुल मिलाकर कुल संख्या में जोड़ें। तीसरे के लिए आप इसे दो बार गुणा करके जोड़ते हैं, चौथे भाग के लिए इसे 26 गुणा और गुणा करके गुणा करें।

तो स्तंभ ABC के लिए आप क्या करेंगे:

C = 3 
B = 2 * 26 = 52 
A = 1 * 26 *26 = 676 
3 + 52 + 676 = 731 

सी # में निम्नलिखित काम करेगा:

private static int? GetColumnIndex(string cellReference) 
{ 
    if (string.IsNullOrEmpty(cellReference)) 
    { 
     return null; 
    } 

    //remove digits 
    string columnReference = Regex.Replace(cellReference.ToUpper(), @"[\d]", string.Empty); 

    int columnNumber = -1; 
    int mulitplier = 1; 

    //working from the end of the letters take the ASCII code less 64 (so A = 1, B =2...etc) 
    //then multiply that number by our multiplier (which starts at 1) 
    //multiply our multiplier by 26 as there are 26 letters 
    foreach (char c in columnReference.ToCharArray().Reverse()) 
    { 
     columnNumber += mulitplier * ((int)c - 64); 

     mulitplier = mulitplier * 26; 
    } 

    //the result is zero based so return columnnumber + 1 for a 1 based answer 
    //this will match Excel's COLUMN function 
    return columnNumber + 1; 
} 

ध्यान दें कि CellReference नहीं एक्सएमएल या तो (हालांकि में होने की गारंटी है मैंने इसे कभी नहीं देखा है)। ऐसे मामले में जहां CellReference शून्य है, सेल को बाईं ओर उपलब्ध सेल में रखा गया है। RowIndex भी spec में अनिवार्य नहीं है, इसलिए यह भी छोड़ा जा सकता है कि सेल को उच्चतम पंक्ति में रखा गया है। this question में अधिक जानकारी देखी जा सकती है। @BCdotWEB से answer उन मामलों में सही दृष्टिकोण है जहां CellReferencenull है।

+0

आप कॉलम नम्बर = 0 से शुरू कर सकते हैं और लौटने पर एक को जोड़ नहीं सकते हैं। –

+0

दूसरे पत्र में जेड के साथ क्या होगा? क्या यह तीसरे पर ए जैसा नहीं होगा? तो 'जेड = 26 * 26' और' ए = 1 * 26 * 26'। मैं पूछ रहा हूं क्योंकि मैं सेल इंडेक्स से सेल नाम पर जा रहा रिवर्स करने की कोशिश कर रहा हूं। – bostero2

+0

दूसरे अक्षर में एक 'जेड' 26 "लायक" है। इसे पहले अक्षर के मूल्य में 26 गुना जोड़ा जाएगा। जैसे 'ZZ'' (26 * 26) + 26 = 702' होगा। तीसरे कॉलम में 'ए' 'लायक' '1' है। यह दूसरे पत्र के मूल्य 26 गुणा और 26 * 26 गुना पहले के मूल्य में जोड़ा जाएगा। उदा। 'एएए' '(26 * 26 * 1) + (26 * 1) + 1 = 703' होगा। – petelids

6

छोटे सुंदर

int ColumnIndex(string reference) 
{ 
    int ci=0; 
    reference=reference.ToUpper(); 
    for (int ix = 0; ix < reference.Length && reference[ix] >= 'A';ix++) 
     ci = (ci * 26) + ((int)reference[ix] - 64); 
    return ci; 
} 
+0

64 की व्याख्या करने के लिए देखभाल? – Yaron

+0

@Yaron: 64 है ('ए' - 1) – Captain

+0

@ कैप्टन धन्यवाद! – Yaron

2
[TestCase(1, 0, "A1")] 
    [TestCase(2, 25, "Z2")] 
    [TestCase(2, 38, "AM2")] 
    [TestCase(2, (26 * 4) + 1, "DB2")] 
    [TestCase(2, (26 * 26 * 26 * 18) + (26 * 26 * 1) + (26 * 26 * 1) + (26 * 1) + 2, "RBAC2")] 
    public void CanGetCorrectCellReference(int row, int column, string expected) 
     => GetCellReference((uint)row, (uint)column).Value.ShouldEqual(expected); 

    public static StringValue GetCellReference(uint row, uint column) => 
     new StringValue($"{GetColumnName("",column)}{row}"); 

    static string GetColumnName(string prefix, uint column) => 
     column < 26 ? $"{prefix}{(char)(65 + column)}" : 
     GetColumnName(GetColumnName(prefix, (column - column % 26)/26 - 1), column % 26); 
संबंधित मुद्दे