В чем зло VBA? - Страница 9
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Сообщество > Разное > В чем зло VBA?

В чем зло VBA?

Закрытая тема
Поиск в этой теме
 
Непрочитано 19.11.2008, 08:46
#161
Кулик Алексей aka kpblc
Moderator

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


Да, кстати, ganjour, поскольку ты поклонник VB(A), нарисуй код для работы с массивом неопределенного размера. На VB(A), естественно.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 19.11.2008, 11:36
#162
AlexV

Инженер
 
Регистрация: 02.10.2008
С-Пб
Сообщений: 3,692


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Да, кстати, ganjour, поскольку ты поклонник VB(A), нарисуй код для работы с массивом неопределенного размера. На VB(A), естественно.
А что этот код должен делать?И в чем может быть проблема?
AlexV вне форума  
 
Непрочитано 19.11.2008, 11:42
#163
Кулик Алексей aka kpblc
Moderator

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


Проблема в постоянном переопределении границ массива. А что должен делать? Ну, например, добавить элемент в конец массива (это делается достаточно просто, если забыть о потерях ресурсов, связанных с ReDim); удалить элемент(ы) по какому-либо условию (аналог vl-remove-if); заменить элемент, вычисленный по какому-либо условию (аналог subst); применить ко всем элементам какую-либо (заранее не определенную) функцию (аналог mapcar).
По рекурсии просить ничего не буду, поскольку у меня в свое время не получилось нормального решения на VB.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 19.11.2008, 11:44
#164
ganjour


 
Регистрация: 16.10.2008
Сообщений: 45


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
По коду:
  1. Зачем делать несколько строк с setq, когда можно обойтись одним? Имеется в виду заменить
    Код:
    [Выделить все]
    (setq symbol_list (list "<" "d" "'" "\""))
      (setq int_matrix (list 0 1 2 3))
      (setq i 0)
      (setq element "")
      (setq out_string "")
      (setq char_list (input_string->list inp_string))
    на
    Код:
    [Выделить все]
    (setq symbol_list (list "<" "d" "'" "\"")
            int_matrix  (list 0 1 2 3)
            i           0
            element     ""
            out_string  ""
            char_list   (input_string->list inp_string)
            ) ;_ end of setq
    Скорость выполнения будет выше.
  1. Здесь с тобой абсолютно согласен, именно так следовало мне и сделать.
    Цитата:
  2. У тебя не учитывается (точнее, неверно учитывается) вариант десятых долей секунд. Попробуй запустить (result_list "16,15,,1.16") и сравни, например, с (conv-string-to-string "16,15,,1.16"). Кстати, (test) выдаст свой результат.
  3. это я знаю, доли секунд не учитываются, а так ли это необходимо? в большинстве случаев это будет излишняя точность.
    Цитата:
  4. В коде присутствуют лишние progn.
по моему это не беда, а вдруг нужно будет что нибудь добавить
Цитата:
Читать тебе лекции по штатным функциям AutoLISP'a у меня нет никакого желания, особенно учитывая тональность, в которой ты общаешься.
я просто пошутил
ganjour вне форума  
 
Непрочитано 19.11.2008, 11:46
#165
Кулик Алексей aka kpblc
Moderator

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


