Ошибка при выделении текста в AutoCAD из Delphi
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Ошибка при выделении текста в AutoCAD из Delphi

Ошибка при выделении текста в AutoCAD из Delphi

Ответ
Поиск в этой теме
Непрочитано 20.10.2010, 14:49 #1
Ошибка при выделении текста в AutoCAD из Delphi
praeeo
 
Регистрация: 20.10.2010
Сообщений: 10

Приветствую!
Вроде и мелочь, но я на ней застрял. Ниже кусок кода для выделения текста в Автокаде из Делфи. При запуске вылетает ошибка "Недопустимый аргумент FilterType в Select". FilterType - это в данном примере переменная txtcode. Пробовал и как integer объявлять, как это делается в VBA - безуспешно. В чем тут соль?
Код:
[Выделить все]
procedure TForm2.Button1Click(Sender: TObject);
var
  iadoc: IAcadDocument;
  iselset: IAcadSelectionSet;
  iselsets: IAcadSelectionSets;
  txtcode: OleVariant;
  txttype: OleVariant;
begin;
  txtcode := 0;
  txttype := 'TEXT';
  ... //запуск Автокада
  iadoc := AcadApp.Documents.Open('c:\111.dxf', EmptyParam, EmptyParam);
  iselsets := iadoc.SelectionSets;
  iselset := iselsets.Add('t');
  iselset.Select(acSelectionSetAll, EmptyParam, EmptyParam,      txtcode, txttype); //здесь вылетает ошибка
end;
Просмотров: 4438
 
Непрочитано 20.10.2010, 15:25
#2
AlexV

Инженер
 
Регистрация: 02.10.2008
С-Пб
Сообщений: 3,692


По аналогии с VBA, наверное, txtcode должна быть integer, а txttype variant. Только там вроде бы массив должен быть, даже если он из одного элемента.. чего-то типа

Код:
[Выделить все]
 Dim txtcode(0) As Integer
 Dim txttype(0) As Variant
 Set sstext = ThisDrawing.SelectionSets.Add("t")
 txtcode(0) = 0
 txttype(0) = "TEXT"
 sstext.Select acSelectionSetAll, , ,  txtcode, txttype
__________________
...Не пытайся гнуть ты ложку,
Не вяжи её узлом.
Ложка - ложка понарошку,
А по правде, - это лом!

Последний раз редактировалось AlexV, 20.10.2010 в 15:41.
AlexV вне форума  
 
Автор темы   Непрочитано 20.10.2010, 15:37
#3
praeeo


 
Регистрация: 20.10.2010
Сообщений: 10


Цитата:
Сообщение от AlexV Посмотреть сообщение
По аналогии с VBA, наверное, txtcode должна быть integer, а txttype variant. Только там вроде бы массив должен быть, даже если он из одного элемента.. чего-то типа
Пробовал и integer с variant... Безрезультатно. Тем более что какая по идее разница, что за тип данных, если в делфийском варианте Select параметры типа OleVariant. Насчет массива в VBA я в курсе, только вот в Делфи такой вариант вроде как не реализовать (на array Делфи ругается).
praeeo вне форума  
 
Непрочитано 20.10.2010, 15:46
#4
AlexV

Инженер
 
Регистрация: 02.10.2008
С-Пб
Сообщений: 3,692


А почему в iselset.Select(acSelectionSetAll, EmptyParam, EmptyParam, txtcode, txttype) аргументы в скобках? Я, конечно, дельфей не знаю, но в VBA они без скобок.. Либо перед вызовом процедуры должно быть "Call".

Цитата:
Насчет массива в VBA я в курсе, только вот в Делфи такой вариант вроде как не реализовать (на array Делфи ругается).
Неужто в дельфи нет массива вообще как типа данных??
__________________
...Не пытайся гнуть ты ложку,
Не вяжи её узлом.
Ложка - ложка понарошку,
А по правде, - это лом!
AlexV вне форума  
 
Автор темы   Непрочитано 20.10.2010, 16:00
#5
praeeo


 
Регистрация: 20.10.2010
Сообщений: 10


Цитата:
Сообщение от AlexV Посмотреть сообщение
А почему в iselset.Select(acSelectionSetAll, EmptyParam, EmptyParam, txtcode, txttype) аргументы в скобках? Я, конечно, дельфей не знаю, но в VBA они без скобок.. Либо перед вызовом процедуры должно быть "Call".
=))) Потому что синтаксис в Делфи такой. Для меня например открытием было, что в VBA без скобок можно аргументы писать))))
Массивы конечно же есть, только они в эту процедуру никак не хотят лезть))))

Решил поступить по-другому. Добавил следующие строчки для нахождения текста в iselset и теперь вылазит где-то на 16-й итерации (всего объектов в iselset выдает больше 2000) такое страшное окошко - "Разрушительный сбой" =))):
Код:
[Выделить все]
  for I := 0 to iselset.Count - 1 do
  if iselset.Item(i).EntityType = 0 then
  ShowMessage(iselset.Item(i).EntityName);
