Вставить программно ссылку на позицию

Автор klimvv, 16.08.11, 23:58:31

« назад - далее »

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

klimvv

Хочу сделать скриптик, чтоб выделив позицию вставлял надпись типа "Дет. поз. 1" (как на рисунке).
Подскажите, плиз, как сделать чтоб вставка - цифра "1" -  была именно ссылкой, а не простым текстом.

333

см в API7 ITextLine::InsertHypertextReference
IHypertextReferenceParam - дополнительный интерфейс для ITextItem

klimvv

хоть убейте - не могу найти такого метода ни в справке ни в заголовочных файлах.... :`(

Все там есть, воспользуйтесь поиском в справке.

ITextLine::InsertHypertextReference - Добавить ссылку в текст

Синтаксис Automation:LPDISPATCH InsertHypertextReference( long TextItemIndex,
                                                                                              IKompasAPIObject * Object,
                                                                                              ksHypertextTypeEnum Type,
                                                                                              BOOL Brackets,
                                                                                              long TextLineIndex,
                                                                                              long Precision,
                                                                                              double PropertyId);

Синтаксис COM: HRESULT InsertHypertextReference( long TextItemIndex,
                                                                                IKompasAPIObject * Object,
                                                                                ksHypertextTypeEnum Type,
                                                                                BOOL Brackets,
                                                                                long TextLineIndex,
                                                                                long Precision,
                                                                                double PropertyId,
                                                                                ITextItem ** Result );
Входные параметры:

TextItemIndex - индекс компонента текста
Object - объект, на который сделана ссылка
Type - тип ссылки
Brackets - признак скобок
TextLineIndex - индекс строки в тексте
Precision - точность вывода числовых значений
PropertyId - идентификатор свойства

Возвращаемое значение: указатель на интерфейс компонента текста, содержащего ссылку


klimvv

Наконец-то снова вернулся к давней мечте - написать subject - и никак не поборю этот метод InsertHypertextReference
при вызове выскакивает Access Violation, хотя вроде ссылка на Object вполне реальная
Гляньте, плиз, код, что я не так делаю? Вот без этого вызова все работает - и позиционная выноска строится (т.е. ее reference сюда передается корректный) и сам по себе текст вставляется, а с InsertHypertextReference проблема
procedure InsertText(ref: Reference);
var pView: IView;
pDrawingContainer: IDrawingContainer;
pDrawingTexts: IDrawingTexts;
pDrawingText: IDrawingText;
pText: IText;
pTextLine: ITextLine;
  pTextItem: ITextItem;
  kobj: IKompasAPIObject;
begin
  pView:= GetView;
  if pView <> nil then begin
pDrawingContainer:= pView as IDrawingContainer;
if pDrawingContainer <> nil then begin
pDrawingTexts:= pDrawingContainer.DrawingTexts;
pDrawingText:= pDrawingTexts.Add();
pDrawingText.Allocation := 0;
pDrawingText.Angle := 0;
pDrawingText.Height := 10;
pDrawingText.Width := 50;
pDrawingText.HFormat := ksHFormatNot;
pDrawingText.VFormat := false;
pDrawingText.X := 0.0000;
pDrawingText.Y := 0.0000;

pText:= pDrawingText as Itext;

kobj:= IUnknown(ksTransferReference( ref, ksGetCurrentDocument(0) )) as IKompasAPIObject;
pTextLine:= pText.Add();
pTextLine.Str:= 'Дет. поз.  ';

    pTextLine.InsertHyperTextReference(1, kobj, ksHTPositionNumber, false, 0, 0, 0);
pDrawingText.Update();
end; //iDrawingContainer <> nil
  end; //iView <> nil
end;


p.s. и еще - что такое последний параметр PropertyID? где его брать?

ТрындецЪ

Я тоже упёрся в стену при попытке вставить ссылку в ячейку штампа на масштаб активного вида.
Вот код на python.
# -*- coding: cp1251 -*-
# Вставка в штамп ссылки на масштаб активного вида

import pythoncom
from win32com.client import Dispatch, gencache

KAPI7 = gencache.EnsureModule("{69AC2981-37C0-4379-84FD-5DD2F3C0A520}", 0, 1, 0)
iApplication = KAPI7.IApplication(Dispatch("Kompas.Application.7")._oleobj_.QueryInterface(KAPI7.IApplication.CLSID, pythoncom.IID_IDispatch))

iDocument = iApplication.ActiveDocument # получить текущий документ
iKompasDocument2D = KAPI7.IKompasDocument2D(iDocument) # Базовый класс графических документов КОМПАС
iViewsAndLayersManager = iKompasDocument2D.ViewsAndLayersManager # Менеджер слоев и видов графического документа
iViews = iViewsAndLayersManager.Views # Интерфейс коллекции видов графического документа
iView = iViews.ActiveView # Интерфейс активного вида

iLayoutSheets = iDocument.LayoutSheets # Интерфейс коллекции листов оформления
iLayoutSheet = iLayoutSheets.ItemByNumber (1) # Лист оформления, заданный по номеру

iStamp = iLayoutSheet.Stamp # Основная надпись листа
iText = iStamp.Text( 6 ) # Интерфейс текста ячейки штампа (6 ячейка - "Масштаб")
iTextLine = iText.TextLines[0] # интерфейс первой строки текста

#iTextLine.Str = 'Масштаб'  # Вставить текст

iTextLine.InsertHypertextReference(0, iView, 1, False, 0, 0, None) # Вставить ссылку

###########################################
##iTextItem = iTextLine.TextItems[0]
##iHypertextReferenceParam = KAPI7.IHypertextReferenceParam(iTextItem)
##iHypertextReferenceParam.LinkObject = iView
##iHypertextReferenceParam.HypertextType = 1
###########################################

iStamp.Update()  # Обновить данные в штампе


Не могу подобрать корректные аргументы для метода InsertHypertextReference, чтобы он их принял не выдав ошибку.


ТрындецЪ

Спасибо всем сочувствующим и неравнодушным, хотевшим помочь и не сумевшим это сделать.
Методом научного тыка с применением логических рассуждений решил-таки проблему самостоятельно.
Забил на метод  InsertHypertextReference, наверное он не для этого случая.
Решилось всё через IHypertextReferenceParam
Вот рабочий код:
# -*- coding: cp1251 -*-
# Вставка в штамп ссылки на масштаб активного вида

import pythoncom
from win32com.client import Dispatch, gencache

KAPI7 = gencache.EnsureModule("{69AC2981-37C0-4379-84FD-5DD2F3C0A520}", 0, 1, 0)
iApplication = KAPI7.IApplication(Dispatch("Kompas.Application.7")._oleobj_.QueryInterface(KAPI7.IApplication.CLSID, pythoncom.IID_IDispatch))

iDocument = iApplication.ActiveDocument # получить текущий документ
iKompasDocument2D = KAPI7.IKompasDocument2D(iDocument) # Базовый класс графических документов КОМПАС
iViewsAndLayersManager = iKompasDocument2D.ViewsAndLayersManager # Менеджер слоев и видов графического документа
iViews = iViewsAndLayersManager.Views # Интерфейс коллекции видов графического документа
iView = iViews.ActiveView # Интерфейс активного вида
iLayoutSheets = iDocument.LayoutSheets # Интерфейс коллекции листов оформления
iLayoutSheet = iLayoutSheets.ItemByNumber (1) # Лист оформления, заданный по номеру

iStamp = iLayoutSheet.Stamp # Основная надпись листа
iText = iStamp.Text( 6 ) # Интерфейс текста ячейки штампа (6 ячейка - "Масштаб")
iText.Str = '' # очищаем содержимое ячейки

iTextLine = iText.TextLines[0] # интерфейс первой строки текста
iTextItem =iTextLine.TextItems[0] # интерфейс первой компоненты строки текста
iTextItem.ItemType = 0x2000 # задаём тип компоненты строки текста (0x2000 - Cсылка на текст или положение объекта)
iHypertextReferenceParam = KAPI7.IHypertextReferenceParam(iTextItem) # Интерфейс параметров вставки ссылки в текст
iHypertextReferenceParam.LinkObject = iView # указываем интерфейс объекта, на который сделана ссылка
iHypertextReferenceParam.HypertextType = 1 # указываем тип ссылки на текст (для ссылки на вид: 1 - Масштаб вида)
iTextItem.Update() # обновляем компоненту строки текста

iStamp.Update()  # обновляем данные в штампе
+ Благодарностей: 3

msvteh

 Вставить в текст ссылку на положение объекта: Номер листа и Обозначение зоны
вот рабочий код:


procedure InsertText(ref: Reference; x : double; y : double);
var
pDrawingContainer: IDrawingContainer;
pDrawingTexts: IDrawingTexts;
pDrawingText: IDrawingText;
pText: IText;
pTextLine: ITextLine;
  pTextItem: ITextItem;
  kobj: IKompasAPIObject;
begin
// Получить контейнер графических объектов
pDrawingContainer := GetDrawingContainer;
if pDrawingContainer <> nil then
  begin
pDrawingTexts:= pDrawingContainer.DrawingTexts;
pDrawingText:= pDrawingTexts.Add();
pDrawingText.Allocation := ksAlCentre ; //0; 1 По центру.
pDrawingText.Angle := 0;
pDrawingText.Height := 10;
pDrawingText.Width := 50;
pDrawingText.HFormat := ksHFormatNot;
pDrawingText.VFormat := false;
pDrawingText.X := x-20 ;
pDrawingText.Y := y ;

pText:= pDrawingText as Itext;
    if pText <> nil then
    begin
      kobj:= IUnknown(ksTransferReference( ref, ksGetCurrentDocument(0) )) as IKompasAPIObject;
      if kobj <> nil then
      begin
        pTextLine:= pText.Add(); //Добавить строку в конец текста
        pTextLine.Align:= ksAlignCenter ; //1 Выравнивание по центру
        pTextLine.Str:= 'K';
         pTextLine:= pText.Add(); //Добавить строку в конец текста
        pTextLine.Align:= ksAlignCenter ; //1 Выравнивание по центру
        pTextItem :=pTextLine.Add() ;
        if ( pTextItem <> nil ) then
    begin
          pTextItem.Str := '(';
          // Задать тип
          pTextItem.ItemType := ksTItString ;//tType;
          // Применить параметры
          pTextItem.Update;
        end;
        // ссылка на Номер листа ksHTObjectSheet -2
        pTextLine.InsertHyperTextReference(2, kobj, ksHTObjectSheet, false, 0, 0, 0); //Номер листа
        // Получить интерфейс компоненты текста
        pTextItem :=pTextLine.Add() ;
        if ( pTextItem <> nil ) then
    begin
          pTextItem.Str := ',';
          // Задать тип
          pTextItem.ItemType := ksTItString ;//tType;
          // Применить параметры
          pTextItem.Update;
        end;
        // ссылка на Обозначение зоны ksHTObjectZone -1
        pTextLine.InsertHyperTextReference(4, kobj, ksHTObjectZone, false, 0, 0, 0);  //Обозначение зоны
        // Получить интерфейс компоненты текста
        pTextItem :=pTextLine.Add() ;
        if ( pTextItem <> nil ) then
    begin
          pTextItem.Str := ')';
          // Задать тип
          pTextItem.ItemType := ksTItString ;//tType;
          // Применить параметры
          pTextItem.Update;
        end;
        pDrawingText.Update();
      end;
    end;
end; //iDrawingContainer <> nil
end;
+ Благодарностей: 1

ТрындецЪ

18.09.18, 13:41:47 #8 Последнее редактирование: 18.09.18, 16:06:53 от ТрындецЪ
Не могу вставить в ЭСКИЗ ссылку на свойство документа, хотя в 2D документах всё корректно работает.
Вот кусок кода:

iTextLine = iText.Add()
iTextItem = iTextLine.Add()
iTextItem.ItemType = 0x2000
iHypertextReferenceParam = KAPI7.IHypertextReferenceParam(iTextItem)
iHypertextReferenceParam.LinkObject = iDocument
iHypertextReferenceParam.PropertyId = 5.0
iTextItem.Update()

KAPI7.IDrawingObject(iText).Update()


Upd: Кто-нибудь знает принцип формирования текста, полученного от ссылки?
Например, есть ссылка на свойство "Наименование", её текст выглядит так:

^(#6~Деталь)1;162442068216.000000;0;5.000000


6 - это длина текста;
Деталь - текст, который виден пользователю;
1 - ???;
162442068216.000000 - ???;
0 - тип ссылки на текст (ksHypertextTypeEnum);
5.000000 - ID свойства "Наименование".

С остальными я не разобрался. Больше всего интересует самое большое число, не пойму что это за идентификатор.

18.09.18, 16:18:24 #9 Последнее редактирование: 18.09.18, 16:42:14 от Sabahs
Читайте, тут http://forum.ascon.ru/index.php/topic,24881.msg191325.html#msg191325
Есть немного воды.
PS. Вам, ещё глубже нужно смотреть.
+ Благодарностей: 1

ТрындецЪ

Цитата: Sabahs от 18.09.18, 16:18:24
Читайте, тут http://forum.ascon.ru/index.php/topic,24881.msg191325.html#msg191325
Есть немного воды.
PS. Вам, ещё глубже нужно смотреть.
Спасибо за ответ, но я не понял, что из этого мне может помочь.
TextLineData для ссылки возвращает None

Возвращаясь к разбору строки получаемой от ссылки (^(#6~Деталь)1;162442068216.000000;0;5.000000).
Число 162442068216 явно идентификатор объекта ссылки, отсюда следует вопрос: как получить идентификатор не графического объекта (документа, фрагмента, тела, детали и т.п.)?
Когда я получал параметры ссылки на свойство созданной в эскизе, то объектом ссылки был фрагмент.


ТрындецЪ

Цитата: Sabahs от 19.09.18, 08:59:25
А эскиз это и есть документ типа фрагмент.
Это я понимаю. Как получить его идентификатор, а не Reference?

IFragmentDocument:=ISketch.BeginEdit - Войти в режим редактирования эскиза.

ТрындецЪ

Цитата: Sabahs от 19.09.18, 09:09:48
IFragmentDocument:=ISketch.BeginEdit - Войти в режим редактирования эскиза.
IFragmentDocument я получаю, но у него нет свойства Id, есть только Reference.

Например, Reference = 221130864
А ссылка вот такая:
^(#6~Деталь)1;162442068216.000000;0;5.000000~

Mary

вопрос в продолжение темы ссылок

есть выбранный на чертеже макроэлемент, присваиваю ему ему наименование и  дальше нужно создать текст со ссылкой на свойство

вставку ссылки списала отсюда:
Цитата: ТрындецЪ от 18.09.18, 13:41:47


iTextLine = iText.Add()
iTextItem = iTextLine.Add()
iTextItem.ItemType = 0x2000
iHypertextReferenceParam = KAPI7.IHypertextReferenceParam(iTextItem)
iHypertextReferenceParam.LinkObject = iDocument
iHypertextReferenceParam.PropertyId = 5.0
iTextItem.Update()

KAPI7.IDrawingObject(iText).Update()


и собственно вопрос в том, что подставляю в LinkObject  документ - все ок, выбранный макроэлемент - и ошибка
пробовала привести к  IKompasAPIObject, как здесь (ну почти - апи5 все еж не пользую)

Цитата: msvteh от 01.03.18, 22:01:51


      kobj:= IUnknown(ksTransferReference( ref, ksGetCurrentDocument(0) )) as IKompasAPIObject;
    <...>
       pTextLine.InsertHyperTextReference(2, kobj, ksHTObjectSheet, false, 0, 0, 0); //Номер листа


- тоже не работает

Помогите пожалуйста
Часть кода по теме вот, так же прикладываю файлом  весь макрос(обязательно выбрать в активном чертеже макро) и подопытный чертеж


# создание текста
newText = QI(v0, KAPI7.IDrawingContainer).DrawingTexts.Add()
# добираемся до iTextItem, создаем ссылку
iText = QI(newText, KAPI7.IText)
iTextItem = iText.Add().Add()
iTextItem.ItemType = 0x2000
iHypertextReferenceParam = KAPI7.IHypertextReferenceParam(iTextItem)
iHypertextReferenceParam.PropertyId = 5.0

# =================!!!!==================
# в SDK: "Тип данных: указатель на интерфейс IKompasAPIObject"
# iHypertextReferenceParam.LinkObject = iKSDoc2D  # все ок
iHypertextReferenceParam.LinkObject = macroObject  # !!!!!!!!!!!!!!!!!!!!
# iHypertextReferenceParam.LinkObject = KAPI7.IKompasAPIObject(macroObject)  # и тоже грустно


iTextItem.Update()
newText.Update()


Slaviation

Во вложении чертеж с макроэлементом и макрос создания текста со ссылкой на свойство "Наименование"макроэлемента.
+ Благодарностей: 1

Mary

возвращаете к вопросу формирования строки

text.Str = u"Свойство ^(#10~два кружка)1;150923381361.0;0;5.0~"

чертеж мне не открыть - V16.0

как из макро добыть (#10~два кружка) и 150923381361.0 ?


Mary

Примеры с форума очень помогают, Спасибо за возможность. С InsertHyperTextReference справиться не удалось, тем не менее - мой скромный вклад: функционал по отображению на чертеже наименования макрообъектов ( вроде блоков с атрибутами в автокаде):
- собирает все макро на чертеже
- для каждого макро находит текст внутри и в него вписывает наименование и подкрашивает
Дополнительно.  Цветовая кодировка в  ITextFont.Color  для компаса уникальная, прикладываю палитру


# -*- coding: cp1251 -*-

import Kompas10API7 as KAPI7
from win32com.client import Dispatch, gencache
import pythoncom


class KS(object):
    module7 = gencache.EnsureModule("{69AC2981-37C0-4379-84FD-5DD2F3C0A520}", 0, 1, 0)
    app7 = Dispatch('KOMPAS.Application.7')
    api7 = module7.IKompasAPIObject(app7._oleobj_.QueryInterface(module7.IKompasAPIObject.CLSID, pythoncom.IID_IDispatch))

    const = gencache.EnsureModule("{2CAF168C-7961-4B90-9DA2-701419BEEFE3}", 0, 1, 0).constants
    propMng = module7.IPropertyMng(app7._oleobj_.QueryInterface(module7.IPropertyMng.CLSID, pythoncom.IID_IDispatch))

    module5 = gencache.EnsureModule("{0422828C-F174-495E-AC5D-D31014DBBE87}", 0, 1, 0)
    api5 = module5.KompasObject(Dispatch("Kompas.Application.5")._oleobj_.QueryInterface(module5.KompasObject.CLSID, pythoncom.IID_IDispatch))
    iDocument3D = api5.Document3D()


def QI(fromInterface, toInterface):
    return toInterface(fromInterface._oleobj_.QueryInterface(toInterface.CLSID, pythoncom.IID_IDispatch))


def CollectMarcoObjects():
    views = KAPI7.IKompasDocument2D(KS.app7.ActiveDocument).ViewsAndLayersManager.Views
    v0 = views.ViewByNumber(0)
    # в данном случае макроэлементы собираются только в нулевом виде
    iMacroObjects = QI(v0, KAPI7.IDrawingContainer).MacroObjects
    return iMacroObjects


def ItemsList(iMacroObjects):
    eList = []
    for j in range(len(iMacroObjects)):
        m = iMacroObjects.MacroObject(j)
        eList.append(ShemElement(m))
    return eList


class ShemElement:
    def __init__(self, iMacroObject):
        self.macro = iMacroObject
        self.propKeeper = QI(self.macro, KAPI7.IPropertyKeeper)
        self.id = self.propKeeper.GetPropertyValue(idProp, "", True, True)[1]


# настройка стиля куска текста
def styleTextItem(iTextItem,  height=False):
    iTextFont = QI(iTextItem, KAPI7.ITextFont)
    iTextFont.Color = 0x808080
    if height:
        iTextFont.Height = height
    iTextFont.Italic = False
    iTextItem.Update()


# Интерфейс текущего 2д документа в апи7
iKSDoc2D = KAPI7.IKompasDocument2D(KS.app7.ActiveDocument)
iKSDoc2D1 = QI(iKSDoc2D, KAPI7.IKompasDocument2D1)

# и в апи5
doc2D = KS.api5.ActiveDocument2D()

# свойство "Наименование"
idProp = KS.propMng.GetProperty(iKSDoc2D, 5.0)

# собираем макроэлементы в лист
macroObjects = CollectMarcoObjects()

# из листа макроэлементов делаем лист элементов класса ShemElement
itemsList = ItemsList(macroObjects)

for i in itemsList:
    refMacro = i.macro.Reference  # реф используется в апи5 в 2д в качестве указателя на геометрию и прочее

    doc2D.ksOpenMacro(refMacro)  # переходим в режим редактирования макроэлемента
    iterator = KS.api5.GetIterator()  # создаем итератор - предназначен для перебора объектов заданного типа
    iterator.ksCreateIterator(4, refMacro)  # здесь использую для поиска текстового примитива внутри макроэлемта

    obj_i = iterator.ksMoveIterator("F")  # выбрать первый объект в итераторе

    if doc2D.ksExistObj(obj_i):

        iDrawingText = KS.api5.TransferReference(obj_i, 0)  # редактировать текст будем в апи7 - по ссылке получаем соответствующий указатель
        iText = QI(iDrawingText, KAPI7.IText)

        iText.Str = i.id  # подставить значение
        # эта функция полностью заменяет содержимое текста - создает новый со стилем по умолчанию
        # т.о. форматирование в текстовом примитиве не сохранится - цвет, размер шрифта, шаг строк править либо настройкой стиля
        # либо поверх - как в следующей функии:
        styleTextItem(iText.TextLine(0).TextItem(0))  # подкрасить текст - чтобы видно было на чертеже, какие объекты обновляются

        iDrawingText.Update()

    doc2D.ksEndObj()



открыть схему, изменить название макро, запустить код -  подписи в чертеже будут обновлены
+ Благодарностей: 1

Slaviation

ЦитироватьС InsertHyperTextReference справиться не удалось,
Добрый день.
Может пример из вложения поможет? Запустите его на активном чертеже из вложения. Он создаст текст у которого один из итемов ссылается на текст в линии - выноске обозначения позиции (строки 64 - 82).
Пример записан в PyKompasMacro с параметром  FormattedTextMode = 1. Его можно установить в файле conf\PyKompasMacro.ini в каталоге установки PyKompasMacro.