Логотип сайта поддержки пользователей САПРО сайте поддержки пользователей САПР Translate to:

AutoCAD 2000 и Visual LISP. Самоучитель
Купить книгу
Глава из книги "AutoCAD 2004:
разработка приложений и адаптация"
Н.Н. Полещука.
На домашнюю страницу автора

Применение COM

Фирма Microsoft разработала модель COM (Component Object Model — модель компонентных объектов), позволяющую связывать самые разнородные приложения. Построенный по спецификации этой модели программный комплекс предоставляет описание своих компонентов и средств доступа к ним другим программам. Это дает возможность проектировать такие системы, в которых одни приложения (приложения-клиенты) обращаются к другим приложениям (приложениям-серверам) для выполнения некоторых операций, специфичных для приложений-серверов. При этом приложение-сервер может запускаться в видимом режиме (когда для него открывается свое окно) и в невидимом (приложение работает в оперативной памяти, не открывая своего окна).

Приложения, поддерживающие технологию COM, при установке заносят в реестр Windows информацию о себе, о своих компонентах, объектах. Так, например, имя приложения (ProgID), под которым оно может быть вызвано как приложение-сервер, заносится в реестр в раздел HKEY_CLASSES_ROOT.


Рис. 2.56. Окно редактора реестра Windows (строка, связанная с AutoCAD 2004)

На рис. 2.56 в окне редактора реестра видно, что последняя версия AutoCAD зарегистрирована как AutoCAD.Application.16. Под таким именем нужно вызывать (создавать) объект приложения AutoCAD, если вы будете обращаться к нему из приложения-клиента.

В реестре также находится информация о том, как можно обратиться к любому зарегистрированному объекту (для этого есть специальные интерфейсы), какие методы к нему применимы.

В данном разделе рассматриваются два примера использования технологии COM. В первом из них система AutoCAD читает таблицу, созданную в Microsoft Excel 2002, а во втором — пишет свои данные в книгу Excel 2002. Эти два примера также являются демонстрацией одного из способов работы с электронными таблицами и базами данных из сеанса AutoCAD.

Построение таблицы спецификации с импортом данных из файла Excel 2002

В предыдущей книге "AutoCAD 2002" серии "В подлиннике" был приведен пример переноса данных из Excel 2000 в таблицу, создаваемую в рисунке AutoCAD 2002. Результаты обсуждения этого примера в Интернете использованы в этом разделе. В частности, учтена проблема корректной выгрузки табличного процессора Excel из памяти (возможны случаи, когда программы, используемые в качестве COM-серверов, множатся в оперативной памяти).

Довольно часто приходится в рисунке AutoCAD создавать таблицу (например, спецификации), данные для которой находятся в файле Excel. Пример решения такой задачи приводится в настоящем разделе. Можно было бы такую таблицу получить вставкой OLE-объекта, но это не всегда удобно.

Анализ методов и свойств приложения Excel

Так же, как мы сделали это ранее для системы AutoCAD 2004, узнаем с помощью реестра, под каким именем следует в COM-технологии обращаться к приложению Microsoft Excel 2002. В результате получим строку "Excel.Application.10" (можно пользоваться и укороченной строкой "Excel.Application" — в этом случае операционная система сама определяет, какая версия Excel является последней на данном компьютере, а программист должен учитывать возможность вызова не той версии, на которую он рассчитывал).

С помощью функции vlax-dump-object прочитаем список методов, которые можно применять к объекту приложения Excel, и максимально допустимое количество аргументов этих методов. Делается это с помощью следующего выражения:

(vlax-dump-object (vlax-get-or-create-object "Excel.Application.10") T)

Получим список свойств и методов изучаемого объекта. Перечислим сначала методы (на самом деле они располагаются в конце листинга):

