Страницы: 1
RSS
простой макрос в строке кк = 10 * 1000 * 10 выдает ошибки Overflow (Error 6) офис 2003 ср3
 
Sub проба1()
Dim кк As Double
кк = 10 * 1000 * 10
End Sub
 
Для начала следует прочитатьправила. На пункт 3.2 обратить внимание.
 
Да, прикольно. Глюк VBA?
Что-то не так с типом данных у самих чисел. Ибо в варианте
кк = 10 * 1000! * 10
или
кк = 10# * 1000 * 10
в любой комбинации всё нормально. И в варианте
кк = 10 * 1000
кк = кк * 10
тоже нормально.

Хотя  в работе что-то типа 10 * 1000 * 10 обычно не используется, но сам факт непонятный.
Кто-то знает?

ЗЫ. Считаю, что в наборе символов ника йцукен55 бессмысленности не более, чем в Юрий М или tolikt
 
какой еще глюк?
пока не произошло присвоение переменной типа double, интерпретатор определяет тип и аргументов, и результата на основе операторов и символьной записи чисел.
целые числа и воспринимаются как целые.
а результат уже не умещается в целое.

сравните:
кк = 3270 * 10
и
кк = 3280 * 10

и в обратную :)
кк = 32700 * 10
и
кк = 32800 * 10

достаточно писать так:
кк = 10.0 * 1000 * 10
кстати, VBE автоматом меняет такую строку на
кк = 10# * 1000 * 10
Изменено: ikki - 02.03.2013 16:21:34
фрилансер Excel, VBA - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
Цитата
tolikt пишет:
Считаю, что в наборе символов ника йцукен55 бессмысленности не более, чем в Юрий М или tolikt
А я считаю иначе.
 
Цитата
написал:
А я считаю иначе.
почему не вижу полного ФИО в твоём нике тогда?
почему только неполная "М" ? ты что-то скрываешь? в чём-то замешан?
щас бы в инете к никам придираться. ikki то очень осмысленный ник, намного круче йцукена
надеюсь регистрацию на форуме по тилибону скоро прикрутят? + геолокацию
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
последние две строки выдают ошибку
как полечить?:
Код
'a1 = 100 * 100 * 100
a1# = 1000000
a1 = 100 * 100: a1 = a1 * 100
a1 = 100# * 100 * 100
a1 = CLng(100) * 100 * 100

a1 = CLng(0) + 100 * 100 * 100
a1 = CLng(100 * 100 * 100)

тут последняя строка тоже выдает ошибку при использовании массива
как лечить? только через  a1 = clng(a00(0)) * 100 * 100 ?:
Код
a0 = 100
a1 = a0 * 100 * 100
Dim a00(1) As Integer
a00(0) = 100
a1 = a00(0) * 100 * 100

и так тоже не хочет:
Код
a0 = 100
a1 = a0 * (100 * 100 + 1)
Dim a00(1) As Integer
a00(0) = 100
a1 = CLng(1) * (a00(0) * 100 * 100 + 1)
Изменено: KUDRIN - 21.05.2023 13:52:20
 
Цитата
KUDRIN написал: ... как полечить? ...
Добрый день.
1. Сначала выполняются вычисления в скобках по частям по математическим правилам и приоритетам вычисления.

2. В каждой вычисляемой части учитывается типы данных и их ограничения.
Если в вычисляемой части мат. выражения тип не указан, а все числа от -32768 до 32767, то Excel трактует числа и результат как Integer и выдает ошибку, если результат не укладывается в интервал Integer (-32768 … 32767).
Например, в окне Immediate:
?10000 * 10 выдаст ошибку
?32768 * 10 ошибки нет, тип результата - long

3. Если в вычисляемой части мат.выражения хоть одно число или переменная имеет  тип double, то результат этой части (и общий результат) также будет иметь тип double и переполнения не будет.
Аналогично, если нет ни одного double, но есть long, то тип результата будет long.
?10000 * 10 выдаст ошибку
?10000& * 10 ошибки нет, тип результата - long
?10000# * 10 ошибки нет, тип результата - double
Изменено: ZVI - 21.05.2023 17:38:50
 
Цитата
написал:
В каждой вычисляемой части учитывается типы данных и их ограничения.
имеются ввиду 2 части слева и справа от знака равенства? или имеются ввиду слагаемые части справа от равно?
Код
aa# = 0
a1& = 10
a2% = 10
aa = (a1 * 100000) * (a2 * 1000)
aa = (a1 * 100000) + (a2 * 1000)
aa = (a1 * 10000) * (a2 * 1000)