Нечто подобное кстати было и при похожей операции в VBA. AlexV, Вы, кажется, в VBA больше меня разбираетесь? Почему так может быть?

Последний раз редактировалось praeeo, 20.10.2010 в 16:22.
praeeo вне форума  
 
Непрочитано 20.10.2010, 17:19
#6
AlexV

Инженер
 
Регистрация: 02.10.2008
С-Пб
Сообщений: 3,692


То есть, я так понимаю, Select без фильтра нормально работает..
А что нужно-то, из всех примитивов в файле выбрать однострочный текст?
Если просто без фильтра перебирать все объекты набора, то зачем вообще тогда создавать набор? Можно тупо перебрать все объекты modelspace, проверяя их тип..
__________________
...Не пытайся гнуть ты ложку,
Не вяжи её узлом.
Ложка - ложка понарошку,
А по правде, - это лом!
AlexV вне форума  
 
Автор темы   Непрочитано 20.10.2010, 17:36
#7
praeeo


 
Регистрация: 20.10.2010
Сообщений: 10


Да, без фильтра Select работает. И он действительно тогда не нужен)) Но дело в том, что и при использовании ModelSpace.Count выдает ту же самую ошибку - "Разрушительный сбой" где-то после 15 повторений цикла...
praeeo вне форума  
 
Непрочитано 20.10.2010, 17:52
#8
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,413
Отправить сообщение для Александр Ривилис с помощью Skype™


Цитата:
Сообщение от praeeo Посмотреть сообщение
Пробовал и как integer объявлять, как это делается в VBA - безуспешно. В чем тут соль?
В VBA Integer - это короткое целое (16-битное). Так что тебе нужен аналогичный тип и на Делфи.
Александр Ривилис вне форума  
 
Автор темы   Непрочитано 20.10.2010, 18:08
#9
praeeo


 
Регистрация: 20.10.2010
Сообщений: 10


