Forum Discussion

John_Laird's avatar
8 years ago

how to best manage large numbers of controls that you have to set?

At my organization I use TestComplete Python scripts to automate setting large numbers nested of controls (check boxes, textboxes, drop down combo boxes, etc) in Windows Forms. In one case there is up to 1800 controls on a single page. Usually there is a combination of drop down boxes and tabs that make the controls visible or not and let the user have a sane experience.


My question is, how do other people at other organizations manage large numbers of control and map out settings like in that scenario where there are over a 1000 settings on a form and a dozen or more forms?


After a lot of experimentation, my solution is below...what are other peoples? It works but it isn't perfect.


I make a function that maps every setting for a given form. This function takes the new settings to use and the name of the object it works on as arguments. Then I re-use the same function (I call it) to test different test cases with different objects of the same type.


One tab on such a simple form looks like this (some of it obfuscated):


















I have this code to map the settings for this one tab (again some of it obfuscated):

def mapBlah(objname, propvalueDict):
  propfuncBlahTabDict = {
    'RBE Init Message' : {'func' : setCheckBox, 'formprop' : "Prop_blah1", 'tab': "RBE"},
    'RBE Poll Interval' : {'func' : setComboBox, 'formprop' : "Prop_blah2", 'tab': "RBE"},
    'RBE Poll Priority' : {'func' : setComboBox, 'formprop' : "Prop_blah3", 'tab': "RBE"},
    'Primary RBE Scan Rate' : {'func' : setTextBox, 'formprop' : "Prop_blah4", 'tab': "RBE", 'navfunc' : [clickConfigSubTab], 'navfuncargs' : [["Primary", Aliases.blatApp.blahTab.WinFormsObject("tabPage7").WinFormsObject("tabPriSec")]]},
    'Primary RBE Scan Slice' : {'func' : setTextBox, 'formprop' : "Prop_blah5", 'tab': "RBE", 'navfunc' : [clickConfigSubTab], 'navfuncargs' : [["Primary", Aliases.blatApp.blahTab.WinFormsObject("tabPage7").WinFormsObject("tabPriSec")]]},
    'Primary RBE Timeout' : {'func' : setTextBox, 'formprop' : "Prop_blah6", 'tab': "RBE", 'navfunc' : [clickConfigSubTab], 'navfuncargs' : [["Primary", Aliases.blatApp.blahTab.WinFormsObject("tabPage7").WinFormsObject("tabPriSec")]]},
    'Secondary RBE Scan Rate' : {'func' : setTextBox, 'formprop' : "Prop_blah7", 'tab': "RBE", 'navfunc' : [clickConfigSubTab], 'navfuncargs' : [["Secondary", Aliases.blatApp.blahTab1.WinFormsObject("tabPage7").WinFormsObject("tabPriSec")]]},
    'Secondary RBE Scan Slice' : {'func' : setTextBox, 'formprop' : "Prop_blah8", 'tab': "RBE", 'navfunc' : [clickConfigSubTab], 'navfuncargs' : [["Secondary", Aliases.blatApp.blahTab.WinFormsObject("tabPage7").WinFormsObject("tabPriSec")]]},
    'Secondary RBE Timeout' : {'func' : setTextBox, 'formprop' : "Prop_blah9", 'tab': "RBE", 'navfunc' : [clickConfigSubTab], 'navfuncargs' : [["Secondary", Aliases.blatApp.blahTab.WinFormsObject("tabPage7").WinFormsObject("tabPriSec")]]},
  for propname in propvalueDict.keys():
    if  propfuncBlahTabDict[propname]['tab'] == "RBE":
      if 'navfunc' in propfuncBlahTabDict[propname]:
        executeNavFuncs(propfuncBlahTabDict[propname]['navfunc'], propfuncBlahTabDict[propname]['navfuncargs'])
      propfuncBlahTabDict[propname]['func'](propfuncBlahTabDict[propname]['formprop'], propvalueDict[propname])

def executeNavFuncs(navfuncValue, navfunargsValue):
  navfunargsIndex = 0
  for func in navfuncValue:
    navfunargsIndex = navfunargsIndex + 1

And then use this to set them:

def mapBlahDriver():
  propvalueDict =  collections.OrderedDict()
  propvalueDict["RBE Init Message"] = cbChecked
  propvalueDict["Primary RBE Scan Rate"] = 6
  propvalueDict["Secondary RBE Scan Rate"] = 7
  mapBlah("blahobject", propvalueDict)

So...what does everyone else do? Guidance?

3 Replies

  • Manfred_F's avatar
    Regular Contributor

    I've got the same Situation: table views with 20 lines à 45 data fields.

    My solution is not to use Aliases for each control. I just use one single Alias to identify the Dialog.

    The rest is done by my libraries (as You do it in Your example, too), which provide means to Access each control via caption/hierarchical location/value.

    An additional Advantage is, that my Alias processing allows me to handle multiple instances of the same Dialog, which is not possible with Standard alias usage.

    • John_Laird's avatar

      Yeah I only use a fixed alias for navigating through sub tabs or manipulating the UI in order to get the desired control on-screen. Kind of got lazy there. For setting the controls (example SetTextBox) my code looks like this...



      def setTextBox(tbRef, newValue, altref=None):
        rootref = Aliases.ACMConfig.frmMain.panelControl1.superTabControl1.suptabConfiguration.userControlConfiguration1.toolStripContainer2.ToolStripContentPanel.tabObjects.acmObjectView
        if altref == None:
          tbhandle = rootref.FindChild("WinFormsControlName", tbRef, 2000)
          tbhandle = altref.FindChild("WinFormsControlName", tbRef, 2000)
        bsList = ["[BS]"] * len(tbhandle.wText)
        tbhandle.Keys("[End]%s" % "".join(bsList))

      If the control (the name is specified in the value for the 'formprop' key)  happens to be a child of rootref alias then I don't pass in 'altref', if it is not, the I pass in a alias that I can search into. Its the only way I could do it without the code turning into a giant mushroom cloud. :)


      • Manfred_F's avatar
        Regular Contributor

        a code example from my side, "simple code":


        Set myDlg = PVA_0.DialogClassJs.WrpCNew().OpenByMenu("Einrichten", "BDE-Recorder", Aliases.pva.x_MainWin.x_BdeTblEinr)
        '  box having caption 'Name'
        Set myCtrl = myDlg.Frame()("Name")
        ' read
        myTxt = myCtrl.Text



        Another code example using ODT (in ODT, I define data definitions and Dialog Definitions):


        ' use Dialog Definition mTdP2(mcStdDlgIx) to open dialog
        Set BdeStdDlg = mTdP2(mcStdDlgIx).DialogOpenByButton(myRow("Bde"))
        ' use data Definition Td(1) to set the value defined there into the field also defined there, just Hand in the Frame as a context
        Td(1).SetValue BdeStdDlg.Frame()