Имя: Пароль:
1C
 
1c и autocad: получить атрибуты блоков
Ø
0 Sten
 
01.03.06
18:24
Пытаюсь внешней обработкой получить данные атрибутов блоков из открытого файла AutoCad (артикул, ...)
Перед глазами макрос Excel (из стандартной поставки CADa).Там все работает.
1С ругается на "Тип переменой не поддерживается" при обращении GetAttributes.
Может кто делал подобное или сталкивался
1 Sten
 
01.03.06
20:28
Уж очень не хочется через промежуточный файл xls делать, хотелось бы напрямик 1С-CAD
2 pit
 
02.03.06
05:53
так вроде и напрямую работало ... Проблем никогда не было
3 Sten
 
02.03.06
10:16
Уважаемый pit. А можно кусочек кода, я волшебное слово знаю пожалуйста, а то совсем туплю
у меня получается следующее:
CAD = СоздатьОбъект("AutoCad.Application");
doc = CAD.ActiveDocument;
mspace = doc.ModelSpace;
Для i = 0 по mspace.count-1 Цикл
     elem = mspace.item(i);
     Если Строка(elem.EntityName)= "AcDbBlockReference" Тогда
  Если elem.HasAttributes = -1 Тогда
   array = elem.GetAttributes();//вот тут и ругается
.....
4 Денис2
 
02.03.06
10:22
(3) по документации GetAttributes() что возвращает?
5 Sten
 
02.03.06
10:38
Из хелпа VBA AutoCADa:
This method returns an array of editable attribute references attached to the block reference.
6 Sten
 
02.03.06
11:51
Я в отладчике вообще не могу получить ентот GetAttributes
Я и так и сяк, а он "ошибка в выражении"
7 Денис2
 
02.03.06
11:54
Значит, такой аррей возвращает...
8 Sten
 
02.03.06
11:58
pit спаси.....
9 Sten
 
02.03.06
15:15
Неужели никто ничего подобного не делал?
10 dk
 
02.03.06
15:56
Попробуй получить не весь массив, а какой-либо его элемент
11 Sten
 
02.03.06
17:01
to dk
Как?
12 Sten
 
02.03.06
17:07
Бьясь головой о стену:
 - Тип переменой не поддерживается, Тип переменой не поддерживается, Тип переменой не поддерживается....
13 dk
 
03.03.06
07:48
Давно с autocad не работал, так что только в теории:
array_item1 = elem.GetAttributes().item(1);
Зачем тебе array? Наверняка нужны элементы этого array?
14 Sten
 
03.03.06
10:10
to dk
Да элементы array это артрибуты блока, эти атрибуты и требуется получить
15 Sten
 
