Grab Custom Controls on forms

I was wondering if anyone knows of an easy way to search for forms that use the generic columns(Character01, CheckBox01, Date01, Number01, ShortChar01). I tried Inspect.exe, spy++and other UI test tools but I cannot find the label or the fields with these names.

I queried the DB to determine what generic fields are being used in tables and I have a list. So instead of looking in the field help technical details for every control I was hoping there is an easy way to query the DB for this information. I am trying to document what was being used in E9 so I can replicate in E10.

Thanks for any help

1 Like

Very interesting. :thinking:

You can find the customization binary data stored on XXXChunk, inside Chunk column.

Problem is that the Chunk is BZiped and Hex Encoded…
poking around this will turn the “Chunk” data back into a string… You’ll need
NetSword.Common.ICSharpCode.SharpZipLib (nuget)

private string decompressString(string data)
{
    try
    {
        int num;
        MemoryStream stream = new MemoryStream(Convert.FromBase64String(data));
        BZip2InputStream stream2 = new BZip2InputStream(stream);
        byte[] buffer = new byte[0x3e8];
        MemoryStream stream3 = new MemoryStream();
        while ((num = stream2.Read(buffer, 0, 0x3e8)) > 0)
        {
            stream3.Write(buffer, 0, num);
        }
        stream2.Close();
        stream.Close();
        byte[] bytes = stream3.ToArray();
        stream3.Close();
        return Encoding.UTF8.GetString(bytes);
    }
    catch
    {
        return data;
    }
}

So if you want to do this you can BO GenXData
run GetRows where typecode=“Customization”
This will get you all the customizations in the system, then loop through all the XXXChunkRows and run the XXXChuck through that decompression aglorithm. Then use RegEx or another method to see if “CharacterXX, ShortCharXX, NumberXX, appear in the string”

It will turn this

 string myChunk= decompressString("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");

Into this

<CustomizationDS xmlns="http://tempuri.org/XMLSchema.xsd">
  <xs:schema id="CustomizationDS" targetNamespace="http://tempuri.org/XMLSchema.xsd" xmlns:mstns="http://tempuri.org/XMLSchema.xsd" xmlns="http://tempuri.org/XMLSchema.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:msprop="urn:schemas-microsoft-com:xml-msprop" attributeFormDefault="qualified" elementFormDefault="qualified">
    <xs:element name="CustomizationDS" msdata:IsDataSet="true" msdata:Locale="" msprop:BuildVersion="9.05.702A">
      <xs:complexType>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element name="Controls">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="FormsID" type="xs:string" />
                <xs:element name="ControlName" type="xs:string" />
                <xs:element name="Key" type="xs:string" />
                <xs:element name="ParentControlKey" type="xs:string" />
                <xs:element name="ControlType" type="xs:string" />
                <xs:element name="Company" type="xs:string" />
                <xs:element name="Plant" type="xs:string" />
                <xs:element name="DcdUserId" type="xs:string" />
                <xs:element name="GroupID" type="xs:string" />
                <xs:element name="ControlsID" type="xs:string" />
              </xs:sequence>
            </xs:complexType>
          </xs:element>
          <xs:element name="Properties">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="FormsID" type="xs:string" />
                <xs:element name="ControlName" type="xs:string" />
                <xs:element name="Key" type="xs:string" />
                <xs:element name="PropertyName" type="xs:string" />
                <xs:element name="PropertyValue" type="xs:string" />
                <xs:element name="Company" type="xs:string" />
                <xs:element name="Plant" type="xs:string" />
                <xs:element name="DcdUserID" type="xs:string" />
                <xs:element name="GroupID" type="xs:string" />
                <xs:element name="PropertiesID" type="xs:string" />
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:choice>
      </xs:complexType>
    </xs:element>
  </xs:schema>
  <Controls>
    <FormsID>BAQReportForm</FormsID>
    <ControlName>epicor.mfg.bo.transferorderentry.dll</ControlName>
    <Key>EpiString.ExecutionPath*epicor.mfg.bo.transferorderentry.dll</Key>
    <ParentControlKey />
    <ControlType>AssemblyReference</ControlType>
    <Company />
    <Plant />
    <DcdUserId />
    <GroupID />
    <ControlsID />
  </Controls>
  <Controls>
    <FormsID>BAQReportForm</FormsID>
    <ControlName>epicor.mfg.if.itransferorderentry.dll</ControlName>
    <Key>EpiString.ExecutionPath*epicor.mfg.if.itransferorderentry.dll</Key>
    <ParentControlKey />
    <ControlType>AssemblyReference</ControlType>
    <Company />
    <Plant />
    <DcdUserId />
    <GroupID />
    <ControlsID />
  </Controls>
  <Controls>
    <FormsID>BAQReportForm</FormsID>
    <ControlName>epicor.mfg.ad.transferorderentry.dll</ControlName>
    <Key>EpiString.ExecutionPath*epicor.mfg.ad.transferorderentry.dll</Key>
    <ParentControlKey />
    <ControlType>AssemblyReference</ControlType>
    <Company />
    <Plant />
    <DcdUserId />
    <GroupID />
    <ControlsID />
  </Controls>
  <Properties>
    <FormsID>filterListPanel1</FormsID>
    <ControlName>grdFilterList</ControlName>
    <Key>3c83f81e-470d-4ade-9646-152b68de99f2-1</Key>
    <PropertyName>ChildIndex</PropertyName>
    <PropertyValue>0</PropertyValue>
    <Company />
    <Plant />
    <DcdUserID />
    <GroupID />
    <PropertiesID />
  </Properties>
  <Properties>
    <FormsID>BAQReportForm</FormsID>
    <ControlName>Customization</ControlName>
    <Key>2dcd1674-5e34-4d98-b493-c75747027376</Key>
    <PropertyName>Script</PropertyName>
    <PropertyValue>// **************************************************
