{"id":241,"date":"2022-10-10T10:37:35","date_gmt":"2022-10-10T08:37:35","guid":{"rendered":"http:\/\/test.pcbinvestigator.de\/en\/?page_id=241"},"modified":"2022-10-10T13:48:49","modified_gmt":"2022-10-10T11:48:49","slug":"how-to-find-variants-in-odb","status":"publish","type":"page","link":"https:\/\/www.pcb-investigator.com\/en\/support\/help-center\/how-to-instructions\/how-to-find-variants-in-odb\/","title":{"rendered":"How to find variants in ODB++"},"content":{"rendered":"\n<p>Some ODB++ jobs have different variants for components. An easy way to find the variants is to check all attributes and list them in an overview dictionary, here is the code for a class who handles variants over strings. You have a list with all variants, it is possible to save the variant names and load them from a file. In the example there are two standard values included.<\/p>\n\n\n\n<p>To find the variants, you have to call CreateVariantList and get the dictionary with all variants. <\/p>\n\n\n\n<p>Here is the solution file as ZIP:&nbsp;<a href=\"http:\/\/www.easylogix.de\/download\/Examples\/VariantenDemo2013.zip\" target=\"_blank\" rel=\"noopener\">Download<\/a><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>using PCBI.Automation;\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Xml;\nusing System.Xml.Serialization;\n \nnamespace PCBVariantReport\n{\n  public class VariantXMLClass\n  {\n    \/\/list who contains all variant names\n    public List&lt;string&gt; VariantenTable = new List&lt;string&gt;() { \"VARIANT_INSTANCE\", \"comp_variant_list\" };\n \n    \/\/\/ &lt;summary&gt;\n    \/\/\/ The list is saved as simple xml and its possible to load it with an XmlSerializer.\n    \/\/\/ &lt;\/summary&gt;\n    \/\/\/ &lt;param name=\"fullpath\"&gt;The file path + filename&lt;\/param&gt;\n    \/\/\/ &lt;returns&gt;ture if new list is loaded&lt;\/returns&gt;\n    internal bool LoadList(string fullpath)\n    {\n      if (!File.Exists(fullpath))\n        return false;\n \n      XmlSerializer x = new XmlSerializer(typeof(VariantXMLClass));\n      FileStream fs = null;\n      try\n      {\n        using (fs = new FileStream(fullpath, FileMode.Open))\n        {\n          XmlReader reader = new XmlTextReader(fs);\n          VariantXMLClass mainJobEntries = (VariantXMLClass)x.Deserialize(reader);\n \n          \/\/add the loaded names to the standards, this can be change to replace if standard values not interesting\n          this.VariantenTable.AddRange( mainJobEntries.VariantenTable);\n \n          fs.Close();\n        }\n        return true;\n      }\n      catch (Exception ex)\n      {\n        Console.WriteLine(\"Error wihle loading xml \"+ex.ToString());\n        if (fs != null) \/\/get sure to close the files stream\n          fs.Close();\n \n        return false;\n      }\n    }\n    \/\/\/ &lt;summary&gt;\n    \/\/\/ Save custom setting of list, this is necessary if you have special attributes for variants.\n    \/\/\/ &lt;\/summary&gt;\n    \/\/\/ &lt;param name=\"filename\"&gt;&lt;\/param&gt;\n    internal void SaveFileEntries(string filename)\n    {\n      try\n      {\n        XmlSerializer x = new XmlSerializer(typeof(VariantXMLClass));\n        TextWriter writer = new StreamWriter(filename);\n        x.Serialize(writer, this);\n \n        writer.Close();\n      }\n      catch (Exception ex)\n      {\n        Console.WriteLine(\"Error while saving xml file \" + ex.ToString());\n      }\n    }\n    \/\/\/ &lt;summary&gt;\n    \/\/\/ Check the complete step and sort variants in the list.\n    \/\/\/ &lt;\/summary&gt;\n    \/\/\/ &lt;param name=\"parent\"&gt;the current PCBI Window&lt;\/param&gt;\n    \/\/\/ &lt;returns&gt;a list of variants for both component layers&lt;\/returns&gt;\n    internal Dictionary&lt;string, VariantOverview&gt; CreateVariantList(IPCBIWindow parent)\n    {\n      Dictionary&lt;string, VariantOverview&gt; PartList = new Dictionary&lt;string, VariantOverview&gt;();\n      IStep step = parent.GetCurrentStep(); \/\/can be changed for all steps\n      if (step == null) return null;\n \n      ICMPLayer topLayer = step.GetCMPLayer(true);\n      ICMPLayer botLayer = step.GetCMPLayer(false);\n      if (topLayer != null)\n      {\n        AddCMPsForOneLayer(PartList, topLayer);\n      }\n      if (botLayer != null)\n      {\n        AddCMPsForOneLayer(PartList, botLayer);\n      }\n      return PartList;\n    }\n    \/\/\/ &lt;summary&gt;\n    \/\/\/ The actions for one cmp layer.\n    \/\/\/ &lt;\/summary&gt;\n    \/\/\/ &lt;param name=\"PartList\"&gt;List for variants&lt;\/param&gt;\n    \/\/\/ &lt;param name=\"relCMPLayer\"&gt;the relevant component layer&lt;\/param&gt;\n    private void AddCMPsForOneLayer(Dictionary&lt;string, VariantOverview&gt; PartList, ICMPLayer relCMPLayer)\n    {\n      foreach (ICMPObject cmp in relCMPLayer.GetAllLayerObjects())\n      {\n        Hashtable attribs = cmp.GetComponentAttributeHashtable(); \/\/get attributes\n        bool added = false;\n        foreach (string variant in VariantenTable)\n        {\n          if (attribs.ContainsKey(variant)) \/\/check the variant is included?\n          {\n            #region variant element\n            VariantOverview overview;\n            if (!PartList.ContainsKey(variant))\n            {\n              overview = new VariantOverview();\n              overview.Variant = variant;\n              PartList.Add(variant, overview);\n            }\n            else\n              overview = PartList&#91;variant];\n \n            \/\/add to the correct list\n            if (overview.VariantValueAndList.ContainsKey((string)attribs&#91;variant]))\n              overview.VariantValueAndList&#91;(string)attribs&#91;variant]].Add(cmp);\n            else\n              overview.VariantValueAndList.Add((string)attribs&#91;variant], new List&lt;ICMPObject&gt;() { cmp });\n \n            added = true; \/\/maybe there is no variant\n            #endregion\n          }\n        }\n        if (!added) \/\/all cmps without variant\n        {\n          #region no variant\n          string noVariant = \"no variant\";\n          if (!PartList.ContainsKey(noVariant))\n            PartList.Add(noVariant, new VariantOverview() { Variant = noVariant });\n \n          if (PartList&#91;noVariant].VariantValueAndList.ContainsKey(noVariant))\n            PartList&#91;noVariant].VariantValueAndList&#91;noVariant].Add(cmp);\n          else\n            PartList&#91;noVariant].VariantValueAndList.Add(noVariant, new List&lt;ICMPObject&gt;() { cmp });\n          #endregion\n        }\n      }\n    }\n    \/\/\/ &lt;summary&gt;\n    \/\/\/ we have a simple class to sort the variants with lists\n    \/\/\/ &lt;\/summary&gt;\n    internal class VariantOverview\n    {\n      public string Variant = \"\";\n      public Dictionary&lt;string, List&lt;ICMPObject&gt;&gt; VariantValueAndList = new Dictionary&lt;string, List&lt;ICMPObject&gt;&gt;();\n    }\n  }\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Some ODB++ jobs have different variants for components. An easy way to find the variants is to check all attributes and list them in an overview dictionary, here is the code for a class who handles variants over strings. You have a list with all variants, it is possible to save the variant names and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":246,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-241","page","type-page","status-publish","hentry","entry"],"_links":{"self":[{"href":"https:\/\/www.pcb-investigator.com\/en\/wp-json\/wp\/v2\/pages\/241","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pcb-investigator.com\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.pcb-investigator.com\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.pcb-investigator.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pcb-investigator.com\/en\/wp-json\/wp\/v2\/comments?post=241"}],"version-history":[{"count":2,"href":"https:\/\/www.pcb-investigator.com\/en\/wp-json\/wp\/v2\/pages\/241\/revisions"}],"predecessor-version":[{"id":351,"href":"https:\/\/www.pcb-investigator.com\/en\/wp-json\/wp\/v2\/pages\/241\/revisions\/351"}],"up":[{"embeddable":true,"href":"https:\/\/www.pcb-investigator.com\/en\/wp-json\/wp\/v2\/pages\/246"}],"wp:attachment":[{"href":"https:\/\/www.pcb-investigator.com\/en\/wp-json\/wp\/v2\/media?parent=241"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pcb-investigator.com\/en\/wp-json\/wp\/v2\/categories?post=241"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pcb-investigator.com\/en\/wp-json\/wp\/v2\/tags?post=241"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}