03.03.06
10:14
to dk
array_item1 = elem.GetAttributes().item(1);
//Тип переменной не поддерживается
:-(
16 Sten
 
03.03.06
14:59
Up - ну разок
18 pit
 
06.03.06
15:51
Писалось это около двух лет назад... Писали вдвоем...
1 этап - запускался аутокад и вызывалась 1С под определенным юзером, с запуском отчета, который просто формировал ДБФ с остатками и себестоимостью...
.
Конструктор делал чертеж, и помещал его в шару на сервере...
Если клиент подтверждал заказ, то оператор вводил в обработке в 1С название чертежа, она звала аутокад и по оле из аутокада брала из чертежа использованные материалы и их количество...
.
Вся инфа получалась в текстовом виде (числа как текст, названия как текст, коды материалов как текст, расход материала как текст). Вся поддержка этих запросов была на стороне аутокада писана не мной - моя только одноЭсная часть. Как это было реализовано в аутокаде - меня не интересовало шибко.
Проблемы с аутокадом были, но человек был грамотный и их решил. Кстати, аутокад был 2002 - в аутокаде 2004 разработка в лоб не заработала...
.
P.S. в ВБА есть два способа задания параметров (позиционный и по именам). По ОЛЕ в аутокаде работает только один способ - на эти грабли наступили...
Примеры работы по ОЛЕ брали из полного дистрибутива АУТОКАДА - разобрались довольно быстро. Там есть примеры для Экселя и еще чего то - пользовались эксельными примерами... В тех дистрибутивах, которые гуляют на пиратских дисках, примеры работы по оле есть, но их мало. У чела был расширенный лицензионный дистрибутив Аутокада...
19 Sten
 
06.03.06
15:58
Спасибо большое.
Насколько я понял CAD сам разбирался с блоками и атрибутами, загонял инфу в текст, а уж 1с работала с текстовым файлом. Верно?
20 smaharbA
 
06.03.06
16:10
(19)(0) Можно получить и аррей...
пользуй
Scr=CreateObject("MSScriptControl.ScriptControl");
scr.language="vbscript";
CAD = СоздатьОбъект("AutoCad.Application");
doc = CAD.ActiveDocument;
mspace = doc.ModelSpace;
Для i = 0 по mspace.count-1 Цикл
     elem = mspace.item(i);
     Если Строка(elem.EntityName)= "AcDbBlockReference" Тогда
  Если elem.HasAttributes = -1 Тогда
   scr.addobject("arrayE",elem.GetAttributes());//
а когда нада вытащить
Элемент=scr.eval("arrayE("+1+");
но можно "поумнее" если javascript и VBArray применить
21 Sten
 
06.03.06
16:22
2 smaharbA
scr.addobject("arrayE",elem.GetAttributes());
Тип переменой не поддерживается
22 smaharbA
 
06.03.06
16:26
(21) Тогда так
scr.addobject("elem",elem);
Элемент=scr.eval("elem.GetAttributes()("+1+")");
23 Sten
 
06.03.06
16:34
Ошибка выполнения Microsoft VBScript: Несоответствие типа: 'elem.GetAttributes()'
8(
24 MetaEditor
 
06.03.06
16:38
посмотрел бы уже давно в _экселевском_ отладчике чего там за массив такой... там то точно покажет.........
25 smaharbA
 
06.03.06
17:04
Вот примерчик с васиковским массивом тут иммитируется твой массив
Процедура Сформировать()
  Scr1=CreateObject("MSScriptControl.ScriptControl");
  scr1.language="vbscript";
  scr1.ехесutestatement("dim a(9)");
  scr1.ехесutestatement("for i=0 to 9: a(i)=i:next");
  Scr2=CreateObject("MSScriptControl.ScriptControl");
  scr2.language="javascript";
  scr2.addobject("scr1",scr1);
  a=scr2.eval("new VBArray(scr1.eval(""a""))");
  Для к=a.lbound(1) По a.ubound(1) Цикл
    Сообщить(a.getItem(к));
  КонецЦикла;
КонецПроцедуры
26 Sten
 
06.03.06
17:18
to MetaEditor
В экселевском отладчике тобишь отладчике VBA я смотрел ссамого начала - массив есть.
Я его в 1с отладчике не вижу!
to smaharbA
Поле агрегатного объекта не обнаружено (ехесutestatement)
Может потому что Win2000 Server? релиз 25 для SQL
8( уже пробил в стене дыркуууууу
27 MetaEditor
 
06.03.06
18:10
26) и что в этом массиве? числа? тогда должны работать примеры выше...
судя по
This method returns an array of editable ATTRIBUTE REFERENCES attached to the block reference
может там массив какихто структур или ещё чегонибуть...............
28 MetaEditor
 
06.03.06
18:20
можно покопать в
Scr1=CreateObject("MSScriptControl.ScriptControl");
scr1.language="vbscript";
  
scr1.AddCode("
|function GetArrItem(cnt)
|set CAD = CreateObject(""AutoCad.Application"")
|set doc = CAD.ActiveDocument
|set mspace = doc.ModelSpace
|for i = 0 to mspace.count-1
| set elem = mspace.item(i)
| if elem.EntityName = ""AcDbBlockReference"" then
| if elem.HasAttributes then
| GetArrItem = elem.GetAttributes(cnt)
| exit for
| end if
| end if
|next
|end function;");
CodeObject=scr1.Modules("Global").CodeObject;
зн = CodeObject.GetArrItem(2);
Сообщить(зн);
//ушол спать
29 Sten
 
06.03.06
18:26
(25) Попробывал на ХР такая же картина
30 smaharbA
 
06.03.06
18:39
Дак это и в 98 должно работать
Есть еще вариант(изврат), добавляешь в ексель функцию аналогичную (28) и пользуешь ее...
31 smaharbA
 
06.03.06
18:43
в (25) это "фишка" форума все схожие буквы он заменяет на русские ;)
32 Sten
 
06.03.06
18:50
(28) Ошибка компиляции Microsoft VBScript: Предполагается наличие окончания инструкции.
33 Sten
 
06.03.06
18:52
(31) Правда што ли. Не порядок.
34 smaharbA
 
06.03.06
18:52
(32) Ты все-же буковки в (25) и (28) проверь, лучче ручками напиши
в (28)
|end function;");
и
|end function");
35 Sten
 
06.03.06
18:55
(31) 25 код заработал
36 smaharbA
 
06.03.06
19:00
Теперь так
  Scr2=CreateObject("MSScriptControl.ScriptControl");
  scr2.language="javascript";
CAD = СоздатьОбъект("AutoCad.Application");
doc = CAD.ActiveDocument;
mspace = doc.ModelSpace;
Для i = 0 по mspace.count-1 Цикл
     elem = mspace.item(i);
     Если Строка(elem.EntityName)= "AcDbBlockReference" Тогда
  Если elem.HasAttributes = -1 Тогда
  scr2.addobject("elem",elem);
  a=scr2.eval("new VBArray(elem.GetAttributes())");
  Для к=a.lbound(1) По a.ubound(1) Цикл
    Сообщить(a.getItem(к));
  КонецЦикла;
///
Попробуй, может надо Enumerator, но этт потом позырим
37 smaharbA
 
06.03.06
19:04
Кстати идея хорошая, у меня мебеля тоже в автокаде рисуют, может тож раскрой и спецификацию прямо из него делать...
38 Sten
 
06.03.06
19:08
smaharbA
А у нас отопление: фитинги, краники....
39 pit
 
06.03.06
19:32
Встроенная мебель из дорогих материалов...
Основная идея нашей разработки была такова.
Беседуя с заказчиком и предлагая варианты, конструктор сразу лепит чертеж и начерно считает себестоимость прямо в аутокаде (но показывается стоимость+ работа, умноженные на процент наценки ) ...
По оперативно полученным данным... При этом можно применять материалы только те, которые в данный момент есть на складе - для этого и получаются остатки...
.
Если же клиент сразу подтвердил заказ - то чертеж идет в производство (после выверки точных размеров), а в 1С оператором формируется Документ "заказ" сразу со списком требуемых материалов и их количеством...
.
По условиям договора цена клиенту при заказе считалась предварительной и в ходе производства уточнялась, отклонение не могло быть больше 2-3 тыс рублей (опять таки по договору)...
40 smaharbA
 
06.03.06
19:41
(39) У нас больше серийное производство, но встречается и такое, да и меняются изделия со временем, вот и думаю в момент их пересматривания можно будет чтойто подобное соорудить, но пока не до этого замаяла бухия(вернее ГБ со своей непроходимостью)...
41 Sten
 
06.03.06
19:51
(36) Ошибка выполнения Microsoft JScript: Предполагается наличие VBArray
43 Sten
 
06.03.06
19:54
(41) относилось к
a=scr2.eval("new VBArray(elem.GetAttributes())");
44 smaharbA
 
06.03.06
19:58
(43) этт я понял, массив не VB...скорее думаю что это не массив а коллекция...
45 Sten
 
06.03.06
20:00
макрос из примера к АвтоГаду
//
Public acad As Object
Public mspace As Object
Public excel As Object
Public AcadRunning As Integer
Public excelSheet As Object
Sub Extract()
    Dim sheet As Object
    Dim shapes As Object
    Dim elem As Object
    Dim excel As Object
    Dim Max As Integer
    Dim Min As Integer
    Dim NoOfIndices As Integer
    Dim excelSheet As Object
    Dim RowNum As Integer
    Dim Array1 As Variant
    Dim Count As Integer
     
    Set excel = GetObject(, "Excel.Application")
    Worksheets("Attributes").Activate
    Set excelSheet = excel.ActiveWorkbook.Sheets("Attributes")
    excelSheet.Range(Cells(1, 1), Cells(1000, 100)).Clear
    excelSheet.Range(Cells(1, 1), Cells(1, 100)).Font.Bold = True
    Set acad = Nothing
    On Error Resume Next
    Set acad = GetObject(, "AutoCAD.Application")
    If Err <> 0 Then
        Set acad = CreateObject("AutoCAD.Application")
        MsgBox "Please open a drawing file and then restart this macro."
        Exit Sub
    End If
    Set doc = acad.ActiveDocument
    Set mspace = doc.ModelSpace
    RowNum = 1
    Dim Header As Boolean
    Header = False
    For Each elem In mspace
        With elem
            If StrComp(.EntityName, "AcDbBlockReference", 1) = 0 Then
                If .HasAttributes Then
                    Array1 = .GetAttributes
                    For Count = LBound(Array1) To UBound(Array1)
                        If Header = False Then
                            If StrComp(Array1(Count).EntityName, "AcDbAttribute", 1) = 0 Then
Count + 1).Value = Array1(Count).TagString
                            End If
                        End If
                    Next Count
                    RowNum = RowNum + 1
                    For Count = LBound(Array1) To UBound(Array1)
                        excelSheet.Cells(RowNum, Count + 1).Value = Array1(Count).TextString
                    Next Count
                    Header = True
                End If
            End If
        End With
    Next elem
    NumberOfAttributes = RowNum - 1
    If NumberOfAttributes > 0 Then
        Worksheets("Attributes").Range("A1").Sort _
        key1:=Worksheets("Attributes").Columns("A"), _
        Header:=xlGuess
    Else
        MsgBox "No attributes found in the current drawing."
    End If
    Set acad = Nothing
End Sub
46 smaharbA
 
06.03.06
20:04
Ставлю автокад ;)
47 Sten
 
06.03.06
20:07
smaharbA поклон до земли.
Впервые такое участие и желание помочь. Спасибо.
Респект и уважуха (почти цитата из Comedy Club)
48 smaharbA
 
06.03.06
20:09
(47) Просто я сегодня слегка трезв...
49 Sten
 
06.03.06
20:09
Этот пример лежит ...\Sample\ActiveX\ExtAttr\
50 Sten
 
06.03.06
20:11
(48) ;0) Ничего скоро праздники
51 smaharbA
 