ActivateMicrosoftApp (1), AddChartAutoFormat (3), AddCustomList (2), Calculate (), CalculateFull (), CalculateFullRebuild (), CentimetersToPoints (1), CheckAbort (1), CheckSpelling (3), ConvertFormula (5), DDEExecute (2), DDEInitiate (2), DDEPoke (3), DDERequest (2), DDETerminate (1), DeleteChartAutoFormat (1), DeleteCustomList (1), DoubleClick (), Evaluate (1), ExecuteExcel4Macro (1), FindFile (), GetCustomListContents (1), GetCustomListNum (1), GetOpenFilename (5), GetPhonetic (1), GetSaveAsFilename (5), Goto (2), Help (2), InchesToPoints (1), InputBox (8), Intersect (30), MacroOptions (10), MailLogoff (), MailLogon (3), NextLetter (), OnKey (2), OnRepeat (2), OnTime (4), OnUndo (2), Quit (), RecordMacro (2), RegisterXLL (1), Repeat (), Run (31), SaveWorkspace (1), SendKeys (2), SetDefaultChart (2), Undo (), Union (30), Volatile (1), Wait (1), _Evaluate (1), _Run2 (31).

По сравнению с Excel 2000 появились новые методы: CalculateFullRebuild и CheckAbort

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

ActiveCell, ActiveChart, ActivePrinter, ActiveSheet, ActiveWindow, ActiveWorkbook, AddIns, AlertBeforeOverwriting, AltStartupPath, AnswerWizard, Application, AskToUpdateLinks, Assistant, AutoCorrect, AutoFormatAsYouTypeReplaceHyperlinks, AutomationSecurity, AutoPercentEntry, AutoRecover, Build, CalculateBeforeSave, Calculation, CalculationInterruptKey, CalculationState, CalculationVersion, Caller, CanPlaySounds, CanRecordSounds, Caption, CellDragAndDrop, Cells, Charts, ClipboardFormats, Columns, COMAddIns, CommandBars, CommandUnderlines, ConstrainNumeric, ControlCharacters, CopyObjectsWithCells, Creator, Cursor, CursorMovement, CustomListCount, CutCopyMode, DataEntryMode, DDEAppReturnCode, DecimalSeparator, DefaultFilePath, DefaultSaveFormat, DefaultSheetDirection, DefaultWebOptions, Dialogs, DisplayAlerts, DisplayClipboardWindow, DisplayCommentIndicator, DisplayExcel4Menus, DisplayFormulaBar, DisplayFullScreen, DisplayFunctionToolTips, DisplayInsertOptions, DisplayNoteIndicator, DisplayPasteOptions, DisplayRecentFiles, DisplayScrollBars, DisplayStatusBar, EditDirectlyInCell, EnableAnimations, EnableAutoComplete, EnableCancelKey, EnableEvents, EnableSound, ErrorCheckingOptions, Excel4IntlMacroSheets, Excel4MacroSheets, ExtendList, FeatureInstall, FileConverters, FileDialog, FileFind, FileSearch, FindFormat, FixedDecimal, FixedDecimalPlaces, GenerateGetPivotData, Height, Hinstance, Hwnd, IgnoreRemoteRequests, Interactive, International, Iteration, LanguageSettings, Left, LibraryPath, MailSession, MailSystem, MapPaperSize, MathCoprocessorAvailable, MaxChange, MaxIterations, MemoryFree, MemoryTotal, MemoryUsed, MouseAvailable, MoveAfterReturn, MoveAfterReturnDirection, Name, Names, NetworkTemplatesPath, NewWorkbook, ODBCErrors, ODBCTimeout, OLEDBErrors, OnWindow, OperatingSystem, OrganizationName, Parent, Path, PathSeparator, PivotTableSelection, PreviousSelections, ProductCode, PromptForSummaryInfo, Range, Ready, RecentFiles, RecordRelative, ReferenceStyle, RegisteredFunctions, ReplaceFormat, RollZoom, Rows, RTD, ScreenUpdating, Selection, Sheets, SheetsInNewWorkbook, ShowChartTipNames, ShowChartTipValues, ShowStartupDialog, ShowToolTips, ShowWindowsInTaskbar, SmartTagRecognizers, Speech, SpellingOptions, StandardFont, StandardFontSize, StartupPath, StatusBar, TemplatesPath, ThisCell, ThisWorkbook, ThousandsSeparator, Top, TransitionMenuKey, TransitionMenuKeyAction, TransitionNavigKeys, UsableHeight, UsableWidth, UsedObjects, UserControl, UserLibraryPath, UserName, UseSystemSeparators, Value, VBE, Version, Visible, Watches, Width, Windows, WindowsForPens, WindowState, Workbooks, WorksheetFunction, Worksheets, _Default.

