This example shows one simple use LabPP_Automat. It is in the distribution.
Enough to experiment a bit with this example to get an idea about the flexibility and functionality automation.
Text files software scripts allow you to make changes and completely change everything You see.
In the catalog tsprglist You can create a close copy of the directory "Landscape design with price" and give it its own name.
And then immediately begin to create their own automation system on the basis of its own new configuration. To create a button, the programs, ask the panel LabPP_Automat, etc.
Configurations can be any number.

Parsing example.

1. Directory structure and Configuration.
2. Button "Open file Excel".
3. Help button.
4. Export button from ARCHICAD to EXCEL.
5. Import button from EXCEL to ARCHICAD.
6. Find row in EXCEL by selected object in ARCHICAD.
7. Find and select objects in ARCHICAD by current row in EXCEL.

Directory structure and Configuration

LabPP_Automat starts with the selected configuration. Configuration is a directory with a set of scripts and other files which forms the appearance and functionality additions in a particular case.
When entering the menu ARCHICAD "LabPP_Automat show/hide palette" the program analyzes the directory tsprglist.
There are all configurations LabPP_Automat.
Each configuration is a separate directory.

Calculations in ARCHICAD with LabPP_Automat
The name of the configuration directory is displayed in the list selection dialog box configuration (see figure).
Configuration directories have the same structure.
So the configuration of this example contains the subdirectories tsimages и tsprg:

"Landscape Design with Prices"
- tsimages
- tsprg

On the directory "Landscape Design with Prices" are placed example file: Price.xlsx (open on Excel) and Example.pln (file ARCHICAD).
File Example.pln contains object from library LabPP_Landscape. That objects you can download from www.labpp.ru with LabPP_Landscape distributive.
Directory tsimages contains images and icons.
In configuration selection panel near of configurations names the icon tsimages\1.png is displayed.
Files Excel_from.png, Excel_to.png and others are used as button icons.
Catalog tsprg contains programm scripts.
Scripts a placed in files with extention *.cpp. Somtimes, if needed to use part of the code in two or more files, that part of code placed to included file with extention *.h.
And in files, that used it part you can write directive #include "myfile.h"
In this example we use only files *.cpp for simplicity.
When we do selection configuration from the list, file tsprg\config.cpp is running.
Here are its content:

//****************************************************
int main()

{
    int iret;

    int w = 40;
    int sx = 1;
    int offsetx = 1;
    int offsety = 1;
    int iPos=0;
    int sy = 1;
    int h = 40;

    ac_request("create_iconbutton","excel_to.png",sx,sy,sx+w,sy+h,"Export to Excel the only object of each type to be able to set prices","ac_to_excel_1.cpp");
    sx = sx + w + offsetx;
    ac_request("create_iconbutton","excel_from.png",sx,sy,sx+w,sy+h,"Load prices and articules into ARCHICAD","excel_to_ac_1.cpp");
    sx = sx + w + offsetx;
    ac_request("create_iconbutton","select.png",sx,sy,sx+w,sy+h,"Load prices and articules into ARCHICAD","ac_select_pos_excel_1.cpp");
    sx = sx + w + offsetx;
    ac_request("create_iconbutton","selectexcel.png",sx,sy,sx+w,sy+h,"Select objects in ARCHICAD by current EXCEL position","ac_select_excel_by_ac_1.cpp");
    sx = sx + w + offsetx;
    ac_request("create_iconbutton","CALC_H256.png",sx,sy,sx+w,sy+h,"Help","help.cpp");

    sy = sy + h + offsety;
    sx = 1;
    ac_request("set_palette_size_and_message_place",80,100,405,300,sx,sy,326-sx*2,200-sy);
}
//****************************************************

All files *.cpp contains construction:

int main()
{
}

In is main function.

Between curly brace placed execution code.
After // placed a comments. And between /* and */ placed comments too.

/* this in a comment 
for many rows*/

Function ac_request() allows do operations with ARCHICAD.
First argument in this function is a command. In ower case, this command is "create_iconbutton" - mean create button with icon.

    ac_request("create_iconbutton","excel_to.png",sx,sy,sx+w,sy+h,"Export to Excel the only object of each type to be able to set prices","ac_to_excel_1.cpp");

Next argument - name of the file with picture for icon. File gives from catalog tsimages of the current configuration.
Next 4 numbering arguments - specify coordinates of button in window: left, top, width, height in pixels.
Next text argument - comment, that well be whowed when mouse fly above button.
And last argument -- file name of the programm script, that will be executed on button will be pressed.

