C++ Automation Example
Jump to navigation
Jump to search
Navigation: User Guide ➔ COM Automation ➔ C++ Automation
Command Scripts | COM Automation | Python Automation | VBA Automation | C++ Automation | Testing if SysCAD is open |
---|
Below is a C++ source code that can be compiled to a console application. The example is similar to the Excel VBA Automation example.
Example
// SysCAD93Console.cpp : This file contains the 'main' function. Program execution begins and ends there.
#include <atlbase.h>
#include <atlconv.h>
#include <iostream>
#include <string>
#import "ScdSlv93.tlb"
#import "SysCAD93.tlb" named_guids
void UsualExample()
{
HRESULT hRes;
SysCAD93::IScdApplicationPtr pSysCAD = nullptr;
SysCAD93::IScdProjectPtr pPrj = nullptr;
SysCAD93::IScdAppTagsPtr pTags = nullptr;
SysCADSolver93::IScdSolverPtr pSlv = nullptr;
SysCADSolver93::IScdProbalPtr pProBal = nullptr;
//== Set the project name to be loaded..
_bstr_t bstrScenarionPath = L"c:\\SysCAD139\\Examples\\40 Nickel\\Demo Nickel Copper Project.spf\\";
_bstr_t bstrScenarionProject = bstrScenarionPath + L"project.spj";
//== TODO: Test if the project file exists
try
{
//== Start SysCAD..
std::cout << "Start SysCAD\n";
hRes = pSysCAD.CreateInstance(SysCAD93::CLSID_ScdApplication);
if (hRes!=S_OK)
{
std::cout << "Start SysCAD failed. (Run RegAll or ???)\n";
return;
}
//== Get the version number
std::string VersionStr;
const long BuildMajor = pSysCAD->VersionNumber[2];
const long BuildMinor = pSysCAD->VersionNumber[3];
VersionStr = "SysCAD " + std::to_string(pSysCAD->VersionNumber[0]) + "." + std::to_string(pSysCAD->VersionNumber[1])
+ " Build " + std::to_string(BuildMajor) + "." + std::to_string(BuildMinor);
std::cout << "Started " << VersionStr << "\n";
//== Test Build number, and Exit if Build number is less than required Build
const long RequiredBuildMajor = 139;
const long RequiredBuildMinor = 30498;
if (BuildMajor < RequiredBuildMajor || RequiredBuildMinor < RequiredBuildMinor)
{
std::cout << "Version " << VersionStr << "is too old. Require Build " << std::to_string(RequiredBuildMajor) << "." << std::to_string(RequiredBuildMinor) << " or newer!\n";
pSysCAD.Release(); //Close SysCAD
return;
}
//== TODO: Test if a valid steady state license is available. If not Exit.
//== Open the project..
std::cout << "Open project\n";
pPrj = pSysCAD->OpenProject(bstrScenarionProject);
if (pPrj)
{
//== Get a reference to the objects of interest..
pTags = pPrj->GetTags();
pSlv = pPrj->GetSolver();
pProBal = pSlv->GetProbal();
//== Example of setting a tag in SysCAD..
//std::cout << "Set a Tag (PlantModel.EqpDesc)\n";
pTags->put_TagValue(_bstr_t("PlantModel.EqpDesc"), _variant_t(L"Test"));
//== Example of retrieving a tag from SysCAD..
//std::cout << "Get a Tag (PlantModel.System.Version)\n";
_variant_t VersionDesc;
pTags->get_TagValue(_bstr_t("PlantModel.System.Version"), &VersionDesc);
std::cout << "PlantModel.System.Version = " << (_bstr_t)VersionDesc << "\n";
//----------------------------------------------------------
//== Next section of code starts the ProBal solver and then loops waiting
// for the model to converge. The use of Sleep is important because this
// gives CPU access to other applications (i.e. SysCAD).
const long MaxLoop = 5000; //maximum number of loops before giving up
//== Start the ProBal solver..
std::cout << "Start Solver\n";
pProBal->Start();
Sleep(500); //give SysCAD a chance to get started
std::cout << "Busy Solving";
long i;
for (i = 1; i<MaxLoop; i++)
{
std::cout << ".";
//== Wait for 1 second before checking if solved
Sleep(1000); //"sleep" for one second ( 1000 milliseconds )
//== Check if solver has stopped..
if (pProBal->IsStopped)
{
break; //ProBal solver has stopped, exit the loop
}
}
std::cout << "\n";
//== Retrieve the number of iterations to solve
_variant_t Val;
pTags->get_TagValue(_bstr_t("PlantModel.Stats.Iterations"), &Val);
const long Iter = Val;
if (i==MaxLoop)
{
//We did not manage to solve within MaxLoop iterations
//Bomb out and let user know
std::cout << "Stop ProBal solver after " << std::to_string(Iter) << " iterations.\n";
pProBal->Stop();
}
else
{
//Model solved and stopped correctly
//== Retrieve the solve time and display as a message
pTags->get_TagValue(_bstr_t("PlantModel.Stats.SolveTimeDesc"), &Val);
std::cout << "ProBal solve iterations:" << std::to_string(Iter) << " SolveTime:" << (_bstr_t)Val << "\n";
}
//== Save Scenario
std::cout << "Save Scenario\n";
pPrj->SaveScenario("Case001");
//== Close the SysCAD project without saving the changes
std::cout << "Close Project\n";
pSysCAD->CloseProject(VARIANT_FALSE);
//== To ensure that SysCAD exits correctly, ensure ALL referenced objects are released..
pProBal.Release();
pTags.Release();
pSlv.Release();
pPrj.Release();
}
else
{
std::cout << "Open project Failed!\n";
}
std::cout << "Release Final\n";
if (pSysCAD)
pSysCAD.Release();
}
catch (...)
{
// Manually release all interfaces
pProBal.Release();
pTags.Release();
pSlv.Release();
pPrj.Release();
std::cout << "Release Final\n";
if (pSysCAD)
pSysCAD.Release();
}
}
//================================================================================
//================================================================================
int main()
{
std::cout << "testing SysCAD 9.3 COM Automation...\n";
CoInitialize(nullptr);
UsualExample();
std::cout << "Done\n";
CoUninitialize();
}
//================================================================================