<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8299669941450299948</id><updated>2012-01-18T12:15:57.669-08:00</updated><category term='jboss'/><category term='adobe live cycle data services'/><category term='os x'/><category term='flex builder'/><category term='lcds'/><title type='text'>Some Hardware Guy</title><subtitle type='html'>A hardware guy writing code is kind of like a bear riding a bicycle.   Sure he can do it, but why?   Also if you get too close you might get eaten.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://somehardwareguy.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://somehardwareguy.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Some Hardware Guy</name><uri>http://www.blogger.com/profile/17462828792887566460</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>16</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8299669941450299948.post-7133517320198602247</id><published>2012-01-18T12:15:00.000-08:00</published><updated>2012-01-18T12:15:57.687-08:00</updated><title type='text'>Aras Innovator Import Orcad CIS BOM</title><content type='html'>As I've been saying this is definitely a hack way of doing things, but it works. &amp;nbsp;I'm sure there's a better way and if you make one let me know ;) &amp;nbsp; Alright the goal in this section is to go into Orcad Capture, generate a BOM and import it into Innovator. &amp;nbsp; So let's start with Orcad.&lt;br /&gt;
&lt;br /&gt;
Go into Capture like you usually would and generate a CIS Bill Of materials. &amp;nbsp; The only things you want in the BOM are: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Item Number&lt;/li&gt;
&lt;li&gt;Quantity&lt;/li&gt;
&lt;li&gt;PART_NUMBER&lt;/li&gt;
&lt;li&gt;Part Reference&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-5OPLLKqK8sM/Txb8vm3m4yI/AAAAAAAABVs/MK9SL4pBv0w/s1600/orcad_cis_bom.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="640" src="http://1.bp.blogspot.com/-5OPLLKqK8sM/Txb8vm3m4yI/AAAAAAAABVs/MK9SL4pBv0w/s640/orcad_cis_bom.png" width="457" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
When you click OK you should get a csv file with all of your data in it. &amp;nbsp;That looks something like this:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-IhWfksHYwMw/Txb9i8CotzI/AAAAAAAABV0/29RE-AhpHM4/s1600/csv_file.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="196" src="http://3.bp.blogspot.com/-IhWfksHYwMw/Txb9i8CotzI/AAAAAAAABV0/29RE-AhpHM4/s640/csv_file.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
This is the file we'll load into Innovator. &amp;nbsp; Make sure you close this file in excel because I had trouble opening it in innovator if it was already open in another program.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The Form&lt;/b&gt;&lt;br /&gt;
In a previous post I showed how I created a new item type CIP LOADED BOM to store this information. &amp;nbsp; Now we need to go modify the form associated with this item, because that is where we'll import this file. &amp;nbsp;This is kind of a hack way of doing things but at least you can see what I did and do it better on your system.&lt;br /&gt;
&lt;br /&gt;
Go to Administration-&amp;amp;gt;Forms and find the form LOADED BOMs form that we created in the last post.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-i_TDmISm8sM/TxcRNfQjJyI/AAAAAAAABWE/Skt4e9hAJqk/s1600/cip_loaded_bom_form.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="382" src="http://3.bp.blogspot.com/-i_TDmISm8sM/TxcRNfQjJyI/AAAAAAAABWE/Skt4e9hAJqk/s640/cip_loaded_bom_form.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Modifying this form is just like using any gui editor, you can add fields, select, boxes, etc.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Text Fields&lt;/b&gt;&lt;br /&gt;
This is mostly for my own debug but I added four text fields for each of the columns in the CIP LOADED BOM. &amp;nbsp; You can see above where I set the data source for the partID field to partID. &amp;nbsp; Now when you select a row from the CIP LOADED BOM it will populate with that rows data, and you can edit it if you want to. &amp;nbsp;I'll probably disable this for regular users.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Form Events&lt;/b&gt;&lt;br /&gt;
There are two form events that I used, onLoad and onResize. &amp;nbsp;onLoad runs every time the form loads and gets the Innovator parts for the Assembly Part Number select box. &amp;nbsp;onResize runs whenever you resize the form, it will resize the html2 element that holds the table of CIP parts in it.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-mEod5Sj1xr0/TxcSvjMm_rI/AAAAAAAABWM/YmTu_QjWAHU/s1600/cip_loaded_bom_form_events.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="130" src="http://4.bp.blogspot.com/-mEod5Sj1xr0/TxcSvjMm_rI/AAAAAAAABWM/YmTu_QjWAHU/s640/cip_loaded_bom_form_events.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;Form onResize&lt;/b&gt;&lt;br /&gt;
&lt;pre class="brush: javascript; ruler: true; first-line: 10; highlight: [2, 4, 6]"&gt;document.getElementById("MyGrid").style.width = document.body.clientWidth - 100;
&lt;/pre&gt;
&lt;br /&gt;
Notice that we're switching over to javascript here. &amp;nbsp; All the forms are just html documents and all the active elements are done in javascript. &amp;nbsp;This script just re-sizes the form whenever the window resizes.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Form onLoad&lt;/b&gt;&lt;br /&gt;
The user needs to be able to choose which Innovator part to associate this Orcad BOM with. &amp;nbsp; So when the page loads I look up all the parts that are not released and put them in a select box so they can pick one. &amp;nbsp; My basic assumption is you can only load a CIP Bom onto a part that is unreleased, and that part is only used for holding CIP BOM data and nothing else. &lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: javascript; ruler: true; first-line: 10; highlight: [2, 4, 6]"&gt;var item = document.thisItem;
// Set up the query Item. &amp;nbsp;Get all the most current part numbers that are not released
var qryItem = item.newItem("Part","get");
qryItem.loadAML(
"&amp;lt;Item type='Part' action='get' select='item_number,description,cost'&amp;gt;" +
"&amp;lt;item_number condition='like'&amp;gt;*&amp;lt;/item_number&amp;gt;" +
"&amp;lt;is_released condition='eq'&amp;gt;0&amp;lt;/is_released&amp;gt;" +
"&amp;lt;is_current condition='eq'&amp;gt;1&amp;lt;/is_current&amp;gt;" +
"&amp;lt;/Item&amp;gt;"
);
/*qryItem.loadAML(
"&amp;lt;Item type='Part' action='get'&amp;gt;" +&amp;nbsp;
"&amp;lt;generation condition='in'&amp;gt;SELECT MAX(generation) FROM [PART] WHERE is_released='0' AND is_current='1'&amp;lt;/generation&amp;gt;" +&amp;nbsp;
"&amp;lt;/Item&amp;gt;"
);
*/

// Perform the query.
var results = qryItem.apply();
// Test for an error.
if (results.isError()) {
top.aras.AlertError("No items maybe? Item not found: " + results.getErrorDetail());
return;
}
//debugger;
//loop through the returned items
var count = results.getItemCount();
//var select = document.getElementById("assemblyPart");
var select = document.getElementsByName("assemblyPart")[0];
select.options.length = 0;




for (i=0; i&amp;lt;count; ++i) {
&amp;nbsp; &amp;nbsp; &amp;nbsp;var rItem = results.getItemByIndex(i);
&amp;nbsp; &amp;nbsp; &amp;nbsp;//select.options.add(new Option(rItem.getProperty("id"), rItem.getProperty("item_number"));
&amp;nbsp; &amp;nbsp; &amp;nbsp;//select.options.add("Test", "test");
&amp;nbsp; &amp;nbsp; &amp;nbsp;select.options[select.options.length] = new Option(rItem.getProperty("item_number"), rItem.getProperty("id"));

}
&lt;/pre&gt;
&lt;br /&gt;
The code above uses the loadAML function to create a query to get the most current version of all parts, that are also unreleased. &amp;nbsp; This way once a user has uploaded and released a bom part they can only change it buy increasing the rev. &amp;nbsp; That's my idea anyway. &amp;nbsp; The next part runs the query and throws up a dialog box if it finds no parts to use. &amp;nbsp; Finally we get how many results the query returned and stuff all those results into our select box.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Html Table&lt;/b&gt;&lt;br /&gt;
I thought it would be a good idea to first load the .csv bom file from Capture, and show it back to the user for review before we save it. &amp;nbsp; That way if there's some corruption or something, you at least get a chance to cancel. &amp;nbsp;The first step to that is adding an html field to the form, and putting this html code into it: &lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: html; ruler: true; first-line: 10; highlight: [2, 4, 6]"&gt;&amp;lt;script type="text/javascript"&amp;gt;
top.aras.uiAddConfigLink2Doc4Assembly(document, "TreeTable");

&amp;lt;/script&amp;gt;
&amp;lt;object id="MyGrid"
style="width:600px;height:500px;"classid="../cbin/TreeTable.dll#Aras.Client.Controls.GridContainer"&amp;gt;
&amp;lt;/object&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;
Note the object id of MyGrid, it will be used to populate the grid in the next step.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Load CSV Button&lt;/b&gt;&lt;br /&gt;
To add code to the load button I just defined a onClick function under Field Events. &amp;nbsp; Then I used this javascript.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: javascript; ruler: true; first-line: 10; highlight: [2, 4, 6]"&gt;var vault = top.aras.vault;
var fileName = vault.SelectFile();
strData = vault.ReadText(fileName);
//alert(strData);



        strDelimiter = ",";

        // Create a regular expression to parse the CSV values.
        var objPattern = new RegExp(
                (
                        // Delimiters.
                        "(\\" + strDelimiter + "|\\r?\\n|\\r|^)" +

                        // Quoted fields.
                        "(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" +

                        // Standard fields.
                        "([^\"\\" + strDelimiter + "\\r\\n]*))"
                ),
                "gi"
                );


        // Create an array to hold our data. Give the array
        // a default empty first row.
        var arrData = [[]];

        // Create an array to hold our individual pattern
        // matching groups.
        var arrMatches = null;


        // Keep looping over the regular expression matches
        // until we can no longer find a match.
        while (arrMatches = objPattern.exec( strData )){

                // Get the delimiter that was found.
                var strMatchedDelimiter = arrMatches[ 1 ];

                // Check to see if the given delimiter has a length
                // (is not the start of string) and if it matches
                // field delimiter. If id does not, then we know
                // that this delimiter is a row delimiter.
                if (
                        strMatchedDelimiter.length &amp;amp;&amp;amp;
                        (strMatchedDelimiter != strDelimiter)
                        ){

                        // Since we have reached a new row of data,
                        // add an empty row to our data array.
                        arrData.push( [] );

                }


                // Now that we have our delimiter out of the way,
                // let's check to see which kind of value we
                // captured (quoted or unquoted).
                if (arrMatches[ 2 ]){

                        // We found a quoted value. When we capture
                        // this value, unescape any double quotes.
                        var strMatchedValue = arrMatches[ 2 ].replace(
                                new RegExp( "\"\"", "g" ),
                                "\""
                                );

                } else {

                        // We found a non-quoted value.
                        var strMatchedValue = arrMatches[ 3 ];

                }


                // Now that we have our value string, let's add
                // it to the data array.
                arrData[ arrData.length - 1 ].push( strMatchedValue );
        }

window.arrData = arrData;

        // Return the parsed data.
        //alert( arrData );
var item = document.thisItem;
// Get the relationships
var results = item.newItem("CIP LOADED BOM");
//debugger;
test = item.getNewID()
results.setID(test);
//debugger;
//qry.setAttribute("select", "quantity,related_id(item_number,name,cost)");
results.setProperty("quantity", "200");


//prepare the grid
document.getElementById("MyGrid").style.width = document.body.clientWidth - 100;

var propNameArr = new Array("quantity");
var gridXml =
"&amp;lt;table editable='false' draw_grid='true' justify='true'&amp;gt;" +
"&amp;lt;columns&amp;gt;" +
"&amp;lt;column width='10%' align='left' /&amp;gt;" +
"&amp;lt;column width='10%' align='left' /&amp;gt;" +
"&amp;lt;column width='30%' align='right' /&amp;gt;" +
"&amp;lt;column width='50%' align='right' /&amp;gt;" +
"&amp;lt;/columns&amp;gt;" +
"&amp;lt;thead&amp;gt;" +
"&amp;lt;th&amp;gt;Item&amp;lt;/th&amp;gt;" +
"&amp;lt;th&amp;gt;Quantity&amp;lt;/th&amp;gt;" +
"&amp;lt;th&amp;gt;Part Number&amp;lt;/th&amp;gt;" +
"&amp;lt;th&amp;gt;Reference Designator&amp;lt;/th&amp;gt;" +
"&amp;lt;/thead&amp;gt;" +
"&amp;lt;/table&amp;gt;";
var inn = item.getInnovator();
var gridDom = inn.newXMLDocument();
gridDom.loadXML(gridXml);
var tableNd = gridDom.selectSingleNode("/table");


var c = arrData.length;
for (var i=0; i&amp;lt;c; ++i) {
//var bom = results.getItemByIndex(i);
//var part = bom.getRelatedItem();
var trNd = gridDom.createElement("tr");

trNd.setAttribute("id", i);
var tdNd;
tdNd = gridDom.createElement("td");
tdNd.text = arrData[i][0];
trNd.appendChild(tdNd);

tdNd = gridDom.createElement("td");
tdNd.text = arrData[i][1];
trNd.appendChild(tdNd);

tdNd = gridDom.createElement("td");
tdNd.text = arrData[i][2];
trNd.appendChild(tdNd);

tdNd = gridDom.createElement("td");
tdNd.text = arrData[i][3];
trNd.appendChild(tdNd);

tableNd.appendChild(trNd);
}
document.MyGrid.InitXml(gridDom.xml);

&lt;/pre&gt;
The very first part of this code opens a file explorer dialog box to let the user choose the file they want to upload. &amp;nbsp;The next section is borrowed from someone on Stack Overflow. &amp;nbsp;It &amp;nbsp;parses the csv file and converts it into an array of array's that we can work with. &amp;nbsp; &amp;nbsp;I store that array as a global variable, because I don't want to have to parse it again when I click the save button. &amp;nbsp; Something about duplicating the parsing code in two different functions didn't seem right to me.&lt;br /&gt;
&lt;br /&gt;
The rest of the code is dedicated to creating the grid that will display all of the component information. &amp;nbsp; The final action is to take that grid and stuff it into the MyGrid html object we created in the last step.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Save the bom&lt;/b&gt;&lt;br /&gt;
Now that you can upload and preview the bom, you need to save it and this is the last step for that. &amp;nbsp; The onclick code for the save button is below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: javascript; ruler: true; first-line: 10; highlight: [2, 4, 6]"&gt;var bomData = window.arrData;
//check if the global bom data is saved
if (bomData == null) {
top.aras.AlertError("You need to load a BOM before you can save.");
return;
}

if(bomData.length &amp;lt;= 1){
top.aras.AlertError("I think the bom you loaded is empty, is there no header column in your csv file?");
}

var select = document.getElementsByName("assemblyPart")[0];
var partID = select.options[select.selectedIndex].value;

if(partID.length != 32){
     top.aras.AlertError("ID should be 32 long");
     return;
}


var innovator = new Innovator();
//debugger;
var c = bomData.length;
for (var i=1; i&amp;lt;c; ++i) {
     if(bomData[i].length != 4){
          continue;
     }
     
     var partItem = innovator.newItem("CIP LOADED BOM","add");
     partItem.setProperty("partid", partID);
     partItem.setProperty("quantity", bomData[i][1]);
     partItem.setProperty("altiorpartnumber", bomData[i][2]);
     partItem.setProperty("ref_designator", bomData[i][3]); 
     
     var resultItem = partItem.apply();
     if (resultItem.isError()) {
        top.aras.AlertError(resultItem.getErrorDetail());
        return;
     }
}

&lt;/pre&gt;
The above code looks for the global array of bom items from when we loaded the csv file. &amp;nbsp;If it's not found it throws up an error. &amp;nbsp; If it is found it loops through all of the parts, creating a new item for each one and inserting it into the table by calling the apply() method. &amp;nbsp; There's probably a &amp;nbsp;more efficient way to do them all at once but I didn't know what it was. &amp;nbsp; For a large bom this only takes a few seconds for me. &amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Putting it all together&lt;/b&gt;&lt;br /&gt;
That's all there is, if everything came together for you, you should now be able to upload a bom created in orcad into Innovator. &amp;nbsp; To invoke this form you just created you need to go to CIP LOADED BOMS on the design tab and then edit one of the existing items. &amp;nbsp;If you don't have any then just create a fake test one to start. &amp;nbsp; I'm sure eventually I'll figure out how to just click and have this form come up but I don't know today :)&lt;br /&gt;
&lt;br /&gt;
Now just upload a csv bom, choose a part to attach these parts to and save away. &amp;nbsp;When it's done uploading you'll be able to select that part under Design - &amp;gt; Parts, click on the CIP BOM tab and see all your parts under there. &amp;nbsp;Even better you can export that bom to excel to send to your CM.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The End&lt;/b&gt;&lt;br /&gt;
Hope all this helps someone else, I know it's a bit of a mess but it does work. &amp;nbsp; Good Luck!&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;

&lt;a href="http://creativecommons.org/licenses/by-sa/3.0/" rel="license"&gt;&lt;img alt="Creative Commons License" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" style="border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px;" /&gt;&lt;/a&gt;

