Тема: Не могу ввести имя файла из Delphi

Доброе время суток всем!
Написала лисп, в котором есть запрос имени файла

(setq file_name (getstring "File: ") )
(setq file_full_name (findfile file_name))
(setq file (open file_full_name "R"))

В процессе отладки имя файла вводила в командной строке, все нормально работало.
При вызове функции из Delphi

Acad.ActiveDocument.SendCommand('fill_main_blocks'+#13+data_file_name+#13);

на ввод имени файла появляется ошибка

Command: fill_main_blocks
File: "test.ini"
; error: bad argument type: stringp nil
Command: fill_main_blocks
File: test.ini
; error: bad argument type: stringp nil

Как же передать строку из Delphi в командную строку AutoCAD-a?

Re: Не могу ввести имя файла из Delphi

Так похоже, что (setq file_full_name (findfile file_name)) возвращает nil, т.е. файл file_name не находится в путях доступа AutoCAD.
Распечатай в lisp значение file_name и full_file_name

Re: Не могу ввести имя файла из Delphi

А почему при вводе имени файла в командную строку с клавиатуры все работает?

Re: Не могу ввести имя файла из Delphi

Потому, наверное, что getstring надо задавать по типу

(setq file_name (getstring t "File: ") )

Либо вообще использовать (getfiled)

Re: Не могу ввести имя файла из Delphi

Проверьте, как передается путь к файлу (слэши). В командной строке Вы отвечали на запрос LISP-функции, а в

SendCommand('fill_main_blocks'+#13+data_file_name+#13);

передаете просто строки. 'fill_main_blocks' это что? Автокад ее воспримет как строку. В крайнем случае, если он знает в этот момент функцию, определенную как (defun C:fill_main_blocks ...), он попытается выполнить это как команду. А потом ему неизвестно зачем передается значение переменной data_file_name.
Надо не просто символы в комстроку посылать, а сформировать корректное LISP-выражение со всеми скобками, с учетом того, что в полном имени файла надо слэши для LISP передавать или "\\" или "/".

Re: Не могу ввести имя файла из Delphi

Лисп:

;;;DEBUG
(princ "Лисп <read_data_from_file> запущен\n")
;;;DEBUG
   (setq file_name (getstring "File: ") )
;;;DEBUG
(princ (strcat "Введена строка с именем файла: " file_full_name))
;;;DEBUG
   (setq file_full_name (findfile file_name))
;;;DEBUG
(princ (strcat "file_full_name: " file_full_name))
;;;DEBUG
   (setq file (open file_full_name "R"))     ;открыть файл на чтение

Результат:

Command: FILL_MAIN_BLOCKS
Лисп <read_data_from_file> запущен
File: test.ini
; error: bad argument type: stringp nil

Не срабатывает getstring, до findfile лисп не доходит:(

Re: Не могу ввести имя файла из Delphi

Для Кулик Алексей aka kpblc:

(getstring t "File: ")

не помогло
Для ShaggyDoc: слеши не передаются, передается только имя файла test.ini

Re: Не могу ввести имя файла из Delphi

??????????????

(setq [b]file_name[/b] (getstring "File: ") )
;;;DEBUG
(princ (strcat "Введена строка с именем файла: " [b]file_full_name[/b]))
;;;DEBUG
(setq [b]file_name[/b] (getstring "File: ") )
;;;DEBUG
(princ (strcat "Введена строка с именем файла: " [b]file_name[/b]))
;;;DEBUG

Re: Не могу ввести имя файла из Delphi

Ну да... ошибочка вышла в отладочной информации.
Но на работу программы-то это не влияет...

Re: Не могу ввести имя файла из Delphi

Так, я думаю, проблема для начала в лиспе. Может, попробовать такой вариант:

(vl-load-com)
(defun get-file-name-by-string (/ res)
  (while (or (not (vl-catch-all-error-p
            (vl-catch-all-apply
              '(lambda () (setq res (getstring t "\nИмя файла : ")))
              ) ;_ end of vl-catch-all-apply
            ) ;_ end of vl-catch-all-error-p
          ) ;_ end of not
         (= res "")
         (not (findfile res))
         ) ;_ end of or
    (princ (strcat "\nФайл " res " не найден!"))
    ) ;_ end of while
  res
  ) ;_ end of defun
(defun get-file-name-by-dlg (/ res)
  (while (member (setq res (getfiled "ini-файл" "" "ini" 2)) '(nil ""))
    (princ "\nФайл не выбран!")
    ) ;_ end of while
  res
  ) ;_ end of defun

Ессно, лисп должен быть загружен в AutoCAD...
P.S. Код писал на коленках, так что проверить не помешает

Re: Не могу ввести имя файла из Delphi

Разобралась, но не поняла, что и почему...
Дело не в лиспе.
Загрузку лиспа и его запуск выполняла в Delphi ДО сохранения файла.
Было бы понятно, если бы не работал только findfile.
Но почему не работал getstring? Этой-то функции какая разница, где файл находится? Сам-то лисп загрузился и запустился....

Re: Не могу ввести имя файла из Delphi

> Elena
Это не Лисп. Это обрывки. Непонятно, кто что делает и причем здесь Delphi.
Напишите функцию, сделайте локальные переменные, наставьте (print ...) с выводом переменных и ошибка сразу найдется. Особенно внимательно с проверкой результата getstring - кто на запрос отвечает, непонятно.
Если рассчитываете, что в момент запроса придет из Delphi ответ, то это неправильно. Если Delphi знает имя файла, то не надо getstring, передавайте имя в аргументе вызываемой функции, а не печатью в командную строку.

Re: Не могу ввести имя файла из Delphi

Для ShaggyDoc: в качестве аргумента и надо бы, но не удалось:(
Какой синтаксис только не пробовала.... И вроде форум весь перерыла...

Re: Не могу ввести имя файла из Delphi

> Elena
Как не удалось? Это же просто:
Формируете в Delphi строку наподобие:

Command := '(имя_функции "'+Param+'")';

Здесь Param - строковый аргумент, например имя файла, вычисленное в Delphi.
А потом

SendCommand(Command + #13);

Re: Не могу ввести имя файла из Delphi

AutoCAD пробел в сформированной строке распознает как Enter. И после имени функции появляется ошибка "мало аргументов", а Param в командной строке проходит как новая команда....

Re: Не могу ввести имя файла из Delphi

Elena пишет:

AutoCAD пробел в сформированной строке распознает как Enter

Значит строка сформирована неправильно. Вам надо сформировать не просто строку, а LISP-выражение. Внутри его, естественно, будут пробелы. Autocad может заметить дисбаланс скобок, но пробелы в LISP он не анализирует. Он выполнит это выражение.
Пробел может влиять на запрос функции getstring. Если ее вызвать в виде (getstring T "Введи строку с пробелами"), то пробелы не будут восприниматься как Enter.
Но если надо передать известное имя файла в функцию, то get-функция вообще не нужна. А уж как поступать с полученным аргументом, должна решать функция, его получившая. То есть Вы, когда эту функцию пишете.

Re: Не могу ввести имя файла из Delphi

Новая фишка....
Вроде все передалось корректно. Но результат опять - ошибка:(

Command: (load "D:\\Work\\Develop\\TER_SAPR\\TER_CAD\\fill_main_blocks1.lsp")
C:FILL_MAIN_BLOCK
Command: (fill_main_block "test.ini")
; error: no function definition: FILL_MAIN_BLOCK

Лисп:

(defun c:fill_main_block  (file_name / file_full_name file_is_reading file)
;;;*********************  read_from_file  **************************************
;;; функция считывания данных из файла
 (defun read_from_file ()
;;;DEBUG
(print "Лисп <read_data_from_file> запущен")
(print (strcat "Введен параметр с именем файла: " file_name))
;;;DEBUG
   (setq file_is_reading 0)
;;;   (setq file_name (getstring "File: ") )
   (setq file_full_name (findfile file_name))
;;;DEBUG
(print (strcat "file_full_name: " file_full_name))
;;;DEBUG
   (setq file (open file_full_name "R"))     ;открыть файл на чтение
   (if (/= file nil)
   (progn
;;;DEBUG
(print (strcat "Файл <" file_name "> открыт"))
;;;DEBUG
       (setq file_is_reading 1)
       (close file)
       (setq file nil)
;;;DEBUG
(print (strcat "Файл <" file_name "> закрыт"))
;;;DEBUG
   );end of progn
   );end of if (/= file_full_name nil)
  );end of defun read_from_file
;;;*********************  read_from_file  **************************************
   (read_from_file)
;;;DEBUG
   (if (= file_is_reading 1)
     (print (strcat "Файл <" file_name "> прочитан"))
   );end of if (= file_is_reading 1)
;;;DEBUG
);end of defun c:fill_main_block

Re: Не могу ввести имя файла из Delphi

> Elena
Лена. Учите VisualLisp! Если функция определяется с C:, то она определяет команду и тогда ее вызывать нужно с C:. Кроме того такие функции не должны иметь параметров.
Вывод: уберите C: везде в имени своей функции и в вызове ее.

Re: Не могу ввести имя файла из Delphi

> Elena
Естественно.
Функция названа  c:fill_main_block , а вызываете fill_main_block. А такой нет, о чем и сообщается.
В функцию с префиксом C: нельзя передавать аргументы - это специальный синтаксис для вызова имитации команд Автокада.
В командной строке вручную можно набрать
fill_main_block и вызовется функция (c:fill_main_block)
Но вам нужен аргумент, поэтому уберите c: в названии функции
(defun fill_main_block
и вызывайте (fill_main_block "test.ini")
Ну и в теле функции надо делать проверки наподобие

(if (setq file_full_name (findfile file_name))
 (progn
  ... действия с файлом
 )
 (alert "не найден файл")
)

Re: Не могу ввести имя файла из Delphi

Спасибо всем огромное!
Учить, конечно, надо, но некогда... Приходится все осваивать на практике:)

Re: Не могу ввести имя файла из Delphi

> ShaggyDoc (2007-07-05 09:21:41)
Надо не просто символы в комстроку посылать, а сформировать корректное LISP-выражение со всеми скобками, с учетом того, что в полном имени файла надо слэши для LISP передавать или "\\" или "/".

Подскажите а есть ли в Delphi функция заменяющая обратный слеш на двойной, или прямой на обратный?
Ведь все функции Delphi работы с путями к файлам возвращают пути с одинарным обратным слешем.