По сравнению с Excel 2000 появились новые свойства: AutoFormatAsYouTypeReplaceHyperlinks, AutomationSecurity, AutoRecover, CalculationInterruptKey, CalculationState, DecimalSeparator, DisplayFunctionToolTips, DisplayInsertOptions, DisplayPasteOptions, ErrorCheckingOptions, FileDialog, FindFormat, GenerateGetPivotData, Hinstance, Hwnd, MapPaperSize, NewWorkbook, Ready, ReplaceFormat, RTD, ShowStartupDialog, SmartTagRecognizers, Speech, SpellingOptions, ThisCell, ThousandsSeparator, UsedObjects, UseSystemSeparators, Watches.
Тестовый файл книги Excel

Предположим, что данные для таблицы спецификации, которую нам нужно начертить в рисунке AutoCAD, располагаются в листе Спецификация книги (файла) d:\r 16\readex.xls (рис. 2.57).


Рис. 2.57. Окно просмотра листа книги readex.xls

На рисунке видно, что в нашем файле четыре листа (помимо листа Спецификация, есть еще листы Примитивы, Расходы, Материалы), поэтому программа должна не только открыть книгу Excel, но еще и обратиться к нужному листу.

В листе Спецификация для облегчения программирования введены дополнительные данные, которые уточняют характеристики будущей таблицы деталей, создаваемой в системе AutoCAD.

В первой строке в ячейке A1 дано количество деталей (т. е. строк таблицы без учета заголовка — 6), а в ячейке B1 — количество столбцов таблицы (5). Вторая строка листа Спецификация — размеры столбцов по ширине в мм (10, 70, 25, 35 и 25). Третья строка уточняет тип данных, которые располагаются в соответствующем столбце (int — целое, real — вещественное, str — текст). При выводе вещественных чисел будем давать по одной цифре после десятичной точки.

Четвертая строка — названия колонок таблицы (Позиция, Наименование, Толщина, Материал, Количество).

Сделаем аргументами нашей программы следующие:

Будем считать, что в каждой ячейке текст должен быть выровнен по левому краю и располагаться с отступом 1 мм от левой, нижней и правой границ, а если текст будет длинным, его нужно будет вписать в соответствующую ячейку (аналогично опции Fit (По ширине) команды TEXT (ТЕКСТ)).

Тексты программ

В листингах 2.4—2.8 приведен текст основной программы readex10_com и тексты вспомогательных программ (функций).

Листинг 2.4. Программа readex10_com

; Н.Н. Полещук, 2003

;===================================================

; Программа COM-связи AutoCAD - Microsoft Excel 2002

;===================================================

; Вычерчивание таблицы по данным из книги Excel

; Используются текущий слой, текущий цвет и текущий текстовый стиль

;

; Аргументы:

;   tb_xls - имя файла книги Excel;

;   sheetname - имя листа;

;   hcell - высота ячейки таблицы;

;   hlet - высота букв текста таблицы;

;   show - признак показа Excel во время работы (T или nil)

;

; Глобальные переменные:

;   g_oex - VLA-объект приложения Excel 2002;

;   g_wkbs - VLA-объект семейства Workbooks;

;   g_awb - VLA-объект активной книги;

;   g_shs - VLA-объект семейства Sheets;

;   g_mainsh - VLA-объект нужного листа книги;

;   g_cell - VLA-объект ячейки.

;

; Примеры обращения к программе:

; (readex10_com "d:\\r 16\\readex.xls" "Спецификация" 8.0 5.0 T)

; (readex10_com "d:\\r 16\\readex.xls" "Спецификация" 5.0 3.0 nil)

;

