Темы сайта
Интегрированная система ruCAD - приложение к базовой системе AutoCAD.

Система ruCAD - это приложение строительного профиля в широком понимании, то есть предназначенная для автоматизации строительного проектирования, реконструкции и технического перевооружения любых зданий и сооружений.В отличие от других систем, ориентированных на конкретную область применения, в ruCAD включены средства для комплексной разработки проектной документации наиболее распространенных разделов проекта, выполняемых во всех проектных организациях.
Система управления контентом MODx
Ограничения
В соответствии с Договором между издательством и авторами мы не имеем права полностью публиковать в Интернет материалы книги.

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

Так помечены материалы, не опубликованные на сайте!

Новинки
Книга была выпущена в 2004 году. С тех пор многое изменилось - появились версии AutoCAD 2005, 2006, 2007, 2008.

Система ruCAD была выпущена в свет, появились замечания и предложения пользователей. Да и у нас появились новые представления по некоторым вопросам.

Поэтому в материалы книги, публикуемые на сайте, мы вносим дополнительные замечания, выделяемые так:
Так выделяются дополнительные замечания, комментарии, указания!
Где спросить
На нашем сайте было уже несколько форумов. На них было зарегистрировано более 400 посетителей, а многие заходили просто так, в гости. Но сейчас мы вывели форумы из открытого режима. Подробнее о наших форумах
Если очень нужно что-то узнать о ruCAD именно в форумном формате, заходите на Форум сайта
AutoCAD и проектирование
Внимание!
Технические решения и исходные тексты, публикуемые на сайте, могут быть устаревшими!

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


Выполнение SQL-запроса к объекту соединения с ADO



(defun ru-ado-exec-sql (connection_object
                        sql
                        /
                        command_object
                        fields_object
                        field_count
                        field_list
                        field_number
                        is_error
                        item
                        records_affected
                        record_set_list
                        record_set_object
                        result
                        temp_object

                       )
  (setq command_object (vlax-create-object "ADODB.Command"))
  (vlax-put-property command_object "CommandText" sql)
  (vlax-put-property command_object "ActiveConnection" connection_object)
  (setq record_set_object (vlax-create-object "ADODB.RecordSet"))
  ;; Открываем набор данных   и пытаемся выловить ошибки
  (if (vl-catch-all-error-p
        (setq temp_object
               (vl-catch-all-apply
                 'vlax-invoke-method
                 (list command_object
                       "Execute"
                       'records_affected
                       nil
                       ru-ado-const-adcmdtext
                 ) ;_ end of list
               ) ;_ end of vl-catch-all-apply
        ) ;_ end of setq
      ) ;_ end of vl-catch-all-error-p
    (progn
;;; В случае сбойной ситуации выводим сообщение об ошибках
      (ru-ado-error-messages
        (ru-ado-error-handler temp_object connection_object)
        sql
      ) ;_ end of ru-ado-error-messages
      (setq is_error t)
      (vlax-release-object command_object)
      (vlax-release-object record_set_object)
    ) ;_ end of progn
    (setq record_set_object temp_object)
  ) ;_ end of if
;;; Если ошибок нет, обрабатываем данные
  (if (not is_error)
    ;; Если набор закрыт
    (if (= ru-ado-const-adstateclosed
           (vlax-get-property record_set_object "State")
        ) ;_ end of =
      ;; Закрытый набор остается при SQL-запросах,
      ;; содержащих  DELETE, INSERT или UPDATE
      ;; Записи при этом не возвращаются и можно
      ;; удалить объекты
      (progn
        (setq result records_affected)
        (vlax-release-object record_set_object)
        (vlax-release-object command_object)
      ) ;_ end of progn
      (progn
       ;| Для запросов SELECT вытаскиваем данные полей.
Получаем свойство Fields, и количество полей.
Теперь значения полей нужно преобразовать в список. В Delphi мы легко
получали значение любого поля, в LISP это сложнее.

|;
        (setq fields_object
                            (vlax-get-property record_set_object "Fields")
              field_count
                            (vlax-get-property fields_object "Count")
              field_number  -1
        ) ;_ end of setq
        ;; Составляем список отобранных полей
        (while (> field_count (setq field_number (1+ field_number)))
;;; Составляем список всех полей
          (setq
            field_list
             (cons
               (vlax-get-property
                 (vlax-get-property fields_object "Item" field_number)
                 "Name"
               ) ;_ end of vlax-get-property
               field_list
             ) ;_ end of cons
          ) ;_ end of setq
        ) ;_ end of while

        (setq result (list (reverse field_list)))
        ;; составили список имен полей
        ;; Если записей несколько
        (if (not (and (= :vlax-true
                         (vlax-get-property record_set_object "BOF")
                      ) ;_ end of =
                      (= :vlax-true
                         (vlax-get-property record_set_object "EOF")
                      ) ;_ end of =
                 ) ;_ end of and
            ) ;_ end of not
          (setq
            result
;;; Сначала добавляем в результат список имен полей

             (append (list (reverse field_list))
;;; Затем добавляем список значений
                     ;|
Здесь мы используем функцию транспонирования списка
по алгоритму Дугласа Вильсона (Douglas Wilson)
 http://xarch.tu-graz.ac.at/autocad/lisp/
для создания списка записей, так как

GetRows возвращает набор данных в виде
(
(ПОЛЕ1_ЗАПИСЬ1 ПОЛЕ1_ЗАПИСЬ2...ПОЛЕ1_ЗАПИСЬХ)
(ПОЛЕ2_ЗАПИСЬ1 ПОЛЕ2_ЗАПИСЬ2...ПОЛЕ2_ЗАПИСЬХ)
(ПОЛЕХ_ЗАПИСЬ1 ПОЛЕХ_ЗАПИСЬ2...ПОЛЕХ_ЗАПИСЬХ)
)
А нам надо в виде

(
(ПОЛЕ1_ЗАПИСЬ1 ПОЛЕ2_ЗАПИСЬ1... ПОЛЕХ_ЗАПИСЬ1)
(ПОЛЕ1_ЗАПИСЬ2 ПОЛЕ2_ЗАПИСЬ2... ПОЛЕХ_ЗАПИСЬ2)
(ПОЛЕ1_ЗАПИСЬХ ПОЛЕ2_ЗАПИСЬХ... ПОЛЕХ_ЗАПИСЬХ)
)

|;
                     (ru-list-Douglas-Wilson-transpose
                       (mapcar
                         (function(lambda (record_set_list)
                            (mapcar '(lambda (item)
                                       (ru-ado-variant-to-value item)
                                     ) ;_ end of lambda
                                    record_set_list
                            ) ;_ end of mapcar
                          ) ;_ end of lambda
                          )
                         (vlax-safearray->list
                           (vlax-variant-value
                             (vlax-invoke-method
                               record_set_object
                               "GetRows"
                               ru-ado-const-adgetrowsrest
                             ) ;_ end of vlax-invoke-method
                           ) ;_ end of vlax-variant-value
                         ) ;_ end of vlax-safearray->list
                       ) ;_ end of mapcar
                     ) ;_ end of ru-list-Douglas-Wilson-transpose
             ) ;_ end of append
          ) ;_ end of setq
        ) ;_ end of if
        (vlax-invoke-method record_set_object "Close")
        (vlax-release-object record_set_object)
        (vlax-release-object command_object)
      ) ;_ end of progn
    ) ;_ end of if
  ) ;_ end of if
  result
) ;_ end of defun

24-07-2004 23:34:12