In this case this program file is - tsprg\ac_to_excel_1.cpp.
Variables sx,sy and so on need to help to arrange position of the buttons and message window on palette LabPP_Automat.
Last function on config script specify sizes of addons palette and placement on palette the message window.

    ac_request("set_palette_size_and_message_place",80,100,405,300,sx,sy,326-sx*2,200-sy);

The result look as this:

Вид окна LabPP_Automat в демонстрационной конфигурации

Button "Open File Excel"

The file placed in the root configuration directory "Landscape design with price".
To quickly open this file we have created a button with the Excel icon.
Clicking this button runs the program "open_excel_file.cpp":

int main()
{
    shell_func("set_cur_dir","rootconfig"); // to make the current root directory for the current configuration
    shell_func("shellexecute","open","Price.xlsx"); // open file "Price.xlsx"
}

Call function shell_func() with directive "set_cur_dir" allows do change current catalogue.
Next string specify full path to catalogue, or code word. In this case "rootconfig" means that we want to go to root catalogue of current configuration (this is "Landscape Design With Prices").
Next call function with directive "shellexecute" and file name call operation system for open this file with default programm assigned to file extension.

Help button

To make it easier to cope with the development of this example, we put it under the button with the question mark file help.cpp
Clicking the button runs the file tsprg\help.cpp:

//****************************************************
int main()

{
    cout << "Demo programm describes\n import/export data between ARCHICAD and EXCEL.\n";
    cout << "Open the file Price.xslx \n(in directory of this configuration).\n";
    cout << "Place in your project any \nobjects from LabPP_Landscape library (download from www.labpp.ru.\n";
    cout << "Select that objects\n";
    cout << "Press first button with arrow ->X \nfor export list of object types to EXCEL.\n";
    cout << "Change articles and prices.\n";
    cout << "Select in ARCHICAD that objects, for whom need to replace data";
    cout << "Press button with arrow X-> for import\n changed data into ARCHICAD.\n";
    cout << "You may select cell with name of the element\n in EXCEL table and press button with square.\n";
    cout << "As result ARCHICAD select \n all object with that object name.";
    cout << "Also You may select object in ARCHICAD\nwhom matches cell in EXCEL\n";

}
//****************************************************

It contains a simple regular expression to display.
The output is displayed in the message window.

    cout << "Demo programm describes\n import/export data between ARCHICAD and EXCEL.\n";

cout << "Hello World!" << variable << "\n";

So you can write to punctuate text messages, variable values, and if we put "\n" then it will move to the next row.

Each statement should be a semicolon.

Export button from ARCHICAD to EXCEL

Before you open the file Price.xlsx.
By pressing this button runs the program from a file ac_to_excel_1.cpp:

//****************************************************
int main()

