by Ed Merriman
| February 28, 2017
In my previous blog, I discussed the newly available in TP2016.0 (16.0.6187.2) API feature of calibration. Now reliable and repeatable calibrations can be set up through the TruePlanning API easily and quickly. For most users the standard calibration usage will be all they need. That said, there are some users who would like to use a feature that is available the TruePlanning Calibration GUI: the ability to calibrate multiple inputs in one calibration.
The most common reason to use a constant in a calibration is to find a single value, such as Organizational Productivity, across multiple Cost Objects that yields a specific value on a parent Cost Objects like an Assembly. Organizational Productivity is a prime target for this because it is an input that reflects the nature of an organization’s ability to produce software and should be consistent across Software Component under the same Assembly.
In the TruePlanning Calibration GUI this is accomplished by selecting a constant instead of a specific input for a Cost Object. When a constant is chosen and the calibration is run, the constant is updated with a new value with each iteration of the calibration, and this value is then set on all inputs that are linked to the constant. In the TruePlanning Calibration GUI the constant must already exist and be assigned for it to be used.
In the TruePlanning API, the Constant object supports the ability to select a constant at the input value instead of a specific Input object. Where it really gets interesting is that the API also supports the creation and assignment of constants as well, so a new project can be created, a constant can be created in that project, and that constant can be assigned to inputs, and then used in a calibration… all through the API.
Below is a sample VBA Macro subroutine that shows how to work with constants and calibrations. It performs the following steps:
Public Sub Calib_NewConst_TestSub()
Dim app As TruePlanningApi_16_0.Application
Set app = New TruePlanningApi_16_0.Application
Dim p As TruePlanningApi_16_0.Project
Set p = app.OpenProject("c:\a\testProject.tpprj")
' create new constant
Dim newConst As TruePlanningApi_16_0.Constant
Set newConst = p.Constants.New("NewTestConst")
newConst.Value = 2
'' Because the "SetLink" method will eventually accept different types of objects
'' the value passed into needs to be a Variant
'' so we will put the constant object we just create into a Variant object here
'' if you try to use the Constant object in the "SetLink" call Excel will explode
Dim constV As Variant
Set constV = newConst
Dim targetCOName As String
targetCOName = "SoftwareAssembly"
Dim targetAsmCO As TruePlanningApi_16_0.CostObject
Dim targetOutputPath As String
Dim parentLevel As Long
Dim stillLooking As Boolean
stillLooking = False
Dim co As TruePlanningApi_16_0.CostObject
For Each co In p.CostObjects
If ((stillLooking = True) And (co.Level <= parentLevel)) Then
stillLooking = False 'hit a sibling or parent of the target assembly
If (co.Name = targetCOName) Then
' in this example, we are targeting the same CO for the input and the output value, but the output value could belong to any CO in the PBS,
' just remember to make sure the input you are altering impacts the selected output Cost Object
targetOutputPath = co.Path
stillLooking = True
parentLevel = co.Level
If ((stillLooking = True) And (co.Level > parentLevel)) Then
' set constant for input on children
If (co.Definition.InternalName = "Software Component") Then
Dim targetInput As TruePlanningApi_16_0.Input
Set targetInput = co.Inputs.ItemByName("Organizational Productivity")
'' NOTE: use the Varaint with the Constant object in "SetLink"
Call targetInput.SetLink(LinkTypeConstant, constV)
Dim cTest As TruePlanningApi_16_0.Calibration
Set cTest = p.Calibrations.New("COne")
'cTest.Input = tInput
targetOutputPath = targetOutputPath & "::Labor Requirement"
cTest.CostObjectOutput = targetOutputPath
cTest.Tolerance = 1 ' this is a % value 1 = 1%, 10 = 10%
cTest.MaxIterations = 100
' Initial Adapted Size: 6821
' Initial Labor Requirement: 61.5
Dim ws As Worksheet
Set ws = ActiveWorkbook.Worksheets("Sheet1")
Dim startTargetLaborReqForCSCI As Long
startTargetLaborReqForCSCI = 9000
Dim cnt As Long
cnt = 2
Dim laborRateScale As Long
For laborRateScale = 0 To 10
Dim lr As Double
lr = startTargetLaborReqForCSCI + (laborRateScale * 100)
cTest.Target = lr
ws.Cells(cnt, 1).Value = cTest.InputName
ws.Cells(cnt, 2).Value = cTest.CalibratedInput
ws.Cells(cnt, 3).Value = cTest.OutputName
ws.Cells(cnt, 4).Value = cTest.OutputAnswer
ws.Cells(cnt, 5).Value = cTest.Target
ws.Cells(cnt, 6).Value = cTest.LastIteration
ws.Cells(cnt, 7).Value = cTest.Tolerance
ws.Cells(cnt, 8).Value = cTest.MaxIterations
ws.Cells(cnt, 9).Value = targetOutputPath
cnt = cnt + 1
cnt = 1
ws.Cells(cnt, 1).Value = "Constant name: cTest.InputName"
ws.Cells(cnt, 2).Value = "Calbiration input result: cTest.CalibratedInput"
ws.Cells(cnt, 3).Value = "Ouput Name: cTest.OutputName"
ws.Cells(cnt, 4).Value = "Output results within Tolerance: cTest.OutputAnswer"
ws.Cells(cnt, 5).Value = "Taret value of output: cTest.Target"
ws.Cells(cnt, 6).Value = "Number Iterations: cTest.LastIteration"
ws.Cells(cnt, 7).Value = "Tolernce used: cTest.Tolerance"
ws.Cells(cnt, 8).Value = "Max Iterations: cTest.MaxIterations"
ws.Cells(cnt, 9).Value = "Target output path: targetOutputPath"
Set p = Nothing
Set app = Nothing
Examination of the resulting saved TruePlanning project will show the creation of a new constant and its linking to multiple Cost Objects. A working copy of the above code is available upon request.
Please feel free to contact PRICE if you have any questions about this feature, TruePlanning, TrueMapper, or any other PRICE products and services.