2016-08-15 3 views
5

नीचे सी # से गतिशील रूप से निर्भर पिकलिस्ट बनाने में एक सामान्य प्रयास है। जब pick1 से मान 'ए' चुना जाता है, तो pick2 को माध्यमिक श्रेणी से मान प्रदर्शित करना होता है।सी # एक्सेल निर्भरता पिकलिस्ट प्रमाणीकरण और अप्रत्यक्ष

यह कोड लगभग काम करता है, लेकिन माध्यमिक श्रेणी को प्रदर्शित करने के बजाय यह शाब्दिक मान 'ए' प्रदर्शित करता है।

pick2.Validation.Add(XlDVType.xlValidateList, 
        XlDVAlertStyle.xlValidAlertStop, 
        XlFormatConditionOperator.xlBetween, 
        "=INDIRECT(\"A5\")"); 

जब मैं डेटा सत्यापन के निर्यात और संशोधित करने के बाद एक्सेल खोलता हूं तो यह सूत्र दिखाता है।

=INDIRECT("A5") 

यदि मैं उद्धरण को बाहर करने के लिए एक्सेल में मैन्युअल रूप से सूत्र को संशोधित करता हूं तो यह अपेक्षा के अनुसार काम करता है।

=INDIRECT(A5) 

जब मैं निम्नलिखित में कोड संशोधित करता हूं तो मुझे अपवाद मिलता है। कोई विचार?

pick2.Validation.Add(XlDVType.xlValidateList, 
        XlDVAlertStyle.xlValidAlertStop, 
        XlFormatConditionOperator.xlBetween, 
        "=INDIRECT(A5)"); 

अपवाद:

System.Runtime.InteropServices.COMException was unhandled 
    ErrorCode=-2146827284 
    Message=Exception from HRESULT: 0x800A03EC 
Source="" 


StackTrace: 
    at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData) 
    at Microsoft.Office.Interop.Excel.Validation.Add(XlDVType Type, Object AlertStyle, Object Operator, Object Formula1, Object Formula2) 
    at TestExcelValidation.Program.Main(String[] args) in C:\TFS\ExcelInterop\TestExcelValidation\Program.cs:line 44 
    at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args) 
    at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
    at System.Threading.ThreadHelper.ThreadStart() 
    InnerException: 

पूर्ण उदाहरण:

using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using Microsoft.Office.Interop.Excel; 

namespace TestExcelValidation 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string temporaryPath = Path.GetTempPath(); 
      string temporaryFile = Path.GetTempFileName(); 
      Application appl = new Application(); 
      appl.Visible = true; 
      Workbook workbook = appl.Workbooks.Open(temporaryFile, 0, true, 5, "", "", true, XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0); 
      Worksheet worksheet = (Worksheet)workbook.Worksheets.Add(); 



      List<string> primaryList = new List<string>(); 
      primaryList.Add("A"); 
      primaryList.Add("B"); 

      List<string> secondaryListA = new List<string>(); 
      secondaryListA.Add("A1"); 
      secondaryListA.Add("A2"); 
      secondaryListA.Add("A3"); 

      List<string> secondaryListB = new List<string>(); 
      secondaryListB.Add("B1"); 
      secondaryListB.Add("B2"); 
      secondaryListB.Add("B3"); 

      Range primaryRange = AddToExcelNamedRange(worksheet, primaryList, 'A', 1, "PrimaryRange"); 
      Range secondaryRangeA = AddToExcelNamedRange(worksheet, secondaryListA, 'B', 1, "A"); 
      Range secondaryRangeB = AddToExcelNamedRange(worksheet, secondaryListB, 'C', 1, "B"); 

      Range pick1 = worksheet.Range["A5"]; 
      pick1.Validation.Add(XlDVType.xlValidateList, XlDVAlertStyle.xlValidAlertStop, XlFormatConditionOperator.xlBetween, "=PrimaryRange"); 
      Range pick2 = worksheet.Range["A6"]; 
      pick2.Validation.Delete(); 
      pick2.NumberFormat = "Text"; 
      pick2.Validation.Add(XlDVType.xlValidateList, XlDVAlertStyle.xlValidAlertStop, XlFormatConditionOperator.xlBetween, "=INDIRECT(\"A5\")"); 
      pick2.Validation.InCellDropdown = true; 
      pick2.Validation.IgnoreBlank = true; 
     } 

     private static Range AddToExcelNamedRange(Worksheet worksheet, List<string> primaryList, char col, int row, string rangeName) 
     { 
      Range range = worksheet.Range[col.ToString() + row.ToString(), col.ToString() + primaryList.Count().ToString()]; 
      range.Name = rangeName; 
      foreach (string item in primaryList) 
      { 
       worksheet.Cells[row, col - 64] = item; 
       row++; 
      } 
      return range; 
     } 
    } 
} 

उत्तर

3

मैं एक समाधान है के रूप में ही है, लेकिन मैं जानना चाहता है कि यह काम नहीं करता चाहते हैं। मुझे यकीन है कि मैं इसे फिर से चलाऊंगा।

यहां अंग्रेजी में एक जवाब है, भगवान केवल जानता है कि अन्य दो क्या कह रहे हैं।

समस्या

