C++ Automation Example

From SysCAD Documentation
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

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();
 }

//================================================================================