VBA: получить длинные ограничения программно

#vba

#vba

Вопрос:

Есть ли в VBA способ программно получить ограничения (минимальное значение, максимальное значение) числового типа ( Long например)?

Что-то вроде numeric_limits<long>::min() в C .

Ответ №1:

Нет, но в любом случае они имеют фиксированный размер, поэтому вы можете вывести их напрямую.

Вот некоторая информация об их размерах: http://msdn.microsoft.com/en-us/library/aa164754.aspx

Из статьи:

Целочисленные и длинные типы данных могут содержать как положительные, так и отрицательные значения. Разница между ними заключается в их размере: целочисленные переменные могут содержать значения от -32 768 до 32 767, в то время как длинные переменные могут варьироваться от -2 147 483 648 до 2 147 483 647. Традиционно программисты на VBA использовали целые числа для хранения небольших чисел, поскольку они требовали меньше памяти. Однако в последних версиях VBA преобразует все целочисленные значения в тип Long, даже если они объявлены как тип Integer . Таким образом, использование целочисленных переменных больше не дает преимущества в производительности; на самом деле, длинные переменные могут быть немного быстрее, потому что VBA не нужно их преобразовывать.

Комментарии:

1. Если вы предполагаете, что все типы подписаны и что LenB правильно вернет размер значения в байтах (без добавления каких-либо дополнений), вы можете вычислить их диапазон с помощью min=-2^((LenB(value)*8)-1) и max=(((2^((LenB(value)*8)-2))-1)*2) 1 . Более сложная математика в последнем заключается в том, чтобы избежать переполнения, т.Е. Для 32-разрядного int со знаком вычислить 2 ^ 30, вычесть 1, умножить на два, добавить 1, что дает вам (2^30-1)*2 1 = 2^31-1

2. На самом деле, как даже вы упоминаете в своем ответе, «фиксированные размеры» варьируются в зависимости от версии вашего Office, архитектуры процессора, а иногда вы можете подумать даже о погоде. Поэтому, если вы создаете что-то, что хотели бы использовать повторно, независимо от этих изменений, создание модуля со статическими значениями приведет к сбою. Хотя решение, предложенное @user3819867, очень сырое и очень неэффективное, похоже, решает эту проблему. Что бы я сделал (и на самом деле я рассматриваю это), так это объединил оба подхода — создал улучшенную версию функции для распознавания max и заключил ее в модуль.

Ответ №2:

Я не думаю, что для этого есть функция. Я бы создал библиотеку постоянных значений для каждого типа чисел, тогда вы могли бы ссылаться на это.

Ответ №3:

Для платформы программирования с 32-разрядной артикуляцией: «Dim Item1 As Long», длина переменной составляет 32 бита. Это означает, что каждая длинная затемненная переменная является 32-разрядной. максимальное значение, которое он может содержать (положительное или отрицательное), составляет чуть более 2 миллиардов.

     Sub sumall() 
    Dim firstRow As long
   firstRow = 5
   Dim lastRow Aslong
   lastRow = 12
  Dim aRow As long
  Dim sumall As Variant
  Dim sumResult As Variant
  sumResult = 0
  Dim previousValue As Variant

  previousValue = -1
  For aRow = firstRow To lastRow
    If Cells(aRow, 2).Value <> previousValue Then
        sumResult = Cells(aRow, 2).Value
        previousValue = Cells(aRow, 2)
    End If
  Next aRow
sumall = sumResult
End Sub
 

Другим вариантом для tasc было бы использовать scriptingDictionary для получения только уникальных значений:

                 Sub sumall()
                Dim objDictionary As Object
                Dim firstRow As Long
                firstRow = 5
                Dim lastRow As Long
                lastRow = 12
                Dim aRow As Variant
                Dim varKey As Variant
                Dim sumResult As Variant


                Set objDictionary = CreateObject("Scripting.Dictionary")

                For aRow = firstRow To lastRow
                        If objDictionary.exists(Cells(aRow, 2).Value) = False Then
                        objDictionary.Add Cells(aRow, 2).Value, True
                        End If

                Next aRow
                sumResult = 0
                For Each varKey In objDictionary.keys
                sumResult = varKey   sumResult
                Next varKey

                End Sub
 

Комментарии:

1. это будет выглядеть намного лучше, если вы исправите свой отступ

Ответ №4:

 Sub highlong()
Dim x As Long
On Error GoTo Prt
Do While True
   x = x   1
Loop
Prt:
   MsgBox (x)
End Sub
 

Что бы ни плавало в вашей лодке.