Этот пример показывает один из простых вариантов использования LabPP_Automat. Он находится в дистрибутиве.
Достаточно немного поэкспериментировать с этим примером чтобы получить представление о гибкости и функциональности возможностей автоматизации.
Текстовые файлы программных скриптов позволяют вносить изменения и полностью менять все что Вы видите.
В каталоге tsprglist Вы можете создать рядом копию каталога "Ландшафтный дизайн с ценами" и дать ему собственное название.
А затем сразу приступить к созданию собственной системы автоматизации на базе своей собственной новой конфигурации. Создавать кнопки, программы, задавать вид панели LabPP_Automat и т.п.
Конфигураций может быть сколько угодно.
Разбор примера.
1. Структура каталогов и конфигурация.
2. Кнопка "Открыть файл Excel".
3. Кнопка помощи.
4. Кнопка выгрузки из ARCHICAD в EXCEL.
5. Кнопка загрузки из EXCEL в ARCHICAD.
6. Найти строку в EXCEL по выбранному объекту ARCHICAD.
7. Найти объект ARCHICAD по выбранной строке в EXCEL.
Структура каталогов и конфигурации
LabPP_Automat запускается с выбранной конфигурацией. Конфигурация - это каталог с набором скриптов и других файлов, который формирует облик и функционал дополнения в конкретном случае.
При входе в пункт меню ARCHICAD "LabPP_Automat показать/скрыть палитру" программа анализирует каталог tsprglist.
В нем располагаются все конфигурации LabPP_Automat.
Каждая конфигурация является отдельным каталогом.
Имя каталога конфигурации высвечивается в списке в диалоге выбора конфигурации (см. рисунок).
Каталоги конфигураций имеют одинаковую структуру.
Так каталог конфигурации этого примера содержит подкаталоги tsimages и tsprg:
"Ландшафтный дизайн с ценами"
- tsimages
- tsprg
В самом каталоге "Ландшафтный дизайн с ценами" находятся файлы примера: Прайс.xlsx (открыть в Excel) и Пример.pln (файл ARCHICAD).
Файл Пример.pln содержит объекты библиотеки LabPP_Landscape. Их можно скачать вместе с дистрибутивом здесь на этом сайте.
Каталог tsimages содержит изображения и иконки.
В панели выбора конфигурации рядом с именем конфигурации отображается иконка из файла tsimages\1.png.
Файлы Excel_from.png, Excel_to.png и другие используются в качестве иконок на кнопках.
Каталог tsprg содержит программные скрипты.
Скрипты располагаются в файлах с расширениями *.cpp. Иногда, если нужно использовать часть кода в нескольких файлах *.cpp общая часть может быть вынесена в файл *.h.
В этом примере для простоты используются только файлы *.cpp.
При выборе конфигурации из списка, выполняется файл tsprg\config.cpp.
Вот его содержимое:
//****************************************************
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,"Выгрузить в Excel по одному объекту чтобы можно было назначить цены","ac_to_excel_1.cpp");
sx = sx + w + offsetx;
ac_request("create_iconbutton","excel_from.png",sx,sy,sx+w,sy+h,"Загрузить цены и артикулы в ARCHICAD","excel_to_ac_1.cpp");
sx = sx + w + offsetx;
ac_request("create_iconbutton","select.png",sx,sy,sx+w,sy+h,"Выделить объекты в ARCHICAD из позиции EXCEL","ac_select_pos_excel_1.cpp");
sx = sx + w + offsetx;
ac_request("create_iconbutton","selectexcel.png",sx,sy,sx+w,sy+h,"Показать позицию в EXCEL, соответствующую выделенному объекту ARCHICAD","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.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);
}
//****************************************************
Каждый файл содержит конструкцию
int main()
{
}
Между фигурными скобками располагается выполняемый код.
Комментарием считается текст после двойного // до конца строки или между знаками /* и */
/* это комментарий
на несколько строк*/
Функция ac_request() позволяет выполнять операции с ARCHICAD.
Первым аргументом идет команда. В нашем случае "create_iconbutton" - означает создать кнопку с иконкой.
ac_request("create_iconbutton","excel_to.png",sx,sy,sx+w,sy+h,"Выгрузить в Excel по одному объекту чтобы можно было назначить цены","ac_to_excel_1.cpp");
Следующая строка - имя файла рисунка для иконки. Файл берется из каталога tsimages текущей конфигурации.
Следующие 4 числовых аргумента задают координаты кнопки в окне: левый край, верхний край, ширина и высота кнопки в пикселях.
Следующий текстовый аргумент - пояснение, которое будет показываться при подводе мыши к кнопке.
И последний аргумент - имя файла программного скрипта, который будет выполняться при нажатии на кнопку.
В этом случае - tsprg\ac_to_excel_1.cpp.
Переменные sx,sy и т.д. играют роль для позиционирования кнопок и окна сообщений интерпретатора LabPP_Automat.
Последняя функция задает размеры палитры LabPP_Automat и расположение в нем окна сообщений.
ac_request("set_palette_size_and_message_place",80,100,405,300,sx,sy,326-sx*2,200-sy);
В результате окно этой конфигурации выглядит так:
Кнопка "Открыть файл Excel"
Для этого примера мы создали файл Excel с именем "Прайс.xlsx". В нем назвали одну из таблиц "Растения".
Файл поместили в корневой каталог конфигурации "Ландшафтный дизайн с ценами".
Чтобы быстро открыть этот файл мы создали кнопку с иконкой Excel.
При нажатии этой кнопки выполняется программа "open_excel_file.cpp":
int main()
{
shell_func("set_cur_dir","rootconfig"); // сделать текущим корневой каталог текущей конфигурации
shell_func("shellexecute","open","Прайс.xlsx"); // открыть файл "Прайс.xlsx"
}
Обращение к функции shell_func() с директивой "set_cur_dir" позволяет изменить текущий каталог.
Следующей строкой задается либо полный путь к каталогу, либо кодовое слово. В данном случае "rootconfig" означает что мы хотим переместиться в корневой каталог текущей конфигурации (здесь ""Ландшафтный дизайн с ценами").
Следующий вызов функции с директивой "shellexecute" и именем файла обращается к операционной системе чтобы открыть этот файл.
Кнопка помощи
Чтобы легче справиться с освоением этого примера мы подложили под кнопку со знаком вопроса файл help.cpp
При нажатии на кнопку выполняется файл tsprg\help.cpp:
//****************************************************
int main()
{
cout << "Демонстрационная программа по\n загрузке/выгрузке данных между ARCHICAD и EXCEL.\n";
cout << "Откройте файл Прайс.xslx \n(в каталоге этой конфигурации).\n";
cout << "Поставьте в своем проекте несколько\nобъектов из библиотеки LabPP_Landscape.\n";
cout << "Выделите эти объекты\n";
cout << "Нажмите первую кнопку со стрелкой ->X \nчтобы выгрузить список видов объектов в EXCEL.\n";
cout << "Измените артикулы и цены.\n";
cout << "Выделите в ARCHICAD объекты, у которых нужно заменить данные";
cout << "Нажмите кнопку со стрелкой X-> чтобы загрузить\n измененные данные в объекты в Ваш проект ARCHICAD.\n";
cout << "Можно выделить ячейку с наименованием\nэлемента в таблице EXCEL и нажать кнопку с квадратиком.\n";
cout << "В результате в ARCHICAD будут выделены\nвсе объекты с этим наименованием";
cout << "Можно выделить объект в ARCHICAD\nкоторому соответствует ячейка в EXCEL\n";
}
//****************************************************
Здесь содержатся простык стандартные выражения вывода на экран.
Вывод осуществляется в окно сообщений.
cout << "Демонстрационная программа по\n загрузке/выгрузке данных между ARCHICAD и EXCEL.\n";
cout << "текст" << variable << "\n";
Так можно писать чтобы перемежать текстовые сообщения, значения переменных и если где-то поставить "\n" то это будет переход на следующую строку.
После каждого оператора должна быть точка с запятой.
Кнопка выгрузки из ARCHICAD в Excel
Перед нажатием откройте файл Прайс.xlsx.
По нажатию этой кнопки запускается программа из файла ac_to_excel_1.cpp:
//****************************************************
int main()
{
int res;
res = excel_attach(); // подключаем текущую таблицу Excel
if(res != 0) {
cout << "ошибка подключения к Excel";
return -1;
} else {
cout << "ok\n";
}
res = excel_request("workbook_select","Прайс.xlsx");
if(res!=0) { cout << "не открыт файл Прайс.xlsx"; return -1;}
res = excel_request("sheet_select","Растения");
if(res!=0) { cout << "не могу переключиться на страницу Растения"; return -1;}
cout << "Выгружаем." << "\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 << "\nвсего объектов = "<< iObjectCount << "\n";
int TableDescr1;
object("create","ts_table",TableDescr1);
ts_table(TableDescr1, "add_column",0,"string","наименование объекта");
ts_table(TableDescr1, "add_column",1,"string","артикул");
ts_table(TableDescr1, "add_column",2,"double","цена");
ts_table(TableDescr1, "set_first_key","наименование объекта"); // устанавливаем колонку как ключевую (не будет одинаковых значений в ней);
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 << "артикул=" << articul << " название объекта=" << objectname << " цена="<< price <<"\n";
ts_table(TableDescr1,"add_row",0,objectname,1,articul,2,price); // добавляем строку в нашу таблицу. После "add_row" перечисляются номер колонки и значение, номер колонки, значение и т.д. может быть не по порядку, могут быть не все колонки.
}
Последний оператор цикла - добавление строки в таблицу.
Т.к. мы задали инструкцией "set_first_ker" ключевую колонку - в таблицу не добавится строка, если имя объекта будет совпадать с уже имеющимся.
Тогда данные других полей заместятся новыми. В инструкции "add_row" могут присутствовать не все колонки.
Если вместо "add_row" использовать инструкцию "add_row_sum", то значения числовых колонок будет суммироваться с уже имеющимися в этой строке.
Это очень удобно.
Дальше сортируем таблицу по колонке 0.
ts_table(TableDescr1,"sort",0);
cout << "\nпечатаем таблицу";
int rowcount;
ts_table(TableDescr1,"get_rows_count", rowcount);
string srange = get_posd("A",1);
excel_select_range(srange);
excel_putstrvalue("Название объекта");
srange = get_posd("B",1);
excel_select_range(srange);
excel_putstrvalue("Артикул");
srange = get_posd("C",1);
excel_select_range(srange);
excel_putstrvalue("Цена");
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(); // отключаем Excel
cout << "\nЗавершение работы программы \n";
ac_save_messages_to_file("c:\\LabPP_Automat_1.rep"); // записываем текст окна сообщений в файл
}
//------------------------------------------------------------------------------------------
// Функция чтобы cоставить строку-адрес ячейки Excel
string get_posd(string ch, int row)
{
string sposd=ch+itoa(row)+":"+ch+itoa(row);
return sposd;
}
//****************************************************
Разберем подробно текст программного скрипта. Может показаться сложным на первый взгляд. Однако на самом деле все легко читается.
Начнем с конца.
За пределами фигурных скобок функции main() находится описание еще одной функции.
// Составить строку-адрес ячейки Excel
string get_posd(string ch, int row)
{
string sposd=ch+itoa(row)+":"+ch+itoa(row);
return sposd;
}
Ее удобно использовать чтобы сформировать адрес ячейки в таблице Excel.
На входе мы подаем строку с буквой колонки (например "А") и номером строки.
На выходе получаем строку "A1:A1".
Вернемся и пойдем с начала функции main().
Следующий фрагмент подключает Excel.
int res;
res = excel_attach(); // подключаем текущую таблицу Excel
if(res != 0) {
cout << "ошибка подключения к Excel";
return -1;
} else {
cout << "ok\n";
}
Функция excel_attach() подключает LabPP_Automat к открытой программе Excel.
Если операция прошла успешно, то возвращается 0. В ином случае -1. Тогда мы выдаем сообщение в окно сообщений и прекращаем выполнение скрипта.
Конструкция if в языке C++ пишется так:
if(условие)
{
// здесь если условие истинно
}
else if (еще условие)
{
// здесь если еще условие истинно
}
else
{
// здесь - если все было ложно
}
Блоки else if и else могут отсутствовать.
В отличии от классического C++, ограничение интерпретатора LabPP_Automat в том, что фигурные скобки должны присутствовать обязательно.
Следующий фрагмент выбирает нужный файл и страницу в нем:
res = excel_request("workbook_select","Прайс.xlsx");
if(res!=0) { cout << "не открыт файл Прайс.xlsx"; return -1;}
res = excel_request("sheet_select","Растения");
if(res!=0) { cout << "не могу переключиться на страницу Растения"; return -1;}
При неудаче выдаем сообщение в окно сообщений и заканчиваем работу.
Или идем дальше. Выдаем сообщение о том, что мы продолжаем.
cout << "Выгружаем." << "\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 << "\nвсего объектов = "<< iObjectCount << "\n";
Инструкция "load_elements_list_from_selection" записывает все текущие выбранные элементы ARCHICAD в список с определенным номером.
LabPP_Automat предоставляет для работы 10 списков элементов. Здесь задействован список №4. Индекс идет от 0 до 9.
Здесь имеются уточнения - элементы должны быть типа "объект".
При этом фильтр оставляет только элементы на видимом слое и редактируемые (значение флага 4+2).
Инструкция "get_loaded_elements_list_count" запрашивает LabPP_Automat сколько элементов загружено в список.
Результат получаем функцией ac_getnumvalue();
Выдаем количество объектов в выборке на экран в окно сообщений.
Далее идет работа с динамической таблицей. Это очень удобный инструмент LabPP_Automat.
Таблица может содержать переменное количество колонок, строк, может сортироваться (строки упорядочиваются по колонке), можно организовывать быстрый поиск нужной строки.
Особенная удобная возможность: можно сделать так, чтобы в клонках данные автоматически суммировались числовые значения у одинаковых элементов.
Таблица создается как объект. Объект имеет дескриптор. Это целое число.
int TableDescr1;
object("create","ts_table",TableDescr1); // создать объект типа "ts_table"
ts_table(TableDescr1, "add_column",0,"string","наименование объекта"); // добавить колонку типа строка с именем "наименование объекта"
ts_table(TableDescr1, "add_column",1,"string","артикул");
ts_table(TableDescr1, "add_column",2,"double","цена"); // добавить колонку типа число с плавающей точкой с именем "цена"
ts_table(TableDescr1, "set_first_key","наименование объекта"); // ключевым сделать колонку "наименование объекта"
После того, как шаблон таблицы создан, заполняем ее значениями.
string objectname;
string articul;
double price;
for(int i=0;i<iObjectCount; i++) // обрабатываем в цикле все объекты выборки
{
ac_request("set_current_element_from_list",4,itoa(i)); // устанавливаем текущим элемент с номером i
ac_request("get_object_property_value","LabPP_IGRo_Artikul"); // считываем из этого объекта значение переменной LabPP_IGRo_Artikul
articul = ac_getstrvalue(); // записываем считанное значение во временную переменную articul
ac_request("get_object_property_value","ObjectName");
objectname = ac_getstrvalue();
ac_request("get_object_property_value","LabPP_IGRo_Cost");
price = ac_getnumvalue(); // записываем значение цены во временную переменную price. Обратите внимание здесь численное значение а не строка.
cout << "артикул=" << articul << " название объекта=" << objectname << " цена="<< price <<"\n";
ts_table(TableDescr1,"add_row",0,objectname,1,articul,2,price);
}
ts_table(TableDescr1,"sort",0); // сортировать (упроядочить) строки в таблице по колонке 0
Теперь выкладываем таблицу в Excel.
cout << "\nпечатаем таблицу";
int rowcount;
ts_table(TableDescr1,"get_rows_count", rowcount); // определить количество строк в таблице;
string srange = get_posd("A",1); // объявляем строковую переменную srange и сразу записываем туда строку адрес ячейки таблицы Excel
excel_select_range(srange); // фокусируем эту ячейку в Excel
excel_putstrvalue("Название объекта"); // записываем текст в ячейку.
srange = get_posd("B",1);
excel_select_range(srange);
excel_putstrvalue("Артикул");
srange = get_posd("C",1);
excel_select_range(srange);
excel_putstrvalue("Цена");
В цикле получаем значения из таблицы и записываем их в позиции Excel
for(i=0;i<rowcount;i++)
{
ts_table(TableDescr1,"select_row",i); // выбрать текущую строку № i
ts_table(TableDescr1,"get_value_of",0,objectname); // считать значение колонки №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); // записать строковое значение в ячейку A строки 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); // записать числовое значение в ячейку Б строки i+2;
}
После работы удаляем объект таблицы по дескриптору TableDescr1:
object("delete",TableDescr1);
Отключаем Excel:
excel_detach(); // отключаем Excel
Сообщаем в окно сообщений, что программа закончилась успешно.
cout << "\nЗавершение работы программы \n";
Записываем (если нужно) окно сообщений в файл для дальнейшего анализа.
ac_save_messages_to_file("c:\\LabPP_Automat_1.rep"); // записываем текст окна сообщений в файл
Кнопка загрузки из Excel в ARCHICAD
Кнопка запускает программный скрипт из файла excel_to_ac_1.cpp:
int main()
{
int res;
res = excel_attach(); // подключаем текущую таблицу Excel
if(res != 0) {
cout << "ошибка подключения к Excel";
return -1;
} else {
cout << "ok\n";
}
res = excel_request("workbook_select","Прайс.xlsx");
if(res!=0) { cout << "не открыт файл Прайс.xlsx"; return -1;}
res = excel_request("sheet_select","Растения");
if(res!=0) { cout << "не могу переключиться на страницу Растения"; return -1;}
cout << "Загружаем." << "\n";
int TableDescr1;
object("create","ts_table",TableDescr1);
ts_table(TableDescr1, "add_column",0,"string","наименование объекта");
ts_table(TableDescr1, "add_column",1,"string","артикул");
ts_table(TableDescr1, "add_column",2,"double","цена");
ts_table(TableDescr1, "set_first_key","наименование объекта");
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 << "артикул=" << articul << " название объекта=" << objectname << " цена="<< price <<"\n";
}
ts_table(TableDescr1,"sort",0);
cout << "\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 << "\nвсего объектов = "<< 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();
// найти в таблице значение
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(); // отключаем Excel
cout << "\nЗавершение работы программы \n";
ac_save_messages_to_file("c:\\LabPP_Automat_2.rep"); // записываем текст окна сообщений в файл
}
В начале программы идет уже известный фрагмент подключения к Excel с файлом и таблицей.
Дальше идет создание объекта таблицы ts_table для загрузки из Excel.
int TableDescr1;
object("create","ts_table",TableDescr1); // создать объект типа ts_table и сохранить числовой дескриптор в переменную TableDescr1
ts_table(TableDescr1, "add_column",0,"string","наименование объекта"); // добавить строковую колонку с заголовком
ts_table(TableDescr1, "add_column",1,"string","артикул");
ts_table(TableDescr1, "add_column",2,"double","цена"); // добавить числовую колонку
ts_table(TableDescr1, "set_first_key","наименование объекта"); // задать ключевую колонку
Дальше в цикле считываем данные из Excel и заполняем таблицу
for(int i=0;1==1;i++) // "бесконечный цикл", где переменная i увеличивается всякий раз на 1
{
srange = get_posd("A",i+2); // сформировать строку адреса ячейки
excel_select_range(srange); // выделить ячейку в Excel
objectname = excel_getstrvalue(); // считать текстовое значение в переменную 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(); // считать числовое значение в переменную price (цена)
if(objectname == "") // если в переменной objectname оказалась пустая строка (ячейка Excel пустая, т.к. достигнут конец списка)
{ break; } // то выйти из цикла, т.е. закончить считывание из Excel
ts_table(TableDescr1,"add_row",0,objectname,1,articul,2,price); // добавить запись в таблицу с дескрипторомTableDescr1
cout << "артикул=" << articul << " название объекта=" << objectname << " цена="<< price <<"\n"; // написать в окне сообщений то, что мы считали.
}
Теперь отсортируем ts_table, т.е. упорядочим записи в ней по колонке №0 ("Наименование объекта")
ts_table(TableDescr1,"sort",0);
Сформируем список объектов ARCHICAD в списке №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();
Выборка будет содержать элементы типа объект, видимые и доступные для редактирования ("MainFilter",4+2).
Количество объектов в выборке запишем в переменную iObjectCount.
Перебираем последовательно все объекты из списка №4.
for(int i=0;i<iObjectCount; i++)
{
ac_request("set_current_element_from_list",4,itoa(i)); // сделать текущим объект i в списке №4
ac_request("get_object_property_value","ObjectName"); // считать название объекта
objectname = ac_getstrvalue(); // записать последнее считанное значение в переменную objectname
// найти в таблице значение
int irow = ts_table(TableDescr1,"search",0,objectname); // задать поиск в таблице ts_table с дескриптором TableDescr1 по полю №0 на соответствие имени объекта из ARCHICAD.
// если значение не найдено - то irow будет содержать число -1. Иначе число будет означать номер строки в таблице ts_table
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); // записать артикул в переменную "LabPP_IGRo_Artikul" текущего объекта
ac_request("set_object_property_value","LabPP_IGRo_Cost",price); // записать цену в переменную "LabPP_IGRO_Cost" текущего объекта
}
}
Осталось удалить таблицу ts_table из памяти и отключиться от Excel
object("delete",TableDescr1);
excel_detach(); // отключаем Excel
Найти строку в EXCEL по выбранному объекту ARCHICAD
Программа скрипта находится в файле ac_select_excel_by_ac_1.cpp:
int main()
{
int res;
res = excel_attach(); // подключаем текущую таблицу Excel
if(res != 0) {
cout << "ошибка подключения к Excel";
return -1;
} else {
cout << "ok\n";
}
res = excel_request("workbook_select","Прайс.xlsx");
if(res!=0) { cout << "не открыт файл Прайс.xlsx"; return -1;}
res = excel_request("sheet_select","Растения");
if(res!=0) { cout << "не могу переключиться на страницу Растения"; return -1;}
ac_request("load_elements_list_from_selection",4,"ObjectType","MainFilter",4+2); // загрузить в список №4 выбранный элемент ARCHICAD
ac_request("get_loaded_elements_list_count",4);
int iObjectCount = ac_getnumvalue();
if(iObjectCount == 0) // если количество элементов в списке равно нулю - то нечего показывать в таблице Excel
{
cout << "\nне выделены объекты в ARCHICAD";
return -1;
}
ac_request("set_current_element_from_list",4,0); // взять первый элемент ARCHICAD из списка №4 (индекс в списке - 0)
ac_request("get_object_property_value","ObjectName"); // считать имя объекта
string objectname_to_select;
objectname_to_select = ac_getstrvalue(); // получить в переменную objectname_to_select считанное значение
string srange;
string objectname;
for(int i=0;1==1;i++) // в цикле перебрать все наименования объектов в колонке "Наименование объекта" ("A") в таблице Excel до пустой ячейки
{
srange = get_posd("A",i+2);
excel_select_range(srange); // сфокусирьвать ячейку Excel
objectname = excel_getstrvalue(); // считать текстовое значение из этой ячейки
if(objectname == "")
{ break; }
if(objectname == objectname_to_select) // если значение в ячейке Excel совпадает с именем объекта ARCHICAD - то остановиться.
{ break; }
}
excel_detach(); // отключаем Excel
}
// Составить строку-адрес ячейки Excel
string get_posd(string ch, int row)
{
string sposd=ch+itoa(row)+":"+ch+itoa(row);
return sposd;
}
Найти объект ARCHICAD по выбранной строке в EXCEL
Нам необходимо считать название объекта из текущей ячейки Excel, найти все объекты в ARCHICAD с таким именем и выделить их.
Программный скрипт, выполняемый по этой кнопке находится в файле ac_select_pos_excel_1.cpp:
int main()
{
int res;
res = excel_attach(); // подключаем текущую таблицу Excel
if(res != 0) {
cout << "ошибка подключения к Excel";
return -1;
} else {
cout << "ok\n";
}
res = excel_request("workbook_select","Прайс.xlsx");
if(res!=0) { cout << "не открыт файл Прайс.xlsx"; return -1;}
res = excel_request("sheet_select","Растения");
if(res!=0) { cout << "не могу переключиться на страницу Растения"; return -1;}
string objectname;
objectname = excel_getstrvalue(); // считать текстовое значение из текущей ячейки Excel
if(objectname!="") // если значение не пустая строка, то
{
ac_request("load_elements_list",4,"ObjectType","ObjectName",objectname,"MainFilter",4+2); // в ARCHICAD считать элементы типа объект с названием из переменной objectname в список №4
ac_request("select_elements_from_list",4); // сделать выбранными в ARCHICAD элементы из списка №4
}
excel_detach(); // отключаем Excel
}