Цитата:
Сообщение от Александр Ривилис Посмотреть сообщение
В VBA Integer - это короткое целое (16-битное). Так что тебе нужен аналогичный тип и на Делфи.
Перепробовал разные типы - smallint, shortint, word... Ничего не помогает(( Делфисты, хелп!
praeeo вне форума  
 
Непрочитано 20.10.2010, 19:15
#10
zamtmn

КИПиА
 
Регистрация: 21.03.2005
Tyumen
Сообщений: 1,352
<phrase 1=


Рискну предположить что нужен массив variant`ов, попробуй VarArrayCreate
zamtmn вне форума  
 
Автор темы   Непрочитано 21.10.2010, 14:11
#11
praeeo


 
Регистрация: 20.10.2010
Сообщений: 10


Цитата:
Сообщение от zamtmn Посмотреть сообщение
Рискну предположить что нужен массив variant`ов, попробуй VarArrayCreate
zamtmn, спасибо, Вы указали верное направление! И указание Александра Ривилиса очень помогло. Теперь Select работает. Вообще же я хотел бы реализовать функцию поиска и замены текста в Автокаде из Делфи. Решил не пользоваться сгенерированными при импорте библиотеки Автокада классами, а работать напрямую с интерфейсами. Но, реализовав Select, наткнулся на трудность с приведением типов. Ниже исправленный код с Select и "камень преткновения":

Код:
[Выделить все]
procedure TForm2.Button1Click(Sender: TObject);
var
  i: integer;
  iadoc: IAcadDocument;
  iselset: IAcadSelectionSet;
  iselsets: IAcadSelectionSets;
  txtcode,
  txttype: Variant;
begin
  txtcode:= VarArrayCreate ([0,3], varSmallint);
  txtcode[0]:= -4;
  txtcode[1]:= 0;
  txtcode[2]:= 0;
  txtcode[3]:= -4;
  txttype:= VarArrayOf (['<OR','TEXT','MTEXT','OR>']);
  AcadApp := GetAcadApplication(false);
  iadoc := AcadApp.Documents.Open('c:\111.dwg', EmptyParam, EmptyParam);
  iselsets := iadoc.SelectionSets;
  iselset := iselsets.Add('t');
  iselset.Select(acSelectionSetAll, EmptyParam, EmptyParam, txtcode, txttype);
  for I := 0 to iselset.Count - 1 do
  if pos ('AAA', string ((iselset.Item(i) as IAcadText).TextString)) <> 0 then ///ругается, на EIntfCastError, "Interface not supported"
  StringReplace (string ((iselset.Item(i) as IAcadText).TextString), 'AAA', 'BBB', [rfReplaceAll]); ///и здесь, соответственно, тоже 
end;
Как мне тогда использовать задействовать IAcadText? Что-то другие варианты в голову не приходят.
В VBA реализуется проще:
Код:
[Выделить все]
For Each objText In objSelSet
...
Next
Добавление:
Хм, вот так работает:
Код:
[Выделить все]
var
itxt: IAcadText;
itxt:= iselset.Item(2) as IAcadText; //явное указание Item
а вот так нет:
Код:
[Выделить все]
for i := 1 to iselset.Count - 1 do
itxt:= iselset.Item(i) as IAcadText; //через переменную i. Пишет, как и прежде, "Interface not supported"
Неужели дело снова в несоответствии числовых типов?

Последний раз редактировалось praeeo, 21.10.2010 в 15:16.
praeeo вне форума  
 
Непрочитано 21.10.2010, 16:57
#12
zamtmn

КИПиА
 
Регистрация: 21.03.2005
Tyumen
Сообщений: 1,352
<phrase 1=


а если в Item`у подсунуть variant, а не нативную переменную?
zamtmn вне форума  
 
Автор темы   Непрочитано 21.10.2010, 17:21
#13
praeeo


 
Регистрация: 20.10.2010
Сообщений: 10


Цитата:
Сообщение от zamtmn Посмотреть сообщение
а если в Item`у подсунуть variant, а не нативную переменную?
Из-за ошибки при i: variant(OleVariant) "E2032 For loop control variable must have ordinal type" (в цикле ,в общем, использовать Вариант нельзя)делаю вот так:
Код:
[Выделить все]
var
iole: Variant (или OleVariant)
...
for i := 1 to iselset.Count - 1 do
  begin
    iole:= i;
    itxt:= iselset.Item(iole) as IAcadText;
  end;
- но это тоже не помогает.

добавление:

Всё, разобрался. Дело было в разных типах текста: IAcadText (однострочный) и IAcadMText (многострочный). Вот исправленный, хотя еще и сырой, юнит поиска и замены, может кому понадобится. Спасибо всем за участие, тему можно закрыть )
Код:
[Выделить все]
unit acad;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, AutoCAD_TLB, StdCtrls, ComObj;

type
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    Function GetAcadApplication(Visible: Boolean): IAcadApplication;
    function ReplaceTxt (ss:IAcadSelectionSet; i: integer): WideString;
  private
    AcadApp: IAcadApplication;
  public
    { Public declarations }
  end;

var
  Form2: TForm2;
implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
var
  i: integer;
  iadoc: IAcadDocument;
  iselsets: IAcadSelectionSets;
  iselset: IAcadSelectionSet;
  txtcode, txttype: Variant;
begin
  txtcode := VarArrayCreate([0, 3], varSmallint);
  txtcode[0] := -4;
  txtcode[1] := 0;
  txtcode[2] := 0;
  txtcode[3] := -4;
  txttype := VarArrayOf(['<OR', 'TEXT', 'MTEXT', 'OR>']);
  AcadApp := GetAcadApplication(false);
  iadoc := AcadApp.Documents.Open('c:\123.dwg', EmptyParam,
    EmptyParam);
  iselsets := iadoc.SelectionSets;
  iselset := iselsets.Add('t');
  iselset.Select(acSelectionSetAll, EmptyParam, EmptyParam, txtcode, txttype);
  for i := 0 to iselset.Count - 1 do
  begin
    if iselset.Item(i).EntityName = 'AcDbText' then
       (iselset.Item(i) as IAcadText).TextString:= ReplaceTxt (iselset, i);
    if iselset.Item(i).EntityName = 'AcDbMText' then
       (iselset.Item(i) as IAcadMText).TextString:= ReplaceTxt (iselset, i);
    iselset.Update;
  end;
end;

function TForm2.ReplaceTxt(ss:IAcadSelectionSet; i: integer): WideString;
begin
  if ss.Item(i).EntityName = 'AcDbText' then
    if pos('23', string((ss.Item(i) as IAcadText).TextString)) <> 0 then
      Result := StringReplace(string((ss.Item(i) as IAcadText).TextString),
        '23', '89', [rfReplaceAll]);
  if ss.Item(i).EntityName = 'AcDbMText' then
    if pos('23', string((ss.Item(i) as IAcadMText).TextString)) <> 0 then
      Result := StringReplace(string((ss.Item(i) as IAcadMText).TextString),
        '23', '89', [rfReplaceAll]);
end;

function TForm2.GetAcadApplication(Visible: Boolean): IAcadApplication;
var
  v : OleVariant;
begin
  Try
    v := GetActiveOleObject('AutoCAD.Application');
  Except
    v:= CreateOleObject('AutoCAD.Application');
  end;
  Result := IDispatch(v) as IAcadApplication;
  if Visible then Result.Visible := True;
end;

Последний раз редактировалось praeeo, 22.10.2010 в 10:41.
praeeo вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Ошибка при выделении текста в AutoCAD из Delphi



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
В русской версии AutoCAD 2010 SP1 32-bit файл Acad.PGP содержит ошибки. hwd Баги и пожелания в Autodesk 21 21.04.2010 20:27
Ошибка 1308, что делать??? (Autocad 2007) yhukym AutoCAD 6 15.03.2010 17:53
Мигает многострочный текст при выделении в AutoCAD 2010 alex182 AutoCAD 3 15.01.2010 15:29
Delphi and AutoCAD John Ch. Программирование 4 31.01.2004 13:58