एक व्यापक सी # (या VBA) के माध्यम से Excel में एक मान्यता का उपयोग कर ड्रॉप डाउन सूची जोड़ना एक COMException 0x800A03EC साथ विफल रहता है।

कारण

कारण यह काम नहीं करता क्योंकि स्रोत वास्तव में खाली है।

मुझे आपको दिखाएं कि मैंने यह कैसे किया। मैं Excel में मैक्रो इंजेक्शन और यह भाग गया:

Range pick1 = worksheet.Range["A5"]; 
pick1.Validation.Add(XlDVType.xlValidateList, XlDVAlertStyle.xlValidAlertStop, XlFormatConditionOperator.xlBetween, "=PrimaryRange"); 
Range pick2 = worksheet.Range["A6"]; 

StringBuilder sb = new StringBuilder(); 
sb.Append("Sub InsertCascadingDropDown()" + Environment.NewLine); 
sb.Append(" Range(\"A6\").Select" + Environment.NewLine); 
sb.Append(" With Selection.Validation" + Environment.NewLine); 
sb.Append("  .Delete" + Environment.NewLine); 
sb.Append("  .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= xlBetween, Formula1:=\"=INDIRECT(A5)\"" + Environment.NewLine); 
sb.Append("  .IgnoreBlank = True" + Environment.NewLine); 
sb.Append("  .InCellDropdown = True" + Environment.NewLine); 
sb.Append("  .ShowInput = True" + Environment.NewLine); 
sb.Append("  .ShowError = True" + Environment.NewLine); 
sb.Append(" End With" + Environment.NewLine); 
sb.Append("End Sub" + Environment.NewLine); 

//You need to add a COM reference to Microsoft Visual Basic for Applications Extensibility for this to work 
var xlmodule = workbook.VBProject.VBComponents.Add(Microsoft.Vbe.Interop.vbext_ComponentType.vbext_ct_StdModule); 

xlmodule.CodeModule.AddFromString(sb.ToString()); 
appl.Run("InsertCascadingDropDown"); 

यह एक रन-टाइम त्रुटि '1004' जब मैक्रो सत्यापन जोड़ने के लिए लाइन कार्यान्वित कारण बनता है:

.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:="=INDIRECT(A5)" 

enter image description here

इसलिए इसने मुझे विश्वास किया कि चयन ऑब्जेक्ट को परिभाषित नहीं किया गया था (या चयन शब्द की व्याख्या करने के तरीके के आधार पर यह खाली था।

समाधान

मैं इस के साथ चारों ओर खेला और अंत में कोड नियंत्रण रुका और मैन्युअल रूप से मान्यता जोड़ा जब मैं इस खोज की:

enter image description here

स्रोत वर्तमान में एक त्रुटि मूल्यांकन करता है।

वह धूम्रपान बंदूक थी कि चयन ऑब्जेक्ट शून्य नहीं था, यह ए 5 ड्रॉप डाउन सूचियों का चयन/मूल्य वास्तव में खाली था!

कैस्केडिंग ड्रॉप डाउन सूची को जोड़ना अपने माता-पिता को मूल्य रखने की आवश्यकता है!

pick1.Value2 = "A"; //< set the parent to have a value 
pick2.Validation.Delete(); //<- this is not really needed, unless you run this again 
pick2.Validation.Add(XlDVType.xlValidateList, XlDVAlertStyle.xlValidAlertStop, XlFormatConditionOperator.xlBetween, "=INDIRECT(A5)"); 
+0

यह चाल किया:

तो यह सब आप सब करने की ज़रूरत है! –

0

कम से कम एक्सेल 2007 और 2010, =Indirect(A5) साथ उद्धरण चिह्नों के बिना जब एक सेल में इस्तेमाल #REF मूल्यांकन करता है। मैं सोच रहा हूं कि सी # से यह कोड कैसे पारित किया गया है अपवाद के साथ कुछ करने के लिए है (क्योंकि यह एक त्रुटि का मूल्यांकन करेगा)। साथ ही, सत्यापन को मैन्युअल रूप से बनाते समय एक ही फ़ंक्शन का उपयोग करके यह संदेश एक्सेल में त्रुटि के लिए मूल्यांकन करता है। संपादित करें: हालांकि मैं कुछ शोधों के साथ यहां कुछ बिंदुओं के साथ सुधार हुआ हूं।

अप्रत्यक्ष() से अपेक्षित इनपुट वास्तविक सेल संदर्भ के बजाय ए 1 या आर 1 सी 1 प्रारूप में स्ट्रिंग मान की अपेक्षा करता है। जब तक, लक्ष्य सीमा एक सेल संदर्भ पूर्व नहीं है: ए 5 ए 1 था।

एमएसडीएन के अनुसार, अप्रत्यक्ष() केवल तभी गणना करेगा जब फ़ाइल खुली होगी और स्मृति MSDN 151323 में होगी। कार्यपुस्तिका खोलना और सत्यापन सूची को बदलना और इसे सही ढंग से मूल्यांकन करने का अर्थ यह नहीं है कि त्रुटि तब मौजूद नहीं है जब सी # में कोड चलाया जाता है।

0

उदाहरण के लिए A5 में मूल्य B है तो =INDIRECT(A5) जो जो मान्य सूत्र या कक्ष संदर्भ नहीं है एक ही =B के रूप में है =INDIRECT("B") के समान है।

=INDIRECT("A5")=A5

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