LISP. Обращение к Excel'y и смена адреса ячейки
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > LISP. Обращение к Excel'y и смена адреса ячейки

LISP. Обращение к Excel'y и смена адреса ячейки

Ответ
Поиск в этой теме
Непрочитано 28.04.2006, 12:22 #1
LISP. Обращение к Excel'y и смена адреса ячейки
Кулик Алексей aka kpblc
Moderator
 
LISP, C# (ACAD 200[9,12,13,14])
 
С.-Петербург
Регистрация: 25.08.2003
Сообщений: 40,409

Задача - прочитать весь лист Excel'a в лисповой список. Указатели на Excel, Workbook, Worksheet получены. Дальше делаю примерно следующее:
Код:
[Выделить все]
(vlax-for cell (vlax-get-property xls_sheet 'cells)
  (if (vlax-variant-value (vlax-get-property cell 'value))
    ;; Данные есть, их попробуем распечатать
    (princ
      (strcat "\nCol : "
	      (vl-princ-to-string (vlax-get-property cell 'column))
	      "; Row : "
	      (vl-princ-to-string (vlax-get-property cell 'row))
	      "; Value : "
	      (vl-princ-to-string
		(vlax-variant-value (vlax-get-property cell 'value))
		) ;_ end of vl-princ-to-string
	      ) ;_ end of strcat
      ) ;_ end of princ
    ;; Данных нет, меняем row и col
    (progn
      ;; Вот здесь будут ошибки - свойства ReadOnly
      (vlax-put-property cell 'column 1)
      (vlax-put-property cell 'row (1+ (vlax-get-property cell 'row)))
      ) ;_ end of progn
    ) ;_ end of if
  ) ;_ end of vlax-for
Количество строк и столбцов заранее не известно, гарантированно только, что если значения в столбце А нет, то строку не читать (в принципе и дальше проходить не надо). Я понимаю, что представленный вариант будет идти по всем строкам, соответственно скорость выполнения этого куска будет отвратительной, но как выйти из цикла я не представляю. Если еще и с этим подскажете, будет совсем здорово
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Просмотров: 14000
 
Непрочитано 28.04.2006, 12:57
#2
PSW


 
Регистрация: 12.01.2006
Донецк
Сообщений: 30


Сделать в ExCELe макрос, который будет выводить данные в текстовый файл, из которого можно сформировать нужный тебе список. Скорость увеличится на порядок, да из выхода из цикла не будет проблем.
PSW вне форума  
 
Автор темы   Непрочитано 28.04.2006, 13:05
#3
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,409


Из текстового файла я читать и так могу, и макрос писать не надо - Excel и сам прекрасно экспорт делает. Хочется сделать так, чтоб не надо было дополнительных телодвижений делать - ни в каде, ни в Excel'e.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 28.04.2006, 14:01
#4
X-DeViL

Бизнес-шмизнес
 
Регистрация: 26.05.2004
Питер
Сообщений: 1,911


могу предложить идею написать письмо Alxd
X-DeViL вне форума  
 
Непрочитано 28.04.2006, 14:10
#5
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,996


Цитата:
Количество строк и столбцов заранее не известно
Набрел и инете на прогу, там так получали кол-во сток и столбцов

Код:
[Выделить все]
              ;;;--- Get the selected worksheet
              (setq mySht(vlax-get-property mySheets 'Item sheetName))

              ;;;--- Make the selected worksheet active
              (vlax-invoke-method mysht "Activate")

              ;;;--- Get the used range of the worksheet
              (setq myRange(vlax-get-property mySht 'UsedRange))

              ;;;--- Get the cells from the range
              (setq myCells(vlax-get-property myRange 'Cells))

              ;;;--- Get the addresses of the top left and bottom right cells
              (setq myAddress(JXCL-get-address myRange myCells 2 3 1))
	      ;;;Можно использовать
	      ;;;(setq myAddress (vlax-get-property myrange 'address mycells 2 3 1))
	      ;;; Что такое 2 3 1 знает Бил Гадс
	      ;;;Получаем myAddress = "[Книга2]Лист1!R3C3:R6C6"
	      
              ;;;--- Strip off the workbook and worksheet names
              (setq myAddress(substr myAddress (+ 3 (vl-string-search "!" myAddress))))
	      ;;; myAddress = "3C3:R6C6"

              ;;;--- Get the starting row number of the range
              (setq 1stRow(fix(atof myAddress)))
	      ;;;1stRow = 3

              ;;;--- Get the starting column number of the range
              (setq 1stCol(fix(atof (substr myAddress (+ (strlen (itoa 1stRow)) 2)))))
	      ;;;1stCol = 3

              ;;;--- Strip off the first row and column from the address string
              (setq myAddress(substr myAddress (+ 3 (vl-string-search ":" myAddress))))
	      ;;;myAddress = "6C6"

              ;;;--- Get the ending row number of the range
              (setq LstRow(fix(atof myAddress)))
	      ;;;LstRow = 6

              ;;;--- Get the ending column number of the range
              (setq LstCol(fix(atof (substr myAddress (+ (strlen (itoa LstRow)) 2)))))
	      ;;;LstCol = 6
Сама прога и адреса в архиве
[ATTACH]1146219033.rar[/ATTACH]
VVA вне форума  
 
Автор темы   Непрочитано 28.04.2006, 14:16
#6
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,409


За ссылку спасибо, тут на autocad.ru Кипятильник подсказал, что можно использовать UsedRange объекта Worksheet. А для него уже можно получить и адрес последней ячейки . Копаю в этом направлении. Код (если получится) показывать?
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 28.04.2006, 14:22
#7
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,996


Да, но по моему то, что я показал одно и то же
Код:
[Выделить все]
;;;--- Get the used range of the worksheet 
  (setq myRange(vlax-get-property mySht UsedRange)) 
;;;--- Get the cells from the range 
    (setq myCells(vlax-get-property myRange 'Cells)) 
;;;(setq myAddress (vlax-get-property myrange 'address mycells 2 3 1))
;;;Получаем myAddress = "[Книга2]Лист1!R3C3:R6C6"
Узнать бы что такое 2 3 1 и что еще может быть?

Цитата:
А для него уже можно получить и адрес последней ячейки
И 1-й тоже. Проверено.

Последний раз редактировалось VVA, 16.07.2008 в 10:16.
VVA вне форума  
 
Непрочитано 28.04.2006, 17:49
#8
Lexa

Конструктор
 
Регистрация: 18.12.2005
Минск
Сообщений: 74
<phrase 1=


Добрый день!!! Братцы!! спасите, подскажите плизз, как таблицу из екселя прикрить к каду, и, например в таблице даны координаты 1000 пунктов и линий, и чтоб он их сам начертил, помогите плиз!!!!
Lexa вне форума  
 
Непрочитано 14.05.2006, 10:23
#9
Елпанов Евгений

программист
 
Регистрация: 20.12.2005
Москва
Сообщений: 1,439
Отправить сообщение для Елпанов Евгений с помощью Skype™


Извиняюсь, не хорошо получилось...
Прочитав эту ветку, сразу написал программу читающую экселевский файл в лисп - список, причем без участия экселя, т.е. на компьютере может не стоять оффиса!
Далее все скинул Алексею, на прямую, в аську, а про эту тему забыл...
Исправляюсь и выкладываю код...
Код:
[Выделить все]
(defun rec-rem-dupl (lst)
  (if lst
    (cons (car lst) (rec-rem-dupl (vl-remove (car lst) (cdr lst))))
  ) ;_  if
) ;_  defun
(defun GET_xl (tbl / ADOCONNECT ADORECORDSET LST)
  ;(setq tbl "D:\\7.xls")
  ;(GET_xl tbl)
  (setq
    ADOConnect   (vlax-get-or-create-object "ADODB.Connection")
    ADORecordset (vlax-get-or-create-object "ADODB.Recordset")
  ) ;_  setq
  (if (not (vl-catch-all-error-p
       (vl-catch-all-apply
         (function vlax-invoke-method)
         (list
     ADOConnect
     "Open"
     (strcat
       "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="
       tbl
       ";Extended Properties=;Excel 8.0;HDR=No"
     ) ;_  strcat
     "admin"
     ""
     nil
         ) ;_  list
       ) ;_  vl-catch-all-apply
     ) ;_  vl-catch-all-error-p
      ) ;_  not
    (progn
      (setq lst
       (mapcar
         (function
     (lambda (l / i c)
       (vlax-invoke-method
         ADORecordset
         "Open"
         (strcat "SELECT * FROM [" l "]")
         ADOConnect
         1
         3
         nil
       ) ;_  vlax-invoke-method
       (setq
         i (length
       (car
         (vlax-safearray->list
           (vlax-variant-value
             (vlax-invoke-method
         ADORecordset
         "GetRows"
         65535
             ) ;_  vlax-invoke-method
           ) ;_  vlax-variant-value
         ) ;_  vlax-safearray->list
       ) ;_  car
           ) ;_  length
       ) ;_  setq
       (vlax-invoke-method ADORecordset "Close")
       (while (not (zerop i))
         (vlax-invoke-method
           ADORecordset
           "Open"
           (strcat "SELECT * FROM [" l "a" (itoa i) ":IV" (itoa i) "]")
           ADOConnect
           1
           3
           nil
         ) ;_  vlax-invoke-method
         (setq
           c (cons (car (apply
              (function mapcar)
              (cons
          'list
          (mapcar
            (function
              (lambda (a)
                (mapcar
            (function
              (lambda (b)
                (vlax-variant-value b)
              ) ;_  lambda
            ) ;_  function
            a
                ) ;_  mapcar
              ) ;_  lambda
            ) ;_  function
            (vlax-safearray->list
              (vlax-variant-value
                (vlax-invoke-method
            ADORecordset
            "GetRows"
            65535
                ) ;_  vlax-invoke-method
              ) ;_  vlax-variant-value
            ) ;_  vlax-safearray->list
          ) ;_  mapcar
              ) ;_  cons
            ) ;_  apply
             ) ;_  car
             c
       ) ;_  cons
           i (1- i)
         ) ;_  setq
         (vlax-invoke-method ADORecordset "Close")
       ) ;_  while
       (if (equal c '((nil) (nil)))
         (list l)
         (cons l c)
       ) ;_  if
     ) ;_  lambda
         ) ;_  function
         (rec-rem-dupl
     (caddr
       (mapcar
         (function
           (lambda (a)
       (mapcar
         (function
           (lambda (b)
             (vlax-variant-value b)
           ) ;_  lambda
         ) ;_  function
         a
       ) ;_  mapcar
           ) ;_  lambda
         ) ;_  function
         (vlax-safearray->list
           (vlax-variant-value
       (vlax-invoke-method
         (vlax-invoke-method
           ADOConnect
           "OpenSchema"
           4
         ) ;_  vlax-invoke-method
         "GetRows"
         65535
       ) ;_  vlax-invoke-method
           ) ;_  vlax-variant-value
         ) ;_  vlax-safearray->list
       ) ;_  apply
     ) ;_  caddr
         ) ;_  rec-rem-dupl
       ) ;_  mapcar
      ) ;_  setq
      (vlax-invoke-method ADOConnect "Close")
      (vlax-release-object ADORecordset)
      (vlax-release-object ADOConnect)
      (setq ADORecordset nil
      ADOConnect nil
      ) ;_  setq
      lst
    ) ;_  progn
    (progn
      (vl-catch-all-apply
  'vlax-invoke-method
  (list ADOConnect "Close")
      ) ;_  vl-catch-all-apply
      (vlax-release-object ADORecordset)
      (vlax-release-object ADOConnect)
      (setq ADORecordset nil
      ADOConnect nil
      ) ;_  setq
      nil
    ) ;_  progn
  ) ;_  if
) ;_  defun
Елпанов Евгений вне форума  
 
Непрочитано 15.05.2006, 09:40
#10
игорёк

проектирование
 
Регистрация: 30.10.2005
москва
Сообщений: 216


Кто подскажет почему lisp не "работает"
Пытаюсь прочитать данные из Excel и выдает
"; error: ActiveX Server returned the error: unknown name: workbooks"



(defun ex10_set_connect (vis /)
(vl-load-com)
(setq g_oex (vlax-get-or-create-object "Excel.Application"))
(if (null g_oex)
(progn
(alert "Невозможно запустить Exel")
(exit)
)
);if
(if vis (vlax-put-property g_oex "visible" :vlax-true))
)

..........
(setq g_wkbs (vlax-get-property g_oex "workbooks"))
..........
игорёк вне форума  
 
Непрочитано 15.05.2006, 10:42
#11
fixo

Lisp/VBA/VB.NET Hobbyist
 
Регистрация: 24.03.2005
Славен Град Петров
Сообщений: 367


Ты неправ, у Полещука все работает как часы,
только нужно правильно вызывать функцию
Например в невидимом режиме Экселя:
Код:
[Выделить все]
(ex10_set_connect nil)
Или в видимом режиме
Код:
[Выделить все]
(ex10_set_connect T)
где nil и T соответственно значения аргумента vis
для функции ex10_set_connect

Fatty

~'J'~
fixo вне форума  
 
Непрочитано 09.06.2006, 15:58
#12
dio

Администрирование ПО
 
Регистрация: 09.06.2006
Сообщений: 1


В Программе представленной Елпановым Евгением предлагается
сперва создавать в памяти объект ADO.Recordset, перегонять
в него весь лист Excel а затем его читать.
Но если на листе всего 100 ячеек с нужными данными
то это излишний расход памяти и ресурсов процессора.
предлагаю следующий способ.

В AutoLisp из активной ячейки листа в которой находимся в текущий
момент надо считывать свойство "Offset <на_строк> <на_колонок>"

Смысл значения параметров для Offset узнать можно из
справочной системы Excel
в разделе "Сведения для программирования" -
"Microsoft Excel Visual Basic Reference"
"Properties"
- "Offset Property"

Это свойство возвращает указатель на другую ячейку (в другой
строке и колонке в зависимости от указанных параметров),
и выполнять для него метод Select или Activate кому что нравиться
Так можно переходить от ячейки к ячейке в листе.


На вопрос VVA что означает параметры 2 3 1 для свойства
Address.
Ответ также можно найти из справочной системы Excel
в разделе "Сведения для программирования" -
"Microsoft Excel Visual Basic Reference"
"Properties"
- "Addres Property"

там для VBA синтаксис команды для чтения свойства такой:
expression.Address(RowAbsolute, ColumnAbsolute, ReferenceStyle, External, RelativeTo)
правда первые два параметра имеют логический тип данных,
но здесь наверное работает особенность Autolisp для логического типа
где все значения отличные от nil считается как True
dio вне форума  
 
Автор темы   Непрочитано 09.06.2006, 16:08
#13
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,409


Метод создания объекта Excel'a на порядок более ресурсоемок. Во-первых, Excel надо иметь на машине. Во-вторых, даже после (vlax-release-object) процесс Excel'a остается висеть в памяти. И его оттуда можно выкинуть только руками - сама винда его не трогает. Так что после 4-5 обращений в памяти будет болтаться 4-5 Excel'ей, которые никому не нужны. Это проверено.
В-третьих. Для выполнения предложенной логики Excel должен быть запущен именно из-под AutoCAD'a, потому как получить хэндл окна из-под лиспа без танцев с бубнами вряд ли возможно. Вот это уже на уровне предположений, потому как подобными вещами не занимался.
---
Добавлено.
Да, объекты, которые не nil, считаются как true, но, например, при обращении к методам сторонних объектов надо передавать не nil | t, а :vlax-false | :vlax-true. Тоже учитывать потребуется...
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 06.09.2006, 12:59
#14
kolobrod


 
Регистрация: 01.09.2006
Москва
Сообщений: 12


Хочется задать вопрос к программе Елпанова Евгения.

Если в книге Excel-я есть названия листов с пробелами, то получаем следующее:

Код:
[Выделить все]
; error: Automation Error. Объект ''Сп. бл. [1вар]$'a39:IV39' не найден ядром базы данных Microsoft Jet.  Проверьте существование объекта и правильность имени и пути.
может кто знает как можно с этим бороться?
kolobrod вне форума  
 
Непрочитано 16.07.2008, 11:39
#15
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,996


Косвенно коснулись в другой ветке этой темы. Так, для исторической справедливости. Развитие кода Евгения Елпанова получило здесь
Data reading from Microsoft Excel not using Excel
LISP.LIB Чтение Excel файлов, используя ADO
__________________
Как использовать код на Лиспе читаем здесь

Последний раз редактировалось VVA, 16.07.2008 в 16:41. Причина: Добавлена ссылка на caduser
VVA вне форума  
 
Непрочитано 16.07.2008, 14:01
#16
T-Yoke

Артиллерист - вертолётчик. Дипломированный инженер-механик. Technologist
 
Регистрация: 29.11.2004
Где-то около Москвы
Сообщений: 16,753
Отправить сообщение для T-Yoke с помощью Skype™


Цитата:
Сообщение от VVA Посмотреть сообщение
Косвенно коснулись в другой ветке этой темы. Так, для исторической справедливости. Развитие кода Евгения Елпанова получило здесь
Data reading from Microsoft Excel not using Excel
А ссылка то битая Проверте коллега.
__________________
«Артиллерия не токмо грохот, но и наука!» Пётр I
T-Yoke вне форума  
 
Непрочитано 16.07.2008, 14:25
#17
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,996


Ссылка не битая, просто на этом форуме необходима регистрация. Даже для просмотра постов
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Непрочитано 16.07.2008, 16:32
#18
Елпанов Евгений

программист
 
Регистрация: 20.12.2005
Москва
Сообщений: 1,439
Отправить сообщение для Елпанов Евгений с помощью Skype™


Цитата:
Сообщение от kolobrod Посмотреть сообщение
Хочется задать вопрос к программе Елпанова Евгения.

Если в книге Excel-я есть названия листов с пробелами, то получаем следующее:

Код:
[Выделить все]
; error: Automation Error. Объект ''Сп. бл. [1вар]$'a39:IV39' не найден ядром базы данных Microsoft Jet.  Проверьте существование объекта и правильность имени и пути.
может кто знает как можно с этим бороться?
я конечно понимаю, что прошло много времени, но попробую переспросить...
как вам удалось добиться ошибки - сейчас попробовал - ошибка не повторилась...

ps. пробовал последнюю версию, которая есть на caduser.ru и theswamp.org...
Елпанов Евгений вне форума  
 
Непрочитано 25.09.2008, 16:22
#19
Makswell

Инженер-строитель
 
Регистрация: 15.08.2007
Киров
Сообщений: 2,204


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
...
Во-вторых, даже после (vlax-release-object) процесс Excel'a остается висеть в памяти. И его оттуда можно выкинуть только руками - сама винда его не трогает.
...
Алексей, хочу тебя спросить: решена ли эта проблема, т.е. убивание процесса Excel именно посредством лиспа.
Всё таки больше 2-х лет прошло с момента написания того поста - может ты за это время что-то придумал?..
Makswell вне форума  
 
Автор темы   Непрочитано 25.09.2008, 16:56
#20
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,409


Если честно, я не стал связываться с процессом Excel'a. Использую другие пути.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > LISP. Обращение к Excel'y и смена адреса ячейки