{
    int res;
    res = excel_attach(); // attach Excel programm
    if(res != 0) {
        cout << "error attach to Excel";
        return -1;
    } else     {
        cout << "ok\n";
    }

    res = excel_request("workbook_select","Price.xlsx");
    if(res!=0) { cout << "Do not opened file Price.xlsx"; return -1;}
    res = excel_request("sheet_select","Plants");
    if(res!=0) { cout << "Can't select page Plants"; return -1;}

    cout << "Exporting." << "\n";

    ac_request("load_elements_list_from_selection",4,"ObjectType","MainFilter",4+2);
    ac_request("get_loaded_elements_list_count",4);
    int iObjectCount = ac_getnumvalue();

    cout << "\nCount of objects = "<< iObjectCount << "\n";

    int TableDescr1;
    object("create","ts_table",TableDescr1);
    ts_table(TableDescr1, "add_column",0,"string","object name");
    ts_table(TableDescr1, "add_column",1,"string","article");
    ts_table(TableDescr1, "add_column",2,"double","price");
    ts_table(TableDescr1, "set_first_key","object name"); // set column as primary key (will not be the same values in it);


    string objectname;
    string articul;
    double price;
    for(int i=0;i<iObjectCount; i++)
    {
        ac_request("set_current_element_from_list",4,itoa(i));
        ac_request("get_object_property_value","LabPP_IGRo_Artikul");
        articul = ac_getstrvalue();
        ac_request("get_object_property_value","ObjectName");
        objectname = ac_getstrvalue();
        ac_request("get_object_property_value","LabPP_IGRo_Cost");
        price = ac_getnumvalue();

        cout << "article=" << articul << " object name=" << objectname << " price="<< price <<"\n";

        ts_table(TableDescr1,"add_row",0,objectname,1,articul,2,price);  // add the line to our table. After the "add_row" lists the column number and value, column number, value, etc. may be out of order, may not be all columns.
    }

The last loop statement - adds a row to the table.
Since we asked the user "set_first_ker" key column in the table is not added to the string, if the object name will match the existing.
Then other field data will be replaced with a new one. In "add_row" you may not have all the speakers.
If instead of "add_row" use manual "add_row_sum", then the values of numeric columns will be added to already existing in that row.
It is very convenient.

Then sort the table on column 0.

    ts_table(TableDescr1,"sort",0);

    cout << "\nPrint the table";

    int rowcount;
    ts_table(TableDescr1,"get_rows_count", rowcount);

    string srange = get_posd("A",1);
    excel_select_range(srange);
    excel_putstrvalue("Object name");
    srange = get_posd("B",1);
    excel_select_range(srange);
    excel_putstrvalue("Article");
    srange = get_posd("C",1);
    excel_select_range(srange);
    excel_putstrvalue("Price");

    for(i=0;i<rowcount;i++)
    {
        ts_table(TableDescr1,"select_row",i);
        ts_table(TableDescr1,"get_value_of",0,objectname);
        ts_table(TableDescr1,"get_value_of",1,articul);
        ts_table(TableDescr1,"get_value_of",2,price);

        srange = get_posd("A",i+2);
        excel_select_range(srange);
        excel_putstrvalue(objectname);
        srange = get_posd("B",i+2);
        excel_select_range(srange);
        excel_putstrvalue(articul);
        srange = get_posd("C",i+2);
        excel_select_range(srange);
        excel_putnumvalue(price);
    }

    object("delete",TableDescr1);

    excel_detach(); // detach Excel

    cout << "\nProgramm end successfull \n";
    ac_save_messages_to_file("c:\\LabPP_Automat_1.rep"); // write message window to file
}

//------------------------------------------------------------------------------------------
// Agragate cell adress string Excel
//------------------------------------------------------------------------------------------
string get_posd(string ch, int row)
{
    string sposd=ch+itoa(row)+":"+ch+itoa(row);
    return sposd;
}
//****************************************************

Let us examine in detail the code of the script. It may seem complicated at first glance. However, it is actually easy to read.
Start with the end.
Outside the curly braces of main() function is a description of another function.

// Make a string-the cell address Excel
string get_posd(string ch, int row)
{
    string sposd=ch+itoa(row)+":"+ch+itoa(row);
    return sposd;
}

It can be conveniently used to form the address of the cell in the Excel spreadsheet.
At the entrance we give a string with the column letter (e.g. "A") and line number.
The output is the string "A1:A1".

Come back and let's go from the beginning of the main () function.
The following snippet connects Excel.

    int res;
    res = excel_attach(); // attaching current instance of programm Excel
    if(res != 0) {
        cout << "error attaching Excel";
        return -1;
    } else     {
        cout << "ok\n";
    }

Excel_attach function() connects LabPP_Automat to open the Excel program.
If the operation is successful, it returns 0. Otherwise, -1. Then we display a message in a message box and aborting the script.

The if construct in C++ is written like this:

if(condition)
{
   // here if condition is true
}
else if (else condition)
{
   // here if else condition is true
}
else
{
   // here if all conditions are false
}

Blocks the else if and else may be missing.
Unlike classic C++, the restriction of the interpreter LabPP_Automat that braces should be required.

The following snippet selects the desired file and page in it:

    res = excel_request("workbook_select","Price.xlsx");

    if(res!=0) { cout << "Price.xlsx not opened"; return -1;}
    res = excel_request("sheet_select","Plants");
    if(res!=0) { cout << "Can't switch to page Plants"; return -1;}

If it fails, display a message in the message window and finish the work.
Or go further. Give the message that we continue.

    cout << "Exporting." << "\n";

Make a selection of elements.

    ac_request("load_elements_list_from_selection",4,"ObjectType","MainFilter",4+2);
    ac_request("get_loaded_elements_list_count",4);
    int iObjectCount = ac_getnumvalue();

    cout << "\nCount of the objects = "<< iObjectCount << "\n";

Function "load_elements_list_from_selection" logs all currently selected ARCHICAD elements in a list with a specific number.
LabPP_Automat provides to the 10 item lists. There is the list number 4. The index goes from 0 to 9.
There are more elements must be of type "object".
The filter leaves only elements on visible and layer editable (flag value 4+2).
Manual "get_loaded_elements_list_count" requests LabPP_Automat how many items loaded in the list.
The result is a function ac_getnumvalue();
Give the number of objects in the sample on the screen in the message window.

