Вставка стандартных изделий в Компас 17.1 с помощью VBA

Автор Semargl1990, 25.02.20, 13:27:46

« предыдущая - следующая »

0 Пользователей и 1 гость просматривают эту тему.

Semargl1990

Здравствуйте! Не могу вставить в сборку болт из библиотеки Стандартные изделие с помощью VBA Excel. Excel тупо зависает в конце, и болт не вставляется в сборку. Кто знает решение, в чем может быть проблема?

Public Declare Function PLInsert3D Lib "C:\Program Files (x86)\ASCON\PartLib\Clients\plclient_kompas.dll" ()
 
Private Sub CommandButton1_Click()
Dim iPath As String
iPath = ActiveWorkbook.Path & "\" & "project" & "\" & "1" & ".a3d"

'Создаю документ сборки
Set kompas = New Kompas6API5.Application
    kompas.Visible = True
    Set ksdoc = kompas.Document3D
    ksdoc.Create False, False
 
'Сохраняю на диске
    kompas.ksMessage ("")
    ksdoc.Filename = iPath
    ksdoc.UpdateDocumentParam
    ksdoc.Save

'Создаю клиент СИ
Set BOPARTLib = New PARTLibClient.BOSimpleProvider
BOPARTLib.Connect ("Error")

BOPARTLib.SetInstrumentOptions "Kompas", "17124", "3DSolid", "3", "", gspShowMeasureDistance
Set aMethodResponse = BOPARTLib.SelectEx(0, "", "", 0)

'Получаю интерфейс сборки
Set kompas7 = kompas.ksGetApplication7
Set iDoc3D = kompas7.ActiveDocument
Set iMainPart = iDoc3D.TopPart

'Вставляю СИ в сборку
Set iMainPart = PLInsert3D(BOPARTLib, aMethodResponse, 0)

BOPARTLib.Disconnect

Semargl1990

Прошло неделя. Неужто никто не поможет? Хотя бы в каком направлении копать?
Sabahs  может Вы, как Гуру сообщества, сможете помочь?

Sabahs

Я не пользуюсь СИ.
У меня нет, SDK СИ.
Возможно, нужно создать новый компонент сборки, а потом передать указатель на СИ.
Тут мне непонятно.

Цитата: undefinedSet iMainPart = iDoc3D.TopPart

'Вставляю СИ в сборку
Set iMainPart = PLInsert3D(BOPARTLib, aMethodResponse, 0)

Semargl1990


Sabahs



Sabahs

Судя по справке, вставляется экземпляр в активный документ, из справочника, в заданное положение и возвращает указатель на вставленную деталь.
PS. Обычно с SDK идут примеры.

Semargl1990

Да примеры есть только в Delphi, C++,C#. То что "перевел", скажем так, не работает. Плюс выявилось такой момент: когда в конце зависает при нажатий клавиш CTRL + Break выскакивает ошибка.авто еррор.png

Semargl1990

Вот пример Delphi.

\\
Пример показывает, как с помощью API-функций вставить в документ КОМПАС-3D  типа сборка, спецификация, чертеж или фрагмент множество стандартных изделий одного типа, но имеющих все возможные типоразмеры, перечисленные в ISO.
Пример содержит полный листинг кода основного файла библиотеки под КОМПАС-3D на языке Delphi. В нем встречаются вызовы  API КОМПАС. Предполагается, что пользователь знает API КОМПАС. В тексте даны комментарии к вызовам функций Справочника. Названия функций выделены цветом. Цветом выделено также все то, что имеет отношение к этим функциям.
\\
unit apPLAPI;
interface
uses BOSimple_TLB, PARTLibClient_TLB, KsTLB;
function PLInsert3D(const aPLClient: IPARTLibProvider;
                    const aMethodResponse: IBOResponseDisp;
                    const aPlacement: ksPlacement): IDispatch; stdcall;
function PLInsert2D(const aPLClient: IPARTLibProvider;
                    const aMethodResponse: IBOResponseDisp;
                    const aX, aY, aAngle: Double): Integer; stdcall;
implementation
function PLInsert3D; external 'plclient_kompas.dll' Name 'PLInsert3D';
function PLInsert2D; external 'plclient_kompas.dll' Name 'PLInsert2D';
end.
//----------------------------------------------------------------------------------------------------
unit apMain;
interface
uses ksTLB, ksAuto, LDefin3D, ksConstTLB, Dialogs, ksApi7, Variants, SysUtils,
    LibTool, LDefin2D, Classes, PARTLibClient_TLB, BOSimple_TLB;
const
IDR_LIBID = 9940; // Идентификатор библиотеки
sLibName  = 'Тест: API'; //Имя библиотеки
plm2D              = '2D';            // Документ 2D
plm3D              = '3DSolid';      // Документ 3D
MethodNames: array[ksDocumentUnknown..ksDocumentTextual] of string =
    ('', 'КОМПАС 2D', 'КОМПАС 2D', 'КОМПАС 3D', 'КОМПАС 3D', 'КОМПАС 3D', '');
