Сравнение значений переменной и текстбокса в VBA.

Автор Тема: Сравнение значений переменной и текстбокса в VBA.  (Прочитано 8246 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн R.I.ChernovАвтор темы

  • ADN Club
  • *****
  • Сообщений: 568
  • Карма: 18
Здравствуйте, уважаемые форумчане. Помогите пожалуйста решить такую вот задачу:
Не знаю даже, как описать проблему, чтобы побыстрее и попонятнее... Прикладываю файл детали с кодом VBA внутри.

В общем, у меня есть параметр в детали (мм), к нему я приравниваю переменную в VBA (double), а затем к этой переменной приравниваю значение текстбокса и загружаю форму. Получается что значение текстбокса численно равно значению параметра в модели. Пользователь меняет текстбокс и нажимает применить, после чего запускается обратная операция (текстбокс-->переменная-->модель). Но вначале, программа сравнивает значение текстбокса и переменной VBA, и если они равны, всплывает сообщение, что параметр не изменен.
Суть проблемы такова, что написанный мною код проверки работает не при всех значениях. Примеры нерабочих значений параметра:7, 12, 14, 23, 666...
Т.е. если установить значение, например, 666 и закрыть форму, затем снова ее открыть и ничего не меняя нажать "применить значение", то сообщения, что параметр не изменен не появится.
П.С. Всю голову себе сломал, не могу найти, как это исправить. Буду признателен за любую идею!
Единственное решение пришедшее на ум - сравнивать значение текстбокса и переменной в формате стринг, используя Cstr. Но оно мне что-то не очень нравится.
В программировании я новичок...но ненадолго! ;)

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Единственное решение пришедшее на ум - сравнивать значение текстбокса и переменной в формате стринг, используя Cstr. Но оно мне что-то не очень нравится.
Почти. Только наоборот. Значение, введенное в текстбоксе нужно привести к типу Double с помощью функции CDbl и уже это значение сравнивать со значением переменной.
Только имейте ввиду, что в текстбокс можно вбить не только числа, и тогда при вызове функции  CDbl возникнет ошибка.
Также можно использовать другой контрол вместо текстбокса (не подскажу точно какой это контрол в VBA), который позволяет вводить только числа. Как правило, у таких контролов есть свойства типа Value с типом данных Double. В этом случае не нужно делать дополнительное преобразование и беспокоиться о валидности введенных данных.

Отмечено как Решение R.I.Chernov 21-05-2015, 08:59:45

Оффлайн Владимир Ананьев

  • ADN DevHelp
  • *
  • Сообщений: 148
  • Карма: 8
В параметрах Инвентора вы можете видеть, скажем, значение 7, а на самом деле, оказывается, там хранится действительное число 7.000000000001.  Лобовое сравнение даст неравенство.  Именно поэтому действительные числа следует сравнивать между собой, непременно учитывая некоторую точность.  Точность обычно вытекает из особенностей предметной области.  Одному миллиметра достаточно, а другому и микрон – грубо.

Итак, сравниваем два числа x и y:

Вариант 1.
If (Math.Abs(x-y) < Точность) then
    ‘числа можно считать равными
Else
    ‘числа отличаются
End if

Вариант 2.
Округляем оба числа до некоторого знака после запятой, после чего уже и проверяем равенство
X = Math.Round(x, 6)
Y = Math.Round(y, 6)
If x = y then
    ‘числа можно считать равными
Else
    ‘числа отличаются
End if

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Вариант 2.
Может запросто не сработать. Вариант 1 значительно лучше.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Владимир Ананьев

  • ADN DevHelp
  • *
  • Сообщений: 148
  • Карма: 8
Согласен.  Вариант 1  -  канонический.


Оффлайн R.I.ChernovАвтор темы

  • ADN Club
  • *****
  • Сообщений: 568
  • Карма: 18
Почти. Только наоборот. Значение, введенное в текстбоксе нужно привести к типу Double с помощью функции CDbl и уже это значение сравнивать со значением переменной.
Спасибо, Виктор, за ответ. К сожалению CDbl я уже пробовал, и точно также не работает. Тут загвоздка идет с каким-то некорректным экспортом из инвентора походу.
Также можно использовать другой контрол вместо текстбокса (не подскажу точно какой это контрол в VBA), который позволяет вводить только числа. Как правило, у таких контролов есть свойства типа Value с типом данных Double
Мне такой не знаком ;(  Был бы безгранично признателен, если бы кто-нибудь подсказал, где искать :) а то каждый раз приходится проверять, число ли ввели в текстбоксе
В программировании я новичок...но ненадолго! ;)

Оффлайн R.I.ChernovАвтор темы

  • ADN Club
  • *****
  • Сообщений: 568
  • Карма: 18
числа следует сравнивать между собой
Спасибо, Владимир Николаевич, за ответ. Сейчас доеду до работы, обязательно попробую предложенные вами варианты.
В программировании я новичок...но ненадолго! ;)

Оффлайн R.I.ChernovАвтор темы

  • ADN Club
  • *****
  • Сообщений: 568
  • Карма: 18
Владимир Николаевич оказался прав. Нашел разность между значением текстбокса и переменной:  1E-13. Откуда она берется - непонятно,  да и не важно - вопрос решен! Еще раз большое спасибо!
П.С. В моей работе точность идет до второго знака после запятой, за погрешность взял на порядок меньше - 0,001. Все корректно начало работать:
Вместо  "If param=textbox.value Then" теперь такой вот аналог "If Abs(param-textbox.value)<0.001 Then".
В программировании я новичок...но ненадолго! ;)