Next is work with the dynamic table. This is a very handy tool LabPP_Automat.
A table can contain a variable number of columns, rows can be sorted (rows are ordered by column), you can organize a quick search for the required string.
Special handy feature: you can make clooncah data is automatically summarized numeric values have the same elements.
The table is created as an object. The object has a descriptor. This is an integer.

    int TableDescr1;

    object("create","ts_table",TableDescr1);  // to create an object of type "ts_table"
    ts_table(TableDescr1, "add_column",0,"string","object name"); // to add a column of type string named "object name"
    ts_table(TableDescr1, "add_column",1,"string","article");
    ts_table(TableDescr1, "add_column",2,"double","price"); // to add a column of type float with the name "price"
    ts_table(TableDescr1, "set_first_key","наименование объекта");  // the key to make the column "object name"

After a template table is created, fill it with values.

    string objectname;
    string articul;
    double price;
    for(int i=0;i<iObjectCount; i++)  // processed in the cycle, all objects of the sample
    {
        ac_request("set_current_element_from_list",4,itoa(i)); // set the current item number i
        ac_request("get_object_property_value","LabPP_IGRo_Artikul");  // read from this object the value of the variable LabPP_IGRo_Artikul
        articul = ac_getstrvalue(); // writable read value in a temporary variable articul
        ac_request("get_object_property_value","ObjectName");
        objectname = ac_getstrvalue();
        ac_request("get_object_property_value","LabPP_IGRo_Cost");
        price = ac_getnumvalue(); // write the value in a temporary variable price. Note here that the numerical value and not a string.

        cout << "article=" << articul << " object name=" << objectname << " price="<< price <<"\n";

        ts_table(TableDescr1,"add_row",0,objectname,1,articul,2,price);
    }

    ts_table(TableDescr1,"sort",0);  // to sort rows in table by column 0

Now spread the table in Excel.

    cout << "\nPrint the table on Excel";


    int rowcount;
    ts_table(TableDescr1,"get_rows_count", rowcount); // to determine the number of rows in the table;

    string srange = get_posd("A",1); // declare a string variable srange and once recorded there, the row address of the cell of the Excel spreadsheet
    excel_select_range(srange);  // focus to the cell in Excel
    excel_putstrvalue("Object name"); // write the text in a cell.
    srange = get_posd("B",1);
    excel_select_range(srange);
    excel_putstrvalue("Article");
    srange = get_posd("C",1);
    excel_select_range(srange);
    excel_putstrvalue("Price");

In a loop get the values from the table and write them in positions to Excel

    for(i=0;i<rowcount;i++)
    {
        ts_table(TableDescr1,"select_row",i); // to select the current row number i
        ts_table(TableDescr1,"get_value_of",0,objectname); // to read the value of the column number 0 in the variable objectname;
        ts_table(TableDescr1,"get_value_of",1,articul);
        ts_table(TableDescr1,"get_value_of",2,price);

        srange = get_posd("A",i+2);
        excel_select_range(srange);
        excel_putstrvalue(objectname); // to write a string value in cell A of the row i+2;
        srange = get_posd("B",i+2);
        excel_select_range(srange);
        excel_putstrvalue(articul);
        srange = get_posd("C",i+2);
        excel_select_range(srange);
        excel_putnumvalue(price); // to write a numeric value in cell B of the row i+2;
    }

After work, delete the table object in the descriptor TableDescr1:

    object("delete",TableDescr1);

Detach Excel

    excel_detach();

Reported in the message window that the program ended successfully.

    cout << "\nProgram ended successfully \n";

Burn (if needed) in the message window to a file for further analysis.

    ac_save_messages_to_file("c:\\LabPP_Automat_1.rep");

Button Import from Excel to ARCHICAD

Button launches a software script from a file excel_to_ac_1.cpp:

int main()
{
    int res;
    res = excel_attach(); // attaching current instance of Excel
    if(res != 0) {
        cout << "Excel attaching error";
        return -1;
    } else     {
        cout << "ok\n";
    }

    res = excel_request("workbook_select","Price.xlsx");
    if(res!=0) { cout << "no opened file Price.xlsx"; return -1;}
    res = excel_request("sheet_select","Plants");
    if(res!=0) { cout << "can't switch to page Plants"; return -1;}

    cout << "Importing" << "\n";

    int TableDescr1;
    object("create","ts_table",TableDescr1);
    ts_table(TableDescr1, "add_column",0,"string","object name");
    ts_table(TableDescr1, "add_column",1,"string","article");
    ts_table(TableDescr1, "add_column",2,"double","price");
    ts_table(TableDescr1, "set_first_key","object name");

    string objectname=" ";
    string articul;
    double price;
    string srange;

    for(int i=0;1==1;i++)
    {
        srange = get_posd("A",i+2);
        excel_select_range(srange);
        objectname = excel_getstrvalue();
        srange = get_posd("B",i+2);
        excel_select_range(srange);
        articul = excel_getstrvalue();
        srange = get_posd("C",i+2);
        excel_select_range(srange);
        price = excel_getnumvalue();
        if(objectname == "")
        { break; }
        ts_table(TableDescr1,"add_row",0,objectname,1,articul,2,price);
        cout << "article=" << articul << " object name=" << objectname << " price="<< price <<"\n";
    }

    ts_table(TableDescr1,"sort",0);

    cout << "\nImporting prices and articles";

    ac_request("load_elements_list_from_selection",4,"ObjectType","MainFilter",4+2);
    ac_request("get_loaded_elements_list_count",4);
    int iObjectCount = ac_getnumvalue();

    cout << "\ncount of objects = "<< iObjectCount << "\n";

    for(int i=0;i<iObjectCount; i++)
    {
        ac_request("set_current_element_from_list",4,itoa(i));
        ac_request("get_object_property_value","ObjectName");
        objectname = ac_getstrvalue();
        // search row in table on the column 0 (object name) by value object name
        int irow = ts_table(TableDescr1,"search",0,objectname);
        if(irow != -1)
        {
            ts_table(TableDescr1,"select_row",irow);

            ts_table(TableDescr1,"get_value_of",1,articul);
            ts_table(TableDescr1,"get_value_of",2,price);

            ac_request("set_object_property_value","LabPP_IGRo_Artikul",articul);
            ac_request("set_object_property_value","LabPP_IGRo_Cost",price);
        }
    }

    object("delete",TableDescr1);

    excel_detach(); // detach Excel

    cout << "\nProgramm ended successfully \n";
    ac_save_messages_to_file("c:\\LabPP_Automat_2.rep"); // write text of the message window to file
}

In the beginning of the program is already a well-known passage connections to the Excel file and the table.
Then there is the creation of a table object ts_table for download from Excel.

    int TableDescr1;
    object("create","ts_table",TableDescr1); // to create an object of type ts_table and keep a numeric handle to a variableTableDescr1
    ts_table(TableDescr1, "add_column",0,"string","object name"); // add a string column with a header
    ts_table(TableDescr1, "add_column",1,"string","article");
    ts_table(TableDescr1, "add_column",2,"double","price"); // add a numeric column
    ts_table(TableDescr1, "set_first_key","object name"); // specify key column

Then in a loop we read data from Excel and fill the table

    for(int i=0;1==1;i++)   // "infinite loop", where the variable i will be incremented by 1

    {
        srange = get_posd("A",i+2); // to form a string of the cell address
        excel_select_range(srange);  // select cell in Excel
        objectname = excel_getstrvalue(); // read text vsalue from current selected cell to variable objectname
        srange = get_posd("B",i+2);
        excel_select_range(srange);
        articul = excel_getstrvalue();
        srange = get_posd("C",i+2);
        excel_select_range(srange);
        price = excel_getnumvalue();  // read numeric value to variable price
        if(objectname == "")             // if cell is empty (end of list)
        { break; }                             // do bread the loop (end reading from Excel)
        ts_table(TableDescr1,"add_row",0,objectname,1,articul,2,price);  // add row with descriptor TableDescr1
        cout << "arcticle=" << articul << " object name=" << objectname << " price="<< price <<"\n";  // write in message window
    }

ts_table(TableDescr1,"sort",0); // do sorting the table by column object name

Form the list of objects in the ARCHICAD list No. 4

    ac_request("load_elements_list_from_selection",4,"ObjectType","MainFilter",4+2);

    ac_request("get_loaded_elements_list_count",4);
    int iObjectCount = ac_getnumvalue();