DOC_NAME: array[ksDocumentUnknown..ksDocumentTextual] of string =
    ('?', plm2D, plm2D, plm3D, plm3D, plm3D, '?');
// Задает идентификатор библиотеки
function  LIBRARYID: Cardinal; stdcall;
// Задает имя библиотеки
function LIBRARYNAMEW: PChar; stdcall;
// Головная функция библиотеки
procedure LIBRARYENTRY(command: WORD); stdcall;
implementation
uses Windows, StrUtils, ComObj, apPLAPI, forms;
var LastSuccCheckMsg: string;
//------------------------------------------------------------------------------
// Задать идентификатор ресурсов
//---
function  LIBRARYID: Cardinal; stdcall;
begin
  Result := IDR_LIBID;
end;
//------------------------------------------------------------------------------
// Задает имя библиотеки
//------------------------------------------------------------------------------
function LIBRARYNAMEW: PChar; stdcall;
begin
  Result := sLibName;
end;
procedure Truth(const aTrueValue: Boolean; const aErrorMessage: string);
begin
  if not aTrueValue then
    raise EAbort.Create(aErrorMessage)
  else
    LastSuccCheckMsg := aErrorMessage;
end;
function GetDocType(const aKompasApp: IApplication): DocumentTypeEnum;
var iDoc: IKompasDocument;
begin
  Result := ksDocumentUnknown;
  try
    Truth(Assigned(aKompasApp), 'aKompasApp is nil');
    iDoc := aKompasApp.ActiveDocument;
    if Assigned(iDoc) then
      Result := iDoc.DocumentType
    else
      Result := ksDocumentUnknown;
  except
  end;
end;
procedure LIBRARYENTRY(command: WORD); stdcall;
const
  // код папки со стандартами ISO
  ISO_FOLDER_ID = 'A259_151417DFF6474BF6';
var iKompasApp: IApplication;
    iKompasObj: KompasObject;
    iDoc2D: ksDocument2D;
    iDoc3D: ksDocument3D;
    iMainPart, iPrt: ksPart;
    // основной интерфейс Справочника
    iPLClient: IPARTLIbProvider;
    // метод, который будет применяться в КОМПАСе
    aMethodResponse: IBOResponseDisp;
    aPlace: ksPlacement;
    mac: Reference;
    // интерфейсы, которые будут использоваться, и переменные
    CD: ICommonData;
    ISOFolder: IFolder;
    ISOClass: IplClass;
    PG : IParamGrid;
    OutLocation: string;
    ClassInstances : IInstances;
    dt: DocumentTypeEnum;
    i : integer;