This &lt;span href="http://purl.org/dc/dcmitype/Text" rel="dct:type" xmlns:dct="http://purl.org/dc/terms/"&gt;work&lt;/span&gt; is licensed under a &lt;a href="http://creativecommons.org/licenses/by-sa/3.0/" rel="license"&gt;Creative Commons Attribution-ShareAlike 3.0 Unported License&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8299669941450299948-7133517320198602247?l=somehardwareguy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://somehardwareguy.blogspot.com/feeds/7133517320198602247/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://somehardwareguy.blogspot.com/2012/01/aras-innovator-import-orcad-cis-bom.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/7133517320198602247'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/7133517320198602247'/><link rel='alternate' type='text/html' href='http://somehardwareguy.blogspot.com/2012/01/aras-innovator-import-orcad-cis-bom.html' title='Aras Innovator Import Orcad CIS BOM'/><author><name>Some Hardware Guy</name><uri>http://www.blogger.com/profile/17462828792887566460</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-5OPLLKqK8sM/Txb8vm3m4yI/AAAAAAAABVs/MK9SL4pBv0w/s72-c/orcad_cis_bom.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8299669941450299948.post-7274736903078235313</id><published>2012-01-18T11:41:00.001-08:00</published><updated>2012-01-18T11:41:44.790-08:00</updated><title type='text'>CIP Innovator Association</title><content type='html'>Now it's time to make an association between my Orcad CIP parts and my Innovator Parts. &amp;nbsp;Let me say again this is a hack and probably not the way you should do it, etc, etc. &amp;nbsp; &amp;nbsp;Anyway step one is to create a new Item Type called CIP LOADED BOM. &amp;nbsp; &amp;nbsp;To create the fields I needed I just added them in the property section. &amp;nbsp; Each property you add ends up being a column in the CIP LOADED BOM table. &amp;nbsp; So all I needed were:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;partID: the part id of the Innovator part we're linking to&lt;/li&gt;
&lt;li&gt;quantity: this comes from the Orcad CIS BOM it's how many of this part you need&lt;/li&gt;
&lt;li&gt;ref_designator: these are the reference designators for you part like, C1, C2 C3 etc.&lt;/li&gt;
&lt;li&gt;companyPartnumber: &amp;nbsp;This is our internal part number.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
The relationship of partId and companyPartnumber is how I link what CIP components go with what Innovator part.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-KSCnKgj8NI8/Txb47b_zFII/AAAAAAAABVc/Os6C-Bzdxc4/s1600/cip_loaded_bom.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="388" src="http://4.bp.blogspot.com/-KSCnKgj8NI8/Txb47b_zFII/AAAAAAAABVc/Os6C-Bzdxc4/s640/cip_loaded_bom.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
The next step is to create a form for this part, just click on the Views tab and create a new form called Loaded Bom like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-HSqOwGPNIxM/Txb--Vd0bjI/AAAAAAAABV8/Phxs_S7bJoE/s1600/cip_loaded_bom_form.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="388" src="http://2.bp.blogspot.com/-HSqOwGPNIxM/Txb--Vd0bjI/AAAAAAAABV8/Phxs_S7bJoE/s640/cip_loaded_bom_form.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
That was pretty simple, and we'll use that form in the next post. &amp;nbsp;Now all you have to do is add it to the TOC. &amp;nbsp;Click the TOC Access tab and add it to the Design section.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-HsqGjKqTLRA/Txb5podmHaI/AAAAAAAABVk/YRzHHiHFQws/s1600/cip_loaded_bom_toc.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="281" src="http://2.bp.blogspot.com/-HsqGjKqTLRA/Txb5podmHaI/AAAAAAAABVk/YRzHHiHFQws/s400/cip_loaded_bom_toc.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Now if you wanted to you could go to this part under design view and add some CIP &amp;lt;-&amp;gt; Innovator part relationships. &amp;nbsp;Then when you click on the Innovator part under Design-&amp;gt;Parts and choose the CIP BOM tab you'll see your parts that have been pulled from your CIP database.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The real goal of this for me was to generate a bom from Capture and import it directly into innovator. &amp;nbsp;I'll show you my hacked up way of doing that in my next post.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8299669941450299948-7274736903078235313?l=somehardwareguy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://somehardwareguy.blogspot.com/feeds/7274736903078235313/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://somehardwareguy.blogspot.com/2012/01/cip-innovator-association.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/7274736903078235313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/7274736903078235313'/><link rel='alternate' type='text/html' href='http://somehardwareguy.blogspot.com/2012/01/cip-innovator-association.html' title='CIP Innovator Association'/><author><name>Some Hardware Guy</name><uri>http://www.blogger.com/profile/17462828792887566460</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-KSCnKgj8NI8/Txb47b_zFII/AAAAAAAABVc/Os6C-Bzdxc4/s72-c/cip_loaded_bom.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8299669941450299948.post-6267279879764869145</id><published>2012-01-18T11:41:00.000-08:00</published><updated>2012-01-18T11:43:43.179-08:00</updated><title type='text'>Linking Orcad Parts To Innovator Parts onGet Function</title><content type='html'>In the previous step we created a part called CIP Part BOM, and my originally idea had been to copy how Aras does their Part, Part BOM relationship. &amp;nbsp; I had a little trouble with that and I was pressed for time so I ended up just overriding the onGet function of the CIP Part BOM. &amp;nbsp; Then I used that to return the correct list of CIP Parts associated with the Innovator Part.&lt;br /&gt;
&lt;br /&gt;
Here's the complete, uncut, non-cleaned up code of my onGet function. &amp;nbsp;I didn't want to strip something out and have it not work for you by accident..&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: csharp; ruler: true; first-line: 10; highlight: [2, 4, 6]"&gt; 
       //C:\Program Files (x86)\Aras\Innovator\Innovator\Server\temp
    //this.dom.Save(CCO.Server.MapPath("./temp/Incoming_AML.xml"));
    //StreamWriter sw = null;
    //sw = File.CreateText("C:/Program Files (x86)/Aras/Innovator/Innovator/Server/temp/loge.txt");
    //sw.WriteLine("--- BEGIN LOG ---");
    //sw.WriteLine("source");

    //sw.Flush();
    //sw.Close();return;
    //try to get part number

    //these two items are what is going to get returned
    Item res = this.getInnovator().newResult("");
    XmlElement resultNd = (XmlElement) res.dom.SelectSingleNode("/*/*/*");

    string sSource;
    try{
         XmlNode xSource = this.dom.SelectSingleNode("/Item/source_id/text()");
         sSource = xSource.Value;
                 
        }catch (Exception ex){
             //part number missing from request
             return res;
        }
    
    //This is the SQL connection string to connect to the innovator SQL Express database.  
    System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection ();
    conn.ConnectionString = 
     "data source=MININT-PHRAUUK\\sqlexpress;User Id=innovator;Password=;" +
     "initial catalog=InnovatorSolutions;";
    System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
    System.Data.SqlClient.SqlDataReader reader;
    //A58793C29830417C9938C75C031EB103
    //this query only gets parts with a quantity, we'll get the extra manufacturers in the next step
    cmd.CommandText = "WITH BOM_ITEMS AS (SELECT PARTID, companyPARTNUMBER, QUANTITY, REF_DESIGNATOR, ROW_NUMBER() "
                      + "OVER (ORDER BY companyPARTNUMBER) AS 'RowNumber' FROM CIP_LOADED_BOM WHERE PARTID = @partID) "
                      + "SELECT * FROM BOM_ITEMS "
                      + "WHERE RowNumber Between @low AND @high";
    cmd.CommandType = CommandType.Text;
    //cmd.Parameters.AddWithValue("partID", "A58793C29830417C9938C75C031EB103");
    cmd.Parameters.AddWithValue("partID", sSource);
    
    //This is the SQL connection string to connect to the CIP SQL Express database.  
    //Note the login details are the default CIP internal user according to EMA's
    //documentation.
    System.Data.SqlClient.SqlConnection cipConn = new System.Data.SqlClient.SqlConnection ();
    cipConn.ConnectionString = 
     "data source=MININT-PHRAUUK\\sqlexpress;User Id=CIP_E_Internal_User;Password=bra#ru5=phaT;" +
     "initial catalog=CIP_E;";
    System.Data.SqlClient.SqlCommand cipCmd = new System.Data.SqlClient.SqlCommand();
    System.Data.SqlClient.SqlDataReader cipReader;
    //cipCmd.Parameters.Clear 
    cipCmd.CommandText = "WITH PARTS AS(SELECT p.PART_NUMBER, p.RowID, des.description, b.manufacturer, b.[manufacturer PN], ROW_NUMBER() OVER (ORDER BY p.PART_NUMBER) AS 'RowNumber' FROM  [CIP_E].[dbo].[AllParts] AS p " 
            + "INNER JOIN [CIP_E].[dbo].[Component Manufacturer Parts] AS a ON p.RowID = a.PartGUID " 
            + "INNER JOIN [CIP_E].[dbo].[Manufacturer Part Info] AS b ON a.ManufacturerGUID = b.RowID " 
            + "Inner Join [CIP_E].[dbo].[CT_PART_DESCRIPTIONS] AS des ON des.RowID = p.RowID "
            + "WHERE p.PART_NUMBER = @partNumber )"
            + "SELECT * FROM PARTS ";
            // +"WHERE RowNumber Between @low AND @high";
    
    cipConn.Open();
    cipCmd.Connection = cipConn;

    
    System.Data.SqlClient.SqlParameter param_low  = new System.Data.SqlClient.SqlParameter();
      param_low.ParameterName = "@low";
      param_low.Value         = 0;
      cmd.Parameters.Add(param_low);

    System.Data.SqlClient.SqlParameter param_high  = new System.Data.SqlClient.SqlParameter();
      param_high.ParameterName = "@high";
      param_high.Value         = 20000;
      cmd.Parameters.Add(param_high);
    
    conn.Open();
    cmd.Connection = conn;
    reader = cmd.ExecuteReader();

//need to get ID of BOM



    //string bomID = "0FBE827DE1394675A68C13FA13C67F9C";
    //string bomID = "EE8D6833EF2A480994DC7FE3A0C1641E";
    string bomID = this.getNewID();
    int i = 0;    
    while(reader.Read() &amp;&amp; i &amp;lt; 100){
         i++;
         //first create the CIP Part BOM
         //Item bom_item = this.newItem("CIP Part BOM");
         //bom.setType("CIP Part BOM");
         //bom.setID("0FBE827DE1394675A68C13FA13C67F9C");
         //bom.removeAttribute("isNew");
         //bom.removeAttribute("isTemp");
         //bom.apply();    
         
         //grab the company part number for this result
         string companyPartNumber = reader["companyPARTNUMBER"].ToString();
         cipCmd.Parameters.Clear();
         cipCmd.Parameters.AddWithValue("partNumber", companyPartNumber);
         cipReader = cipCmd.ExecuteReader();         

         bool firstTime = true;
         while(cipReader.Read()){
          
              //first create the CIP Part BOM
              Item bom_item = this.newItem("CIP Part BOM");
              bom_item.setType("CIP Part BOM");
              //bom_item.setID("0FBE827DE1394675A68C13FA13C67F9C");
              bom_item.setID(bomID);
              bom_item.removeAttribute("isNew");
              bom_item.removeAttribute("isTemp");
              bom_item.setProperty("keyed_name", bomID);
              bom_item.setAttribute("typeId", " 74B6F95348AA4DE3B84F89D45E3ED56D");
              if(firstTime == true){
               firstTime = false; 
               try{
                  bom_item.setProperty("quantity", reader["QUANTITY"].ToString());
                  bom_item.setProperty("reference_designator", reader["REF_DESIGNATOR"].ToString()); 
               }catch (Exception ex){
               
               }
            }
              bom_item.apply(); 
         
              Item part = this.newItem("CIP_PART");
              string id = cipReader["RowID"].ToString();
              id = id.Replace("-", "");
              part.setID(id);
              part = part.apply();
              part.setProperty("part_number", cipReader["PART_NUMBER"].ToString());
              part.setProperty("manf_part_number", cipReader["Manufacturer PN"].ToString());
              part.setProperty("manufacturer", cipReader["Manufacturer"].ToString());
              part.setProperty("description", cipReader["description"].ToString());
              bom_item.setRelatedItem(part);
              resultNd.AppendChild(resultNd.OwnerDocument.ImportNode(bom_item.node, true)); 
         }
 
         cipReader.Close();
         
         //if we didn't find any manufacturing data add blank part
         if(firstTime){
            //first create the CIP Part BOM
              Item bom_item = this.newItem("CIP Part BOM");
              bom_item.setType("CIP Part BOM");
              //bom_item.setID("0FBE827DE1394675A68C13FA13C67F9C");
              bom_item.setID(bomID);
              bom_item.removeAttribute("isNew");
              bom_item.removeAttribute("isTemp");
              bom_item.setProperty("keyed_name", bomID);
              bom_item.setAttribute("typeId", " 74B6F95348AA4DE3B84F89D45E3ED56D");
              try{
                  bom_item.setProperty("quantity", reader["QUANTITY"].ToString());
                  bom_item.setProperty("reference_designator", reader["REF_DESIGNATOR"].ToString()); 
            }catch (Exception ex){
               
            }
              bom_item.apply(); 
         
              Item part = this.newItem("CIP_PART");
              part.setID(getNewID());
              part = part.apply();
              part.setProperty("part_number", reader["companyPARTNUMBER"].ToString());
              part.setProperty("manf_part_number", "NOT IN DBASE");
              part.setProperty("manufacturer", "NOT IN DBASE");
              part.setProperty("description", "NOT IN DBASE");
              bom_item.setRelatedItem(part);
              resultNd.AppendChild(resultNd.OwnerDocument.ImportNode(bom_item.node, true)); 
         }
         
         }
 
    conn.Close();
    return res;




///////////////Ignore below this line, this code never runs it's just here as notes to me////////////////

    //C:\Program Files (x86)\Aras\Innovator\Innovator\Server\temp
    this.dom.Save(CCO.Server.MapPath("./temp/Incoming_AML.xml"));
    


    //get the source ID
    XmlNode xSourceId = dom.SelectSingleNode("/Item/source_id/text()");
    string sSourceId = xSourceId.Value;



    Item bom = this.newItem("CIP Part BOM");
    //bom.setAttribute("typeId", "74B6F95348AA4DE3B84F89D45E3ED56D");
    bom.setType("CIP Part BOM");
    bom.setID("0FBE827DE1394675A68C13FA13C67F9C");

    //bom.setProperty("source_id", sSourceId);
    bom.removeAttribute("isNew");
    bom.removeAttribute("isTemp");

    bom.apply();


    //create a fake CIP_PART here
    Item res5 = this.newItem("CIP_PART");
    //Item res5 = bom.createRelatedItem("CIP_PART", "");
             string newid = getNewID();
             res5.setID("A6F68F1E57C3432AA07E598F2468FFE2");
             res5 = res5.apply();
             res5.setProperty("part_number", "CT-ERIC-TEST");
             res5.setProperty("manf_part_number", "00-333-0000");
             res5.setProperty("manufacturer", "ACME");
             res5.setProperty("description", "Road Runner Bait");
  
    bom.setRelatedItem(res5);
    
    resultNd.AppendChild(resultNd.OwnerDocument.ImportNode(bom.node, true));
    //bom.apply();
    
    Item bom4 = bom.clone(false);
    
    Item res4 = this.newItem("CIP_PART");
    //Item res5 = bom.createRelatedItem("CIP_PART", "");
             newid = getNewID();
             res4.setID(newid);
             res4 = res4.apply();
             res4.setProperty("part_number", "CT-ERIC-TEST-saldklasdk");
             res4.setProperty("manf_part_number", "00-333-0000");
             res4.setProperty("manufacturer", "ACME");
             res4.setProperty("description", "Road Runner Bait");
    // don't work yet res5.appendItem(res4);
    bom4.setRelatedItem(res4);
    resultNd.AppendChild(resultNd.OwnerDocument.ImportNode(bom4.node, true));
        
/*
    StreamWriter sw = null;
    sw = File.CreateText("C:/Program Files (x86)/Aras/Innovator/Innovator/Server/temp/loge.txt");
    sw.WriteLine("--- BEGIN LOG ---");
    sw.WriteLine("bom: {0}", xNode);

    sw.Flush();
    sw.Close();
    */
    //return res4;
    //return res;
    
/**
*   Ignore below this line it was for when things weren't working
*
*/
//&amp;lt;Item type =" CIP Part BOM " id =" EE8D6833EF2A480994DC7FE3A0C1641E " &amp;gt;


Item wtf = this.newItem("CIP Part BOM");