(defun readex10_com (tb_xls sheetname hcell hlet show / nlines ncolumns

  table_items i j row pt0 widths types headers xx1 xx2 yy1 ww val

  old_ortho old_snap old_osnap old_echo)

; Подгрузка библиотек, обеспечивающих работу с ActiveX

(vl-load-com)

; Отключение эхо-вывода

(setq old_echo (getvar "CMDECHO"))

(setvar "CMDECHO" 0);

; Установление связи с Excel

(ex10_set_connect show)

; Указатель семейства Workbooks

(setq g_wkbs (vlax-get-property g_oex "Workbooks"))

; Открытие файла (книги) и получение указателя книги

(setq g_awb (vlax-invoke-method g_wkbs "Open" tb_xls))

; Проверка открытия файла

(if (not g_awb)

  (progn

    (alert (strcat "Не обнаружен файл " tb_xls))

    (ex_break_connect)

    (exit)

  )

)

; Чтение списка листов; не обязательно активизировать нужный

(setq g_shs (vlax-get-property g_awb "Worksheets"))

; Указатель на лист с нужным именем  

(vlax-for s g_shs (if (= sheetname (vlax-get-property s "Name"))(setq g_mainsh s)))

(if (not g_mainsh)

  (progn

    (alert (strcat "Не обнаружен лист " sheetname))

    (ex_break_connect)

    (exit)

  )

)

;

; Чтение количества строк в будущей таблице спецификации

;  (из ячейки A1 листа Excel), без учета строки заголовков

(setq g_cell

  (vlax-variant-value (vlax-invoke-method g_mainsh "Evaluate" "A1")))

(setq nlines

  (fix (vlax-variant-value (vlax-get-property g_cell "Value"))))

(vlax-release-object g_cell)

; Чтение количества столбцов в будущей таблице спецификации

;  (из ячейки B1 листа Excel)

(setq g_cell

  (vlax-variant-value (vlax-invoke-method g_mainsh "Evaluate" "B1")))

(setq ncolumns

  (fix (vlax-variant-value (vlax-get-property g_cell "Value"))))

(vlax-release-object g_cell)

;

; Получение списка элементов таблицы (ряды 2,3,4, ... Excel)

; Ряд 2 - ширины столбцов в мм

; Ряд 3 - заголовки столбцов

(setq table_items nil j 1)

(repeat (+ nlines 3)

  (setq row nil j (1+ j) i -1)

  (repeat ncolumns

    (setq i (1+ i))

    (setq g_cell

      (vlax-variant-value

        (vlax-invoke-method

          g_mainsh

          "Evaluate"

          (strcat (chr (+ i (ascii "A"))) (itoa j))

        )

      )

    )

    (setq row

      (append

        row

        (list

          (vlax-variant-value

            (vlax-get-property g_cell "Value")

          )

        )

      )

    )

    (vlax-release-object g_cell)

  );repeat ncolumns

  (setq table_items (append table_items (list row)))

);repeat nlines

;

; Закрытие и выгрузка Excel

(ex_break_connect)

;

; Запрос точки левого верхнего угла таблицы

(setq pt0 nil)

(while (null pt0)

  (setq pt0 (getpoint "\nТочка левого верхнего угла таблицы: "))

);while

;

(setq widths (nth 0 table_items) types (nth 1 table_items))

;

; Рисование сетки (высота ячеек hcell)

(tab_lines pt0 ncolumns nlines widths hcell) 

;

; Заголовки таблицы

(setq headers (nth 2 table_items) i –1

      xx1 (car pt0) yy1 (- (cadr pt0) hcell))

(repeat ncolumns

  (setq i (1+ i) ww (nth i widths) xx2 (+ xx1 ww))

  (setq val (nth i headers))

  (write_item val "str" xx1 xx2 yy1 hlet)

  (setq xx1 xx2)

);

;

; Вписывание элементов таблицы

(setq j 2)

(repeat nlines

  (setq j (1+ j) i -1 xx1 (car pt0) yy1 (- (cadr pt0) (* (1- j) hcell)))

  (repeat ncolumns

    (setq i (1+ i) ww (nth i widths) xx2 (+ xx1 ww))

    (setq val (nth i (nth j table_items)))

    (setq itype (nth i types))

    (write_item val itype xx1 xx2 yy1 hlet)

    (setq xx1 xx2)

  );repeat ncolumns

);repeat nlines

;

; Восстановление режима эхо-вывода

(setvar "CMDECHO" old_echo)

;

(redraw)

(princ)

)
Листинг 2.5. Программа ex10_set_connect
; Установка связи с Excel 2002

; Аргумент:

;   vis = T – сделать Excel видимым;