вот три строки, 1 выдаст ошибку, а 2 и 3 не выдадут
хотя непонятно как это работает - если плюс изменил ситуацию, значит тип мат операции имеет значение
а дальше в 3й строке мы убрали нолик около лонга - на лонг a1 этот ноль вообще не влияет, а каким образом он влияет на a2 тоже не понятно. т.е. если учитывается общий результат справа от равно, то наличие лонга должно решать все проблемы, т.к. справа 10 нулей, а у лонга 18
Код
aa# = 0
a1& = 10
a2& = 10
aa = (a1 * 100000) * (a2 * 1000)
или вот = справа два лонга, максимум 18 разрядов, а слева 300 разрядов, число 10 разрядов, но выдает ошибку, пока не сделаешь a1# или a2#
за всю практику первый раз столкнулся напрямую с перемножением в vba и это всё сделано как то криво косо неудобно

да еще если часто менять типы данных у переменной, то выскакивает ошибка о несоответствии. причем если ты менял с 1 на 10 - то эта ошибка никак не обойдётся, пока не введешь третье число типа 200, тогда он успешно обновляет тип данных (MS 2010)


в общем в любой непонятной ситуации пиши CDbl() или CLng() и это в большинстве случаев поможет
Изменено: KUDRIN - 21.05.2023 19:49:44
 
Цитата
KUDRIN написал:
... имеются ввиду 2 части слева и справа от знака равенства? или имеются ввиду слагаемые части справа от равно?
Вычисляемые в очередности по правилам математики части справа от равно.
Выражение (a1 * 100000) * (a2 * 1000) вычисляются по частям так:
1. (a1 * 100000) =  1000000&
2. (a2 * 1000)   = 10000%
3. 1000000& * 10000& =10000000000 = ошибка, т.к. макс. значение Long равно 2147483647
Код
Sub Test1()
  Dim aa#, a1&, a2%
  Dim v1 As Variant, v2 As Variant
  a1 = 10
  a2 = 10
  v1 = a1 * 100000
  v2 = a2 * 1000
  Debug.Print VarType(v1) & "(vbLong=3)", VarType(v2) & "(vbInteger=2)"
  'aa = (a1 * 100000) * (a2 * 1000) ' ОШИБКА overflow !
  aa = v1 * v2  ' Нет ошибки, т.к. переменные типа Variant при компилировании кода приведены к типу aa#, т.е. к double,
                ' по сути, вычисляется так:  aa = CDbl(v1) * CDbl(v2)
  Debug.Print aa
End Sub


Цитата
... вот три строки, 1 выдаст ошибку, а 2 и 3 не выдадут
Ошибка, потому что результат 10 000 000 000 вне диапазона Long (-2 147 483 648 ... 2 147 483 647)

Цитата
... если часто менять типы данных у переменной, то выскакивает ошибка о несоответствии
Здесь не понял, но правильнее задавать типы переменных в операторе Dim:
Код
Dim aa#, a1&, a2%
Изменено: ZVI - 22.05.2023 00:24:03
 
Цитата
KUDRIN написал:
в общем в любой непонятной ситуации
не допускайте в коде непонятных ситуаций, непонятная ситуация = - это потенциальная ошибка, макросом с непредсказуемым результатом пользоваться нельзя
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Цитата
ZVI написал:
т.к. макс. значение Long равно 2147483647
ах, это многое объясняет
а то https://learn.microsoft.com/ru-ru/dotnet/visual-basic/language-reference/data-types/long-data-type
Цитата
Тип данных Long (Visual Basic)
Содержит 64-разрядные (8-байтовые) целые числа со знаком в диапазоне от -9 223 372 036 854 775 808 до 9 223 372 036 854 775 807 (9,2...E+18).
оказывается у них ещё и бейсики разные - один для офиса, а второй для дотнета


Цитата
ZVI написал:
переменные типа Variant при компилировании кода приведены к типу aa#, т.е. к double
жаль у Variant нет короткого объявления
хотя наоборот есть - оно без короткого знака
Код
Sub sdd()
Dim a0 As Variant 'All types
a1! = 1 'Single / -3.402823E38 to -1.401298E-45, 1.401298E-45 to 3.402823E38
a2@ = 1 'Currency / -922,337,203,685,477.5808 to 922,337,203,685,477.5807
a3# = 1 'Double / -1.79769313486232E+308 to -4.94065645841247E-324, 4.94065645841247E-324 to 1.79769313486232E+308
a4$ = 1 'String / 0 to 2,147,483,647 characters
a5% = 1 'Integer / -32,768 to 32,767
a6^ = 1 'LongLong / -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
a7& = 1 'Long / -2,147,483,648 to 2,147,483,648
a8 = 1 'Variant 'All types
End Sub
Изменено: KUDRIN - 22.05.2023 05:41:26
 
Цитата
KUDRIN написал: жаль у Variant нет короткого объявления
Есть короткое - просто не указывать тип,
вместо Dim a0 As Variant
можно записать Dim a0
это одно и то же
Страницы: 1
Читают тему
Наверх