string aml = "&amp;lt;Result&amp;gt;"
+"&amp;lt;Item type =\" CIP Part BOM \" typeId =\" 74B6F95348AA4DE3B84F89D45E3ED56D \" id =\" 0FBE827DE1394675A68C13FA13C67F98 \" &amp;gt;"
//+"&amp;lt;Item type =\" CIP Part BOM \" id =\" EE8D6833EF2A480994DC7FE3A0C1641E \" &amp;gt;"
//+"&amp;lt;created_by_id keyed_name =\" Innovator Admin \" type =\" User \" &amp;gt;30B991F927274FA3829655F50C99472E&amp;lt;/created_by_id&amp;gt;"
//+"&amp;lt;created_on&amp;gt;2012-01-11T11:48:15&amp;lt;/created_on&amp;gt;"
//+"&amp;lt;css is_null =\" 1 \" /&amp;gt;"
//+"&amp;lt;current_state is_null =\" 1 \" /&amp;gt;"
//+"&amp;lt;id keyed_name =\" 0FBE827DE1394675A68C13FA13C67F9C \" type =\" CIP Part BOM \" &amp;gt;0FBE827DE1394675A68C13FA13C67F9A&amp;lt;/id&amp;gt;"
//+"&amp;lt;keyed_name&amp;gt;0FBE827DE1394675A68C13FA13C67F9C&amp;lt;/keyed_name&amp;gt;"
//+"&amp;lt;locked_by_id is_null =\" 1 \" /&amp;gt;"
//+"&amp;lt;major_rev&amp;gt;A&amp;lt;/major_rev&amp;gt;"
//+"&amp;lt;modified_by_id keyed_name =\" Innovator Admin \" type =\" User \" &amp;gt;30B991F927274FA3829655F50C99472E&amp;lt;/modified_by_id&amp;gt;"
//+"&amp;lt;modified_on&amp;gt;2012-01-11T11:48:15&amp;lt;/modified_on&amp;gt;"
//+"&amp;lt;quantity&amp;gt;1&amp;lt;/quantity&amp;gt;"
//+"&amp;lt;reference_designator is_null =\" 1 \" /&amp;gt;"
//+"&amp;lt;related_id is_null =\" 0 \" &amp;gt;" me testing if is_null needed
+"&amp;lt;related_id&amp;gt;"
+"&amp;lt;Item type =\" CIP_PART \" typeId =\" 56D225FB95344D5C87128E28A366C307 \" id =\" A6F68F1E57C3432AA07E598F2468FFE2 \" &amp;gt;"
+"&amp;lt;part_number&amp;gt;CT-ERIC-TEST&amp;lt;/part_number&amp;gt;"
+"&amp;lt;manf_part_number&amp;gt;00-333-0000&amp;lt;/manf_part_number&amp;gt;"//-
+"&amp;lt;manufacturer&amp;gt;ACME&amp;lt;/manufacturer&amp;gt;"
+"&amp;lt;description&amp;gt;Road Runner Bait&amp;lt;/description&amp;gt;"
+"&amp;lt;/Item&amp;gt;"
+"&amp;lt;/related_id&amp;gt;"
//+"&amp;lt;source_id keyed_name =\" ct-test \" type =\" Part \" &amp;gt;5616EF9A14E248C99930A458F760C23B&amp;lt;/source_id&amp;gt;"
+"&amp;lt;/Item&amp;gt;"
+"&amp;lt;/Result&amp;gt;";
    
    wtf.loadAML(aml);
    
    return wtf;
    
    
    
    
&lt;/pre&gt;
I won't go over all the parts above that I covered for creating a CIP Item in an earlier post, but I will go over the important sections.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: csharp; ruler: true; first-line: 10; highlight: [2, 4, 6]"&gt;    //This is the SQL connection string to connect to the innovator SQL Express database.  
    System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection ();
    conn.ConnectionString = 
     "data source=MININT-PHRAUUK\\sqlexpress;User Id=innovator;Password=;" +
     "initial catalog=InnovatorSolutions;";
    System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
    System.Data.SqlClient.SqlDataReader reader;
&lt;/pre&gt;
&lt;br /&gt;
The above is the SQL connection to the innovator database. &amp;nbsp; There's other ways to get data out of Innovator using their IOM api, but I was comfortable with this. &amp;nbsp; I did not have a password set for my connection string, that's why it's blank.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: csharp; ruler: true; first-line: 10; highlight: [2, 4, 6]"&gt;    cmd.CommandText = "WITH BOM_ITEMS AS (SELECT PARTID, companyPARTNUMBER, QUANTITY, REF_DESIGNATOR, ROW_NUMBER() "
                      + "OVER (ORDER BY companyPARTNUMBER) AS 'RowNumber' FROM CIP_LOADED_BOM WHERE PARTID = @partID) "
                      + "SELECT * FROM BOM_ITEMS "
                      + "WHERE RowNumber Between @low AND @high";
    cmd.CommandType = CommandType.Text;
    //cmd.Parameters.AddWithValue("partID", "A58793C29830417C9938C75C031EB103");
    cmd.Parameters.AddWithValue("partID", sSource);
&lt;/pre&gt;
&lt;br /&gt;
I store the relationship between an Innovator Part and a CIP part in another Item Type called CIP LOADED BOM. &amp;nbsp; That means there is a table created for that Item Type called CIP_LOADED_BOM. &amp;nbsp;So in the above query I'm selecting all the CIP components that are tied to the partID. &amp;nbsp;The partID has been passed to us by Innovator when the user clicked on the CIP Part BOM tab. &amp;nbsp; It sends an AML request that basically says get me the CIP Part BOM for partID: blah blah blah. &amp;nbsp;Then I use that to look up the CIP components I need.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: csharp; ruler: true; first-line: 10; highlight: [2, 4, 6]"&gt;    cipCmd.CommandText = "WITH PARTS AS(SELECT p.PART_NUMBER, p.RowID, des.description, b.manufacturer, b.[manufacturer PN], ROW_NUMBER() OVER (ORDER BY p.PART_NUMBER) AS 'RowNumber' FROM  [CIP_E].[dbo].[AllParts] AS p " 
            + "INNER JOIN [CIP_E].[dbo].[Component Manufacturer Parts] AS a ON p.RowID = a.PartGUID " 
            + "INNER JOIN [CIP_E].[dbo].[Manufacturer Part Info] AS b ON a.ManufacturerGUID = b.RowID " 
            + "Inner Join [CIP_E].[dbo].[CT_PART_DESCRIPTIONS] AS des ON des.RowID = p.RowID "
            + "WHERE p.PART_NUMBER = @partNumber )"
            + "SELECT * FROM PARTS ";