The sample will contain elements of type object, visible and editable ("MainFilter",4+2).
The number of objects in the sample record into a variable iObjectCount.
Sequentially iterate through all items in list No. 4.

    for(int i=0;i<iObjectCount; i++)
    {
        ac_request("set_current_element_from_list",4,itoa(i));  // make current object i in list No. 4
        ac_request("get_object_property_value","ObjectName"); // read object name
        objectname = ac_getstrvalue();                                    // record the last reading in a variable objectname
        // search on table row by objectname
        int irow = ts_table(TableDescr1,"search",0,objectname);  // to search the table ts_table descriptor TableDescr1 on the field number 0 to correspond to the name of an object from ARCHICAD.
        // if a value is not found - irow will contain the number -1. Otherwise the number will mean the number of rows in the table ts_table
        if(irow != -1)  // if such a line is (the table has row with the matching name of the object)
        {
            ts_table(TableDescr1,"select_row",irow);  // make row as current

            ts_table(TableDescr1,"get_value_of",1,articul);  // read article value from column 1
            ts_table(TableDescr1,"get_value_of",2,price);   // read price value from column 2

            ac_request("set_object_property_value","LabPP_IGRo_Artikul",articul);  // to write the article into the variable "LabPP_IGRo_Artikul" of the current object
            ac_request("set_object_property_value","LabPP_IGRo_Cost",price);      // record the price in the variable "LabPP_IGRO_Cost" of the current object
        }
    }
 

It remains to remove the table ts_table from the memory and disconnect from Excel

    object("delete",TableDescr1);
    excel_detach(); // detach Excel

Find string on EXCEL by selected object on ARCHICAD

The program script is in the file ac_select_excel_by_ac_1.cpp:

int main()
{
    int res;
    res = excel_attach(); // attach current instance of the Excel
    if(res != 0) {
        cout << "error attaching to Excel";
        return -1;
    } else     {
        cout << "ok\n";
    }

    res = excel_request("workbook_select","Price.xlsx");
    if(res!=0) { cout << "no opened file Price.xlsx"; return -1;}
    res = excel_request("sheet_select","Plants");
    if(res!=0) { cout << "can't switch to page Plants"; return -1;}

    ac_request("load_elements_list_from_selection",4,"ObjectType","MainFilter",4+2); // download in list No. 4 of the selected ARCHICAD element
    ac_request("get_loaded_elements_list_count",4);
    int iObjectCount = ac_getnumvalue();
    if(iObjectCount == 0)                           // if the number of elements in the list is zero - there is nothing to show in the table Excel
    {
        cout << "\nno selected objects in ARCHICAD";
        return -1;
    }

    ac_request("set_current_element_from_list",4,0); // take the first element from the list ARCHICAD No. 4 (the index in the list is 0)
    ac_request("get_object_property_value","ObjectName");  //  read object name
    string objectname_to_select;
    objectname_to_select = ac_getstrvalue();  // to variable objectname_to_select reading

    string srange;
    string objectname;
    for(int i=0;1==1;i++)  // in a loop to iterate through all the object names in column "Name of object" ("A") in the Excel spreadsheet until a blank cell
    {
        srange = get_posd("A",i+2);
        excel_select_range(srange); // focus cell in Excel
        objectname = excel_getstrvalue(); // read text value from this cell
        if(objectname == "")
        { break; }
        if(objectname == objectname_to_select)   // if the value in the Excel cell the same name as the object ARCHICAD to stay.
        { break; }
    }

    excel_detach(); // detach Excel
}

// Create address string Excel
string get_posd(string ch, int row)
{
    string sposd=ch+itoa(row)+":"+ch+itoa(row);
    return sposd;
}

Find object in ARCHICAD by selected row in EXCEL

We need to consider the name of the current Excel cell to find all the objects in ARCHICAD with the same name and highlight them.
Software script on this button is in the file ac_select_pos_excel_1.cpp:

int main()
{
    int res;
    res = excel_attach(); // attach Excel
    if(res != 0) {
        cout << "attaching error";
        return -1;
    } else     {
        cout << "ok\n";
    }

    res = excel_request("workbook_select","Price.xlsx");
    if(res!=0) { cout << "Nor opened file Price.xlsx"; return -1;}
    res = excel_request("sheet_select","Plants");
    if(res!=0) { cout << "can't switch to page Plants"; return -1;}

    string objectname;
    objectname = excel_getstrvalue();  // consider the text value of the current cell in Excel
    if(objectname!="")   // if a value is not the empty string, then
    {
        ac_request("load_elements_list",4,"ObjectType","ObjectName",objectname,"MainFilter",4+2); // in ARCHICAD to count elements of type object with the name objectname in a variable from list No. 4
        ac_request("select_elements_from_list",4); // make the selected ARCHICAD elements from list No. 4
    }
    excel_detach(); // detach Excel
}