06.03.06
20:56
1. Это несовсем массив, это объект, счас зырю
52 Sten
 
06.03.06
20:59
Значит хелп наврал.
53 smaharbA
 
06.03.06
21:45
(52) Не наврал, там сказано что в ВБА он преобразуется в вариант при присвоении
54 smaharbA
 
07.03.06
06:10
Точна, утро вечера умнее...
//*******************************************
Процедура Сформировать()
  Scr2=CreateObject("MSScriptControl.ScriptControl");
  scr2.language="vbscript";
  acad = CreateObject("AutoCAD.Application");
  excel = CreateObject("Excel.Application");
  acad.Visible = -1;
  wbook=excel.workbooks.Open("C:\Program Files\ACAD2000\SAMPLE\ACTIVEX\ExtAttr\getatt.xls");
  doc = acad.Documents.Open("C:\Program Files\ACAD2000\SAMPLE\ACTIVEX\ExtAttr\attrib.dwg");
  doc = acad.ActiveDocument;
  mspace = doc.ModelSpace;
  RowNum = 1;
  Для i = 0 по mspace.count-1 Цикл
    elem = mspace.item(i);
    Если Строка(elem.EntityName)= "AcDbBlockReference" Тогда
      Если elem.HasAttributes = -1 Тогда
        scr2.addobject("wbook",wbook);
        scr2.addobject("elem",elem);
        scr2.ехесutestatement("obj=elem.GetAttributes()");
        Для к=scr2.eval("lbound(obj)") По scr2.eval("ubound(obj)") Цикл
          scr2.ехесutestatement("set a=wbook.getatt(obj,"+к+")");
          Сообщить(scr2.eval("a.TextString"));
        КонецЦикла;
        scr2.Reset();
      КонецЕсли;
    КонецЕсли;
  КонецЦикла;