&lt;/pre&gt;
&lt;br /&gt;
This next query is a modified version of the query from the CIP PART post. &amp;nbsp; The thing to notice here is the line WHERE p.PART_NUMBER = @partNumber. &amp;nbsp; If you're not familiar with this kind of notation it's not that hard to follow. &amp;nbsp;Basically I've created this query and the @partNumber is a place holder for the actual CIP part number. &amp;nbsp; There are all sorts of good reasons to do your queries like this, but in this case I'm going to re-use this query over and over again in a loop changing that partNumber each time. &amp;nbsp; It will make things a little easier.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: csharp; ruler: true; first-line: 10; highlight: [2, 4, 6]"&gt;    string bomID = this.getNewID();
    int i = 0;    
    while(reader.Read() &amp;amp;&amp;amp; i &amp;lt; 100){
         i++;
         //grab the company part number for this result
         string companyPartNumber = reader["companyPARTNUMBER"].ToString();
         cipCmd.Parameters.Clear();
         cipCmd.Parameters.AddWithValue("partNumber", companyPartNumber);
         cipReader = cipCmd.ExecuteReader();   
&lt;/pre&gt;
&lt;br /&gt;
This is the first part of the loop to create the response. &amp;nbsp;I'm looping through all the CIP parts associated with this Innovator part. &amp;nbsp;I grab the company part number from each result and store it as the @partNumber parameter from the previous step. &amp;nbsp; Also notice that I call Parameters.Clear, that will remove the last parameter &amp;nbsp;you set for each loop iteration. &amp;nbsp;At the end I execute the SQL query.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: csharp; ruler: true; first-line: 10; highlight: [2, 4, 6]"&gt;bool firstTime = true;
         while(cipReader.Read()){
          
              //first create the CIP Part BOM
              Item bom_item = this.newItem("CIP Part BOM");
              bom_item.setType("CIP Part BOM");
              //bom_item.setID("0FBE827DE1394675A68C13FA13C67F9C");
              bom_item.setID(bomID);
              bom_item.removeAttribute("isNew");
              bom_item.removeAttribute("isTemp");
              bom_item.setProperty("keyed_name", bomID);
              bom_item.setAttribute("typeId", " 74B6F95348AA4DE3B84F89D45E3ED56D");
              if(firstTime == true){
               firstTime = false; 
               try{
                  bom_item.setProperty("quantity", reader["QUANTITY"].ToString());
                  bom_item.setProperty("reference_designator", reader["REF_DESIGNATOR"].ToString()); 
               }catch (Exception ex){
               
               }
            }
              bom_item.apply(); 
         
              Item part = this.newItem("CIP_PART");
              string id = cipReader["RowID"].ToString();
              id = id.Replace("-", "");
              part.setID(id);
              part = part.apply();
              part.setProperty("part_number", cipReader["PART_NUMBER"].ToString());
              part.setProperty("manf_part_number", cipReader["Manufacturer PN"].ToString());
              part.setProperty("manufacturer", cipReader["Manufacturer"].ToString());
              part.setProperty("description", cipReader["description"].ToString());
              bom_item.setRelatedItem(part);
              resultNd.AppendChild(resultNd.OwnerDocument.ImportNode(bom_item.node, true)); 
         }
 
         cipReader.Close();
&lt;/pre&gt;
&lt;br /&gt;
This is the sub loop that creates the actual response. &amp;nbsp;I read each returned value from the CIP &amp;nbsp;Loaded BOM and a new Item CIP Part BOM part for each one. &amp;nbsp; If this is the first &amp;nbsp;time through this loop I'll add the quantity and and reference designator. &amp;nbsp;If not it will be blank. &amp;nbsp; This supports CIP having multiple manufacturers per part number. &amp;nbsp; You don't want to produce a bom that says &amp;nbsp;you need twice as many CT-CAP-00001s just because you have two manufacturing sources for it.&lt;br /&gt;
&lt;br /&gt;
Next we get the actual CIP component data from the CIP database, create a new part for it, and append it to the CIP Part Bom Item we just created. &amp;nbsp; We'll go through this loop until we get through all of the CIP part numbers associated with the Innovator Part.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: csharp; ruler: true; first-line: 10; highlight: [2, 4, 6]"&gt;    conn.Close();
    return res;
&lt;/pre&gt;
&lt;br /&gt;
That's it, now we just return the res result set. &amp;nbsp; If all went well you should now see the list of CIP Components associated with your innovator part. &amp;nbsp; Well actually at this point you won't see anything because we still need to create that CIP LOADED BOM association. &amp;nbsp;I'll do that in my next post.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&lt;a href="http://creativecommons.org/licenses/by-sa/3.0/" rel="license"&gt;&lt;img alt="Creative Commons License" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" style="border-width: 0;" /&gt;&lt;/a&gt;&lt;br /&gt;
This &lt;span href="http://purl.org/dc/dcmitype/Text" rel="dct:type" xmlns:dct="http://purl.org/dc/terms/"&gt;work&lt;/span&gt; is licensed under a &lt;a href="http://creativecommons.org/licenses/by-sa/3.0/" rel="license"&gt;Creative Commons Attribution-ShareAlike 3.0 Unported License&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8299669941450299948-6267279879764869145?l=somehardwareguy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://somehardwareguy.blogspot.com/feeds/6267279879764869145/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://somehardwareguy.blogspot.com/2012/01/linking-orcad-parts-to-innovator-parts.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/6267279879764869145'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/6267279879764869145'/><link rel='alternate' type='text/html' href='http://somehardwareguy.blogspot.com/2012/01/linking-orcad-parts-to-innovator-parts.html' title='Linking Orcad Parts To Innovator Parts onGet Function'/><author><name>Some Hardware Guy</name><uri>http://www.blogger.com/profile/17462828792887566460</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8299669941450299948.post-737573007437427948</id><published>2012-01-18T11:38:00.000-08:00</published><updated>2012-01-18T11:38:31.292-08:00</updated><title type='text'>Linking Orcad CIP parts to Innovator parts</title><content type='html'>OK in the last post I showed you how I connected to the CIP database and got my parts into Innovator. &amp;nbsp;My next step was to try to attach those parts to a regular innovator part. &amp;nbsp;Originally I thought I'd use those CIP PARTs we just created and make my own CIP BOM to contain all of them. &amp;nbsp; Then I'd like the CIP BOM to an Innovator Part. &lt;br /&gt;
&lt;br /&gt;
Instead I ended up creating a CIP BOM, and overriding it's onGet function. &amp;nbsp; Then whenever a part called get for it's CIP BOM I return it the list of CIP PARTS that belong to it. &amp;nbsp; I keep that association in another table/item I created called CIP LOADED BOM (terrible naming conventions I used). &amp;nbsp; I use that CIP LOADED BOM part's form to load in a .csv bom file exported from Orcad Capture.&lt;br /&gt;
&lt;br /&gt;
The downside of this approach, among other things, is that you can only update the Innovator part you attach your CIP parts to when you want to add a new BOM. &amp;nbsp;You can go from preliminary to released, but you can't say add an additional Innovator part to it because that will create a new version of your part, with a new id and that breaks my approach. &amp;nbsp; So in short I decided I'll always create a part like CT-BOM-000001 and it's only job will be to hold my Orcad BOM. &amp;nbsp; Hack hack hackity hack :) &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;First Steps&lt;/b&gt;&lt;br /&gt;
Alright my first step was to create a new item called CIP BOM, I just made a copy of Innovator's Part BOM item. &amp;nbsp; Then I added the CIP_BOM_GET method to the onGet Event.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-K9qVvc6ICyo/TxbfyYp8jDI/AAAAAAAABU0/mV5oa6C_mqQ/s1600/cip_part_bom.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="388" src="http://2.bp.blogspot.com/-K9qVvc6ICyo/TxbfyYp8jDI/AAAAAAAABU0/mV5oa6C_mqQ/s640/cip_part_bom.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;Part Relationship&lt;/b&gt;&lt;br /&gt;
The next step was to create a relationship with an Innovator Part and my brand new CIP Part BOM. &amp;nbsp; To do that go edit the Part Item Type. &amp;nbsp;Then click on the RelationshipTypes tab. &amp;nbsp;Next select pick related and click the new button. &amp;nbsp; Now search for the CIP Part Bom part, add it and your window should look like this.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-Hx2-Lac3uhw/TxbnwUJxCmI/AAAAAAAABU8/NiC7K2of2a8/s1600/item_relate.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="388" src="http://4.bp.blogspot.com/-Hx2-Lac3uhw/TxbnwUJxCmI/AAAAAAAABU8/NiC7K2of2a8/s640/item_relate.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;CIP PART BOM Relationship&lt;/b&gt;&lt;br /&gt;
I can't remember if this part is absolutely needed or not, but I'll include it here. &amp;nbsp;I edited the CIP Part BOM relationship to point to my CIP PARTS I created in another post. &amp;nbsp; The important part was to set the Source Item Type and Related Item Type correctly.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-iCc1zg-JB0g/TxbpMC3K74I/AAAAAAAABVM/GgUzL2e5QJE/s1600/cip_bom_relation.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="460" src="http://4.bp.blogspot.com/-iCc1zg-JB0g/TxbpMC3K74I/AAAAAAAABVM/GgUzL2e5QJE/s640/cip_bom_relation.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;b&gt;Finally&lt;/b&gt;&lt;/div&gt;
Now that all that is done you can go select an Innovator Part and you'll see a new tab called CIP Part BOM in the bottom pane. &amp;nbsp; This is where we'll see, but not add the associated CIP Parts for this Innovator Part. &amp;nbsp; You'll notice I made it the second tab, and I did that mainly for development work. &amp;nbsp; Innovator only calls the AML function to load that tab when you click on it. &amp;nbsp; So if you're trying to isolate why something doesn't work you can just load the part, click the tab and then you'll be able to see all the requests that were called for that tab.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-ZhjDfOUiy-c/TxbqSEfE8kI/AAAAAAAABVU/JQQJSjoF5cc/s1600/part_cip_bom.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="560" src="http://2.bp.blogspot.com/-ZhjDfOUiy-c/TxbqSEfE8kI/AAAAAAAABVU/JQQJSjoF5cc/s640/part_cip_bom.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://creativecommons.org/licenses/by-sa/3.0/" rel="license"&gt;&lt;img alt="Creative Commons License" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" style="border-width: 0;" /&gt;&lt;/a&gt;&lt;br /&gt;
This &lt;span href="http://purl.org/dc/dcmitype/Text" rel="dct:type" xmlns:dct="http://purl.org/dc/terms/"&gt;work&lt;/span&gt; is licensed under a &lt;a href="http://creativecommons.org/licenses/by-sa/3.0/" rel="license"&gt;Creative Commons Attribution-ShareAlike 3.0 Unported License&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8299669941450299948-737573007437427948?l=somehardwareguy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://somehardwareguy.blogspot.com/feeds/737573007437427948/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://somehardwareguy.blogspot.com/2012/01/linking-orcad-cip-parts-to-innovator.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/737573007437427948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/737573007437427948'/><link rel='alternate' type='text/html' href='http://somehardwareguy.blogspot.com/2012/01/linking-orcad-cip-parts-to-innovator.html' title='Linking Orcad CIP parts to Innovator parts'/><author><name>Some Hardware Guy</name><uri>http://www.blogger.com/profile/17462828792887566460</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-K9qVvc6ICyo/TxbfyYp8jDI/AAAAAAAABU0/mV5oa6C_mqQ/s72-c/cip_part_bom.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8299669941450299948.post-4037274929309955255</id><published>2012-01-17T14:13:00.002-08:00</published><updated>2012-01-18T11:38:17.410-08:00</updated><title type='text'>Aras Innovator Orcad CIP onGet Part 2</title><content type='html'>Now in the last part I had included all the code that was right out of our Innovator function.  Including somethings I stopped working on like the get_single path.  So we're going to skip ahead to the list_all path which is what I use most.
&lt;br /&gt;
&lt;pre class="brush: csharp; ruler: true; first-line: 10; highlight: [2, 4, 6]"&gt; 
    //open the sql connection     
    conn.Open();
&lt;/pre&gt;
Just before the switch statement I call conn.Open which opens the connection to the CIP database&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: csharp; ruler: true; first-line: 10; highlight: [2, 4, 6]"&gt;     case "list_all":
         /*
            *   Here we check to see if the user is searching for anything
            */
             try{
                  XmlNode xPart = this.dom.SelectSingleNode("/Item/part_number/text()");
                  XmlNode xCond = this.dom.SelectSingleNode("/Item/part_number/@condition");

                  string sPart = xPart.Value;
                  System.Data.SqlClient.SqlParameter param_part  = new System.Data.SqlClient.SqlParameter();
                  param_part.ParameterName = "@part";
                  if(xCond.Value == "like"){
                       //where += " AND p.PART_NUMBER LIKE '" + sPart.Replace("*", "%") + "'";
                       where += " AND p.PART_NUMBER LIKE @part";
                 param_part.Value = sPart.Replace("*", "%");
                 cmd.Parameters.Add(param_part);
                  }else{
                       //where += " AND p.PART_NUMBER = '" + sPart + "'";
                       where += " AND p.PART_NUMBER = @part";
                       param_part.Value = sPart;
                 cmd.Parameters.Add(param_part);
                  }
             }catch (Exception ex){

             }

             try{
                  XmlNode xManfNum = this.dom.SelectSingleNode("/Item/manf_part_number/text()");
                  XmlNode xCond = this.dom.SelectSingleNode("/Item/manf_part_number/@condition");
                  string sManfNum = xManfNum.Value;
                  System.Data.SqlClient.SqlParameter param_manfnum  = new System.Data.SqlClient.SqlParameter();
                  param_manfnum.ParameterName = "@manfnum";
                  if(xCond.Value == "like"){
                       //where += " AND b.[Manufacturer PN] LIKE '" + sManfNum.Replace("*", "%") + "'";
                       where += " AND b.[Manufacturer PN] LIKE @manfnum";
                 param_manfnum.Value = sManfNum.Replace("*", "%");
                 cmd.Parameters.Add(param_manfnum);
                  }else{
                       //where += " AND b.[Manufacturer PN] = '" + sManfNum + "'";
                       where += " AND b.[Manufacturer PN] = @manfnum";
                 param_manfnum.Value = sManfNum;
                 cmd.Parameters.Add(param_manfnum);
                  }
             }catch (Exception ex){

             }
             
             try{
                  XmlNode xManf = this.dom.SelectSingleNode("/Item/manufacturer/text()");
                  XmlNode xCond = this.dom.SelectSingleNode("/Item/manufacturer/@condition");
                  string sManf = xManf.Value;
                  System.Data.SqlClient.SqlParameter param_manf  = new System.Data.SqlClient.SqlParameter();
                  param_manf.ParameterName = "@manf";
                  if(xCond.Value == "like"){
                       //where += " AND b.[Manufacturer] LIKE '" + sManf.Replace("*", "%") + "'";
                       where += " AND b.[Manufacturer] LIKE @manf";
                 param_manf.Value = sManf.Replace("*", "%");
                 cmd.Parameters.Add(param_manf);
                  }else{
                       //where += " AND b.[Manufacturer] = '" + sManf + "'";
                       where += " AND b.[Manufacturer] = @manf";
                 param_manf.Value = sManf;
                 cmd.Parameters.Add(param_manf);
                  }
             }catch (Exception ex){
                  //sw.WriteLine("No Manf found Found");
             }


             try{
                  XmlNode xDesc = this.dom.SelectSingleNode("/Item/description/text()");
                  XmlNode xCond = this.dom.SelectSingleNode("/Item/description/@condition");
                  string sDesc = xDesc.Value;
                  System.Data.SqlClient.SqlParameter param_desc  = new System.Data.SqlClient.SqlParameter();
                  param_desc.ParameterName = "@desc";
                  if(xCond.Value == "like"){
                       //where += " AND des.[Description] LIKE '" + sDesc.Replace("*", "%") + "'";
                       where += " AND des.[Description] LIKE @desc";
                 param_desc.Value = sDesc.Replace("*", "%");
                 cmd.Parameters.Add(param_desc);
                  }else{
                       //where += " AND des.[Description] = '" + sDesc + "'";
                       where += " AND des.[Description] = @desc";
                 param_desc.Value = sDesc.Replace("*", "%");
                 cmd.Parameters.Add(param_desc);
                  }
             }catch (Exception ex){
                  //sw.WriteLine("No description Found");
             } 
&lt;/pre&gt;
In the section above I'm parsing that AML request to see if there are query options set in it. &amp;nbsp; In clearer terms I'm looking to see if the user tried to run a search instead of listing all the results. &amp;nbsp; When you're in Innovator and you have selected say parts, you'll see a blue highlighted line at the top of the part table in the right hand pane. &amp;nbsp; If you go in to one of those fields, say part number and type CT-CAP* and hit enter that will return all the parts with the part number like CT-CAP*. &amp;nbsp; Like CT-CAP-000001, CT-CAP-000002. &lt;br /&gt;
&lt;br /&gt;
So by searching the AML query for all those fields we can create a query that will return only the parts the user is searching for. &amp;nbsp; So for each of the query options above I add some SQL to the variable where. &amp;nbsp;Later I'll tie that variable into my main SQL request.&lt;br /&gt;
&lt;br /&gt;
Now comes the fun part, the main SQL request that is going to get all these parts for us. &amp;nbsp; I ran into a little trouble at first because CIP keeps part descriptions in separate tables for each part type. &amp;nbsp;So capacitor descriptions are in the capacitor table, switch descriptions in the switch table etc. &amp;nbsp; To make my life easier I went into SQL Express manager and created a view to do a union of all the tables. &amp;nbsp;Someone on stack overflow suggested this approach to me. &lt;br /&gt;
&lt;br /&gt;
Creating a view is pretty easy, just go into MS SQL Server Managment studio and login. &amp;nbsp;Then find the CIP_E database, select the view tab, right click and create new. &amp;nbsp; Then give it a name and use this as the SQL that describes it.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: sql; ruler: true; first-line: 10; highlight: [2, 4, 6]"&gt; 
SELECT PART_NUMBER, [Part Type], Description, RowID
FROM  dbo.Capacitors
WHERE PART_NUMBER LIKE 'CT-%'
UNION
SELECT PART_NUMBER, [Part Type], Description, RowID
FROM  dbo.Connectors
WHERE PART_NUMBER LIKE 'CT-%'
UNION
SELECT PART_NUMBER, [Part Type], Description, RowID
FROM  dbo.[Crystals and Oscillators]
WHERE PART_NUMBER LIKE 'CT-%'
UNION
SELECT PART_NUMBER, [Part Type], Description, RowID
FROM  dbo.Diodes
WHERE PART_NUMBER LIKE 'CT-%'
UNION
SELECT PART_NUMBER, [Part Type], Description, RowID
FROM  dbo.ICS
WHERE PART_NUMBER LIKE 'CT-%'
UNION
SELECT PART_NUMBER, [Part Type], Description, RowID
FROM  dbo.inductors
WHERE PART_NUMBER LIKE 'CT-%'
UNION
SELECT PART_NUMBER, [Part Type], Description, RowID
FROM  dbo.misc
WHERE PART_NUMBER LIKE 'CT-%'
UNION
SELECT PART_NUMBER, [Part Type], Description, RowID
FROM  dbo.Relays
WHERE PART_NUMBER LIKE 'CT-%'
UNION
SELECT PART_NUMBER, [Part Type], Description, RowID
FROM  dbo.Resistors
WHERE PART_NUMBER LIKE 'CT-%'
UNION
SELECT PART_NUMBER, [Part Type], Description, RowID
FROM  dbo.Switches
WHERE PART_NUMBER LIKE 'CT-%'
UNION
SELECT PART_NUMBER, [Part Type], Description, RowID
FROM  dbo.Transformers
WHERE PART_NUMBER LIKE 'CT-%'
UNION
SELECT PART_NUMBER, [Part Type], Description, RowID
FROM  dbo.Transistors
WHERE PART_NUMBER LIKE 'CT-%'
&lt;/pre&gt;
&lt;br /&gt;
Now if you want you can select the new view and select show top 1000 rows and you'll see that it combines all of the tables into one for our query.&lt;br /&gt;
&lt;pre class="brush: csharp; ruler: true; first-line: 10; highlight: [2, 4, 6]"&gt; 
            cmd.CommandText = "WITH PARTS AS(";
          cmd.CommandText += "SELECT *, ROW_NUMBER() OVER (ORDER BY p.PART_NUMBER) AS 'RowNumber'  FROM  dbo.AllParts AS p WHERE p.PART_NUMBER LIKE 'CT%'"; 
            cmd.CommandText += ")";
            cmd.CommandText += "SELECT COUNT(*) FROM PARTS as p "
            + "INNER JOIN dbo.[Component Manufacturer Parts] AS a ON p.RowID = a.PartGUID "
            + "INNER JOIN dbo.[Manufacturer Part Info] AS b ON a.ManufacturerGUID = b.RowID " 
            + "LEFT Join dbo.[CT_PART_DESCRIPTIONS] AS des ON des.RowID = p.RowID ";                      

            if(where != ""){
                 cmd.CommandText += "WHERE 'monkey' = 'monkey' " + where;
            }
            
            
            //sw.WriteLine("sql: {0}", cmd.CommandText);
            cmd.CommandType = CommandType.Text;
            cmd.Connection = conn;
         
            int count = (int) cmd.ExecuteScalar();           
         //sw.WriteLine("Found: {0} parts", count);
         
         //calculate the start and stop
         int iStart = (iPage - 1) * iPageSize + 1;
         int iEnd = iPage * iPageSize;
         int iPageMax = count / iPageSize;
         
         //is there an extra non full page?
         if(iPageMax * iPageSize &amp;lt; count){
              iPageMax++; 
         }
         
         //looking for more records than exist
         if(iEnd &amp;gt; count){
             iEnd = count;
             //iStart = iEnd - iPageSize;
             
             if(iStart &amp;lt;0){
              iStart = 0;
             } 
         }
         
         //now execute query for real

            
            cmd.CommandText = "WITH PARTS AS(SELECT p.PART_NUMBER, p.RowID, des.description, b.manufacturer, b.[manufacturer PN], ROW_NUMBER() OVER (ORDER BY p.PART_NUMBER) AS 'RowNumber' FROM  [CIP_E].[dbo].[AllParts] AS p " 
            + "INNER JOIN [CIP_E].[dbo].[Component Manufacturer Parts] AS a ON p.RowID = a.PartGUID " 
            + "INNER JOIN [CIP_E].[dbo].[Manufacturer Part Info] AS b ON a.ManufacturerGUID = b.RowID " 
            + "Inner Join [CIP_E].[dbo].[CT_PART_DESCRIPTIONS] AS des ON des.RowID = p.RowID "
            + "WHERE 'monkey' = 'monkey' " + where + ") "
            + "SELECT * FROM PARTS WHERE RowNumber Between @low AND @high";
            
            
      System.Data.SqlClient.SqlParameter param_low  = new System.Data.SqlClient.SqlParameter();
      param_low.ParameterName = "@low";
      param_low.Value         = iStart;
      cmd.Parameters.Add(param_low);

      System.Data.SqlClient.SqlParameter param_high  = new System.Data.SqlClient.SqlParameter();
      param_high.ParameterName = "@high";
      param_high.Value         = iEnd;
      cmd.Parameters.Add(param_high);
            cmd.CommandType = CommandType.Text;
            cmd.Connection = conn;

         //damn you for having no LIMIT function MS SQL

         reader = cmd.ExecuteReader();
&lt;/pre&gt;
&lt;br /&gt;
The first thing I do above is run a count query to find out how many records our query will return. &amp;nbsp;I'll use this to let the user interface know how many more pages of results there are. &amp;nbsp; After that query you'll see that I use that data to calculate the start, end and pagemax values.&lt;br /&gt;
&lt;br /&gt;
Let's skip ahead to the main query and try to break it down. &amp;nbsp; Here I'll take a moment to say how much I did not like working with MS SQL. &amp;nbsp;Compared to say MySQL with PHP it felt clumsy, and more difficult than it need to be. &amp;nbsp;Especially since there's no LIMIT clause to limit the number of results. &amp;nbsp;Instead I have to do what you see above, using a main query to select the row numbers and then using a Between statement to limit the returned results. &amp;nbsp; Such a pain, and if you want to know more just google MS SQL Limit function...&lt;br /&gt;
&lt;br /&gt;
Anyway the query says Select everything from the CIP AllParts table, which contains all of the part numbers in our CIP system. &amp;nbsp;Then join that with the Component Manufacturer Parts table which has all the manufacturer data. &amp;nbsp; Then finally join that with the view we just made to get the part descriptions. &amp;nbsp;The whole where 'monkey' = 'monkey' thing is just a statement that will always be true so I can just insert those where clauses we generated a few steps ago without having to do anything fancy.&lt;br /&gt;
&lt;br /&gt;
Next we select from Parts which is not a real table we just created it in the query by saying WITH PARTS AS(....). &amp;nbsp; We use the Between statement combined with the start and end values we previously calculated to just get the few rows that we want.&lt;br /&gt;
&lt;br /&gt;
Finally we set the connection to our database connection and execute the query using ExecuteReader. &amp;nbsp; That will return a reader that we'll use to read the result data from the query.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: csharp; ruler: true; first-line: 10; highlight: [2, 4, 6]"&gt;         i = 0;    
            while(reader.Read() &amp;amp;&amp;amp; i &amp;lt; iPageSize){
          i++;

          Item res5 = this.newItem("CIP_PART");
             string newid = getNewID();
             string id = reader["RowID"].ToString();
             id = id.Replace("-", "");
             res5.setID(id);
             res5 = res5.apply();
             res5.setProperty("part_number", reader["PART_NUMBER"].ToString());
             res5.setProperty("start", iStart.ToString());
             res5.setProperty("pageSize", iPageSize.ToString());
             res5.setProperty("end", iEnd.ToString());
             res5.setProperty("manf_part_number", reader["Manufacturer PN"].ToString());
             res5.setProperty("manufacturer", reader["Manufacturer"].ToString());
             res5.setProperty("description", reader["description"].ToString());
             res5.setAttribute("page", iPage.ToString());
             res5.setAttribute("pagemax", iPageMax.ToString());
             res5.setAttribute("itemmax", count.ToString());            
             resultNd.AppendChild(resultNd.OwnerDocument.ImportNode(res5.node, true));
             } 
&lt;/pre&gt;
&lt;br /&gt;
Almost Done! &amp;nbsp; In the above code I repeatedly call the reader.Read() function to get the result rows from the CIP database. &amp;nbsp; For each result I create a new Item, and since CIP has 32 bit IDs but uses several '-' characters between them I strip out the dash character and use that for the ID. &amp;nbsp; Then I apply the item, which I'll be honest I'm not sure I have to do but I saw it in the docs and it seems to work. &amp;nbsp; Next I just set the properties for each CIP PART. &amp;nbsp; Finally I use resultND to append this new item to res, the result set.&lt;br /&gt;
&lt;br /&gt;
If you don't know already, this setProperty, setAttribute is basically setting up the AML ( XML) inside this item. &amp;nbsp;If you print out the res you'll see that you've just created a large AML response containing all of the CIP PARTS you requested.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: csharp; ruler: true; first-line: 10; highlight: [2, 4, 6]"&gt;   

    //close db connection
    conn.Close();
      
    return res;
&lt;/pre&gt;
&lt;br /&gt;
As a last step we return the res result set, and that's it! &amp;nbsp;Now you can go into innovator, select Design from the TOC menu. &amp;nbsp;Now select CIP_PART, right click it and choose list all. &amp;nbsp;If everything went well you should see a list of all of your parts.&lt;br /&gt;
&lt;br /&gt;
&lt;a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"&gt;&lt;img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /&gt;&lt;/a&gt;&lt;br /&gt;This &lt;span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/Text" rel="dct:type"&gt;work&lt;/span&gt; is licensed under a &lt;a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"&gt;Creative Commons Attribution-ShareAlike 3.0 Unported License&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8299669941450299948-4037274929309955255?l=somehardwareguy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://somehardwareguy.blogspot.com/feeds/4037274929309955255/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://somehardwareguy.blogspot.com/2012/01/aras-innovator-orcad-cip-onget-part-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/4037274929309955255'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/4037274929309955255'/><link rel='alternate' type='text/html' href='http://somehardwareguy.blogspot.com/2012/01/aras-innovator-orcad-cip-onget-part-2.html' title='Aras Innovator Orcad CIP onGet Part 2'/><author><name>Some Hardware Guy</name><uri>http://www.blogger.com/profile/17462828792887566460</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8299669941450299948.post-8582518730362948352</id><published>2012-01-17T14:13:00.001-08:00</published><updated>2012-01-18T11:36:07.579-08:00</updated><title type='text'>Aras Innovator Orcad CIP Part onGet Part 1</title><content type='html'>First things first you need to open up the method we created in the last step. &amp;nbsp;So in the TOC menu on the left choose Administration-&amp;gt;methods&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-_pU3zCQXngM/TxXYbcbZiyI/AAAAAAAABUs/V1IPe09Nwlk/s1600/cip_on_get_choose.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="290" src="http://3.bp.blogspot.com/-_pU3zCQXngM/TxXYbcbZiyI/AAAAAAAABUs/V1IPe09Nwlk/s400/cip_on_get_choose.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
Now you should be in the method editor, note if you can't edit anything you probably just double clicked it or selected view. &amp;nbsp;Go back, right click the method name and select edit and you should be ok.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
Now here's the full code for my method, it's straight out of my system and not cleaned up at all:&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;pre class="brush: csharp; ruler: true; first-line: 10; highlight: [2, 4, 6]"&gt;
/**
*    This function gets our Orcad CIP/CIS parts out of our database and returns them to 
*    Aras Innovator
*/

    //This is the SQL connection string to connect to our SQL Express database.  
    //Note the login details are the default CIP internal user according to EMA's
    //documentation.
    System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection ();
    conn.ConnectionString = 
     "data source=MININT-PHRAUUK\\sqlexpress;User Id=CIP_E_Internal_User;Password=bra#ru5=phaT;" +
     "initial catalog=CIP_E;";
    System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
    System.Data.SqlClient.SqlDataReader reader;
    
    //these two items are what is going to get returned
    Item res = this.getInnovator().newResult("");
    XmlElement resultNd = (XmlElement) res.dom.SelectSingleNode("/*/*/*");

    //this is a handy debug statement htat saves the "Incoming AML Request" to the temp directory
    //of the Innovator server.  For us that is:
    //C:\Program Files (x86)\Aras\Innovator\Innovator\Server\temp
    //this.dom.Save(CCO.Server.MapPath("./temp/Incoming_AML.xml"));
    /*StreamWriter sw = null;
    sw = File.CreateText("C:/Program Files (x86)/Aras/Innovator/Innovator/Server/temp/loge.txt");
    sw.WriteLine("--- BEGIN LOG ---");
    sw.Flush();
    */
    string action = "nothing";

    //check if this is a List All
    int iPage = 1;
    int iPageSize = 25;
    try{
         XmlNode xPage = this.dom.SelectSingleNode("/Item/@page"); 
         XmlNode xPageSize = this.dom.SelectSingleNode("/Item/@pagesize"); 
    
         if(xPage.Value != "" &amp;&amp; xPageSize.Value != ""){
             iPage = int.Parse(xPage.Value);
             iPageSize = int.Parse(xPageSize.Value);
         //action = "list_all"; 
         } 
         
         XmlNode xAction = this.dom.SelectSingleNode("/Item/@select");
         string sAction = xAction.Value;
         if(sAction != ""){
              action = "list_all";
         }
    }catch (Exception ex){
        
            
    }
    //check if it is a single get
    // &amp;lt;Item type="CIP_PART" levels="1" action="get" idlist="3FF86EECC96342C7825197321EFCC40D" /&amp;gt; 
    string sID = "";
    try{
         XmlNode xAction = this.dom.SelectSingleNode("/Item/@action");
         XmlNode xIdlist = this.dom.SelectSingleNode("/Item/@idlist");
    
         if(xAction.Value == "get" &amp;&amp; xIdlist.Value != "")
         {
             //convert ID
             string sIdlist = xIdlist.Value;
             if(sIdlist.Length == 32){

                 sID = sIdlist.Substring(0, 8) + sIdlist.Substring(8,4) + sIdlist.Substring(12,4) + sIdlist.Substring(16,4) + sIdlist.Substring(20,12);      
                 action = "get_single";
             }
         }
    }catch (Exception ex){

    }
    //open the sql connection     
    conn.Open();
    //action = "list_all";
    string where = "";
    switch(action){
     case "get_single":
          //sw.WriteLine("action_single");
         cmd.CommandText = "WITH PARTS AS(SELECT p.PART_NUMBER, p.RowID, des.description, b.manufacturer, b.[manufacturer PN], ROW_NUMBER() OVER (ORDER BY p.PART_NUMBER) AS 'RowNumber' FROM  [CIP_E].[dbo].[AllParts] AS p " 
            + "INNER JOIN [CIP_E].[dbo].[Component Manufacturer Parts] AS a ON p.RowID = a.PartGUID " 
            + "INNER JOIN [CIP_E].[dbo].[Manufacturer Part Info] AS b ON a.ManufacturerGUID = b.RowID " 
            + "Inner Join [CIP_E].[dbo].[CT_PART_DESCRIPTIONS] AS des ON des.RowID = p.RowID) "
            + "SELECT * FROM PARTS WHERE RowID = @rowid";
            //WITH PARTS AS(SELECT p.PART_NUMBER, p.RowID, des.description, b.manufacturer, b.[manufacturer PN], ROW_NUMBER() OVER (ORDER BY p.PART_NUMBER) AS 'RowNumber' FROM  [CIP_E].[dbo].[AllParts] AS p 
            //INNER JOIN [CIP_E].[dbo].[Component Manufacturer Parts] AS a ON p.RowID = a.PartGUID 
            //INNER JOIN [CIP_E].[dbo].[Manufacturer Part Info] AS b ON a.ManufacturerGUID = b.RowID 
            //Inner Join [CIP_E].[dbo].[CT_PART_DESCRIPTIONS] AS des ON des.RowID = p.RowID) 
            //SELECT * FROM PARTS WHERE RowID = '0BF585C8-14D8-4248-BDA0-4D7EDBB7BAB2'
            //set the rowid      
      System.Data.SqlClient.SqlParameter param_rowid  = new System.Data.SqlClient.SqlParameter();
      param_rowid.ParameterName = "@rowid";
      param_rowid.Value         = "0BF585C8-14D8-4248-BDA0-4D7EDBB7BAB2";
      cmd.Parameters.Add(param_rowid);
            cmd.CommandType = CommandType.Text;

            //sw.WriteLine("single sql: {0}", cmd.CommandText);

            cmd.Connection = conn;
         reader = cmd.ExecuteReader();

         int i = 0;    
            while(reader.Read() &amp;&amp; i &amp;lt; 100){
          i++;

          Item res5 = this.newItem("CIP_PART");
             string newid = getNewID();
             string id = reader["RowID"].ToString();
             id = id.Replace("-", "");
             res5.setID(id);
             res5 = res5.apply();
             res5.setProperty("part_number", reader["PART_NUMBER"].ToString());
             res5.setProperty("manf_part_number", reader["Manufacturer PN"].ToString());
             res5.setProperty("manufacturer", reader["Manufacturer"].ToString());
             res5.setProperty("description", reader["description"].ToString());          
             resultNd.AppendChild(resultNd.OwnerDocument.ImportNode(res5.node, true));
             }
     break;
     case "list_all":
         /*
            *   Here we check to see if the user is searching for anything
            */
             try{
                  XmlNode xPart = this.dom.SelectSingleNode("/Item/part_number/text()");
                  XmlNode xCond = this.dom.SelectSingleNode("/Item/part_number/@condition");

                  string sPart = xPart.Value;
                  System.Data.SqlClient.SqlParameter param_part  = new System.Data.SqlClient.SqlParameter();
                  param_part.ParameterName = "@part";
                  if(xCond.Value == "like"){
                       //where += " AND p.PART_NUMBER LIKE '" + sPart.Replace("*", "%") + "'";
                       where += " AND p.PART_NUMBER LIKE @part";
                 param_part.Value = sPart.Replace("*", "%");
                 cmd.Parameters.Add(param_part);
                  }else{
                       //where += " AND p.PART_NUMBER = '" + sPart + "'";
                       where += " AND p.PART_NUMBER = @part";
                       param_part.Value = sPart;
                 cmd.Parameters.Add(param_part);
                  }
             }catch (Exception ex){

             }

             try{
                  XmlNode xManfNum = this.dom.SelectSingleNode("/Item/manf_part_number/text()");
                  XmlNode xCond = this.dom.SelectSingleNode("/Item/manf_part_number/@condition");
                  string sManfNum = xManfNum.Value;
                  System.Data.SqlClient.SqlParameter param_manfnum  = new System.Data.SqlClient.SqlParameter();
                  param_manfnum.ParameterName = "@manfnum";
                  if(xCond.Value == "like"){
                       //where += " AND b.[Manufacturer PN] LIKE '" + sManfNum.Replace("*", "%") + "'";
                       where += " AND b.[Manufacturer PN] LIKE @manfnum";
                 param_manfnum.Value = sManfNum.Replace("*", "%");
                 cmd.Parameters.Add(param_manfnum);
                  }else{
                       //where += " AND b.[Manufacturer PN] = '" + sManfNum + "'";
                       where += " AND b.[Manufacturer PN] = @manfnum";
                 param_manfnum.Value = sManfNum;
                 cmd.Parameters.Add(param_manfnum);
                  }
             }catch (Exception ex){

             }
             
             try{
                  XmlNode xManf = this.dom.SelectSingleNode("/Item/manufacturer/text()");
                  XmlNode xCond = this.dom.SelectSingleNode("/Item/manufacturer/@condition");
                  string sManf = xManf.Value;
                  System.Data.SqlClient.SqlParameter param_manf  = new System.Data.SqlClient.SqlParameter();
                  param_manf.ParameterName = "@manf";
                  if(xCond.Value == "like"){
                       //where += " AND b.[Manufacturer] LIKE '" + sManf.Replace("*", "%") + "'";
                       where += " AND b.[Manufacturer] LIKE @manf";
                 param_manf.Value = sManf.Replace("*", "%");
                 cmd.Parameters.Add(param_manf);
                  }else{
                       //where += " AND b.[Manufacturer] = '" + sManf + "'";
                       where += " AND b.[Manufacturer] = @manf";
                 param_manf.Value = sManf;
                 cmd.Parameters.Add(param_manf);
                  }
             }catch (Exception ex){
                  //sw.WriteLine("No Manf found Found");
             }


             try{
                  XmlNode xDesc = this.dom.SelectSingleNode("/Item/description/text()");
                  XmlNode xCond = this.dom.SelectSingleNode("/Item/description/@condition");
                  string sDesc = xDesc.Value;
                  System.Data.SqlClient.SqlParameter param_desc  = new System.Data.SqlClient.SqlParameter();
                  param_desc.ParameterName = "@desc";
                  if(xCond.Value == "like"){
                       //where += " AND des.[Description] LIKE '" + sDesc.Replace("*", "%") + "'";
                       where += " AND des.[Description] LIKE @desc";
                 param_desc.Value = sDesc.Replace("*", "%");
                 cmd.Parameters.Add(param_desc);
                  }else{
                       //where += " AND des.[Description] = '" + sDesc + "'";
                       where += " AND des.[Description] = @desc";
                 param_desc.Value = sDesc.Replace("*", "%");
                 cmd.Parameters.Add(param_desc);
                  }
             }catch (Exception ex){
                  //sw.WriteLine("No description Found");
             }
     
         //cmd.CommandText = "SELECT COUNT(*) FROM  dbo.AllParts WHERE PART_NUMBER LIKE 'CT%'" + where;
            cmd.CommandText = "WITH PARTS AS(";
          cmd.CommandText += "SELECT *, ROW_NUMBER() OVER (ORDER BY p.PART_NUMBER) AS 'RowNumber'  FROM  dbo.AllParts AS p WHERE p.PART_NUMBER LIKE 'CT%'"; 
            cmd.CommandText += ")";
            cmd.CommandText += "SELECT COUNT(*) FROM PARTS as p "
            + "INNER JOIN dbo.[Component Manufacturer Parts] AS a ON p.RowID = a.PartGUID "
            + "INNER JOIN dbo.[Manufacturer Part Info] AS b ON a.ManufacturerGUID = b.RowID " 
            + "LEFT Join dbo.[CT_PART_DESCRIPTIONS] AS des ON des.RowID = p.RowID ";                      
            //+ "WHERE 1" + where;
            if(where != ""){
                 cmd.CommandText += "WHERE 'monkey' = 'monkey' " + where;
            }
            
            
            //sw.WriteLine("sql: {0}", cmd.CommandText);
            cmd.CommandType = CommandType.Text;
            cmd.Connection = conn;
         
            int count = (int) cmd.ExecuteScalar();           
         //sw.WriteLine("Found: {0} parts", count);
         
         //calculate the start and stop
         int iStart = (iPage - 1) * iPageSize + 1;
         int iEnd = iPage * iPageSize;
         int iPageMax = count / iPageSize;
         
         //is there an extra non full page?
         if(iPageMax * iPageSize &amp;lt; count){
              iPageMax++; 
         }
         
         //looking for more records than exist
         if(iEnd &amp;gt; count){
             iEnd = count;
             //iStart = iEnd - iPageSize;
             
             if(iStart &amp;lt;0){
              iStart = 0;
             } 
         }
         
         //now execute query for real
         /* cmd.CommandText = "WITH PARTS AS(";
          cmd.CommandText += "SELECT *, ROW_NUMBER() OVER (ORDER BY p.PART_NUMBER) AS 'RowNumber'  FROM  dbo.AllParts AS p WHERE p.PART_NUMBER LIKE 'CT%'"; 
            cmd.CommandText += ")";
            cmd.CommandText += "SELECT * FROM PARTS as p "
            + "INNER JOIN dbo.[Component Manufacturer Parts] AS a ON p.RowID = a.PartGUID "
            + "INNER JOIN dbo.[Manufacturer Part Info] AS b ON a.ManufacturerGUID = b.RowID " 
            + "LEFT Join dbo.[CT_PART_DESCRIPTIONS] AS des ON des.RowID = p.RowID "                      
            + "WHERE RowNumber Between @low AND @high" + where;
          */
         /* cmd.CommandText = "SELECT *, ROW_NUMBER() OVER (ORDER BY p.PART_NUMBER) AS 'RowNumber'  FROM  dbo.AllParts AS p "; 
            cmd.CommandText += ""
            + "INNER JOIN dbo.[Component Manufacturer Parts] AS a ON p.RowID = a.PartGUID "
            + "INNER JOIN dbo.[Manufacturer Part Info] AS b ON a.ManufacturerGUID = b.RowID " 
            + "INNER Join dbo.[CT_PART_DESCRIPTIONS] AS des ON des.RowID = p.RowID "                      
            + "WHERE RowNumber Between @low AND @high" + where;*/
            
            cmd.CommandText = "WITH PARTS AS(SELECT p.PART_NUMBER, p.RowID, des.description, b.manufacturer, b.[manufacturer PN], ROW_NUMBER() OVER (ORDER BY p.PART_NUMBER) AS 'RowNumber' FROM  [CIP_E].[dbo].[AllParts] AS p " 
            + "INNER JOIN [CIP_E].[dbo].[Component Manufacturer Parts] AS a ON p.RowID = a.PartGUID " 
            + "INNER JOIN [CIP_E].[dbo].[Manufacturer Part Info] AS b ON a.ManufacturerGUID = b.RowID " 
            + "Inner Join [CIP_E].[dbo].[CT_PART_DESCRIPTIONS] AS des ON des.RowID = p.RowID "
            + "WHERE 'monkey' = 'monkey' " + where + ") "
            + "SELECT * FROM PARTS WHERE RowNumber Between @low AND @high";
            
            
      System.Data.SqlClient.SqlParameter param_low  = new System.Data.SqlClient.SqlParameter();
      param_low.ParameterName = "@low";
      param_low.Value         = iStart;
      cmd.Parameters.Add(param_low);

      System.Data.SqlClient.SqlParameter param_high  = new System.Data.SqlClient.SqlParameter();
      param_high.ParameterName = "@high";
      param_high.Value         = iEnd;
      cmd.Parameters.Add(param_high);
            cmd.CommandType = CommandType.Text;
            cmd.Connection = conn;
         //sw.WriteLine("Low: {0} High: {1}", iStart, iEnd);
         //damn you for having no LIMIT function MS SQL
         //sw.WriteLine("query: {0}", cmd.CommandText);
         reader = cmd.ExecuteReader();

         i = 0;    
            while(reader.Read() &amp;&amp; i &amp;lt; iPageSize){
          i++;

          Item res5 = this.newItem("CIP_PART");
             string newid = getNewID();
             string id = reader["RowID"].ToString();
             id = id.Replace("-", "");
             res5.setID(id);
             res5 = res5.apply();
             res5.setProperty("part_number", reader["PART_NUMBER"].ToString());
             res5.setProperty("start", iStart.ToString());
             res5.setProperty("pageSize", iPageSize.ToString());
             res5.setProperty("end", iEnd.ToString());
             res5.setProperty("manf_part_number", reader["Manufacturer PN"].ToString());
             res5.setProperty("manufacturer", reader["Manufacturer"].ToString());
             res5.setProperty("description", reader["description"].ToString());
             res5.setAttribute("page", iPage.ToString());
             res5.setAttribute("pagemax", iPageMax.ToString());
             res5.setAttribute("itemmax", count.ToString());            
             resultNd.AppendChild(resultNd.OwnerDocument.ImportNode(res5.node, true));
             }
         
         break;
        default:
            break; 
    }



    ////// I used to have everything in a try catch but it's hard to debug that way ;)  So left this here
    /////  as a place holder.
    try{

    }
        catch (Exception ex)
    {

    }
    finally
    {
     //close db connection
        conn.Close();
    }
    
    //sw.Flush();
    //sw.Close();
    return res;
&lt;/pre&gt;
&lt;br /&gt;
Alright now I'll try to break it down a little bit to explain what I did here. &amp;nbsp;The first part is the sql connection to the CIP database. &amp;nbsp; For me the CIP database resides on the same MS SQL EXPRESS 2008 server as the CIP database does.&lt;br /&gt;
&lt;pre class="brush: csharp; ruler: true; first-line: 10; highlight: [2, 4, 6]"&gt;    //This is the SQL connection string to connect to our SQL Express database.  
    //Note the login details are the default CIP internal user according to EMA's
    //documentation.
    System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection ();
    conn.ConnectionString = 
     "data source=MININT-PHRAUUK\\sqlexpress;User Id=CIP_E_Internal_User;Password=bra#ru5=phaT;" +
     "initial catalog=CIP_E;";
    System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
    System.Data.SqlClient.SqlDataReader reader;
&lt;/pre&gt;
&lt;br /&gt;
The above code use the C# .net SqlConnection class to make a connection to our CIP database. &amp;nbsp; Note the &amp;nbsp;connection string which is the most important part. &amp;nbsp;MINIT-PHRAUUK is the name IT gave my machine and sqlexpress is the instance of my sqlexpress server. &amp;nbsp; The user ID and Password are the default user ID and password for the internal CIP user from EMAs setup docs. &amp;nbsp;If you changed this you'll need to enter your info. &amp;nbsp;Note this is not the same as the CIP user login, this is the login CIP itself uses. &amp;nbsp;Finally initial catalog is set to CIP_E which is the default name of your CIP database.&lt;br /&gt;
&lt;br /&gt;
The last two&amp;nbsp;lines just create the sql command we'll use later, and the reader we'll use to read data out of the database.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: csharp; ruler: true; first-line: 10; highlight: [2, 4, 6]"&gt;    //these two items are what is going to get returned
    Item res = this.getInnovator().newResult("");
    XmlElement resultNd = (XmlElement) res.dom.SelectSingleNode("/*/*/*");
&lt;/pre&gt;
The above two lines create a new Item, called res and an XmlElement that points to res. &amp;nbsp; Res will be what we end up returning when we are call, and resultNd will help us write other Items into the Res result set.&lt;br /&gt;
&lt;br /&gt;
Before the next part I'll go off track a little in case you're totally new to Aras. &amp;nbsp; Everything that happens in Aras happens with an AML request and response. &amp;nbsp; Something that helped me a lot was when someone on the forum pointed out to me that you can save all the AML requests that Innovator sends, even the ones for the standard built in functions. &amp;nbsp;Just go to Tools-&amp;gt;Admin in the top menu bar and select "save all requests". &amp;nbsp;Now all your requests will be saved in your working directly. &amp;nbsp;Which&amp;nbsp;incidentally&amp;nbsp;you can set under Tools -&amp;gt; preferences&lt;br /&gt;
&lt;br /&gt;
Now you can do something in Innovator and see what kind of requests it makes. &amp;nbsp; As an example here's the request that gets sent when I try to List All CIP Parts in Innovator:&lt;br /&gt;
&lt;pre class="brush: csharp; ruler: true; first-line: 10; highlight: [2, 4, 6]"&gt; 
    int iPage = 1;
    int iPageSize = 25;
    try{
         XmlNode xPage = this.dom.SelectSingleNode("/Item/@page"); 
         XmlNode xPageSize = this.dom.SelectSingleNode("/Item/@pagesize"); 
    
         if(xPage.Value != "" &amp;amp;&amp;amp; xPageSize.Value != ""){
             iPage = int.Parse(xPage.Value);
             iPageSize = int.Parse(xPageSize.Value);
         //action = "list_all"; 
         } 
         
         XmlNode xAction = this.dom.SelectSingleNode("/Item/@select");
         string sAction = xAction.Value;
         if(sAction != ""){
              action = "list_all";
         }
    }catch (Exception ex){

    }
&lt;/pre&gt;
So every time your onGet function gets called it is passed an AML request like we just talked about. &amp;nbsp; The code above is using Xpath notation to parse that request and get the page and pagesize variables. &amp;nbsp; These are sent from the UI if you choose to have say only 5 records returned per page or use the little up and down arrows to move through the page results. &lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: csharp; ruler: true; first-line: 10; highlight: [2, 4, 6]"&gt; 
 string sID = "";
    try{
         XmlNode xAction = this.dom.SelectSingleNode("/Item/@action");
         XmlNode xIdlist = this.dom.SelectSingleNode("/Item/@idlist");
    
         if(xAction.Value == "get" &amp;amp;&amp;amp; xIdlist.Value != "")
         {
             //convert ID
             string sIdlist = xIdlist.Value;
             if(sIdlist.Length == 32){

                 sID = sIdlist.Substring(0, 8) + sIdlist.Substring(8,4) + sIdlist.Substring(12,4) + sIdlist.Substring(16,4) + sIdlist.Substring(20,12);      
                 action = "get_single";
             }
         }
    }catch (Exception ex){

    }
&lt;/pre&gt;
The code above is doing something similar, but here we're getting the action and id list variables. &amp;nbsp;Then in a bit of a hack I'm checking to see if the id list only has one id in it and if it does I decide this is a single get request.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8299669941450299948-8582518730362948352?l=somehardwareguy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://somehardwareguy.blogspot.com/feeds/8582518730362948352/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://somehardwareguy.blogspot.com/2012/01/aras-innovator-orcad-cip-part-onget.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/8582518730362948352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/8582518730362948352'/><link rel='alternate' type='text/html' href='http://somehardwareguy.blogspot.com/2012/01/aras-innovator-orcad-cip-part-onget.html' title='Aras Innovator Orcad CIP Part onGet Part 1'/><author><name>Some Hardware Guy</name><uri>http://www.blogger.com/profile/17462828792887566460</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-_pU3zCQXngM/TxXYbcbZiyI/AAAAAAAABUs/V1IPe09Nwlk/s72-c/cip_on_get_choose.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8299669941450299948.post-9039518776330837521</id><published>2012-01-17T14:13:00.000-08:00</published><updated>2012-01-18T11:30:46.709-08:00</updated><title type='text'>Aras Innovator Orcad CIP Part Federation</title><content type='html'>Ok step one for me was to try to figure out how to get all those CIP PARTS into the ARAS user interface.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Step 1 Create a Federated Part&lt;/span&gt;&lt;br /&gt;
First make sure you are logged in as an Administrator, then in the Table of Contents, select Administration-&amp;gt;Item Types-&amp;gt;New Item Type&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-1YYai1W7QUc/TxXQ74Hym3I/AAAAAAAABUE/fiTUkkCk21M/s1600/aras_new_item.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-1YYai1W7QUc/TxXQ74Hym3I/AAAAAAAABUE/fiTUkkCk21M/s320/aras_new_item.png" width="207" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Step 2 Fill out form&lt;/span&gt;&lt;br /&gt;
Now you need to fill out the form that appears, all I filled out in the top form was the name as CIP_PART, and then make sure you click the Federated radio button. &amp;nbsp; Federated basically means "comes from some other source or database". &amp;nbsp; Now that I think about it I might have just made a copy of the standard Innovator PART and then modified it to be like this.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-17WTvAxdbxg/TxXU_JSEARI/AAAAAAAABUM/LGhfxS_f05U/s1600/cip_part.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="388" src="http://2.bp.blogspot.com/-17WTvAxdbxg/TxXU_JSEARI/AAAAAAAABUM/LGhfxS_f05U/s640/cip_part.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Now I also had to setup a few things in the lower section, first I wanted to make sure I could get to these parts from the table of contents (what they call the main menu on the left hand side of innovator). &amp;nbsp;So I went to the TOC Access tab and added CIP_PART to the Design menu.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-DLOt2OrGsUQ/TxXVwuVvsrI/AAAAAAAABUU/mn-6WOtPXEk/s1600/cip_part_toc_access.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="186" src="http://3.bp.blogspot.com/-DLOt2OrGsUQ/TxXVwuVvsrI/AAAAAAAABUU/mn-6WOtPXEk/s640/cip_part_toc_access.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Next I wanted to make sure no one could try to add one of these parts manually, and just to basically disable an field editing. &amp;nbsp;So I went into Can Add and unchecked the checkbox there.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-9Bx_RduOv-A/TxXWP0Prv4I/AAAAAAAABUc/0GIIM5_Q5eA/s1600/cip_part_can_add.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="168" src="http://3.bp.blogspot.com/-9Bx_RduOv-A/TxXWP0Prv4I/AAAAAAAABUc/0GIIM5_Q5eA/s640/cip_part_can_add.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Finally since I'm going to be providing the CIP PART data from our CIP database I need to add an event handler for the onGet event. &amp;nbsp; Basically this means whenever Innovator tries to get a CIP PART, it will call my code instead of their standard code. &amp;nbsp;Oh and ignore the onUpdate event handler, I never got around to that ;)&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-OI2HAxXTlbA/TxXW-y6u0cI/AAAAAAAABUk/ff350W0CXwk/s1600/cip_part_server_events.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="178" src="http://1.bp.blogspot.com/-OI2HAxXTlbA/TxXW-y6u0cI/AAAAAAAABUk/ff350W0CXwk/s640/cip_part_server_events.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
To create a new event handler just choose Create Related from the select box and click the new button right next to it (see the red arrow above). &amp;nbsp;Give the method a name, mine is CIP_GET, choose CSharp, and &amp;nbsp;select onGet as the event type.&lt;br /&gt;
&lt;br /&gt;
That's it, save your new part and in the next step I'll go through my onGet function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8299669941450299948-9039518776330837521?l=somehardwareguy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://somehardwareguy.blogspot.com/feeds/9039518776330837521/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://somehardwareguy.blogspot.com/2012/01/aras-innovator-orcad-cip-part.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/9039518776330837521'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/9039518776330837521'/><link rel='alternate' type='text/html' href='http://somehardwareguy.blogspot.com/2012/01/aras-innovator-orcad-cip-part.html' title='Aras Innovator Orcad CIP Part Federation'/><author><name>Some Hardware Guy</name><uri>http://www.blogger.com/profile/17462828792887566460</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-1YYai1W7QUc/TxXQ74Hym3I/AAAAAAAABUE/fiTUkkCk21M/s72-c/aras_new_item.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8299669941450299948.post-4278939400058045679</id><published>2012-01-17T14:12:00.000-08:00</published><updated>2012-01-18T11:30:37.766-08:00</updated><title type='text'>Aras Innovator Orcad CIP CIS Integration</title><content type='html'>While looking around for a cheaper PLM solution I came across ARAS's open source model.   The tool itself looked great, but I needed it to integrate with our Orcad CIP system we use from EMA.   I quickly found out that there were commercial solutions to this in the $15k range, a lot more than I wanted to spend just for that feature.   The other problem I'd encountered with this, and other PLM systems is that often they expect to be the center of the world when it comes to part data management.   If you're a CIP user though then I bet like me you don't want to give up CIP's direct integration into Digikey, or Arrow, or your favorite vendor's catalog.  I mean it's nice to be able to look up a part, make sure I can buy it at Arrow and Digikey for both large and small runs, then automatically have all that data populated in our database. &lt;br /&gt;
&lt;br /&gt;
The goal of this project was to bring the component data from CIP into ARAS, be able to assign it to other parts in ARAS based on the BOMS coming out of Orcad CIS.  All while having CIP be the only source of the actual component data.   I should warn you that the following is likely the wrong way to do things, a massive hack, and quite possibly a mess. &amp;nbsp;I only put about two to three weeks worth of effort into this before I was pulled off. &amp;nbsp; I should also warn you that, like the blog title says, I am an electrical engineer. &amp;nbsp; People come to me when they want to know why they're seeing cross talk, or a board won't boot properly, not when they want to know the right design pattern, or syntax to use.&lt;br /&gt;
&lt;br /&gt;
I put this together by basically reverse engineering how ARAS worked, asking questions on their forum, and a lot of trial and error.  Saying reverse engineering makes it sound like I did something ARAS didn't want me to do, on the contrary they were very helpful to me on the forum, and in fact they pointed me to the tools and methods to do the reverse engineering in the first place.

Below is the list of things I did to make this work.

&lt;br /&gt;
&lt;br /&gt;
All disclaimers aside here's what I &amp;nbsp;did:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Brought the CIP component data into Innovator as federated "CIP PARTS"&lt;/li&gt;
&lt;li&gt;Made a custom database view in the MS SQL CIP database to get all the part descriptions into one database.&lt;/li&gt;
&lt;li&gt;Made a fake part in Innovator called CIP PART BOM to act as the container for the CIP PARTS and overloaded it's onGet function to run my own code.&lt;/li&gt;
&lt;li&gt;Made a new item in Innovator called CIP LOADED BOM to keep track of the relationship between CIP PARTS and Innovator Parts&lt;/li&gt;
&lt;li&gt;Some other things I've likely forgotten at the moment but should come out in the following posts.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8299669941450299948-4278939400058045679?l=somehardwareguy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://somehardwareguy.blogspot.com/feeds/4278939400058045679/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://somehardwareguy.blogspot.com/2012/01/aras-innovator-orcad-cip-cis.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/4278939400058045679'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/4278939400058045679'/><link rel='alternate' type='text/html' href='http://somehardwareguy.blogspot.com/2012/01/aras-innovator-orcad-cip-cis.html' title='Aras Innovator Orcad CIP CIS Integration'/><author><name>Some Hardware Guy</name><uri>http://www.blogger.com/profile/17462828792887566460</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8299669941450299948.post-2350627596957179842</id><published>2009-07-16T13:27:00.000-07:00</published><updated>2009-07-16T14:11:23.575-07:00</updated><title type='text'>Flex As3crypto + php + rsa + openssl</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Flex As3crypto + php + rsa + openssl&lt;/span&gt;&lt;br&gt;
Well damn, all I wanted to do was encrypt a little data in my flex application upload it to php and decrypt it there.    Of course that turns out to be incredibly complicated.    So to all those who will come after me here’s an example of how I generated a 1024 bit RSA key pair with openssl, and used the public key to encrypt a phrase in flex, and the private key to decrypt the phrase in php.
First a disclaimer though, I don’t know a lot about encryption or even a lot about what I’m doing but it seems to work and maybe you’ll find it useful.
&lt;br&gt;&lt;br&gt;
&lt;span style="font-weight:bold;"&gt;PHP and openssl&lt;/span&gt;&lt;br&gt;
If you want to play along you’re going to need php installed with openssl support.    If you make a php file and put this in it:
&lt;pre class="brush:php"&gt;
phpinfo();
&lt;/pre&gt;
&lt;br&gt;
and you scroll through the php info page and you don’t see this:

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_SptOLbsvC-4/Sl-O0OAJbAI/AAAAAAAABPY/XVYzEzp2-Cs/s1600-h/openssl.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 50px;" src="http://3.bp.blogspot.com/_SptOLbsvC-4/Sl-O0OAJbAI/AAAAAAAABPY/XVYzEzp2-Cs/s320/openssl.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5359159109357235202" /&gt;&lt;/a&gt;

Then you don’t have php and openssl working together, if you want to continue you’ll need to figure that out on your own.   It’s not too hard though.
&lt;br&gt;&lt;br&gt;
&lt;span style="font-weight:bold;"&gt;As3Crypto Build and Install&lt;/span&gt;&lt;br&gt;
I’ll assume you’ve figured out your php and openssl configuration, so now it’s time to get the as3crypto library.   DON’T JUST DOWNLOAD THE BINARY VERSION.   I can’t stress that enough don’t just go to Hurlant’s website and get he latest binary version.   
Instead use svn to get the latest code base:
&lt;br&gt;
&lt;br&gt;
svn checkout http://as3crypto.googlecode.com/svn/trunk/ as3crypto-read-only
&lt;br&gt;
&lt;br&gt;
If you don’t have svn or you don’t want to compile it yourself… you’ll be sad that you didn’t.   Believe me I tried the easy way and it just didn’t work.
&lt;br&gt;&lt;br&gt;
Once you get it downloaded get a command line or terminal window and go to the download directory.   You can compile with this command:
&lt;br&gt;&lt;br&gt;
compc -load-config=build-swc.xml
&lt;br&gt;&lt;br&gt;
You’ll probably have to find out where your compc is located if it’s not in your path, and instead run something like:
&lt;br&gt;&lt;br&gt;
/pathToCompC/compc –load-config=build-swc.xml
&lt;br&gt;&lt;br&gt;
I also ran into the problem of it not knowing  where playerglobal.swc was so I ended up editing that line in build-swc.xml to fit my installation.   For me it was:
&lt;br&gt;&lt;br&gt;
&lt;path-element&gt;${flexlib}/libs/player/10/playerglobal.swc&lt;/path-element&gt;
&lt;br&gt;&lt;br&gt;
When you finally get it to compile it will put the file as3crypto.swc in the bin folder  where you found build-swc.xml.   Either leave that file there or copy it somewhere you like to keep these things.
&lt;br&gt;&lt;br&gt;
&lt;span style="font-weight:bold;"&gt;Make yourself some keys&lt;/span&gt;&lt;br&gt;
The next thing you’re going to want is a key pair.   I made mine on my linux server using openssl.   For me this is the same server I’m running php on.  I’m sure there are a bunch of ways to generate the key pair but I followed the advice found here:
&lt;br&gt;&lt;br&gt;
 &lt;a href="http://www.devco.net/archives/2006/02/13/public_-_private_key_encryption_using_openssl.php"&gt;http://www.devco.net/archives/2006/02/13/public_-_private_key_encryption_using_openssl.php&lt;/a&gt;
&lt;br&gt;&lt;br&gt;
To make a private key just do:
&lt;br&gt;&lt;br&gt;
openssl genrsa -out private.pem 1024 
&lt;br&gt;&lt;br&gt;
Then to extract the public key out of that private key do this:
&lt;br&gt;
openssl rsa -in private.pem -out public.pem -outform PEM -pubout 
&lt;br&gt;&lt;br&gt;
Now you have two files private.pem, and public.pem that we’ll use in the next section.
&lt;br&gt;&lt;br&gt;
&lt;span style="font-weight:bold;"&gt;Flex Code&lt;/span&gt;&lt;br&gt;
All right enough BS here’s the code I used to encrypt a small phrase in my Flex-Air application.  
&lt;br&gt;&lt;br&gt;
&lt;pre class="brush:actionscript3"&gt;
            import com.hurlant.crypto.symmetric.ICipher;
            import com.hurlant.crypto.prng.Random;
            import com.hurlant.crypto.Crypto;
            //import com.hurlant.util.Base64;
            import mx.utils.Base64Encoder;
   
            import com.hurlant.util.Hex;
            import com.hurlant.util.der.PEM;
            import com.hurlant.crypto.rsa.RSAKey;


            private function sign():void
            {
             
             var publicKey:String = "-----BEGIN PUBLIC KEY-----\n" +
                 "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDIyrrhK7L1JQATG1zu/4ktyDdj\n" +
                 "Y41EIZxa5vUiq+ejUlQXNWmQZw8ATDGV2x/xJEcsZSbPqcxgyqDPQ8kGjQkv1kS/\n" +
                 "5ZP3oru5WSEypVPq1nfMCBoGTspyYIRpS+MjhhhN2X5y0NzR08kQQA81GRvBpmxM\n" +
                 "Ymy1r50CmtcVuIbuKwIDAQAB\n"+
                 "-----END PUBLIC KEY-----\n";
                         

                //var rsa:RSAKey = RSAKey.parsePublicKey(getModulus(), exponent.text);
                var rsaPublicKey:RSAKey = PEM.readRSAPublicKey(publicKey);
                var data:ByteArray = new ByteArray;

                data.writeUTFBytes("fuck this crazy ass crap");
                var dst:ByteArray = new ByteArray;
                rsaPublicKey.encrypt(data, dst, data.length);
               
                var Enc64:Base64Encoder = new Base64Encoder;
                Enc64.encodeBytes(dst);
                trace(Enc64.toString());
    
                //use this on linux side to test
                //openssl rsautl -decrypt -inkey mykey.pem -in test.out -out decrypted.txt
                ///usr/bin/openssl enc -base64 -d -in test.64 -out test.out



            }
&lt;/pre&gt;

&lt;br&gt;
The first thing you’ll notice is my public key that I got in the previous step.  I have no idea if the \n’s are necessary but I put them there because I saw other people do that so monkey see monkey do.   
&lt;br&gt;&lt;br&gt;
Next I read the key into an RSAKey.
&lt;br&gt;&lt;br&gt;
Then you make yourself a new Byte array to store the phrase you want to encrypt .  In this example it’s called data.
&lt;br&gt;&lt;br&gt;
Then you write the phrase into the byte array.
&lt;br&gt;&lt;br&gt;
Now you make yourself another byte array called dst, this is where the encrypted data will go.
&lt;br&gt;&lt;br&gt;
Next you base64 encode the data so you can easily copy and paste it.   Base64 encoding just encodes all that encrypted data into normal text characters that you can safely drag around.
&lt;br&gt;&lt;br&gt;
Finally you output that data with a trace so you can get it easily.   For me the trace outputs:
&lt;br&gt;&lt;br&gt;
XTLpqt9mNtyFchsjvFnffEplqaa+LHXCh52DpLi9CxvED4fUq5cWPuTX/1tHeG7deNBiGBiRW02r
+LfW3JreVSkkc+sH6rq4ggKWi+1iPZoQd45f2VmwHVTvgC/IQX4eRuyFtSVoheHSLRL8zRO2/M27
K2jx49V+4JFVhtFAbQw=
&lt;br&gt;&lt;br&gt;
This is your encrypted base64 encoded data, that we’ll decrypt in the next section.
&lt;br&gt;&lt;br&gt;
&lt;span style="font-weight:bold;"&gt;PHP Time&lt;/span&gt;&lt;br&gt;
I don’t know how you plan on getting your encrypted phrase to php, and frankly I don’t care.   For me I just wanted to see it work so all I did was copy and paste.    Here’s the PHP code I used to decrypt the phrase:

&lt;pre class="brush:php"&gt;

$privkey3 = "-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDIyrrhK7L1JQATG1zu/4ktyDdjY41EIZxa5vUiq+ejUlQXNWmQ
Zw8ATDGV2x/xJEcsZSbPqcxgyqDPQ8kGjQkv1kS/5ZP3oru5WSEypVPq1nfMCBoG
TspyYIRpS+MjhhhN2X5y0NzR08kQQA81GRvBpmxMYmy1r50CmtcVuIbuKwIDAQAB
AoGAbMucEqGQ589SiQfMhRskgw/3Iv0v7/ieNYrqzAyFCDN1qNWiC0IsGKcwPthq
KEjV37I3I1IHkXJ5S5SY+dm1XaSrM0XpycCCz/OYYZMJ4Z5qQNyeCIDt69UXHlaz
AIITK7rLcGIOERVp80ZtTXfVv+2oLo7IQLHxntQaP2sOIQECQQD/v7QdW8Zm2Zmr
jAAcnmvGdctPKZmg2fsembqI8xS3QjsPK4Fky2r4CWFu9V+pfIQH2i6L0P0SDZ5n
wHMcg9LrAkEAyP01wruazceeh2LIMAKsdtOudXCYv/Hm9utdTGTPWDBdAKFFJ2O5
GuicqUXeVqP1DjZTtpQ6MWBEKekXN3YBwQJBAOeW3zFes/Dax08Svd8sjgfvDyYm
U5nXCpGRP9tX08CHVxfLm6Z8leb6B6MEy5WczaqWpmOx4hkBABqPqS1/KfUCQHIh
j0iwPZzC0RuyFVll+0dStwuLT8IXfH8UchtyV2eNtxIngdx3PWKxWlypBzON0Rcr
9GeGTnFBaBOggAWHZkECQCGou7Uu8jWPZZ3tFgtAGV+W5iPdj5LGoGu6L7EYAy6u
6jAj8SDB6UrTPDMx1Jjv87fJPCJy93CJI4PRWTu078Q=
-----END RSA PRIVATE KEY-----";



$result = openssl_pkey_get_private($privkey3);

if ($result)
{
        print "\nPrivate Key OK\n\n";
} else {
        print "\nPrivate key NOT OK\n\n";
}

$crypttext = "XTLpqt9mNtyFchsjvFnffEplqaa+LHXCh52DpLi9CxvED4fUq5cWPuTX/1tHeG7deNBiGBiRW02r
+LfW3JreVSkkc+sH6rq4ggKWi+1iPZoQd45f2VmwHVTvgC/IQX4eRuyFtSVoheHSLRL8zRO2/M27
K2jx49V+4JFVhtFAbQw=";

$crypttext = base64_decode($crypttext);


openssl_private_decrypt($crypttext,$newsource,$result);
echo "&lt;br&gt;String decrypt : $newsource &lt;br&gt;";

while ($msg = openssl_error_string())
    echo $msg . "&lt;br /&gt;\n";

&lt;/pre&gt;

&lt;br&gt;&lt;br&gt;
First you’ll see that I took the private key from the keys we made earlier and put it in this file.   Make sure yours looks the same, if you paste your private key without the right new lines it won’t work.   At least it didn’t for me so must make sure you format it like you see in the code.
&lt;br&gt;&lt;br&gt;
Next we call openssl_pkey_get_private on that private key.
&lt;br&gt;&lt;br&gt;
Now you’ll see the encrypted phrase from our Air application in the $crypttext variable.
&lt;br&gt;&lt;br&gt;  
We base64 decode that to get back to the raw data.
&lt;br&gt;&lt;br&gt;
Then we run it through openssl_private_decrypt to decrypt the data.
&lt;br&gt;&lt;br&gt;
Finally we just output the data to the screen.
&lt;br&gt;&lt;br&gt;
That last little while loop will output any openssl errors that might have occurred, and can be at least a little useful in debugging.
&lt;br&gt;&lt;br&gt;
&lt;span style="font-weight:bold;"&gt;The End&lt;/span&gt;&lt;br&gt;
Well I hope that helps someone else who comes along and tries to do the same thing.   It was a pain in the ass to figure this all out especially because as3crypto has no documentation.   I’m not knocking it though I mean you just got a completely free cryptography library for your flash project right.
&lt;br&gt;&lt;br&gt;
One last thing if you, like me, know about as much about cryptography as you do about how to win the lottery, then you may be disappointed to find out you can only use RSA to encrypt a relatively small amount of data (it’s dependant on your key size).    So most people use this to either exchange keys, or make a hash of what they’re sending and encrypt that.
&lt;br&gt;&lt;br&gt;
Of course if you happen to know a lot about how to win the lottery... drop me an email with some tips.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8299669941450299948-2350627596957179842?l=somehardwareguy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://somehardwareguy.blogspot.com/feeds/2350627596957179842/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://somehardwareguy.blogspot.com/2009/07/flex-as3crypto-php-rsa-openssl-well.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/2350627596957179842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/2350627596957179842'/><link rel='alternate' type='text/html' href='http://somehardwareguy.blogspot.com/2009/07/flex-as3crypto-php-rsa-openssl-well.html' title='Flex As3crypto + php + rsa + openssl'/><author><name>Some Hardware Guy</name><uri>http://www.blogger.com/profile/17462828792887566460</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_SptOLbsvC-4/Sl-O0OAJbAI/AAAAAAAABPY/XVYzEzp2-Cs/s72-c/openssl.png' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8299669941450299948.post-1290694684962767803</id><published>2009-03-30T08:46:00.001-07:00</published><updated>2009-03-30T09:34:27.930-07:00</updated><title type='text'>datepicker is not a function</title><content type='html'>AUGGGHH!   Why doesn't this work!   Such is the cry of any hacky developer running around cobbling together pieces of code and examples to get something to work.   All while trying to learn whatever he's working on at the same time.

Anyway recently I tried to use jQuery's datepicker function in one of my pages.  I consistently got the error datepicker is not a function.   I tried all sorts of things but nothing worked.   

Well it turns out I was using prototype and another javascript library called tablekit.   Now they both use the $ as a shortcut to refer to themselves, and so does jquery.   So when you try to use them together there's a conflict.  Fortunately jQuery provides a very nice solution to this (you can read more about it &lt;a href="http://docs.jquery.com/Using_jQuery_with_Other_Libraries"&gt;here&lt;/a&gt;.
&lt;br&gt;&lt;br&gt;
Here's what I ended up doing:
&lt;br&gt;
&lt;pre class="brush: js"&gt;
&amp;lt;!-- jQuery JS Includes --&gt;
&amp;lt;script src="javascripts/prototype.js" type="text/javascript"&gt;&amp;lt;/script&gt;
&amp;lt;script type="text/javascript" src="jquery/jquery-1.3.2.js"&gt;&amp;lt;/script&gt;

&amp;lt;script&gt;
  var $j = jQuery.noConflict();
&amp;lt;/script&gt;

&amp;lt;script type="text/javascript" src="jquery/ui.core.js"&gt;&amp;lt;/script&gt;
&amp;lt;script type="text/javascript" src="jquery/ui.datepicker.js"&gt;&amp;lt;/script&gt;
&amp;lt;script src="javascripts/scriptaculous.js?load=effects,builder,dragdrop" type="text/javascript"&gt;&amp;lt;/script&gt;
&lt;/pre&gt;
&lt;br&gt;&lt;br&gt;
Now to you use $j instead of $ in all your jQuery code.
&lt;pre class="brush: js"&gt;
     // Use jQuery via $j(...)
     $j(document).ready(function(){
       $j("div").hide();
     });
     
     // Use Prototype with $(...), etc.
     $('someid').hide();
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8299669941450299948-1290694684962767803?l=somehardwareguy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://somehardwareguy.blogspot.com/feeds/1290694684962767803/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://somehardwareguy.blogspot.com/2009/03/datepicker-is-not-function.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/1290694684962767803'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/1290694684962767803'/><link rel='alternate' type='text/html' href='http://somehardwareguy.blogspot.com/2009/03/datepicker-is-not-function.html' title='datepicker is not a function'/><author><name>Some Hardware Guy</name><uri>http://www.blogger.com/profile/17462828792887566460</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8299669941450299948.post-192248469876032285</id><published>2009-03-15T06:44:00.000-07:00</published><updated>2009-03-15T07:21:54.282-07:00</updated><title type='text'>Part 3 LCDS Insync Example, it works and I'm fed up.</title><content type='html'>Ok so I got this example to work and there was much rejoicing, followed by much disappointment but I'll save that for the end.   There are a ton of steps, and missing one means it's not going to work so I'll try to lay it out for you.

&lt;UL&gt;
&lt;LI&gt;
&lt;span style="font-weight:bold;"&gt;Step One:&lt;/span&gt;  First you need to create a project in flex builder.   This really isn't that hard, just start a new air project and call it insync.  When it's done just drag everything from the flex source into the src directory of your new project.   Let it overwrite insync.mxml.  There now you should have your very own project to play with.
&lt;/LI&gt;
&lt;LI&gt;
&lt;span style="font-weight:bold;"&gt;Step Two:&lt;/span&gt; It's been a while since the original author wrote this insync sample so if you don't want an error that says:"error while loading initial content" then you need to go into your insync-app.xml.   At the second line there is an application block, change it to say &lt;application xmlns="http://ns.adobe.com/air/application/1.5"&gt;.
&lt;/LI&gt;

&lt;LI&gt;
&lt;span style="font-weight:bold;"&gt;Step Two:&lt;/span&gt;Ok now you need the lcds libraries in your path or else you won't be able to compile against them.  If you try you'll just get a bunch of errors which I forget at the moment but they basically say "GET THE LIBRARIES" :)   So where are they?  If you're like me they're hidden in the war files.  Go to your lcds-samples.war file, and unzip it again.   Now under the WEB-INF directory you just made by unzipping the file, there is a flex directory.  Under that directory are two folders libs and locale.   That's where your libraries are.   You can copy them someplace else or leave them where they are that's up to you.

