---
title: "ksSpcObjectCreate - Создать объект спецификации в графическом документе"
type: guide
api: [api7]
tags: [guide, api7, ksspcobjectcreate]
sources:
  - ksspcobjectcreate.html
---

*API экспортных функций > Функции работы с документом-спецификацией *


## ksSpcObjectCreate - Создать объект спецификации в графическом документе

Пример...
Аналог данной функции при использовании Automation - метод ksSpecification::ksSpcObjectCreate.
Синтаксис:
```
int ksSpcObjectCreate (char * nameLib,
unsigned int styleNumb,
unsigned short secNumb,
unsigned short subSecNumb,
double numb,
unsigned char typeObj);
Входные параметры:
nameLib    - имя библиотеки стилей спецификации,
styleNumb    - номер стиля спецификации в библиотеке,
secNumb    - номер раздела,
subSecNumb    - номер подраздела,
numb    - для базового объекта - тип атрибута, который задан по ключам, или 0, для вспомогательного объекта - номер базового объекта, к которому прикрепляется вспомогательный, либо 0,
typeObj    - тип строки спецификации (0- базовый объект, 1 – вспомогательный объект).
Возвращаемое значение:
1    - в случае удачного завершения,
0    - в случае неудачи.
```
Примечания:
1. Объект спецификации - составной объект. Его создание завершается функцией ksSpcObjectEnd.
2. При использовании Unicode следует использовать функцию ksSpcObjectCreateW.


## ksSpcObjectCreate - пример использования