begin
  try
    iKompasApp := IDispatch(CreateKompasApplication) as IApplication;
    Truth(Assigned(iKompasApp), 'iKompasApp is nil');
    iKompasObj := IDIspatch(CreateKompasObject) as KompasObject;
    Truth(Assigned(iKompasObj), 'iKompasObj is nil');
    dt := GetDocType(iKompasApp);
    iDoc2D := ksDocument2D(iKompasObj.ActiveDocument2D);
    iDoc3D := ksDocument3D(iKompasObj.ActiveDocument3D);
    aPlace := nil;
    if Assigned(iDoc3D) then
    begin
      iMainPart := ksPart(iDoc3D.GetPart(integer(pTop_Part)));
      Truth(Assigned(iMainPart), 'iMainPart is nil');
      iPrt := ksPart(iDoc3D.GetPart(0));
      if Assigned(iPrt) then
        aPlace := ksPlacement(iPrt.GetPlacement);
    end;
    //создаем объект Справочника
    iPLClient := CreateOleObject('PARTLibClient.BOSimpleProvider') as IPARTLIbProvider;
    Truth(Assigned(iPLClient), 'Can''t create IPARTLIbProvider');
    try
      // получаем интерфейс для работы через API
      CD := iPLClient.CreateCommonDataObj;
      // инициализируем пользовательские данные
      CD.InitUserData;
      // задаем в контексте режим, в котором будет вестись поиск
      CD.SetFindOptions(DOC_NAME[dt]);
      // ищем интерфейс папки по идентификатору; это корневая папка с исо-стандартами, ее код задан константой, но его можно получить либо из Дизайнера моделей, либо через API, получив содержимое корневой папки
      ISOFolder := CD.FolderByID(ISO_FOLDER_ID);
      // пробегаем вложенные папки
      while ISOFolder.FolderCollection.Count >0 do
        // получаем интерфейс папки
        ISOFolder := ISOFolder.FolderCollection.Folder(0);
      // если в папке есть классы, то получаем интерфейс класса
      if ISOFolder.ClassCollection.Count > 0 then
      begin
        // получаем первый в списке класс
        ISOClass := ISOFolder.ClassCollection.plClass(0);
        // получаем интерфейс экземпляров
        ClassInstances := ISOClass.Instances('', DOC_NAME[dt]);
        // получаем интерфейс первой типоразмерной таблицы
        PG := ClassInstances.ParamGrid(0);
        if dt in [ksDocumentAssembly] then
          aPlace := iMainPart.GetPlacement as ksPlacement;
          // пробегаем все строки в типоразмерной таблице
        for i := 0 to PG.PGRowCount-1 do
          begin
            // выбираем строку
            PG.SelectRow(i);
           // получаем большой локейшен
            OutLocation := ClassInstances.CreateLocation;
            // получаем метод 
            aMethodResponse :=
              IBOResponseDisp(iPLClient.GetMethod(OutLocation, MethodNames[dt]));
            case dt of
              ksDocumentAssembly :
                begin
                  // спираль в плоскости x-y
                  aPlace.SetOrigin(5*i*sin(15*PI*i/180), 5*i*cos(15*PI*i/180), 0);
                  iPrt := ksPart(PLInsert3D(iPLClient, aMethodResponse, aPlace));
                end;
              ksDocumentDrawing,
              ksDocumentFragment:
                begin
                  // спираль в плоскости x-y
                  mac := PLInsert2D(iPLClient, aMethodResponse, 5*i*sin(15*PI*i/180), 5*i*cos(15*PI*i/180),180- i*15);
                  //iDoc2D.ksLightObj(mac, 1);
                end;
              ksDocumentSpecification:
                begin
                  PLInsert3D(iPLClient, aMethodResponse, nil);
                end;
            end;
          end;
      end;
    finally
      // освобождаем интерфейс
      iPLClient := nil;
    end;
  except
    on E: Exception do
      ShowMessage(E.Message + #13#10 + 'Last success check: ' + LastSuccCheckMsg);
  end;
end;

Sabahs

И, что Вы мне предлагаете, перевести на VBA?
Если разработчикам СИ не нужно, чтобы их API самостоятельно изучали, где оно в дистрибутиве?
API КОМПАС-3D идёт в дистрибутиве, с ним проблем нет и можно изучать самостоятельно.

Semargl1990

05.03.20, 12:13:31 #10 Последнее редактирование: 05.03.20, 12:29:50 от Semargl1990
Потому что у вас не корпоративная версия, у меня на работе установлена она. Хотел автоматизировать процесс черчения постоянных изделий, с разными типоразмерами на работе.
Пример выше на Delphi вставляется болты разного типоразмера по 1шт. в зависимости от типа открытого документа в спираль. Я же хотел просто создать 3д сборку, открыть справочник СИ, выбрать нужный болт, шайбу, гайку и вставить в сборку.

Sabahs

Вам нужно всё тоже самое проделать, только не для всех элементов, а для конкретного болта, гайки и шайбы.

Semargl1990

Вообще у меня есть сомнение насчет объявления функций PLInsert3D, оно описано в plclient_kompas.dll который лежит по пути C:\Program Files (x86)\ASCON\PartLib\Clients\plclient_kompas.dll,
обычно библиотеку подключал через TOOLS=>References, но именно этой dll нету в списке, пытался зарегистрировать в реестре не получилось, но когда объявил через эту строчку в VBA:
Public Declare Function PLInsert3D Lib "C:\Program Files (x86)\ASCON\PartLib\Clients\plclient_kompas.dll" ()
то VBA перестал ругаться на не объявленную функцию.
Может надо еще что-то объявлять, не могу понять. В конце тупо зависает, ошибку не выдает. Ошибку выдает как только нажимаешь на CTRL + Break, скрин ошибки выкладывал выше.

Sabahs

По идеи, должны быть библиотеки типов - TLB файлы из которых в Delphi генерируются PARTLibClient_TLB и BOSimple_TLB.
VBA.png

Semargl1990

06.03.20, 10:59:25 #14 Последнее редактирование: 06.03.20, 11:13:18 от Semargl1990
У меня в VBA Excel референсы почти на все нужные библиотеки стоять, кроме этой plclient_kompas.dll.В списке его нет.
подкл библ.png
При попытке добавить через Browser вылетает такая ошибка
подкл библ error.png
А при попытке зарегить выдает такую ошибку
подкл библ рег error 1.png
Только таким образом никакой ошибки не выдает, когда прописываю в блокнот:
Public Declare Function PLInsert3D Lib "C:\Program Files (x86)\ASCON\PartLib\Clients\plclient_kompas.dll" ()
Т.к. никогда до этого библиотеки вручную не объявлял, а указывал референсы через меню, то есть подозрение,
что что-то может упускаю, может еще функций и методы внутри этой библиотеки отдельно вручную объявлять надо?

Semargl1990

Вот файл EXCEL, где пытаюсь вставить СИ с помощью функций PLinsert3D, но безрезультатно, то зависнет, то выдает ошибку. Может кто-то может помочь комраду решить эту проблемку. Был бы очень благодарен.ПРОГА ВСТАВКА СТАНДАРТНЫХ ИЗДЕЛИЙ В СБОРКУ.zip