Next you need to add them to your path.   In Flex Builder go to project properties, then go to the Flex Build Path tab.   Now you need to add two SWC folders, just click on the SWC folder button and add libs and locale.  

Now you need to add two SWC files.  The first is the airfds.swc file, it's in that libs folder you just added, in the air directory.  The last file you need to add is in the locale directory, under the en_US directory, and it's called fds_rb.swc.  Just add that file and you're good to go
&lt;/LI&gt;
&lt;LI&gt;
&lt;span style="font-weight:bold;"&gt;Step Three:&lt;/span&gt;  At this point you should be able to build.  So give it a shot.   If you start up your jboss server from part two and start the sample database, then try to run your application you'll get this error: Error: Unable to initialize destinations on server: ["nameOfDataService"] 

Sigh more errors, unfortunately this one is a bug in lcds, and it's documented &lt;a href="https://bugs.adobe.com/jira/browse/SDK-16530"&gt;here&lt;/a&gt; You'll notice there are others that feel our pain, and at the bottom Jeff from Adobe invites people to email him to receive a fixed copy of a library.  Which I did yesterday, which was Saturday so we'll see what I get back.   

In the meantime his advice to compile in your services descriptions led me to come up with the following modifications to the compiler command line.   Just go back to Project --&gt; properties in Flex Builder.  Now under the Flex Compiler tab, add this to Additional Compiler Arguments:

Fill in your directory paths:
-locale en_US -services {your path to jboss}/jboss-4.2.2.GA/server/default/deploy/{your directory you unziped lcds-samples.war to}/WEB-INF/flex/services-config.xml -context-root=http://localhost/  

Mine looks like this:
-locale en_US -services /Users/Downloads/jboss-4.2.2.GA/server/default/deploy/test26/WEB-INF/flex/services-config.xml -context-root=http://localhost/
&lt;/LI&gt;
&lt;/UL&gt;

Ok well now at this point you should be able to compile and run the program yourself.  You should see the data populate into the application, and if you see the little green online light in the bottom corner you should be able to make changes.  I was pretty happy at this point so I decided to try a little testing, and of course more issues.  I don't think it's the original authors design, but more some lingering issues with LCDS but that's just one mans opinion.

Try this little test, start your application with the server running and get the contact data, then shutdown the server to simulate a loss of connection.  Now add a contact in the insyc application and close it.   Now according to the theory when we start up I'd think it would load the contacts from cache since it's offline and if the server is online it should update the sampledb.   Not so, if you try to startup with the server started you'll get a couldn't fill message.   If you're inclined to dig a little further and debug it you'll see messages about it not being able to initialize the datasource.

If you want to fix your problem just go delete the sqlite database it's using.  On a mac that's under.
/Users/username/Library/Preferences/insync/Local Store/_ds_localstore