;   vis = nil – сделать Excel невидимым.

;

(defun ex10_set_connect (vis / )

(setq g_oex (vlax-get-or-create-object "Excel.Application.10"))

; Если связь не установлена, то аварийно завершить работу

(if (null g_oex)

  (progn

    (alert "Невозможно запустить Microsoft Excel 2002")

    (exit)

  )

);if

; Сделать Excel видимым в зависимости от параметра vis 

(if vis (vlax-put-property g_oex "Visible" :vlax-true))

)
Листинг 2.6. Программа ex_break_connect
; Разрыв связи с Excel и выгрузка из памяти

(defun ex_break_connect ( / )

(vlax-invoke-method g_oex "Quit")

; Освобождаем объекты, связанные с Excel,

; для корректной выгрузки Excel из памяти

(mapcar

  (function (lambda (x)

    (if

      (and x (not (vlax-object-released-p x)))

      (vlax-release-object x)

    )

  ))

  (list g_cell g_mainsh g_shs g_awb g_wkbs g_oex)

)

; Сборка мусора

(setq g_cell nil g_mainsh nil g_shs nil g_awb nil g_wkbs nil g_oex nil)

(gc)

)
Листинг 2.7. Программа write_item
; Вычерчивание элемента таблицы, с отступом от границ ячейки

; Аргументы:

;   item  - элемент (текст, число);

;   typ   - тип ("int", "str", ...);

;   x1,x2 – граничные абсциссы заполняемой ячейки;

;   yi    - ордината нижней границы ячейки;

;   hl    - высота букв надписи;

;   wi    - ширина ячейки.

;

; Пояснение к некоторым рабочим переменным:

; gapx – отступ по X от левой и правой границ ячейки;

; gapy - отступ по Y от левой и правой границ ячейки.

;