// Custom code for BAQReportForm
// Created: 4/9/2015 1:45:56 PM
// **************************************************
using System;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Windows.Forms;
using Epicor.Mfg.Core;
using Epicor.Mfg.UI;
using Epicor.Mfg.UI.Adapters;
using Epicor.Mfg.UI.Customization;
using Epicor.Mfg.UI.ExtendedProps;
using Epicor.Mfg.UI.FormFunctions;
using Epicor.Mfg.UI.FrameWork;
using Epicor.Mfg.UI.Searches;

public class Script
{
	// ** Wizard Insert Location - Do Not Remove 'Begin/End Wizard Added Module Level Variables' Comments! **
	// Begin Wizard Added Module Level Variables **

	// End Wizard Added Module Level Variables **

	// Add Custom Module Level Variables Here **

	public void InitializeCustomCode()
	{
		// ** Wizard Insert Location - Do not delete 'Begin/End Wizard Added Variable Initialization' lines **
		// Begin Wizard Added Variable Initialization

		// End Wizard Added Variable Initialization

		// Begin Wizard Added Custom Method Calls

		// End Wizard Added Custom Method Calls
	}

	public void DestroyCustomCode()
	{
		// ** Wizard Insert Location - Do not delete 'Begin/End Wizard Added Object Disposal' lines **
		// Begin Wizard Added Object Disposal

		// End Wizard Added Object Disposal

		// Begin Custom Code Disposal

		// End Custom Code Disposal
	}

	private void BAQReportForm_Load(object sender, EventArgs args)
	{
		string orderList = BAQReportForm.LaunchFormOptions.ValueIn.ToString();

		//data view for the order list
		EpiDataView orderListDV = (EpiDataView)(this.oTrans.EpiDataViews["FilterList1"]);

		//have to parse the orderList string to get the values 
		if(!orderList.Contains("~")) {
			//add a row
			orderListDV.dataView.Table.Rows.Add();
			//set the default row value for the dataview
			orderListDV.Row = 0;
			//set the value order list value in the table if there's only one
			orderListDV.dataView.Table.Rows[0]["TFOrdNum"] = orderList;
		}
		//if there are multiple order numbers in the order list
		else if(orderList.Contains("~")) {
			//put the order numbers into a string array
			string[] orderNums = orderList.Split('~');
			
			//loop through the string array and set each value on the grid
			for(int i = 0; i &lt; orderNums.Length; i++) {	
				//add a row
				orderListDV.dataView.Table.Rows.Add();		
				//set the default row value for the dataview
				orderListDV.Row = i;	
				//set the order number value
				orderListDV.dataView.Table.Rows[i]["TFOrdNum"] = orderNums[i];
				
			}
		}
	}
}
</PropertyValue>
    <Company />
    <Plant />
    <DcdUserID />
    <GroupID />
    <PropertiesID />
  </Properties>
  <Properties>
    <FormsID>BAQReportForm</FormsID>
    <ControlName>Customization</ControlName>
    <Key>2dcd1674-5e34-4d98-b493-c75747027376</Key>
    <PropertyName>Language</PropertyName>
    <PropertyValue>CSharp</PropertyValue>
    <Company />
    <Plant />
    <DcdUserID />
    <GroupID />
    <PropertiesID />
  </Properties>
</CustomizationDS>
10 Likes

That worked great,

Thanks you just saved me a whole lot of time and headaches

:slight_smile:

This is a cool thread. Does any of this apply to e10?

Yes @Chris_Conn all of it applies to e10

Jose C Gomez
Senior Software Engineer

1 Like

I have to say that is a really great question, and excellent answer. Thanks for the contribution.

3 Likes