You'll see the file you want is named after the datacache id set in your insync program.

So this is where I stopped, lcds was incredibility complicated to setup, and it seems like there are still bugs to be worked out.  These are exactly the type of problems I'd hoped to avoid by using it.  So my conclusion is that for what I want to do it's a lot easier to just write it myself.  I'm thinking I'll just post signed XML requests to a PHP script for proof of concept, then when I want it to go faster I'll just write a server in C.

I hope this helps at least someone out there.

Good Luck&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8299669941450299948-192248469876032285?l=somehardwareguy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://somehardwareguy.blogspot.com/feeds/192248469876032285/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://somehardwareguy.blogspot.com/2009/03/part-3-lcds-insync-example-it-works-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/192248469876032285'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/192248469876032285'/><link rel='alternate' type='text/html' href='http://somehardwareguy.blogspot.com/2009/03/part-3-lcds-insync-example-it-works-and.html' title='Part 3 LCDS Insync Example, it works and I&apos;m fed up.'/><author><name>Some Hardware Guy</name><uri>http://www.blogger.com/profile/17462828792887566460</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8299669941450299948.post-8868750329025480782</id><published>2009-03-14T11:02:00.000-07:00</published><updated>2009-03-14T12:42:19.612-07:00</updated><title type='text'>Using a Wii with a PC monitor and keeping your PC sound</title><content type='html'>Recently a friend of mine presented me with a problem and asked me to help.  He had and his wife were both using the Wii and Wii fit to exercise.  They had moved their Wii to their upstairs office / exercise room and wanted to hook it up to their PC monitor.   Then they'd gone to Best Buy who sold them a video capture card and told them they could use that to hook it up to their PC.   That's where I came into the situation.