Цитата:
а так ли это необходимо?
Живой пример не полностью составленного ТЗ... А если будут вводиться нецелые расстояния (типа 6035.65478? Мне уже лениво проверять, что какой код вернет.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 19.11.2008, 11:55
#166
AlexV

Инженер
 
Регистрация: 02.10.2008
С-Пб
Сообщений: 3,692


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Проблема в постоянном переопределении границ массива. А что должен делать? Ну, например, добавить элемент в конец массива (это делается достаточно просто, если забыть о потерях ресурсов, связанных с ReDim); удалить элемент(ы) по какому-либо условию (аналог vl-remove-if); заменить элемент, вычисленный по какому-либо условию (аналог subst); применить ко всем элементам какую-либо (заранее не определенную) функцию (аналог mapcar).
По рекурсии просить ничего не буду, поскольку у меня в свое время не получилось нормального решения на VB.
Все это вполне реализуемо, хотя согласен - зачастую через большую букву Ж, с затратой немалых усилий как на написание кода, так и аппаратных при исполнении. Особенно с удалением элемента из середины массива.
AlexV вне форума  
 
Непрочитано 19.11.2008, 12:03
#167
AlexV

Инженер
 
Регистрация: 02.10.2008
С-Пб
Сообщений: 3,692


Ну а пример рекурсивной функции на VBA- вот
Код:
[Выделить все]
Public Function Factorial(N As Integer) As Integer
  If N <= 0 Then
            Factorial = 1
   Else
            Factorial = N * Factorial(N - 1)
   End If
End Function
AlexV вне форума  
 
Непрочитано 19.11.2008, 12:10
#168
Кулик Алексей aka kpblc
Moderator

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


AlexV, факториал и я писал - все работало нормально. Но как только начинается более сложное что-то, все, я пас (Добавлено: пробовал нарисовать аналог Replace для чистого VB, результат был плачевным).
Кстати, еще один прикол: а что, если надо использовать аналог Select Case, только условия могут быть разными? То есть
Код:
[Выделить все]
Select Case <?>
  Case Value1=1
  Case Value2="abc"
  Case Value=False
End Select
Я долго мучался, пока не подсмотрел решения
---
Специально пролистал тему обратно. Вроде я не говорил, что VB(A) полный отстой и зло вселенского масштаба... Для некоторых целей он очень даже неплох. При соблюдении некоторых условий
Желающим поразмыслить на досуге: прочитайте топик начиная примерно с #70, становится забавно
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 19.11.2008, 13:35
#169
AlexV

Инженер
 
Регистрация: 02.10.2008
С-Пб
Сообщений: 3,692


Что-то недопонял я конструкцию:
Код:
[Выделить все]
Select Case <?>
  Case Value1=1
  Case Value2="abc"
  Case Value=False
End Select
Имеется в виду, проверка сразу по 3-м условиям в одном операторе? А если одновременно выполняются все условия (Value1=1, Value2="abc", Value=False), то что- должен выполнится код после всех Case? Мне кажется, работать не будет.
AlexV вне форума  
 
Непрочитано 19.11.2008, 13:46
#170
Кулик Алексей aka kpblc
Moderator

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


AlexV, нет. Я имел в виду:
Код:
[Выделить все]
Option Explicit

Sub test()
Dim sVar As String
Dim iVar As Integer
Dim bVar As Boolean
Dim sVar2 As String
Dim iRes As Integer
  sVar = "a": sVar2 = "b": iVar = 100: bVar = True
  Select Case ' Вот что здесь надо поставить / сделать?
    Case UCase(sVar) = "C"
      iRes = iRes + 1
    Case UCase(sVar) = "A" And sVar2 <> ""
      iRes = iRes + 2
    Case UCase(sVar2) = "B"
      iRes = iRes + 4
    Case bVar
      iRes = iRes + 8
    Case iVar > 10 And iVar < 1000
      iRes = iRes + 16
    Case iVar <= 10 Or iVar >= 1000
      iRes = iRes + 32
  End Select
  MsgBox "Сумма битов выполнения условий : " & CStr(iRes), _
    vbOKOnly + vbInformation + vbApplicationModal, _
    "iRes"
End Sub
---
Добавлено: iRes при правильном выполнении будет равен 2 на момент окончания процедуры
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 19.11.2008, 14:01
#171
ganjour


 
Регистрация: 16.10.2008
Сообщений: 45


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Живой пример не полностью составленного ТЗ... А если будут вводиться нецелые расстояния (типа 6035.65478? Мне уже лениво проверять, что какой код вернет.
Ну уж если ты это сделал камнем преткновения...
необходимо просто немного изменить условные операторы, а именно
Код:
[Выделить все]
(or (and (<= (ascii (car char_list)) 57)
		 (>= (ascii (car char_list)) 48)
	    )
	    (and (= (ascii (car char_list)) 46) (or (= i 0) (= i 3)))
	)
вместо
Код:
[Выделить все]
    (if	(and (<= (ascii (car char_list)) 57)
	     (>= (ascii (car char_list)) 48)
	)
и добавить
Код:
[Выделить все]
(if (/= (ascii (car char_list)) 46)
вот и все!
полный код:
Код:
[Выделить все]
;|
***** Преобразование любой строки к виду *<*d*'*" (расстояние/градусы/минуты/секунды) *****
Примеры ввода:
что желаешь то и вводи :)
разделителем может служить что угодно, кроме символа ".":
54,45,32,23
54,,,45,,32,,,,,,,23
54<45d32'23
54<<<<<45ddd32'''''23""""""""
54влалападпп45апавп32,уйцекгн23
54,45,32
54,45
54

Вызов: загрузи и введи в текстовом окне команду test
|;

;;; Преобразование строки в список
(defun input_string->list (inp_string / char_list islen)
  (setq islen (strlen inp_string))
  (setq char_list (list ""))
  (while (< 0 islen)
    (setq char_list (cons (substr inp_string islen 1) char_list))
    (setq islen (1- islen))
  )					; end of while
  char_list
)					; end of input_string->list

;;; Преобразует список в строку необходимого вида
(defun result_list (inp_string	 /	      element	   i
		    j		 symbol_list  char_list	   int_matrix
		    out_string
		   )
;;;  Инициализация
  (setq	symbol_list
	 (list "<" "d" "'" "\"")
	int_matrix
	 (list 0 1 2 3)
	i 0
	element	""
	out_string
	 ""
  )
;;;  Извлечение и группирование элементов списка char_list 
  (setq char_list (input_string->list inp_string))
  (while char_list
;;;    Если элемент цифра
    (if	(or (and (<= (ascii (car char_list)) 57)
		 (>= (ascii (car char_list)) 48)
	    )
	    (and (= (ascii (car char_list)) 46) (or (= i 0) (= i 3)))
	)
      (progn
	(setq element (strcat element (car char_list)))
	(setq j t)
      )
;;;      Если элемент не цифра
      (progn
	(if j
	  (if (/= (ascii (car char_list)) 46)
	    (progn
	      (setq int_matrix (subst element i int_matrix))
	      (setq element "")
	      (setq j nil)
	      (setq i (1+ i))
	    )
	  )
	)
      )
    )
;;;    Следующий элемент
    (setq char_list (cdr char_list))
  )					; end of while
;;;  Очищаю список на всякий случай
  (setq char_list nil)
;;;  Если введенных данных недостаточно
  (while (< i 4)
    (setq int_matrix (subst "0" i int_matrix))
    (setq i (1+ i))
  )					; end of while
;;;  Преобразую список int_matrix в строку и добавляю необходимые символы "<" "d" "'" "\""
  (while symbol_list
    (setq out_string
	   (strcat out_string (car int_matrix) (car symbol_list))
    )
;;;    Следующий элемент
    (setq int_matrix (cdr int_matrix))
    (setq symbol_list (cdr symbol_list))
  )					; end of while
  out_string
)					; end of result_list

;;; Функция тестирования
(defun C:test (/ inp_string)
  (setvar "cmdecho" 0)
  (setq inp_string (getstring "Строка: "))
  (princ (result_list inp_string))
  t
)					; end of test
ganjour вне форума  
 
Непрочитано 19.11.2008, 14:09
#172
AlexV

Инженер
 
Регистрация: 02.10.2008
С-Пб
Сообщений: 3,692


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
AlexV, нет. Я имел в виду:
Код:
[Выделить все]
Option Explicit

Sub test()
Dim sVar As String
Dim iVar As Integer
Dim bVar As Boolean
Dim sVar2 As String
Dim iRes As Integer
  sVar = "a": sVar2 = "b": iVar = 100: bVar = True
  Select Case ' Вот что здесь надо поставить / сделать?
    Case UCase(sVar) = "C"
      iRes = iRes + 1
    Case UCase(sVar) = "A" And sVar2 <> ""
      iRes = iRes + 2
    Case UCase(sVar2) = "B"
      iRes = iRes + 4
    Case bVar
      iRes = iRes + 8
    Case iVar > 10 And iVar < 1000
      iRes = iRes + 16
    Case iVar <= 10 Or iVar >= 1000
      iRes = iRes + 32
  End Select
  MsgBox "Сумма битов выполнения условий : " & CStr(iRes), _
    vbOKOnly + vbInformation + vbApplicationModal, _
    "iRes"
End Sub
---
Добавлено: iRes при правильном выполнении будет равен 2 на момент окончания процедуры
Select Case True? Но в этом случае тоже выполнится код только после 1-го Case с верным значением выражения, остальные проигнорируются

Последний раз редактировалось AlexV, 19.11.2008 в 14:21.
AlexV вне форума  
 
Непрочитано 19.11.2008, 14:19
#173
ganjour


 
Регистрация: 16.10.2008
Сообщений: 45


Цитата:
Сообщение от AlexV Посмотреть сообщение
.
Код:
[Выделить все]
 Select Case ' Вот что здесь надо поставить / сделать?
    Case UCase(sVar) = "C"
      iRes = iRes + 1
    Case UCase(sVar) = "A" And sVar2 <> ""
      iRes = iRes + 2
    Case UCase(sVar2) = "B"
      iRes = iRes + 4
    Case bVar
      iRes = iRes + 8
    Case iVar > 10 And iVar < 1000
      iRes = iRes + 16
    Case iVar <= 10 Or iVar >= 1000
      iRes = iRes + 32
  End Select
тот же if - elseif
ganjour вне форума  
 
Непрочитано 19.11.2008, 14:29
#174
Кулик Алексей aka kpblc
Moderator

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


AlexV, это ты влет определил, а я в свое время мучался
ganjour, в VB есть ограничение на количество вложенных If-Else(ElseIf)-EndIf, насколько мне помнится. И, кстати, распиши тогда и свой вариант этого Select Case.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 19.11.2008, 14:55
#175
AlexV

Инженер
 
Регистрация: 02.10.2008
С-Пб
Сообщений: 3,692


Повторюсь, применение "Select Case True" имело бы смысл, если бы исполнялись все "Case" с верным значением выражения. А здесь игнорируются все, кроме первого (хотя, в специфических случаях, этого возможно достаточно.). А что мешает сделать последовательно нужное кол-во Select Case? Ну код удлинится несколько, может выполнение его будет немного дольше (при нынешних "Corel Duo" надо сильно постараться, что бы это замедление было заметно)
AlexV вне форума  
 
Непрочитано 19.11.2008, 14:59
#176
Кулик Алексей aka kpblc
Moderator

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


Лично мне, например, понадобилось именно Select Case True. Выполнялась операция над несколькими переменными.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 19.11.2008, 15:19
#177
Елпанов Евгений

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


Цитата:
Сообщение от ganjour Посмотреть сообщение
Не знаю что такое "уроки Евгения Елпанова по рекурсиям" и вообще признаюсь - я не понимаю рекурсии и понимать не желаю ,
Можно и без рекурсии, сохранив твой функционал и добавив своего..
Сравнивай!

Код:
[Выделить все]
(defun test1 (s / trim)
 (defun trim (s)
  (while (and (not (= s "")) (or (< 47 (ascii s) 58) (= (ascii s) 46))) (setq s (substr s 2)))
  (while (and (not (= s "")) (not (or (< 47 (ascii s) 58) (= (ascii s) 46)))) (setq s (substr s 2)))
  (if s s "")
 ) ;_  defun
 (strcat (rtos (atof s) 2)
         "<"
         (angtos (angtof (strcat (rtos (atoi (setq s (trim s))) 2)
                                 "d"
                                 (rtos (atoi (setq s (trim s))) 2)
                                 "'"
                                 (rtos (atof (setq s (trim s))) 2)
                                 "\""
                         ) ;_  strcat
                         4
                 ) ;_  angtof
                 1
                 4
         ) ;_  angtos
 ) ;_  strcat
)
Для проверки:
Код:
[Выделить все]
(test1 "4,5000,6000,7000")		;; => "4<61d56'40\""
(test1 "4,5,6,7")			           ;; => "4<5d6'7\""
(test1 "4.5,5,6,7")			;; => "4.5<5d6'7\""
(test1 "54,45")				;; => "54<45d0'-0\""
(test1 "54")				;; => "54<0d0'0\""
(test1 "54,45,32,23")			;; => "54<45d32'23\""
(test1 "54влалападпп45апавп32,уйцекгн23");; => "54<45d32'23\""

Последний раз редактировалось Елпанов Евгений, 19.11.2008 в 15:28.
Елпанов Евгений вне форума  
 
Непрочитано 19.11.2008, 15:27
#178
AlexV

Инженер
 
Регистрация: 02.10.2008
С-Пб
Сообщений: 3,692


Цитата:
...факториал и я писал - все работало нормально. Но как только начинается более сложное что-то, все, я пас...
Интересно, а в чем причина? В принципе, если я правильно понимаю, в любой среде программирования рекурсия - это обращение функции\процедуры к самой себе. Каких инструментов\логических конструкций в VBA не хватает по сравнению с тем же Lisp или C++?(по созданию рекурсий)
AlexV вне форума  
 
Непрочитано 19.11.2008, 15:38
#179
Кулик Алексей aka kpblc
Moderator

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


Я сейчас уже не хочу (да и времени мало) восстанавливать свой код. Помню, что не получилось. Я на этом и успокоился
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 19.11.2008, 22:52
#180
ganjour


 
Регистрация: 16.10.2008
Сообщений: 45


Цитата:
Сообщение от Елпанов Евгений Посмотреть сообщение
Можно и без рекурсии, сохранив твой функционал и добавив своего..
да это пожалуй лучший вариант, разве что часть работы возложена на встроенные функции аутолисп atof и atoi ну зато получилось кратко и вполне читаемо, не понял только конструкцию (if s s "")
ganjour вне форума  
Закрытая тема
Вернуться   Форум DWG.RU > Сообщество > Разное > В чем зло VBA?



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Пароль к VBA karp_b Программирование 24 29.08.2013 12:43
Юмор 2007 Огурец Разное 1172 29.12.2007 11:16
Чем можно удалить файл, занятый не понятно чем? G.A.W. Разное 4 08.10.2007 15:12
ActiveX Automation из VBA karp_b Программирование 5 14.09.2007 18:05
VBA vs LISP Kosenko Sasha LISP 23 06.03.2007 02:56