(defun write_item (item typ x1 x2 yi hl / gapx gapy wi yig st size sizex)

(setq gapx 1.0 gapy 1.0 wi (- x2 x1) yig (+ yi gapy))

(if item

  (progn

;

; Преобразование значения item в текст, в зависимости от типа

; Значения типа "int" нужно обрабатывать без дробной части

    (setq st

      (if (= typ "int") (itoa (fix item))(vl-princ-to-string item)))

;

; Если текст помещается в ячейке, то вписываем его

; с выравниванием по левой нижней точке

; Если текст не помещается, то вписываем его с опцией Fit (По ширине)

    (setq size (textbox (list (cons 1 st) (cons 40 hl))))

    (setq sizex (- (caadr size) (caar size)))

    (if (<= sizex (- wi (+ gapx gapx)))

      (entmake

        (list '(0 . "TEXT") (cons 1 st) (cons 10 (list (+ x1 gapx) yig))

          (cons 40 hl) '(72 . 0)))

      (entmake

        (list '(0 . "TEXT") (cons 1 st) (cons 10 (list (+ x1 gapx) yig))

          (cons 11 (list (- x2 gapx) yig)) (cons 40 hl) '(72 . 5)))

    );if

  );progn

);if item

);
Листинг 2.8. Программа tab_lines
; Вычерчивание линий таблицы

; Аргументы:

;   p0   - точка верхнего левого угла таблицы;

;   nc   - количество столбцов;

;   nl   - количество строк;

;   wids - список ширин столбцов;

;   h    - высота строк.

;

(defun tab_lines (p0 nc nl wids h / w k xx yy htab)

; Вычисление полной ширины таблицы

  (setq w 0.0 k -1)

  (repeat nc (setq k (1+ k) w (+ w (nth k wids))))

;

; Горизонтальные отрезки

  (setq xx (car p0) yy (cadr p0))

  (repeat (+ nl 2)

    (entmake

      (list '(0 . "LINE") (cons 10 (list xx yy))

        (cons 11 (list (+ xx w) yy))))

    (setq yy (- yy h))

  );repeat

;

; Вертикальные отрезки

  (setq xx (car p0) yy (cadr p0) htab (* h (1+ nl)) k -1)

  (entmake

    (list '(0 . "LINE") (cons 10 (list xx yy))

      (cons 11 (list xx (- yy htab)))))

  (repeat nc

    (setq k (1+ k) xx (+ xx (nth k wids)))

    (entmake

      (list '(0 . "LINE") (cons 10 (list xx yy))

        (cons 11 (list xx (- yy htab)))))

  );repeat

);defun

Перед выполнением программ, приведенных в листингах 2.4—2.8, необходимо их загрузить, а затем обратиться к головной программе readex10_com, например:

(readex10_com "d:\\r 16\\readex.xls" "Спецификация" 8.0 5.0 T)

(readex10_com "d:\\r 16\\readex.xls" "Спецификация" 5.0 3.0 nil)

Результат построения таблицы в первом случае приведен на рис. 2.58, во втором — на рис. 2.59.


Рис. 2.58. Построенная таблица (hcell = 8.0, hlet = 5.0)


Рис. 2.59. Построенная таблица (hcell = 5.0, hlet = 3.0)

Анализ программ

Дадим некоторые пояснения к работе комплекса программ.

После установки связи с Microsoft Excel 2002 головная программа вычисляет последовательно указатели: g_oex (указатель объекта самого приложения Excel), g_wkbs (указатель семейства Workbooks), g_awb (указатель активной книги после открытия в Excel файла readex.xls), g_shs (указатель семейства листов), g_mainsh (указатель нужного листа, в нашем примере — Спецификация).

Затем с помощью метода Evaluate читаются значения, записанные в листе Спецификация в ячейках A1 (nlines — количество строк или деталей) и B1 (ncolumns — количество столбцов в будущей таблице). Поскольку метод Evaluate возвращает значение типа VARIANT, для его сохранения в виде обычного целого числа применяется преобразование типа с помощью функции vlax-variant-value.

Далее, применяя тот же метод Evaluate, сканируем строки 2—10 листа Спецификация и получаем список table_items из девяти элементов, каждый из которых является списком, состоящим из пяти значений:

((10.0 70.0 25.0 35.0 25.0) ("int" "str" "real" "str" "int")
("Позиция" "Наименование" "Толщина" "Материал" "Количество")
(1.0 "Планка" 4.5 "A" 2.0) (3.0 "Бракета" 10.0 "C" 1.0)
(4.0 "Кница" 8.0 "A" 3.0) (8.0 "Планка" 6.0 "B" 2.0)
(14.0 "Лист" 18.0 "A" 4.0) (16.0 "Кница" 6.0 "B" 1.0)).

Первый элемент списка table_items (ширина столбцов) сохраняется для удобства в переменной widths, второй (типы значений по столбцам) — в переменной types, а третий (заголовки столбцов) — в переменной headers.

Из списка видно, что все значения, являющиеся как вещественными, так и целыми числами, представлены в вещественном виде. Поэтому при вписывании их в таблицу нужно будет пользоваться типами "int" или "real".

После формирования table_items программа ex_break_connect закрывает соединение с табличным процессором Excel и выгружает его из памяти. При этом проверяется, какие глобальные переменные, содержащие указатели объектов Excel, сформированы, и их объекты аннулируются с помощью функции vlax-release-object. Это позволяет избежать неприятного эффекта, когда приложение Excel не удаляется из памяти. При повторениях процесса количество неудаленных приложений растет и может даже исчерпать всю оперативную память на компьютере.

Далее интерактивно запрашивается точка p0, которая будет точкой верхнего левого угла таблицы спецификации деталей. Цикл, организованный с помощью функции while, исключает возможность пустого ввода нажатием на клавишу (это можно было сделать и путем применения функции initget).

Подпрограмма tab_lines рисует отрезки, формирующие строки и столбцы с ячейками таблицы. В качестве четвертого и пятого аргументов этой функции передаются ширина столбцов и высота строк.

Подпрограмма write_item осуществляет заполнение разлинованной таблицы значениями из списка table_items. Для построения надписи используется не команда TEXT (ТЕКСТ), как в предыдущей книге, а функция entmake, которой передается список с основными данными будущего примитива.

Перед построением надписи программа с помощью функции textbox выясняет размеры будущего примитива, если использовать в качестве способа выравнивания привязку к левому нижнему углу надписи. Если ширина надписи (sizex) оказывается больше допустимой (т. е. надпись не поместится в ячейке, с учетом отступов gapx и gapy), то текст надписи выводится аналогично опции Fit (По ширине) команды TEXT (ТЕКСТ).

Все элементы таблицы перед выводом преобразуются подпрограммой write_item к текстовому виду, при этом используется тип значения, который передается через аргумент typ. Именно здесь числа, которые должны быть целыми, преобразуются к целому типу, а в вещественных сохраняется только один знак после десятичной точки.

Приведенные в листингах 2.4—2.8 программы удобны тем, что в самом файле Excel можно задать такие настройки таблицы, как количество и тип элементов, ширина столбцов. Читатель может на основе этого текста создать для себя наиболее удобный вариант. Опытный программист может добавить к программе более тщательный разбор значений, занесенных предварительно в книгу Excel, поскольку при больших объемах данных обязательно возникают ошибки, которые надо обрабатывать.

Экспорт данных в таблицу Excel 2002

Для передачи данных из рисунка, сформированного в системе AutoCAD, в таблицу Excel, следует использовать другие свойства и методы, но в целом схема решения такой задачи такая же, как и в задаче, рассмотренной в предыдущих разделах этой главы.

  1. Сформировать данные, которые будут экспортироваться.
  2. Вызвать приложение Excel.
  3. Открыть или создать файл книги Excel.
  4. Открыть или создать лист книги;
  5. Назвать ячейки, в которые будут выполняться запись.
  6. Заполнить выбранные ячейки подготовленными данными.
  7. Сохранить файл Excel.
  8. Выйти из Excel.
  9. Освободить все VLA-объекты, открытые для работы с Excel.
Текст программы

В листинге 2.9 приведен текст программы writeex10_com с примером такой операции:

Листинг 2.9. Программа writeex10_com
; Н.Н. Полещук, 2003

;===================================================

; Программа COM-связи AutoCAD - Microsoft Excel 2002

;===================================================

; Занесение подготовленных данных в создаваемый файл книги Excel

;

; Аргументы:

; shname1, shname2 – имена листов;

; bname – имя создаваемого файла.

;

; Глобальные переменные:

;   g_oex - VLA-объект приложения Excel 2002;

;   g_wbs - VLA-объект семейства Workbooks;

;   g_cb  - VLA-объект текущей книги;

;   g_csh - VLA-объект первого листа;

;   g_sh2 - VLA-объект второго листа;

;   g_shs - VLA-объект семейства Sheets;

;   g_r1, g_r2, g_cr - VLA-объекты диапазонов ячеек.

;

; Примеры обращения к программе:

; (writeex10_com "Экспорт (набор 1)" "Секция 2" "d:\\r 16\\ExportBook")

; (writeex10_com "Старт" "Финиш" "d:\\r 16\\ExportBook1")

 

(defun writeex10_com (shname1 shname2 bname / )

(vl-load-com)

; Загружаем Excel без открытых книг

(setq g_oex (vlax-get-or-create-object "Excel.Application.10"))

; Задаем количество листов, которое создается в новой книге

; (по умолчанию обычно 3)

(vlax-put-property g_oex 'SheetsInNewWorkbook 2)

; Делаем окно Excel видимым

(vlax-put-property g_oex 'Visible :vlax-true)

; Указатель семейства Workbooks

(setq g_wbs (vlax-get-property g_oex 'Workbooks))

; Добавлем новую книгу

(setq g_cb (vlax-invoke-method g_wbs 'Add)) 

; Указатель семейства Sheets

(setq g_shs (vlax-get-property g_cb 'Sheets))

;

; С помощью свойства Item получаем указатель первого листа

(setq g_csh (vlax-get-property g_shs 'Item 1))

; Меняем имя первого листа (было Лист1)

 (vlax-put-property g_csh 'Name shname1)

; Указатель второго листа

(setq g_sh2 (vlax-get-property g_shs 'Item 2))

; Имя второго листа

(vlax-put-property g_sh2 'Name shname2)

 

; Задаем первый диапазон ячеек B3:B3 (в первом листе)

(setq g_r1 (vlax-get-property g_oex "Range" "B3:B3"))

; Активация второго листа

(vlax-invoke-method g_sh2 'Activate)

; Задаем второй диапазон ячеек A2:C4 (во втором листе)

(setq g_r2 (vlax-get-property g_oex "Range" "A2:C4"))

; Активация первого листа

(vlax-invoke-method g_csh 'Activate)

; Запись в сформированные диапазоны

(vlax-put-property g_r1 "value2" 1234)

(vlax-put-property g_r2 "value2" "Пишу в тишине")

; Задаем третий диапазон из ячейки E7 (в первом листе)

(setq g_cr (vlax-get-property g_csh 'Range "E7"));

; Запись в ячейку

 (vlax-put-property g_cr "value2" -17.873)

; Сохраняем новую книгу (XLS-файл)

(vlax-invoke-method g_cb 'SaveAs bname -4143 "" ""
    :vlax-false :vlax-false nil)

; Выходим из Excel

(vlax-invoke-method g_oex "Quit")

; Освобождение объектов и выгрузка Excel

(if (and g_cr (not (vlax-object-released-p g_cr)))

  (vlax-release-object g_cr))

(if (and g_r2 (not (vlax-object-released-p g_r2)))

  (vlax-release-object g_r2))

(if (and g_r1 (not (vlax-object-released-p g_r1)))

  (vlax-release-object g_r1))

(if (and g_csh (not (vlax-object-released-p g_csh)))

  (vlax-release-object g_csh))

(if (and g_sh2 (not (vlax-object-released-p g_sh2)))

  (vlax-release-object g_sh2))

(if (and g_shs (not (vlax-object-released-p g_shs)))

  (vlax-release-object g_shs))

(if (and g_cb (not (vlax-object-released-p g_cb)))

  (vlax-release-object g_cb))

(if (and g_wbs (not (vlax-object-released-p g_wbs)))

  (vlax-release-object g_wbs))

(if (and g_oex (not (vlax-object-released-p g_oex)))

  (vlax-release-object g_oex))

; Обнуление использованных глобальных переменных

(setq g_cr nil g_r2 nil g_r1 nil g_csh nil g_sh2 nil

      g_shs nil g_cb nil g_wbs nil g_oex nil)

; Сборка мусора

(gc)

)
После загрузки программы writeex10_com к ней можно обратиться, например, таким образом:

(writeex10_com "Экспорт (набор 1)" "Секция 2" "d:\\r 16\\ExportBook")

Результат заполнения первого листа новой книги приведен на рис. 2.60, в второго — на рис. 2.61.


Рис. 2.60. Первый заполненный лист


Рис. 2.60. Второй заполненный лист

Анализ программы

Теперь пояснения к работе программы, приведенной в листинге 2.9 в рабочем варианте (читатель, внимательно разобравший предыдущий пример, может разбить ее на функции, добавить аргументы).

После установки связи с Microsoft Excel 2002 программа вычисляет указатель g_oex (указатель объекта самого приложения Excel). В памяти создается экземпляр приложения Excel (в нем пока нет ни одной книги и его окно не видно). Затем с помощью метода SheetsInNewWorkbook задается количество листов (2), которые будут генерироваться в новых книгах, и с помощью метода Add, применяемого к семейству (g_wbs — его указатель семейства Workbooks), открывается пустая новая книга. Далее изменение свойства Visible делает окно приложения Excel видимым.

Теперь в новой книге создано два листа и выполняется операция их переименования с помощью изменения значения свойства Name, применяемого к указателю первого (g_csh) и второго (g_sh2) листов.

Далее поочередно формируются три диапазона ячеек: g_r1 и g_cr — в первом листе, g_r2 — во втором листе. В каждый из диапазонов, которые являются объектами типа Range, записываются свои значения (причем во все девять ячеек диапазона g_r2 заносятся одно и то же значение — строка "Пишу в тишине"). В операции записи используется свойство Value2.

В заключительной части выполняется сохранение открытой книги в файле d:\r 16\ExportBook.xls и закрывается окно приложения Excel. После этого освобождаются все VLA-объекты, созданные программой, и приложение Excel покидает оперативную память (Диспетчер задач Windows вам это подтвердит).

Приведенная в листинге 2.9 программа с большой вероятностью будет работать и в других версиях Excel, но возможны отличия в некоторых методах и свойствах.



Copyright © Сайт поддержки пользователей САПР by Victor Tkachenko