а)
#define SPC_NAME 5 //наименование
//-----------------------------------------------------------------------------------------------
// создадим объект спецификации для раздела "Детали"
//-----------------------------------------------------------------------------------------------
reference EditSpcObj(reference geom){
reference spcObj = 0;
//если редактируем макроэлемент, то войдем в режим редактирования объекта
if (::EditMacroMode()) {
//найдем объект спецификации по геометрии
spcObj = ::ksGetSpcObjForGeom("graphic.lyt" , //имя библиотеки типов
1, // номер типа спецификации
0, //для макроредактирования
1, 1);
//войдем в режим редактирования
if (!::ksSpcObjectEdit(spcObj))
spcObj = 0;
}
//если объекта нет, войдем в режим создания объекта спецификации
if(spcObj || ::ksSpcObjectCreate("graphic.lyt", //имя библиотеки типов
1, // номер типа спецификации
20, 0, //номер раздела и подраздела
0,0)) { //тип атрибута
//наименование
::ksSpcChangeValue(SPC_NAME/*номер колонки*/ , 1, "Втулка", STRING_ATTR_TYPE );
//подключим геометрию
if (geom)
::ksSpcIncludeReference(geom, 1);
spcObj = ::ksSpcObjectEnd();
//если объект спецификации создан, дадим возможность пользователю на него посмотреть и отредактировать. Функцию нужно запускать вне Cursor и Placement
if (spcObj)
if (::ksEditWindowSpcObject(spcObj))
return spcObj;
}
return 0;
}
б)
Для стандартных изделий в стиле спецификации (см. "graphic.lyt") колонка "Наименование" имеет тип значения "запись". Это значит, что наименование формируется по шаблону обозначения для данного стандартного изделия (например, болта). Шаблоны создаются на базе типов атрибутов и хранятся в библиотеке типов атрибутов, которая определена в стиле спецификации (например, "spc.lat").
При простановке болта из библиотеки из базы данных заполняется некоторая структура данных BOLT, которая несет информацию для построения геометрии болта и формирования обозначения.
struct BOLT {
float dr; /*диаметр резьбы*/
float p; /*шаг резьбы */
float s; /*размер под ключ*/
float h; /*высота головки */
float D; /* диаметр описанной окружности*/
float d3; /*диаметр отв. в стержне*/
float h2; /*высота подголовка*/
float L; /*длина стержня*/
float l1; /*расстояние до отверстия в стержне*/
float b; /*длина резьбовой части*/
float d2; /*диаметр под головкой*/
float z4; /*величина фаски конца*/
short k; // 1 - длина резьбы ниже ломаной (резьба только на b) ; 2 - выше ломаной (резьба до головки и на в)
unsigned short f; /*битовые маски*/
short klass; /*класс точности*/
unsigned short gost; /*номер госта*/
};
#define SPC_NAME 5 //наименование
//-----------------------------------------------------------------------------------------------
// создадим объект спецификации для раздела "Стандартные изделия"
//-----------------------------------------------------------------------------------------------
reference EditSpcObj (BOLT &tmp, reference geom) {
reference spcObj = 0;
//если редактируем макро объект , то войдем в режим редактирования объекта
if (::EditMacroMode()) {
//найдем объкт спецификации по геометрии
spcObj = ::ksGetSpcObjForGeom("graphic.lyt" , //имя библиотеки типов
1, // номер типа спецификации
0, //для макроредактирования
1, 1);
//войдем в режим редактирования
if (!::ksSpcObjectEdit(spcObj))
spcObj = 0;
}
if(spcObj || ksSpcObjectCreate("graphic.lyt" , //имя библиотеки типов
1, // номер типа спецификации
25, 0, //номер раздела и подраздела определены в стиле спецификации
308437807397.0 , 0)) //тип атрибута определен в библиотеке типов атрибутов spc.lat
uint uBuf;
//исполнение
if(!(tmp.f & ISPOLN)) //если исполнения нет
::ksSpcVisible(SPC_NAME, 2, 0); //выключим исполнение
else {
uBuf = (uint) 2;
::ksSpcVisible(SPC_NAME, 2, 1);
::ksSpcChangeValue(SPC_NAME , 2, &uBuf, UINT_ATTR_TYPE );
}
//изменим диаметр
uBuf = (uint) tmp.dr;
::ksSpcChangeValue(SPC_NAME , 4, &uBuf, UINT_ATTR_TYPE );
//отследим мелкий шаг
if(!(tmp.f & PITCH)){//выключить шаг и его разделитель
::ksSpcVisible(SPC_NAME, 5, 0);
::ksSpcVisible(SPC_NAME, 6, 0); //шаг
}
else {
::ksSpcVisible(SPC_NAME, 5, 1);
::ksSpcVisible(SPC_NAME, 6, 1); //шаг
::ksSpcChangeValue(SPC_NAME , 6, &tmp.p, FLOAT_ATTR_TYPE);
}
// выключим поле допуска
::ksSpcVisible(SPC_NAME, 7, 0);
//изменим длину
uBuf = (uint) tmp.L;
::ksSpcChangeValue(SPC_NAME , 9, &uBuf, UINT_ATTR_TYPE );
// выключим класс прочности
::ksSpcVisible(SPC_NAME, 10, 0);
// выключим материал
::ksSpcVisible(SPC_NAME, 11, 0);
// выключим покрытие
::ksSpcVisible(SPC_NAME, 12, 0);
//изменим ГОСТ
uBuf = (uint) tmp.gost;
::ksSpcChangeValue(SPC_NAME , 14, &uBuf, UINT_ATTR_TYPE );
//подключим геометрию
if (geom)
::ksSpcIncludeReference(geom, 1);
spcObj = ::ksSpcObjectEnd();
//если объект спецификации создан, дадим возможность пользователю на него посмотреть и отредактировать. Функцию нужно запускать вне Cursor и Placement
if (spcObj)
if (::ksEditWindowSpcObject(spcObj))
return spcObj;
}
return 0;
}
в) пример создания шаблона обозначения для стандартного изделия "болт":
Шаблон обозначения можно создать визуальными средствами, предоставленными КОМПАС-ГРАФИК для создания типа атрибута. Этот способ не требует непосредственного программирования, но приводит к затратам времени на создание шаблона, а при потере данных в библиотеке требует повторного создания утраченного шаблона.
Можно создать шаблон обозначения средствами apptool из библиотеки.
Полное обозначение болта :
Болт 1 М12 х 1.25 -6g x 60.58.35X.16 ГОСТ 7808 - 70
Представим это обозначение в виде компонент :
Номер Имя компоненты Умолчательное значение Тип Очередность сортировки
1 Имя элем. Болт строка 1
2 Исполнение 1 uint 3
3 Резьба М строка 0 (не сортируется)
4 Диаметр 12 uint 4 или 3 (сортирует подряд)
5 Разделитель х строка 0 (не сортируется)
6 Шаг 1.25 float 5 или 3 (сортирует подряд)
7 Поле допуска -6g строка 6 или 3 (сортирует подряд)
8 Разделитель х строка 0 (не сортируется)
9 Длина 60 uint 7 или 3 (сортирует подряд)
10 Кл. прочности .58 строка 0 (не сортируется)
11 Материал .35Х строка 0 (не сортируется)
12 Покрытие .16 строка 0 (не сортируется)
13 ГОСТ ГОСТ строка 0 (не сортируется)
14 Номер 7808 uint 2
15 Разделитель - строка 0 (не сортируется)
16 Год 70 строка 0 (не сортируется)
//ключи определены в стиле спецификации
#define ST_KEY1 100 //ключи для стандапртных изделий
#define ST_KEY2_GOST 5 //для стандартных изделий
#define ST_KEY3 1
#define ATTR_TYPE_LIB_NAME_KEY3 "d:\\gr\\spc.lat" имя библиотеки типов атрибутов
//-------------------------------------------------------------------------
// создадим тип атрибута болта
//-------------------------------------------------------------------------
void TypeAttrBolt() {
//Инициализация данных для создания шаблона
//заполним структуру типа атрибута
ksAttributeType attrType;
strcpy(attrType.header,"Болт"); // заголовoк-комментарий типа
attrType.rowsCount = 1; // кол-во строк в таблице
attrType.flagVisible = 1; // видимый, невидимый в таблице
strcpy(attrType.password,""); // пароль, если не пустая строка - защищает от несанкционированного изменения типа
attrType.columns = CreateArray(ATTR_COLUMN_ARR,0); // динамический массив компонент записи
attrType.key1 = ST_KEY1;
attrType.key2 = ST_KEY2_GOST;
attrType.key3 = ST_KEY3;
attrType.key4 = 0;
ColumnInfo parStruct1;
//массив полей записи
// колонка 1 "Имя элем."
strcpy(parStruct1.header, "Имя элем.");// заголовoк-комментарий столбца
parStruct1.type = STRING_ATTR_TYPE; // тип данных в столбце - см.ниже
parStruct1.key = 1; // дополнительный признак, очередность сортировки
strcpy(parStruct1.def,"Болт"); // значение по умолчанию
parStruct1.flagEnum =0; // флаг, включающий режим, когда значение поля атрибута будет заполняться из массива перечисленных значений (1-режим включен, 0-отключен
parStruct1.fieldEnum = 0; // массив неопределенной длины перечислений (строки)
parStruct1.columns = 0; // массив неопределенной длины информации о колонках для записи
//добавим компоненту в массив компонент
AddArrayItem(attrType.columns, -1, &parStruct1, sizeof(parStruct1));
// колонка 2 "Исполнение"
strcpy(parStruct1.header, "Исполнение"); // заголовoк-комментарий столбца
parStruct1.type = UINT_ATTR_TYPE; // тип данных в столбце - см. "ltdefine.h"
parStruct1.key = 3; // дополнительный признак, очередность сортировки
strcpy(parStruct1.def,"1"); // значение по умолчанию
//добавим компоненту в массив компонент
AddArrayItem(attrType.columns, -1, &parStruct1, sizeof(parStruct1));
// колонка 3 "Резьба"
strcpy(parStruct1.header, "Резьба"); // заголовoк-комментарий столбца
parStruct1.type = STRING_ATTR_TYPE; // тип данных в столбце - см. "ltdefine.h"
parStruct1.key = 0; // очередность сортировки
strcpy(parStruct1.def,"М"); // значение по умолчанию
//добавим компоненту в массив компонент
AddArrayItem(attrType.columns, -1, &parStruct1, sizeof(parStruct1));
// колонка 4 "Диаметр"
strcpy(parStruct1.header, "Диаметр"); // заголовoк-комментарий столбца
parStruct1.type = UINT_ATTR_TYPE; // тип данных в столбце - см. "ltdefine.h"
parStruct1.key = 3; // очередность сортировки
strcpy(parStruct1.def,"12"); // значение по умолчанию
//добавим компоненту в массив компонент
AddArrayItem(attrType.columns, -1, &parStruct1, sizeof(parStruct1));
// колонка 5 "разделитель"
strcpy(parStruct1.header, ""); // заголовoк-комментарий столбца
parStruct1.type = STRING_ATTR_TYPE; // тип данных в столбце - см. "ltdefine.h"
parStruct1.key = 0; // очередность сортировки
strcpy(parStruct1.def,"х"); // значение по умолчанию
//добавим компоненту в массив компонент
AddArrayItem(attrType.columns, -1, &parStruct1, sizeof(parStruct1));
// колонка 6 "Шаг"
strcpy(parStruct1.header, "Шаг"); // заголовoк-комментарий столбца
parStruct1.type = FLOAT_ATTR_TYPE; // тип данных в столбце - см. "ltdefine.h"
parStruct1.key = 3; // очередность сортировки
strcpy(parStruct1.def,"1.25"); // значение по умолчанию
//добавим компоненту в массив компонент
AddArrayItem(attrType.columns, -1, &parStruct1, sizeof(parStruct1));
// колонка 7 "Поле допуска"
strcpy(parStruct1.header, "Поле допуска"); // заголовoк-комментарий столбца
parStruct1.type = STRING_ATTR_TYPE; // тип данных в столбце - см. "ltdefine.h"
parStruct1.key = 3; // очередность сортировки
strcpy(parStruct1.def,"-6g"); // значение по умолчанию
//добавим компоненту в массив компонент
AddArrayItem(attrType.columns, -1, &parStruct1, sizeof(parStruct1));
// колонка 8 "разделитель" strcpy(parStruct1.header, ""); // заголовoк-комментарий столбца
parStruct1.type = STRING_ATTR_TYPE; // тип данных в столбце - см. "ltdefine.h"
parStruct1.key = 0; // очередность сортировки
strcpy(parStruct1.def,"х"); // значение по умолчанию
//добавим компоненту в массив компонент
AddArrayItem(attrType.columns, -1, &parStruct1, sizeof(parStruct1));
// колонка 9 "Длина"
strcpy(parStruct1.header, "Длина"); // заголовoк-комментарий столбца
parStruct1.type = UINT_ATTR_TYPE; // тип данных в столбце - см. "ltdefine.h"
parStruct1.key = 3; // очередность сортировки
strcpy(parStruct1.def,"60"); // значение по умолчанию
//добавим компоненту в массив компонент
AddArrayItem(attrType.columns, -1, &parStruct1, sizeof(parStruct1));
// колонка 10 "Кл. прочности"
strcpy(parStruct1.header, "Кл. прочности"); // заголовoк-комментарий столбца
parStruct1.type = STRING_ATTR_TYPE; // тип данных в столбце - см. "ltdefine.h"
parStruct1.key = 0; // очередность сортировки
strcpy(parStruct1.def,".58"); // значение по умолчанию
//добавим компоненту в массив компонент
AddArrayItem(attrType.columns, -1, &parStruct1, sizeof(parStruct1));
// колонка 11 "Материал"
strcpy(parStruct1.header, "Материал"); // заголовoк-комментарий столбца
parStruct1.type = STRING_ATTR_TYPE; // тип данных в столбце - см.ниже
parStruct1.key = 0; // очередность сортировки
strcpy(parStruct1.def,".35Х"); // значение по умолчанию
//добавим компоненту в массив компонент
AddArrayItem(attrType.columns, -1, &parStruct1, sizeof(parStruct1));
// колонка 12 "Покрытие"
strcpy(parStruct1.header, "Покрытие"); // заголовoк-комментарий столбца
parStruct1.type = STRING_ATTR_TYPE; // тип данных в столбце - см. "ltdefine.h"
parStruct1.key = 0; // очередность сортировки
strcpy(parStruct1.def,".16"); // значение по умолчанию
//добавим компоненту в массив компонент
AddArrayItem(attrType.columns, -1, &parStruct1, sizeof(parStruct1));
// колонка 13 "ГОСТ"
strcpy(parStruct1.header, "ГОСТ"); // заголовoк-комментарий столбца
parStruct1.type = STRING_ATTR_TYPE; // тип данных в столбце - см. "ltdefine.h"
parStruct1.key = 0; // очередность сортировки
strcpy(parStruct1.def,"ГОСТ"); // значение по умолчанию
//добавим компоненту в массив компонент
AddArrayItem(attrType.columns, -1, &parStruct1, sizeof(parStruct1));
// колонка 14 "Номер"
strcpy(parStruct1.header, "Номер"); // заголовoк-комментарий столбца
parStruct1.type = UINT_ATTR_TYPE; // тип данных в столбце - см. "ltdefine.h"
parStruct1.key = 2; // очередность сортировки
strcpy(parStruct1.def,"7808"); // значение по умолчанию
//добавим компоненту в массив компонент
AddArrayItem(attrType.columns, -1, &parStruct1, sizeof(parStruct1));
// колонка 15 "разделитель"
strcpy(parStruct1.header, ""); // заголовoк-комментарий столбца
parStruct1.type = STRING_ATTR_TYPE; // тип данных в столбце - см. "ltdefine.h"
parStruct1.key = 0; // очередность сортировки
strcpy(parStruct1.def,"-"); // значение по умолчанию
//добавим компоненту в массив компонент
AddArrayItem(attrType.columns, -1, &parStruct1, sizeof(parStruct1));
// колонка 16 "Год"
strcpy(parStruct1.header, "Год"); // заголовoк-комментарий столбца
parStruct1.type = STRING_ATTR_TYPE; // тип данных в столбце - см. "ltdefine.h"
parStruct1.key = 0; // очередность сортировки
strcpy(parStruct1.def,"70"); // значение по умолчанию
//добавим компоненту в массив компонент
AddArrayItem(attrType.columns, -1, &parStruct1, sizeof(parStruct1));
// создать шаблон обозначения
/*double numbType =*/ ksCreateAttrType(&attrType, // информация о типе атрибута
ATTR_TYPE_LIB_NAME_KEY3); // имя библиотеки типов атрибутов
MessageBoxResult(); // проверяем результат работы нашей функции
//удалим массив колонок
DeleteArray(attrType.columns);
}
г) пример простановки линии-выноски к объекту спецификации :
//фрагмент ресурса
STRINGTABLE {
STR225 "Линию-выноску проставлять?"
STR226 "Укажите позиционную линию-выноску"
STR227 "!Создать новую линию-выноску !Подключить существующую"
STR228 "Ошибка! Объект - не позиционная линия-выноска!"
}
MENU_POS_LEADER MENU
{
MENUITEM "Подключить существующую", 2
MENUITEM "Создать новую линию-выноску ", 1
}
extern TModule *module;
//----------------------------------------------------------------------------------------------
// Отрисовать позиционную линию-выноску
// Уже проверено , что объект спецификации есть
// Функцию нужно запускать вне Cursor и Placement
//----------------------------------------------------------------------------------------------
void DrawPosLeader(reference _spcObj) {
RequestInfo info;
bool flag = false;
reference posLeater = 0;
double x1, y1;
char buf[128];
do {
memset(&info, 0, sizeof(info));
info.commands = (char*)MENU_POS_LEADER;
module->LoadString(STR226, buf, 128); //"Укажите позиционную линию-выноску"
info.prompt = buf;
int j1 = Cursor(&info, &x1, &y1, 0);
switch (j1) {
case 1: //Создать новую линию-выноску
posLeater = ::ksCreateViewObject(POSLEADER_OBJ);
flag = false;
break;
case 2: //Подключить существующую
module->LoadString(STR226, buf, 128); //"Укажите линию-выноску."
memset(&info, 0, sizeof(info));
info.commands = buf;
if(Cursor(&info, &x1, &y1, 0)) {
posLeater = ::FindObj(x1, y1, 100); // величина стороны окошка-ловушки с центром x,y
if (!(posLeater && ::GetObjParam(posLeater, 0, 0, 0) == POSLEADER_OBJ)) {
module->LoadString(STR228, buf, 128); //"Ошибка! Объект-не позиционная линия-выноска!"
Error(buf);
posLeater = 0;
flag = true;
}
else
flag = false;
break;
}
else
flag = false;
break;
case -1:
posLeater = ::FindObj(x1, y1, 100); // величина стороны окошка-ловушки с центром x,y
if (!(posLeater && ::GetObjParam(posLeater, 0, 0, 0) == POSLEADER_OBJ)) {
module->LoadString(STR228, buf, 128); //"Ошибка! Объект-не позиционная линия-выноска!"
Error(buf);
posLeater = 0;
flag = true;
}
else
flag = false;
break;
}
} while(flag);
//линия-выноска есть, подключим ее к объекту спецификации
if (posLeater ) {
//войдем в режим редактирования объекта спецификации
if (::ksSpcObjectEdit(_spcObj)) {
//подключим линию-выноску
::ksSpcIncludeReference(posLeater, true);
//закроем объект спецификации
::ksSpcObjectEnd();
}
}
}