КонецПроцедуры
*******************************
И в файл getatt.xls всего одну функцию
Public Function getatt(a, i)
Set getatt = a(i)
End Function
(можно это и в акад вставить, но не стал разбираться как вызывать)
и конечно снизить уровень безопасности в екселе(ручками или программно в реестре)
Короче пока вышел дурдом, но работает...
55 smaharbA
 
07.03.06
06:34
Немного упростил
//*******************************************
Процедура Сформировать()
  Scr2=CreateObject("MSScriptControl.ScriptControl");
  scr2.language="vbscript";
  acad = CreateObject("AutoCAD.Application");
  excel = CreateObject("Excel.Application");
  acad.Visible = -1;
  wbook=excel.workbooks.Open("C:\Program Files\ACAD2000\SAMPLE\ACTIVEX\ExtAttr\getatt.xls");
  scr2.addobject("wbook",wbook);
  doc = acad.Documents.Open("C:\Program Files\ACAD2000\SAMPLE\ACTIVEX\ExtAttr\attrib.dwg");
  mspace = doc.ModelSpace;
  Для i = 0 по mspace.count-1 Цикл
    elem = mspace.item(i);
    Если Строка(elem.EntityName)= "AcDbBlockReference" Тогда
      Если elem.HasAttributes = -1 Тогда
        scr2.addobject("elem"+i,elem);
        scr2.ехесutestatement("obj=elem"+i+".GetAttributes()");
        Для к=scr2.eval("lbound(obj)") По scr2.eval("ubound(obj)") Цикл
          a=scr2.eval("wbook.getatt(obj,"+к+")");
          Сообщить(a.TextString);
        КонецЦикла;
      КонецЕсли;
    КонецЕсли;
  КонецЦикла;
КонецПроцедуры
56 Sten
 
07.03.06
10:14
Пробую на 2004
58 smaharbA
 
07.03.06
11:19
(57) Отправил, наверно ты уровень безопасности у екселя не снизил...
59 Sten
 
07.03.06
11:22
Спасибочки, получил, буду гладеть.
Еще раз спасибо.
60 Sten
 
07.03.06
11:28
Елы палы. Действительно виновата была безопасность в екселе.
Ну а без екселя никак не обойтись? ;) Нехочется дополнительно грузить оперативку
61 smaharbA
 
07.03.06
11:31
(60) Думаю все это можно и в автокаде проделать, только не разбирался как, там както проект отдельно грузится, посмотрю, но давай послезавтра...
62 callisto
 
07.03.06
11:37
ну круто замутили 1С и AutoCAD :))))
зы. как-то представил сие "прожорство" (или "обжорство"), но даже и не предполагал про практическое пользование... :)))
63 Sten
 
07.03.06
11:42
Ок. До после праздников ;)