Well you probably won't be surprised to learn that that worked about as well as a marketing guy trying to use an oscilloscope.   The quality was terrible, there was significant lag from the time it took the card to process the video, the resolution was poor and finally the program that displayed the video was complicated and crashed a lot.

The first part of the solution was to take that video card back where it came from.  Next we ordered a Wii cable that converted the component video output to a vga output.  I didn't take it apart since it wasn't mine but there isn't much too it, and you could probably make your own but for $35 it's not worth the effort.  Plus it was for non technical people so the easier the better.   The only issue we had was the cable only worked in 480p mode.   Not a big deal but if you don't have a component cable already then the Wii won't go into 480p mode.   They didn't have a cable, but I did so with two more trips the problem was solved. 

The nice thing was they had an lcd monitor with two inputs which meant I could leave both hooked up and they could just switch them whenever they wanted.   Of course they only had one set of speakers so I left that hooked up to the Wii.   It wasn't long before I got the call, "so how do we get sound out of the PC and the Wii?".   

Now the simple answer is swap plugs, but that's a pain.   I want this to be easy.   My next instinct was, "ah we just need to buy a y adapter".   When you think about it that's a pretty bad idea too.  Yeah it will work, there's a pretty good chance you'll get some feed back noise.  Even worse is now you have the possibility of two output drivers competing with one another.   That should work for a while, heck it might even work forever, but if a year from now the output driver on the Wii dies we'll all know who's fault it is.   Also what if you want to exercise but also listen to some mp3s at the same time?

Well I thought back to the first electronic product I ever made and tried to sell myself (note the tried part :).  It was called the Audiovive and the idea was simple.  I was in college and I wanted to play video games and listen to my music at the same time.   Like most techy guys I had a tv, a receiver, some surround sound and more importantly a soldering iron.     The solution was the little guy below:

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_SptOLbsvC-4/SbwIfA4E57I/AAAAAAAABPQ/MwYMGeMDYM4/s1600-h/audiovive.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://3.bp.blogspot.com/_SptOLbsvC-4/SbwIfA4E57I/AAAAAAAABPQ/MwYMGeMDYM4/s320/audiovive.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5313130989294512050" /&gt;&lt;/a&gt;

It's nothing more than a passive two channel mixer, nothing fancy and it gets the job done.  I was going to just give them this, but it was the only one I had left and being a little sentimental I decided I'd rather just build them another one.  So for a few bucks in parts from digikey I whipped up a simpler version that I'll go through below.

First off I ordered the following:
&lt;UL&gt;
&lt;LI&gt;3 of these headphone jacks CP1-3523N-ND
&lt;LI&gt;1 of these pots P2B6203-ND
&lt;/UL&gt;

I chose headphone jacks because I have a ton of 3.5mm jack to RCA converters in my garage from the Audiovive project.   I chose that pot because it was cheap, had two elements, and was logarithmic so we'd have better volume control.  This is just your basic resistive mixer, no input caps no nothing.  Here's the schematic.

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_SptOLbsvC-4/SbwIQ_HD06I/AAAAAAAABPI/H-VxK_Fj-Xc/s1600-h/schematic.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 251px;" src="http://1.bp.blogspot.com/_SptOLbsvC-4/SbwIQ_HD06I/AAAAAAAABPI/H-VxK_Fj-Xc/s320/schematic.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5313130748302316450" /&gt;&lt;/a&gt;

That's about it.  It's pretty simple to wire up.  When you're done you can turn the pot and it will balance the amount of sound sent from the two inputs to the output.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8299669941450299948-8868750329025480782?l=somehardwareguy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://somehardwareguy.blogspot.com/feeds/8868750329025480782/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://somehardwareguy.blogspot.com/2009/03/using-wii-with-pc-monitor-and-keeping.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/8868750329025480782'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/8868750329025480782'/><link rel='alternate' type='text/html' href='http://somehardwareguy.blogspot.com/2009/03/using-wii-with-pc-monitor-and-keeping.html' title='Using a Wii with a PC monitor and keeping your PC sound'/><author><name>Some Hardware Guy</name><uri>http://www.blogger.com/profile/17462828792887566460</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_SptOLbsvC-4/SbwIfA4E57I/AAAAAAAABPQ/MwYMGeMDYM4/s72-c/audiovive.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8299669941450299948.post-6529258452283641850</id><published>2009-03-14T08:31:00.000-07:00</published><updated>2009-03-14T09:01:04.477-07:00</updated><title type='text'>Part Three Getting a sample flex app to work</title><content type='html'>Well prior to all this some googling had brought me to Christophe Coenraets great page on getting LCDS to work with a Flex application.   He was nice enough to write an AIR based contact management application that uses LCDS to connect to the sample database.   He includes all his source code, a compiled version of the application, as well as the server side code and compiled java classes.    I highly recommend reading through all of this as it helped me understand how all this works.   Check it out &lt;a href="http://coenraets.org/blog/2008/05/insync-automatic-offline-data-synchronization-in-air-using-lcds-26/"&gt;here&lt;/a&gt;.  

Now download all the project files, and install the air application.  We'll use that as our litmus test to whether this works or not.

Since I'm using JBoss my setup was a bit different than his.   I don't have any of the directories he's talking about and just dumping the files into the deploy directory doesn't work.  This brings me to the point of actually learning what a .war file is.   I'm sure there's a complex explination but it turns out it's just a zipped up collection of files.   In there are the java classes, some configuration xml files, you name it.    JBoss seems to like to use those so that's what we'll have to do.

Now since you've been following along you have an lcds-samples.war file in your deploy directory.   This part took a while for me to understand, maybe I was just slow that day.   What the example wants you to do is take his files and put them in the classes directory.   But where is that directory?  Try searching for it you won't find it.   The ah ha moment for me was when I realized that it was "inside" the lcds-samples.war file.   Maybe that's obvious to some people but not to me.   So how to we get in there?

It's pretty simple just unzip the .war file.  Watch it thought it just expands into whatever directory you're in.   What I did was create another directory called test, still under the JBoss default/deploy directory and then I moved lcds-samples.ware into test.   Then I opened up another termial window and navigated to that directory.    Now just type unzip lcds-samples.war and behold it creates the whole directory structure before your very eyes.

You'll find the folder to put Christophe's example under WEB-INF--&gt;flex--&gt;classes.   Just drag his lcds folder into here.   But wait you're not done yet, go back up one directory level to WEB-INF--&gt;flex.   Here you'll find the data-managment-config.xml  file that he and most other examples are asking you to add some description code to.   If you don't add this when you run his program you'll get an error saying can't fill, and you'll see an exception on your JBoss terminal window.   I don't know too much about this but it appears to be a description that tells JBoss how to handle an incoming request and what program to pass it on to.

Once you've done all that you need to pack it back up into a war file.  I removed the original lcds-samples.war file, you may want to move it to lcds-samples.bak.   Just go up to the test directory in your terminal window and type "jar -cvf lcds-samples.war *".   That should create the new lcds-samples.war file that you need.


Think you're done? Not so fast, this example also needs some data.   That data is put in the same sample database application that we started up before.  Just take the files in his sampledb and copy them into yours.  It will want to overwrite server.properties which is ok.  If you compare the files you'll see his contains everything the default one does plus his example.   So do that restart the database, restart jboss, and try to run his air application.   If you see names and contact information appear in the application, then congratulations you got it to work.

Next up is getting the flex application code to compile so I can make changes.   When I figure that out I'll add it here.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8299669941450299948-6529258452283641850?l=somehardwareguy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://somehardwareguy.blogspot.com/feeds/6529258452283641850/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://somehardwareguy.blogspot.com/2009/03/part-three-getting-sample-flex-app-to.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/6529258452283641850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/6529258452283641850'/><link rel='alternate' type='text/html' href='http://somehardwareguy.blogspot.com/2009/03/part-three-getting-sample-flex-app-to.html' title='Part Three Getting a sample flex app to work'/><author><name>Some Hardware Guy</name><uri>http://www.blogger.com/profile/17462828792887566460</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8299669941450299948.post-2509469979079937306</id><published>2009-03-14T08:04:00.000-07:00</published><updated>2009-03-14T08:31:13.072-07:00</updated><title type='text'>Part Two Getting LCDS</title><content type='html'>At this point I really didn't quite get what LCDS was.  I mean I know what it does, I know it's some sort of libraries, but what "is" it.   So far I'd gathered that it was a set of libraries and some example java applications that run on your JAVA application server.   Those JAVA applications can have access to server resources like my MySQL server, and they can run as little servers that respond to request from my Flex applications.   So a little complicated but not to bad. 

The first nice surprise about LCDS is although it isn't free, Adobe does have a non expiring one CPU license for developers to use.   So that's what you're going to want to get.   Now the first time around I installed this on my Ubuntu box, only to find that all of the sample code was set to connect to local host.   The next logical step was to install it on my Mac Book but, ahhhhhggg!   Adobe doesn't offically support it for the Mac platform.   Now I won't rant and rave about that I know there aren't as many Macs out there etc etc, and I do have Windows installed here as a Virtual Machine, but did I really want to do that?

No, and thankfully &lt;span style="white-space: normal;"&gt; &lt;span class="green-text author"&gt;&lt;a href="http://www.adobe.com/cfusion/communityengine/index.cfm?event=addSearchUser&amp;amp;loc=en_US&amp;amp;productId=2&amp;amp;mostRecent=on&amp;amp;userId=71338261"&gt;nickul&lt;/a&gt; over at adobe was nice enough to post this article on how to install LCDS on a MAC anyway.    You can read the original article &lt;a href="http://www.adobe.com/cfusion/communityengine/index.cfm?event=showdetails&amp;amp;postid=7584&amp;amp;loc=en_US&amp;amp;productid=2"&gt;here&lt;/a&gt;, although it didn't quite work for me it inspired me to try.   First you need to get LCDS from Adobe and as Nick points out you need the AIX version (the Java Version).    I got mine here &lt;/span&gt;&lt;/span&gt;&lt;a href="http://www.adobe.com/products/livecycle/dataservices/"&gt;http://www.adobe.com/products/livecycle/dataservices/&lt;/a&gt;.   You'll need a free Adobe ID which you should already have if you've downloaded Flex Builder.   Make sure you remember to copy down the serial number they give you, it's the first thing you'll need at install.

When the file is done downloading just double click on it to start the install, enter your serial number, agree to it's terms and it should finish up on it's own.   It will install your new LCDS files in a folder called Adobe, but it puts that folder at the root of your filesystem.   To find it just click on your hard drive icon in finder and you'll see it there at the very top level.

Well now you've installed it, now what?   Well now you need to "deploy" it to your jboss folder.   Remember before when I said I have no idea what I'm doing?   Yeah well here we are.   What you need to do is copy the .war files that are in your new Adobe/LiveCycle Data Services ES 2.5 folder to your JBOSS deploy folder.   As I found out JBOSS has several folders where it goes to run java applications with the default one being called... well default.   You can find this folder under your root JBOSS folder:

JBOSS FOLDER
|
|---Server|
                  |--default|
                                    |--deploy

If you put those .war files in that folder and then start up your server you can then go to &lt;a href="http://localhost:8080/lcds-samples/"&gt;http://localhost:8080/lcds-samples/&lt;/a&gt; and you should see the LCDS samples page.   At this point you can look at the samples but they don't work.   That's because they're trying to connect to the sample database that comes with LCDS, and we haven't started it up yet.

It wasn't really clearly explained to me that the sample database was actually a sample database server that you need to run but it is, and you'll find docs telling you it's no where close to being the kind of thing you'd want to base a product on but it works.   Anyway just open up another terminal window or tab and go back to the Adobe/LiveCycle Data Services ES 2.5 directory.   Under here you'll find a directory called sampledb, and inside sampledb is a script called startdb.sh.   That's what you're looking for, just start that with a ./startdb.sh, then restart your jboss server.   Now you should be able to go to &lt;a href="http://localhost:8080/lcds-samples/"&gt;http://localhost:8080/lcds-samples/&lt;/a&gt; and all the samples should be working for you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8299669941450299948-2509469979079937306?l=somehardwareguy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://somehardwareguy.blogspot.com/feeds/2509469979079937306/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://somehardwareguy.blogspot.com/2009/03/part-two-getting-lcds.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/2509469979079937306'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/2509469979079937306'/><link rel='alternate' type='text/html' href='http://somehardwareguy.blogspot.com/2009/03/part-two-getting-lcds.html' title='Part Two Getting LCDS'/><author><name>Some Hardware Guy</name><uri>http://www.blogger.com/profile/17462828792887566460</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8299669941450299948.post-8611200373641555810</id><published>2009-03-14T07:50:00.000-07:00</published><updated>2009-03-14T08:04:11.111-07:00</updated><title type='text'>Part One Installing JBOSS</title><content type='html'>Well the very first thing I did was read through the docs on LCDS on Adobe's website.   That convinced me that I needed a JBOSS server if this was going to work.   Now later I found that's not entirely true, but I'm not sad that I did it since eventually I want this  application to be able to server thousands of people.    The next thing I did was to install JBOSS on my UBUNTU server, but that's another story.

Before we start you should realize I have absolutely no idea what I'm doing.   I can't remember when the last time I wrote JAVA was.   Heck I didn't even know what JBOSS was two days ago, and I only vaguely remembered the idea of what a JAVA applications server was.   Why let that stop us though?

The first step is to go out and get JBOSS for your mac.   At the time I'm writing this you can find it here &lt;a href="http://www.jboss.org/jbossas/downloads/"&gt;http://www.jboss.org/jbossas/downloads/&lt;/a&gt;.  It's pretty easy, you just download it, let stuffit automatically decompress it and you've got JBOSS.   In fact I'm so lazy I'm still running it out of my Download folder.   

So this is great now you have jboss but how the heck do you run it?   Well in your new jboss directory (mines jboss-4.2.2.GA) there are a lot of directories.   The one you're looking for is the "bin" directory.   Inside the bin directory are several scripts, and if you just run the run.sh file, your new jboss server will begin to start up.   Just do a "./run.sh".   You should now see a bunch of console output from the server and at the very end it will say something like:

"19:12:57,095 INFO  [Server] JBoss (MX MicroKernel) [4.2.2.GA (build: SVNTag=JBoss_4_2_2_GA date=200710221139)] Started in 21s:313ms"   

That means you're good to go.   Now open up your favorite browser and go to http://localhost:8080 and you should see the JBoss welcome page.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8299669941450299948-8611200373641555810?l=somehardwareguy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://somehardwareguy.blogspot.com/feeds/8611200373641555810/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://somehardwareguy.blogspot.com/2009/03/part-one-getting-lcds-and-installing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/8611200373641555810'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/8611200373641555810'/><link rel='alternate' type='text/html' href='http://somehardwareguy.blogspot.com/2009/03/part-one-getting-lcds-and-installing.html' title='Part One Installing JBOSS'/><author><name>Some Hardware Guy</name><uri>http://www.blogger.com/profile/17462828792887566460</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8299669941450299948.post-6848051571552607430</id><published>2009-03-14T07:33:00.000-07:00</published><updated>2009-03-14T07:48:56.975-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='flex builder'/><category scheme='http://www.blogger.com/atom/ns#' term='adobe live cycle data services'/><category scheme='http://www.blogger.com/atom/ns#' term='os x'/><category scheme='http://www.blogger.com/atom/ns#' term='lcds'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>Installing Adobe Live Cycle Data Services, with JBOSS, and getting an example to work in FlexBuilder All while on a MAC  Introduction</title><content type='html'>Ok, first the disclaimer.   I'm a hardware engineer, I shouldn't be writing code to begin with, but I do on the side.   Now if you're like me whenever you're trying to learn something new it's a mixture of trying, and googling, lots of googling.    So I decided that after years of leaching off of others posts and instructions that I'd start writing down what worked for me.   At worst it's just a record for me, at best maybe it helps someone.

I'd been learning to write AIR applications using Adobe's Flex Builder and I was just at the point where I wanted to store things in my Mysql database on my server.   My first instinct was to just write some PHP code and call it from the air app, but I wanted more than that.  I wanted everything to work while I was offline too, and thats when I came across Adobe Live Cycle Data Services.

I even found some great sample code out there that should run in flex buiilder.   So I embarked on a journey to get this all installed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8299669941450299948-6848051571552607430?l=somehardwareguy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://somehardwareguy.blogspot.com/feeds/6848051571552607430/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://somehardwareguy.blogspot.com/2009/03/installing-adobe-live-cycle-data.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/6848051571552607430'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8299669941450299948/posts/default/6848051571552607430'/><link rel='alternate' type='text/html' href='http://somehardwareguy.blogspot.com/2009/03/installing-adobe-live-cycle-data.html' title='Installing Adobe Live Cycle Data Services, with JBOSS, and getting an example to work in FlexBuilder All while on a MAC  Introduction'/><author><name>Some Hardware Guy</name><uri>http://www.blogger.com/profile/17462828792887566460</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
